/// <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); }
/// <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; for (int i = 0; i < txs.Length; i++) { if (!_txValidator.IsWellFormed(txs[i], _specProvider.GetSpec(block.Number))) { if (_logger.IsDebug) { _logger.Debug($"Invalid block ({block.ToString(Block.Format.FullHashAndNumber)}) - invalid transaction ({txs[i].Hash})"); } return(false); } } if (!_ommersValidator.Validate(block.Header, block.Ommers)) { _logger?.Debug($"Invalid block ({block.ToString(Block.Format.FullHashAndNumber)}) - invalid ommers"); 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); } if (block.Header.OmmersHash != Keccak.Compute(Rlp.Encode(block.Ommers))) { _logger?.Debug($"Invalid block ({block.ToString(Block.Format.FullHashAndNumber)}) - invalid ommers hash"); return(false); } Keccak txRoot = block.CalculateTxRoot(); if (txRoot != block.Header.TransactionsRoot) { if (_logger.IsDebug) { _logger.Debug($"Invalid block ({block.ToString(Block.Format.FullHashAndNumber)}) tx root {txRoot} != stated tx root {block.Header.TransactionsRoot}"); } return(false); } return(true); }
public AcceptTxResult Accept(Transaction tx, TxHandlingOptions txHandlingOptions) { IReleaseSpec spec = _specProvider.GetCurrentHeadSpec(); if (!_txValidator.IsWellFormed(tx, spec)) { // It may happen that other nodes send us transactions that were signed for another chain or don't have enough gas. if (_logger.IsTrace) { _logger.Trace($"Skipped adding transaction {tx.ToString(" ")}, invalid transaction."); } return(AcceptTxResult.Invalid); } return(AcceptTxResult.Accepted); }