From 87f893265dcea666f42a7dd39873af847f906830 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 1 Mar 2018 19:55:24 +0100 Subject: [PATCH] fix for verify_block_basic crashing on invalid transaction rlp (#8032) --- ethcore/src/verification/verification.rs | 33 +++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 5b09c201f..ab1d11fd1 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -37,7 +37,7 @@ use client::BlockChainClient; use engines::EthEngine; use error::{BlockError, Error}; use header::{BlockNumber, Header}; -use transaction::SignedTransaction; +use transaction::{SignedTransaction, UnverifiedTransaction}; use views::BlockView; /// Preprocessed block data gathered in `verify_block_unordered` call @@ -68,11 +68,9 @@ pub fn verify_block_basic(header: &Header, bytes: &[u8], engine: &EthEngine) -> verify_header_params(&u, engine, false)?; engine.verify_block_basic(&u)?; } - // Verify transactions. - // TODO: either use transaction views or cache the decoded transactions. - let v = BlockView::new(bytes); - for t in v.transactions() { - engine.verify_transaction_basic(&t, &header)?; + + for t in UntrustedRlp::new(bytes).at(1)?.iter().map(|rlp| rlp.as_val::()) { + engine.verify_transaction_basic(&t?, &header)?; } Ok(()) } @@ -348,6 +346,8 @@ mod tests { use time::get_time; use transaction::{SignedTransaction, Transaction, UnverifiedTransaction, Action}; use types::log_entry::{LogEntry, LocalizedLogEntry}; + use rlp; + use triehash::ordered_trie_root; fn check_ok(result: Result<(), Error>) { result.unwrap_or_else(|e| panic!("Block verification failed: {:?}", e)); @@ -501,6 +501,27 @@ mod tests { Ok(()) } + #[test] + fn test_verify_block_basic_with_invalid_transactions() { + let spec = Spec::new_test(); + let engine = &*spec.engine; + + let block = { + let mut rlp = rlp::RlpStream::new_list(3); + let mut header = Header::default(); + // that's an invalid transaction list rlp + let invalid_transactions = vec![vec![0u8]]; + header.set_transactions_root(ordered_trie_root(&invalid_transactions)); + header.set_gas_limit(engine.params().min_gas_limit); + rlp.append(&header); + rlp.append_list::, _>(&invalid_transactions); + rlp.append_raw(&rlp::EMPTY_LIST_RLP, 1); + rlp.out() + }; + + assert!(basic_test(&block, engine).is_err()); + } + #[test] fn test_verify_block() { use rlp::RlpStream;