public Signature Sign(BlockHeader block, EcdsaKeyPair keyPair) { return(Crypto.SignHashed( block.Keccak().ToBytes(), keyPair.PrivateKey.Encode(), HardforkHeights.IsHardfork_9Active(block.Index) ).ToSignature(HardforkHeights.IsHardfork_9Active(block.Index))); }
private JObject VerifyRawTransaction(string rawTransaction, string signature) { var transaction = Transaction.Parser.ParseFrom(rawTransaction.HexToBytes()); if (!transaction.ToByteArray().SequenceEqual(rawTransaction.HexToBytes())) { throw new Exception("Failed to validate serialized and deserialized transactions"); } var useNewChainId = HardforkHeights.IsHardfork_9Active(_stateManager.LastApprovedSnapshot.Blocks.GetTotalBlockHeight() + 1); var s = signature.HexToBytes().ToSignature(useNewChainId); var txHash = transaction.FullHash(s, useNewChainId); var json = new JObject { ["hash"] = txHash.ToHex() }; var accepted = new TransactionReceipt { Transaction = transaction, Hash = txHash, Signature = s }; var result = _transactionManager.Verify(accepted, useNewChainId); json["result"] = result.ToString(); if (result != OperatingError.Ok) { json["status"] = false; } else { json["status"] = true; } return(json); }
public ExecutionStatus GetDeployHeight(UInt160 contractAddress, SystemContractExecutionFrame frame) { frame.ReturnValue = new byte[64]; try { if (HardforkHeights.IsHardfork_3Active(frame.InvocationContext.Snapshot.Blocks.GetTotalBlockHeight())) { if (HardforkHeights.IsHardfork_6Active( frame.InvocationContext.Snapshot.Blocks.GetTotalBlockHeight())) { frame.ReturnValue = _deployHeight.GetValue(contractAddress.ToBytes()) ?? new byte[64]; } else { frame.ReturnValue = _deployHeight.GetValue(contractAddress.ToBytes()); } } } catch (Exception e) { Logger.LogInformation($"Exception while get deploy height: {e}"); } return(ExecutionStatus.Ok); }
// changed from private to public: GetBlockByNumber() , GetBlockRawByNumber(), GetBlockByHash() public void Test_Web3Block() { ulong total = 1; GenerateBlocksWithGenesis(total); bool fullTx = false; var tx = GiveMeSomeMoney(Money.Parse("100000").ToUInt256(), HardforkHeights.IsHardfork_9Active(1)); var txList = new List <TransactionReceipt> (); txList.Add(tx); AddBatchTransactionToPool(txList, false); total++; GenerateBlocks(1, total); CheckBlockWeb3Format("latest", (ulong)total, fullTx); var randomTxList = GetRandomTransactionBatch(10, HardforkHeights.IsHardfork_9Active(2)); var topUpTxList = TopUpBalanceTxBatch(randomTxList, "10", HardforkHeights.IsHardfork_9Active(2)); AddBatchTransactionToPool(topUpTxList, false); total++; GenerateBlocks(1, total); CheckBlockWeb3Format("latest", (ulong)total, fullTx); AddBatchTransactionToPool(randomTxList, false); total++; GenerateBlocks(1, total); CheckBlockWeb3Format("latest", (ulong)total, fullTx); CheckBlockWeb3Format("earliest", 0, fullTx); CheckBlockWeb3Format("pending", (ulong)total + 1, fullTx); ulong someBlockNumber = 100; CheckBlockWeb3Format(someBlockNumber.ToHex(), someBlockNumber, fullTx); }
private void Check_Random_Address_Storage_Changing() { var randomTx = TestUtils.GetRandomTransaction(HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1)); var balance = randomTx.Transaction.Value; var allowance = balance; var receiver = randomTx.Transaction.From; var tx1 = TopUpBalanceTx(receiver, balance, 0, HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1)); var tx2 = ApproveTx(receiver, allowance, 0, HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1)); var owner = tx2.Transaction.From; var blockTxs = new[] { tx1, tx2 }; var topUpBlock = BuildNextBlock(blockTxs); ExecuteBlock(topUpBlock, blockTxs); var storedBalance = _stateManager.LastApprovedSnapshot.Balances.GetBalance(receiver); Assert.AreEqual(balance.ToMoney(), storedBalance); var storedAllowance = _stateManager.LastApprovedSnapshot.Storage.GetRawValue( ContractRegisterer.LatokenContract, UInt256Utils.Zero.Buffer.Concat(owner.ToBytes().Concat(receiver.ToBytes())) ).ToUInt256().ToMoney(); Assert.AreEqual(allowance.ToMoney(), storedAllowance); }
public void Test_Block_Execution() { _blockManager.TryBuildGenesisBlock(); var block = BuildNextBlock(); var result = ExecuteBlock(block); Assert.AreEqual(OperatingError.Ok, result); // using new chain id Assert.IsFalse(HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight())); while (!HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight())) { block = BuildNextBlock(); result = ExecuteBlock(block); Assert.AreEqual(OperatingError.Ok, result); } int total = 100; for (var it = 0; it < total; it++) { block = BuildNextBlock(); result = ExecuteBlock(block); Assert.AreEqual(OperatingError.Ok, result); } }
private TransactionReceipt BuildSystemContractTxReceipt(ulong blockIndex, UInt160 contractAddress, string methodSignature) { var nonce = _stateManager.LastApprovedSnapshot.Transactions.GetTotalTransactionCount(UInt160Utils.Zero); var abi = ContractEncoder.Encode(methodSignature); var tx = new Transaction { To = contractAddress, Value = UInt256Utils.Zero, From = UInt160Utils.Zero, Nonce = nonce, GasPrice = 0, /* TODO: gas estimation */ GasLimit = 100000000, Invocation = ByteString.CopyFrom(abi), }; return(HardforkHeights.IsHardfork_9Active(blockIndex) ? new TransactionReceipt { Hash = tx.FullHash(SignatureUtils.ZeroNew, true), Status = TransactionStatus.Pool, Transaction = tx, Signature = SignatureUtils.ZeroNew, } : new TransactionReceipt { Hash = tx.FullHash(SignatureUtils.ZeroOld, false), Status = TransactionStatus.Pool, Transaction = tx, Signature = SignatureUtils.ZeroOld, }); }
public void Test_StakeWithdraw() { _blockManager.TryBuildGenesisBlock(); GenerateBlocks(1, 1); _validatorStatusManager.Start(false); Assert.IsTrue(_validatorStatusManager.IsStarted()); Assert.IsFalse(_validatorStatusManager.IsWithdrawTriggered()); int blockNum = (int)_blockManager.GetHeight(); Assert.IsFalse(HardforkHeights.IsHardfork_9Active((ulong)blockNum)); while (!HardforkHeights.IsHardfork_9Active((ulong)blockNum)) { blockNum++; GenerateBlocks(blockNum, blockNum); } var systemContractReader = _container?.Resolve <ISystemContractReader>() ?? throw new Exception("Container is not loaded"); var stake = new Money(systemContractReader.GetStake()); Console.WriteLine($"Current stake is {stake}"); Assert.That(stake > Money.Zero, "Stake is zero"); _validatorStatusManager.WithdrawStakeAndStop(); Assert.IsTrue(_validatorStatusManager.IsStarted()); Assert.IsTrue(_validatorStatusManager.IsWithdrawTriggered()); // Test node is the only validator, so it is a next validator always // and it can't withdraw its stake. TODO: test to check withdraw is working //GenerateBlocks(50); //Assert.IsFalse(_validatorStatusManager.IsStarted()); }
public void TestTxPoolAdding() { bool useNewChainId = HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1); var tx = TestUtils.GetRandomTransaction(useNewChainId); var result = _transactionPool.Add(tx); Assert.AreEqual(OperatingError.InsufficientBalance, result); _stateManager.LastApprovedSnapshot.Balances.AddBalance(tx.Transaction.From, Money.Parse("1000")); result = _transactionPool.Add(tx); Assert.AreEqual(OperatingError.Ok, result); result = _transactionPool.Add(tx); Assert.AreEqual(OperatingError.AlreadyExists, result); var tx2 = TestUtils.GetRandomTransaction(useNewChainId); tx2.Transaction.Nonce++; result = _transactionPool.Add(tx2); Assert.AreEqual(OperatingError.InvalidNonce, result); /* TODO: maybe we should fix this strange behaviour */ var tx3 = TestUtils.GetRandomTransaction(useNewChainId); tx3.Transaction.From = UInt160Utils.Zero; tx3.Transaction.Nonce = _transactionPool.GetNextNonceForAddress(UInt160Utils.Zero); result = _transactionPool.Add(tx3); Assert.AreEqual(OperatingError.Ok, result); }
private TransactionReceipt FinishCycleTxReceipt(ulong blockIndex) { var tx = _transactionBuilder.InvokeTransactionWithGasPrice( UInt160Utils.Zero, ContractRegisterer.GovernanceContract, Utility.Money.Zero, GovernanceInterface.MethodFinishCycle, 0, UInt256Utils.ToUInt256(GovernanceContract.GetCycleByBlockNumber(_blockManager.GetHeight())) ); return(HardforkHeights.IsHardfork_9Active(blockIndex) ? new TransactionReceipt { Hash = tx.FullHash(SignatureUtils.ZeroNew, true), Status = TransactionStatus.Pool, Transaction = tx, Signature = SignatureUtils.ZeroNew, } : new TransactionReceipt { Hash = tx.FullHash(SignatureUtils.ZeroOld, false), Status = TransactionStatus.Pool, Transaction = tx, Signature = SignatureUtils.ZeroOld, }); }
// Changed GetTransactionCount to public public void Test_GetTransactionCount_latest() { _blockManager.TryBuildGenesisBlock(); var tx = TestUtils.GetRandomTransaction(HardforkHeights.IsHardfork_9Active(1)); // adding balance so that it's transaction is added to the pool _stateManager.LastApprovedSnapshot.Balances.AddBalance(tx.Transaction.From, Money.Parse("1000")); var txCountBefore = _apiService !.GetTransactionCount(tx.Transaction.From.ToHex(), "latest").HexToUlong(); Assert.AreEqual(txCountBefore, 0); var result = _transactionPool.Add(tx); Assert.AreEqual(OperatingError.Ok, result); GenerateBlocks(1); var txCountAfter = _apiService !.GetTransactionCount(tx.Transaction.From.ToHex(), "latest").HexToUlong(); Assert.AreEqual(txCountAfter, 1); }
public ExecutionStatus Deploy(byte[] byteCode, SystemContractExecutionFrame frame) { if (HardforkHeights.IsHardfork_2Active(frame.InvocationContext.Snapshot.Blocks.GetTotalBlockHeight())) { return(DeployV2(byteCode, frame)); } return(DeployV1(byteCode, frame)); }
public OperatingError VerifySignature(BlockHeader blockHeader, Signature signature, ECDSAPublicKey publicKey) { var result = Crypto.VerifySignatureHashed( blockHeader.Keccak().ToBytes(), signature.Encode(), publicKey.EncodeCompressed(), HardforkHeights.IsHardfork_9Active(blockHeader.Index) ); return(result ? OperatingError.Ok : OperatingError.InvalidSignature); }
public string SignTransaction(string[] arguments) { var to = arguments[1].HexToUInt160(); var value = Money.Parse(arguments[2]); var from = _keyPair.PublicKey.GetAddress(); var tx = _transactionBuilder.TransferTransaction(from, to, value); var signedTx = _transactionSigner.Sign(tx, _keyPair, HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1)); return(signedTx.Signature.ToString()); }
public void Test_EventFormat() { _blockManager.TryBuildGenesisBlock(); TestEventFormat(); Assert.IsFalse(HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight())); while (!HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight())) { GenerateBlocks(1); } TestEventFormat(); }
public void Test_MessageSender() { TestMessageSender(1); int blockNum = (int)_blockManager.GetHeight(); Assert.IsFalse(HardforkHeights.IsHardfork_9Active((ulong)blockNum)); while (!HardforkHeights.IsHardfork_9Active((ulong)blockNum)) { GenerateBlock(blockNum + 1); blockNum++; } TestMessageSender(blockNum + 1); }
//changed GetTransactionReceipt from private to public public void Test_GetTransactionReceipt() { _blockManager.TryBuildGenesisBlock(); var tx = TestUtils.GetRandomTransaction(HardforkHeights.IsHardfork_9Active(1)); _stateManager.LastApprovedSnapshot.Balances.AddBalance(tx.Transaction.From, Money.Parse("1000")); var result = _transactionPool.Add(tx); Assert.AreEqual(OperatingError.Ok, result); GenerateBlocks(1, 1); var txHashSent = tx.Hash.ToHex(); var txReceipt = _apiService.GetTransactionReceipt(txHashSent); var txHashReceived = txReceipt !["transactionHash"] !.ToString();
public void Test_Tx_Pool_Adding() { TestTxPoolAdding(); _blockManager.TryBuildGenesisBlock(); Assert.IsFalse(HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight())); while (!HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight())) { var block = BuildNextBlock(); var result = ExecuteBlock(block); Assert.AreEqual(OperatingError.Ok, result); } TestTxPoolAdding(); }
private void AddTxToPool(Transaction tx) { var useNewChainId = HardforkHeights.IsHardfork_9Active(_stateManager.LastApprovedSnapshot.Blocks.GetTotalBlockHeight() + 1); var receipt = _transactionSigner.Sign(tx, _privateWallet.EcdsaKeyPair, useNewChainId); _sendingTxHash = tx.FullHash(receipt.Signature, useNewChainId); var result = _transactionPool.Add(receipt); Logger.LogDebug(result == OperatingError.Ok ? $"Transaction successfully submitted: {receipt.Hash.ToHex()}" : $"Cannot add tx to pool: {result}"); }
public BlockWithTransactions Build() { if (_genesisBlock != null) { return(_genesisBlock); } var genesisConfig = _configManager.GetConfig <GenesisConfig>("genesis") ?? throw new InvalidOperationException("No genesis config found"); var fromAddress = UInt160Utils.Zero; // mint initial tokens from zero address var balances = genesisConfig !.Balances .OrderBy(x => x.Key) .ToArray(); var genesisTransactions = balances.Select((t, i) => new Transaction { From = fromAddress, Nonce = (ulong)i, Value = Money.Parse(t.Value).ToUInt256(), To = t.Key.HexToUInt160(), GasPrice = 0, }) .Select(tx => new TransactionReceipt { Transaction = tx, Hash = HardforkHeights.IsHardfork_9Active(0) ? tx.FullHash(SignatureUtils.ZeroNew, true) : tx.FullHash(SignatureUtils.ZeroOld, false), Signature = HardforkHeights.IsHardfork_9Active(0) ? SignatureUtils.ZeroNew : SignatureUtils.ZeroOld, }) .ToList(); var txHashes = genesisTransactions.Select(tx => tx.Hash).ToArray(); var header = new BlockHeader { PrevBlockHash = UInt256Utils.Zero, MerkleRoot = MerkleTree.ComputeRoot(txHashes) ?? UInt256Utils.Zero, Index = 0, StateHash = UInt256Utils.Zero, Nonce = GenesisConsensusData }; var result = new Block { Hash = header.Keccak(), TransactionHashes = { txHashes }, Header = header }; _genesisBlock = new BlockWithTransactions(result, genesisTransactions.ToArray()); return(_genesisBlock); }
// Changed GetCode to public public void Test_GetCode_blockId() { _blockManager.TryBuildGenesisBlock(); var rawTx2 = MakeDummyTx(HardforkHeights.IsHardfork_9Active(1)); ExecuteDummyTransaction(true, rawTx2); var address = "0x9210567c1f79e9e9c3634331158d3143e572c001"; var adCode = _apiService !.GetCode(address, "0x1"); Assert.AreEqual(adCode, ""); }
public void Test_Tx_Pool_Replacement() { _blockManager.TryBuildGenesisBlock(); TestTxPoolAdding(); var privateKey = Crypto.GeneratePrivateKey().ToPrivateKey(); var keyPair = new EcdsaKeyPair(privateKey); AddRandomTxesToPool(keyPair, out var randomTxes); var rnd = new Random(); randomTxes = randomTxes.OrderBy(item => rnd.Next()).ToList(); bool useNewChainId = HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1); var signer = new TransactionSigner(); foreach (var tx in randomTxes) { Console.WriteLine($"nonce: {tx.Transaction.Nonce}"); var newTx = new Transaction(tx.Transaction); // lower price newTx.GasPrice = tx.Transaction.GasPrice - 1; var randomTx = TestUtils.GetRandomTransaction(useNewChainId).Transaction; newTx.To = randomTx.To; newTx.Value = randomTx.Value; newTx.GasLimit = randomTx.GasLimit; var newTxReceipt = signer.Sign(newTx, keyPair, useNewChainId); var result = _transactionPool.Add(newTxReceipt); Console.WriteLine($"old gas price: {tx.Transaction.GasPrice}, new gas price: {newTxReceipt.Transaction.GasPrice}"); Assert.AreEqual(OperatingError.Underpriced, result); // equal price newTx.GasPrice = tx.Transaction.GasPrice; newTxReceipt = signer.Sign(newTx, keyPair, useNewChainId); result = _transactionPool.Add(newTxReceipt); Console.WriteLine($"old gas price: {tx.Transaction.GasPrice}, new gas price: {newTxReceipt.Transaction.GasPrice}"); Assert.AreEqual(OperatingError.Underpriced, result); // higher price newTx.GasPrice = tx.Transaction.GasPrice + 1; newTxReceipt = signer.Sign(newTx, keyPair, useNewChainId); result = _transactionPool.Add(newTxReceipt); Console.WriteLine($"old gas price: {tx.Transaction.GasPrice}, new gas price: {newTxReceipt.Transaction.GasPrice}"); Assert.AreEqual(OperatingError.DuplicatedTransaction, result); // higher price and all fields same newTx = new Transaction(tx.Transaction); newTx.GasPrice = tx.Transaction.GasPrice + 1; newTxReceipt = signer.Sign(newTx, keyPair, useNewChainId); result = _transactionPool.Add(newTxReceipt); Console.WriteLine($"old gas price: {tx.Transaction.GasPrice}, new gas price: {newTxReceipt.Transaction.GasPrice}"); Assert.AreEqual(OperatingError.Ok, result); } }
public OperatingError Add(Transaction transaction, Signature signature, bool notify = true) { var acceptedTx = new TransactionReceipt { Transaction = transaction, // we use next height here because block header should be signed with the same chainId // and this txes will go to the next block Hash = transaction.FullHash(signature, HardforkHeights.IsHardfork_9Active(BlockHeight() + 1)), Signature = signature, Status = TransactionStatus.Pool }; return(Add(acceptedTx, notify)); }
public string?SendRawTransaction(string[] arguments) { if (arguments.Length != 3) { return(null); } bool useNewChainId = HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1); var rawTx = arguments[1].HexToBytes(); var tx = Transaction.Parser.ParseFrom(rawTx); var sig = arguments[2].HexToBytes().ToSignature(useNewChainId); var result = _transactionPool.Add(tx, sig); Console.WriteLine($"Status: {result}"); return($"{tx.FullHash(sig, useNewChainId).ToHex()}"); }
public void Test_Storage_Changing() { _blockManager.TryBuildGenesisBlock(); Check_Random_Address_Storage_Changing(); // using new chain id Assert.IsFalse(HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight())); while (!HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight())) { var block = BuildNextBlock(); var result = ExecuteBlock(block); Assert.AreEqual(OperatingError.Ok, result); } Check_Random_Address_Storage_Changing(); }
public void AddRandomTxesToPool(EcdsaKeyPair keyPair, out List <TransactionReceipt> txes) { bool useNewChainId = HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1); var txCount = 100; txes = new List <TransactionReceipt>(); _stateManager.LastApprovedSnapshot.Balances.AddBalance(keyPair.PublicKey.GetAddress(), Money.Parse("1000")); for (var i = 0; i < txCount; i++) { var tx = TestUtils.GetRandomTransactionFromAddress(keyPair, (ulong)i, useNewChainId); var result = _transactionPool.Add(tx); Assert.AreEqual(OperatingError.Ok, result); txes.Add(tx); } }
public OperatingError VerifySignatures(Block block, bool checkValidatorSet) { if (!block.Header.Keccak().Equals(block.Hash)) { return(OperatingError.HashMismatched); } if (_IsGenesisBlock(block)) { return(OperatingError.Ok); } if (checkValidatorSet && !VerifyValidatorSet(block.Multisig.Validators, block.Header.Index - 1)) { return(OperatingError.InvalidMultisig); } return(_multisigVerifier.VerifyMultisig(block.Multisig, block.Hash, HardforkHeights.IsHardfork_9Active(block.Header.Index))); }
private ExecutionStatus DeployV1(byte[] byteCode, SystemContractExecutionFrame frame) { Logger.LogInformation($"Deploy({byteCode.ToHex()})"); frame.ReturnValue = Array.Empty <byte>(); frame.UseGas(checked (GasMetering.DeployCost + GasMetering.DeployCostPerByte * (ulong)byteCode.Length)); var receipt = _context.Receipt ?? throw new InvalidOperationException(); // calculate contract hash and register it // the contractAddress at which the bytecode will be stored as calculated // from the sender address (To) and its nonce. var hash = UInt160Utils.Zero.ToBytes().Ripemd(); if (receipt.Transaction?.From != null) { hash = receipt.Transaction.From.ToBytes() .Concat(receipt.Transaction.Nonce.ToBytes()) .Ripemd(); } var contract = new Contract(hash, byteCode); if (!VirtualMachine.VerifyContract(contract.ByteCode, false)) { Logger.LogInformation("Failed to verify contract"); return(ExecutionStatus.ExecutionHalted); } try { _context.Snapshot.Contracts.AddContract(_context.Sender, new Contract(hash, contract.ByteCode)); Logger.LogInformation($"New contract with address {hash.ToHex()} deployed"); if (HardforkHeights.IsHardfork_3Active(frame.InvocationContext.Snapshot.Blocks.GetTotalBlockHeight())) { _deployHeight.SetValue(hash.ToBytes(), frame.InvocationContext.Snapshot.Blocks.GetTotalBlockHeight().ToBytes().ToArray()); } } catch (OutOfGasException e) { Logger.LogInformation("Out of gas"); frame.UseGas(e.GasUsed); return(ExecutionStatus.GasOverflow); } return(ExecutionStatus.Ok); }
public void Test_Block_With_Txs_Execution() { _blockManager.TryBuildGenesisBlock(); var topUpReceipts = new List <TransactionReceipt>(); var randomReceipts = new List <TransactionReceipt>(); var txCount = 50; var coverTxFeeAmount = Money.Parse("10.0"); for (var i = 0; i < txCount; i++) { var tx = TestUtils.GetRandomTransaction(HardforkHeights.IsHardfork_9Active(2)); randomReceipts.Add(tx); topUpReceipts.Add(TopUpBalanceTx(tx.Transaction.From, (tx.Transaction.Value.ToMoney() + coverTxFeeAmount).ToUInt256(), i, HardforkHeights.IsHardfork_9Active(1))); } ExecuteTxesInSeveralBlocks(topUpReceipts); ExecuteTxesInSeveralBlocks(randomReceipts); // building random txes for new chain id. will send TopUpTx right now. Assert.IsFalse(HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight())); txCount = 50; topUpReceipts = new List <TransactionReceipt>(); randomReceipts = new List <TransactionReceipt>(); coverTxFeeAmount = Money.Parse("0.0000000001"); Console.WriteLine(Money.Wei.ToString()); for (var i = 0; i < txCount; i++) { var tx = TestUtils.GetCustomTransaction("0", Money.Wei.ToString(), true); randomReceipts.Add(tx); topUpReceipts.Add(TopUpBalanceTx(tx.Transaction.From, (tx.Transaction.Value.ToMoney() + coverTxFeeAmount).ToUInt256(), i, HardforkHeights.IsHardfork_9Active(3))); } ExecuteTxesInSeveralBlocks(topUpReceipts); while (!HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight())) { var block = BuildNextBlock(); var result = ExecuteBlock(block); Assert.AreEqual(OperatingError.Ok, result); } ExecuteTxesInSeveralBlocks(randomReceipts); }
public uint HandleTransactionsFromPeer(IEnumerable <TransactionReceipt> transactions, ECDSAPublicKey publicKey) { lock (_txLock) { var txs = transactions.ToArray(); Logger.LogTrace($"Received {txs.Length} transactions from peer {publicKey.ToHex()}"); var persisted = 0u; foreach (var tx in txs) { if (tx.Signature.IsZero()) { Logger.LogTrace($"Received zero-signature transaction: {tx.Hash.ToHex()}"); if (_transactionPool.Add(tx, false) == OperatingError.Ok) { persisted++; } continue; } var error = _transactionManager.Verify(tx, HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1)); if (error != OperatingError.Ok) { Logger.LogTrace($"Unable to verify transaction: {tx.Hash.ToHex()} ({error})"); continue; } error = _transactionPool.Add(tx, false); if (error == OperatingError.Ok) { persisted++; } else { Logger.LogTrace($"Transaction {tx.Hash.ToHex()} not persisted: {error}"); } } lock (_peerHasTransactions) Monitor.PulseAll(_peerHasTransactions); Logger.LogTrace($"Persisted {persisted} transactions from peer {publicKey.ToHex()}"); return(persisted); } }