public void Can_calculate_root() { Block block = Build.A.Block.WithTransactions(Build.A.Transaction.TestObject).TestObject; TxTrie txTrie = new TxTrie(block.Transactions); Assert.AreEqual("0x29cc403075ed3d1d6af940d577125cc378ee5a26f7746cbaf87f1cf4a38258b5", txTrie.RootHash.ToString()); }
/// <summary> /// Suggested block validation runs basic checks that can be executed before going through the expensive EVM processing. /// </summary> /// <param name="block">A block to validate</param> /// <returns><value>True</value> if the <paramref name="block"/> is valid, otherwise <value>False</value></returns> public bool ValidateSuggestedBlock(Block block) { Transaction[] txs = block.Transactions; IReleaseSpec spec = _specProvider.GetSpec(block.Number); for (int i = 0; i < txs.Length; i++) { if (!_txValidator.IsWellFormed(txs[i], spec)) { if (_logger.IsDebug) { _logger.Debug($"Invalid block ({block.ToString(Block.Format.FullHashAndNumber)}) - invalid transaction ({txs[i].Hash})"); } return(false); } } if (spec.MaximumUncleCount < block.Ommers.Length) { _logger.Debug($"Invalid block ({block.ToString(Block.Format.FullHashAndNumber)}) - uncle count is {block.Ommers.Length} (MAX: {spec.MaximumUncleCount})"); return(false); } if (block.Header.OmmersHash != OmmersHash.Calculate(block)) { _logger.Debug($"Invalid block ({block.ToString(Block.Format.FullHashAndNumber)}) - invalid uncles hash"); return(false); } if (!_ommersValidator.Validate(block.Header, block.Ommers)) { _logger.Debug($"Invalid block ({block.ToString(Block.Format.FullHashAndNumber)}) - invalid uncles"); return(false); } bool blockHeaderValid = _headerValidator.Validate(block.Header); if (!blockHeaderValid) { if (_logger.IsDebug) { _logger.Debug($"Invalid block ({block.ToString(Block.Format.FullHashAndNumber)}) - invalid header"); } return(false); } Keccak txRoot = new TxTrie(block.Transactions).RootHash; if (txRoot != block.Header.TxRoot) { if (_logger.IsDebug) { _logger.Debug($"Invalid block ({block.ToString(Block.Format.FullHashAndNumber)}) tx root {txRoot} != stated tx root {block.Header.TxRoot}"); } return(false); } return(true); }
public BlockBuilder WithTransactions(params Transaction[] transactions) { TestObjectInternal.Body = TestObjectInternal.Body.WithChangedTransactions(transactions); TxTrie trie = new TxTrie(transactions, false); trie.UpdateRootHash(); TestObjectInternal.Header.TxRoot = trie.RootHash; return(this); }
public void Can_collect_proof_trie_case_1() { Block block = Build.A.Block.WithTransactions(Build.A.Transaction.TestObject).TestObject; TxTrie txTrie = new TxTrie(block.Transactions, true); byte[][] proof = txTrie.BuildProof(0); txTrie.UpdateRootHash(); VerifyProof(proof, txTrie.RootHash); }
public void Can_collect_proof_with_trie_case_3_modified() { Block block = Build.A.Block.WithTransactions(Enumerable.Repeat(Build.A.Transaction.TestObject, 1000).ToArray()).TestObject; TxTrie txTrie = new TxTrie(block.Transactions, true); txTrie.UpdateRootHash(); for (int i = 0; i < 1000; i++) { byte[][] proof = txTrie.BuildProof(i); VerifyProof(proof, txTrie.RootHash); } }
public void Can_collect_proof_with_trie_case_2() { Block block = Build.A.Block.WithTransactions( _releaseSpec, Build.A.Transaction.TestObject, Build.A.Transaction.TestObject).TestObject; TxTrie txTrie = new TxTrie(block.Transactions, true); byte[][] proof = txTrie.BuildProof(0); Assert.AreEqual(2, proof.Length); txTrie.UpdateRootHash(); VerifyProof(proof, txTrie.RootHash); }
private bool TryPrepareBlock(BlockInfo blockInfo, BlockBody blockBody, out Block?block) { BlockHeader header = _blockTree.FindHeader(blockInfo.BlockHash); bool txRootIsValid = new TxTrie(blockBody.Transactions).RootHash == header.TxRoot; bool ommersHashIsValid = OmmersHash.Calculate(blockBody.Ommers) == header.OmmersHash; if (txRootIsValid && ommersHashIsValid) { block = new Block(header, blockBody); } else { block = null; } return(block != null); }