public void TestDuplicateOracle() { // Fake balance var snapshot = Blockchain.Singleton.GetSnapshot(); ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, null, long.MaxValue); BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, UInt160.Zero); NativeContract.GAS.Burn(engine, UInt160.Zero, balance); NativeContract.GAS.Mint(engine, UInt160.Zero, 8, false); // Test TransactionVerificationContext verificationContext = new TransactionVerificationContext(); var tx = CreateTransactionWithFee(1, 2); tx.Attributes = new TransactionAttribute[] { new OracleResponse() { Code = OracleResponseCode.ConsensusUnreachable, Id = 1, Result = new byte[0] } }; verificationContext.CheckTransaction(tx, snapshot).Should().BeTrue(); verificationContext.AddTransaction(tx); tx = CreateTransactionWithFee(2, 1); tx.Attributes = new TransactionAttribute[] { new OracleResponse() { Code = OracleResponseCode.ConsensusUnreachable, Id = 1, Result = new byte[0] } }; verificationContext.CheckTransaction(tx, snapshot).Should().BeFalse(); }
async Task <UInt256> SubmitTransactionAsync(Transaction tx) { if (disposedValue) { throw new ObjectDisposedException(nameof(OfflineNode)); } var transactions = new[] { tx }; // Verify the provided transactions. When running, Blockchain class does verification in two steps: VerifyStateIndependent and VerifyStateDependent. // However, Verify does both parts and there's no point in verifying dependent/independent in separate steps here var verificationContext = new TransactionVerificationContext(); for (int i = 0; i < transactions.Length; i++) { if (transactions[i].Verify(neoSystem.Settings, neoSystem.StoreView, verificationContext) != VerifyResult.Succeed) { throw new Exception("Verification failed"); } } var prevHash = NativeContract.Ledger.CurrentHash(neoSystem.StoreView); var prevHeader = NativeContract.Ledger.GetHeader(neoSystem.StoreView, prevHash); var block = ExpressOracle.CreateSignedBlock(prevHeader, consensusNodesKeys.Value, neoSystem.Settings.Network, transactions); await RelayBlockAsync(block).ConfigureAwait(false); return(block.Hash); }
/// <summary> /// Prevent that block exceed the max size /// </summary> /// <param name="txs">Ordered transactions</param> internal void EnsureMaxBlockLimitation(IEnumerable <Transaction> txs) { uint maxBlockSize = NativeContract.Policy.GetMaxBlockSize(Snapshot); long maxBlockSystemFee = NativeContract.Policy.GetMaxBlockSystemFee(Snapshot); uint maxTransactionsPerBlock = NativeContract.Policy.GetMaxTransactionsPerBlock(Snapshot); // Limit Speaker proposal to the limit `MaxTransactionsPerBlock` or all available transactions of the mempool txs = txs.Take((int)maxTransactionsPerBlock); List <UInt256> hashes = new List <UInt256>(); Transactions = new Dictionary <UInt256, Transaction>(); VerificationContext = new TransactionVerificationContext(); // Expected block size var blockSize = GetExpectedBlockSizeWithoutTransactions(txs.Count()); var blockSystemFee = 0L; // Iterate transaction until reach the size or maximum system fee foreach (Transaction tx in txs) { // Check if maximum block size has been already exceeded with the current selected set blockSize += tx.Size; if (blockSize > maxBlockSize) { break; } // Check if maximum block system fee has been already exceeded with the current selected set blockSystemFee += tx.SystemFee; if (blockSystemFee > maxBlockSystemFee) { break; } hashes.Add(tx.Hash); Transactions.Add(tx.Hash, tx); VerificationContext.AddTransaction(tx); } TransactionHashes = hashes.ToArray(); }
public void Deserialize(BinaryReader reader) { Reset(0); if (reader.ReadUInt32() != Block.Version) { throw new FormatException(); } if (reader.ReadUInt32() != Block.Index) { throw new InvalidOperationException(); } Block.Timestamp = reader.ReadUInt64(); Block.NextConsensus = reader.ReadSerializable <UInt160>(); if (Block.NextConsensus.Equals(UInt160.Zero)) { Block.NextConsensus = null; } Block.ConsensusData = reader.ReadSerializable <ConsensusData>(); ViewNumber = reader.ReadByte(); TransactionHashes = reader.ReadSerializableArray <UInt256>(); Transaction[] transactions = reader.ReadSerializableArray <Transaction>(Block.MaxTransactionsPerBlock); PreparationPayloads = reader.ReadNullableArray <ExtensiblePayload>(ProtocolSettings.Default.ValidatorsCount); CommitPayloads = reader.ReadNullableArray <ExtensiblePayload>(ProtocolSettings.Default.ValidatorsCount); ChangeViewPayloads = reader.ReadNullableArray <ExtensiblePayload>(ProtocolSettings.Default.ValidatorsCount); LastChangeViewPayloads = reader.ReadNullableArray <ExtensiblePayload>(ProtocolSettings.Default.ValidatorsCount); if (TransactionHashes.Length == 0 && !RequestSentOrReceived) { TransactionHashes = null; } Transactions = transactions.Length == 0 && !RequestSentOrReceived ? null : transactions.ToDictionary(p => p.Hash); VerificationContext = new TransactionVerificationContext(); if (Transactions != null) { foreach (Transaction tx in Transactions.Values) { VerificationContext.AddTransaction(tx); } } }
public void TestTransactionSenderFee() { var snapshot = Blockchain.Singleton.GetSnapshot(); ApplicationEngine engine = ApplicationEngine.Create(TriggerType.Application, null, snapshot, null, long.MaxValue); BigInteger balance = NativeContract.GAS.BalanceOf(snapshot, UInt160.Zero); NativeContract.GAS.Burn(engine, UInt160.Zero, balance); NativeContract.GAS.Mint(engine, UInt160.Zero, 8, true); TransactionVerificationContext verificationContext = new TransactionVerificationContext(); var tx = CreateTransactionWithFee(1, 2); verificationContext.CheckTransaction(tx, snapshot).Should().BeTrue(); verificationContext.AddTransaction(tx); verificationContext.CheckTransaction(tx, snapshot).Should().BeTrue(); verificationContext.AddTransaction(tx); verificationContext.CheckTransaction(tx, snapshot).Should().BeFalse(); verificationContext.RemoveTransaction(tx); verificationContext.CheckTransaction(tx, snapshot).Should().BeTrue(); verificationContext.AddTransaction(tx); verificationContext.CheckTransaction(tx, snapshot).Should().BeFalse(); }
Block CreateSignedBlock(Transaction[] transactions) { // The logic in this method is distilled from ConsensusService/ConsensusContext + MemPool tx verification logic var snapshot = neoSystem.StoreView; // Verify the provided transactions. When running, Blockchain class does verification in two steps: VerifyStateIndependent and VerifyStateDependent. // However, Verify does both parts and there's no point in verifying dependent/independent in separate steps here var verificationContext = new TransactionVerificationContext(); for (int i = 0; i < transactions.Length; i++) { var q = transactions[i].Size * NativeContract.Policy.GetFeePerByte(snapshot); if (transactions[i].Verify(ProtocolSettings, snapshot, verificationContext) != VerifyResult.Succeed) { throw new Exception("Verification failed"); } } // create the block instance var prevHash = NativeContract.Ledger.CurrentHash(snapshot); var prevBlock = NativeContract.Ledger.GetHeader(snapshot, prevHash); var blockHeight = prevBlock.Index + 1; var block = new Block { Header = new Header { Version = 0, PrevHash = prevHash, MerkleRoot = MerkleTree.ComputeRoot(transactions.Select(t => t.Hash).ToArray()), Timestamp = Math.Max(Neo.Helper.ToTimestampMS(DateTime.UtcNow), prevBlock.Timestamp + 1), Index = blockHeight, PrimaryIndex = 0, NextConsensus = Contract.GetBFTAddress( NeoToken.ShouldRefreshCommittee(blockHeight, ProtocolSettings.CommitteeMembersCount) ? NativeContract.NEO.ComputeNextBlockValidators(snapshot, ProtocolSettings) : NativeContract.NEO.GetNextBlockValidators(snapshot, ProtocolSettings.ValidatorsCount)), }, Transactions = transactions }; // retrieve the validators for the next block. Logic lifted from ConensusContext.Reset var validators = NativeContract.NEO.GetNextBlockValidators(snapshot, ProtocolSettings.ValidatorsCount); var m = validators.Length - (validators.Length - 1) / 3; // generate the block header witness. Logic lifted from ConsensusContext.CreateBlock var contract = Contract.CreateMultiSigContract(m, validators); var signingContext = new ContractParametersContext(snapshot, block.Header, ProtocolSettings.Network); for (int i = 0, j = 0; i < validators.Length && j < m; i++) { var key = consensusNodesKeys.Value.SingleOrDefault(k => k.PublicKey.Equals(validators[i])); if (key == null) { continue; } var signature = block.Header.Sign(key, ProtocolSettings.Network); signingContext.AddSignature(contract, validators[i], signature); j++; } if (!signingContext.Completed) { throw new Exception("block signing incomplete"); } block.Header.Witness = signingContext.GetWitnesses()[0]; return(block); }