diff --git a/crates/executor/Cargo.toml b/crates/executor/Cargo.toml index 8eb3a72f89..c57347abf5 100644 --- a/crates/executor/Cargo.toml +++ b/crates/executor/Cargo.toml @@ -34,6 +34,7 @@ tokio = { version = "1.21.2", features = ["sync"] } # mics aquamarine = "0.3.0" +parking_lot = { version = "0.12", optional = true } triehash = "0.8" # See to replace hashers to simplify libraries @@ -51,3 +52,6 @@ reth-interfaces = { path = "../interfaces", features = ["test-utils"] } reth-primitives = { path = "../primitives", features = ["test-utils"] } reth-provider = { path = "../storage/provider", features = ["test-utils"] } parking_lot = "0.12" + +[features] +test-utils = ["parking_lot"] diff --git a/crates/executor/src/blockchain_tree/mod.rs b/crates/executor/src/blockchain_tree/mod.rs index 984b4d0517..521111ea84 100644 --- a/crates/executor/src/blockchain_tree/mod.rs +++ b/crates/executor/src/blockchain_tree/mod.rs @@ -631,73 +631,21 @@ impl BlockchainTree #[cfg(test)] mod tests { use super::*; - use parking_lot::Mutex; + use crate::test_utils::TestExecutorFactory; use reth_db::{ mdbx::{test_utils::create_test_rw_db, Env, WriteMap}, transaction::DbTxMut, }; use reth_interfaces::test_utils::TestConsensus; - use reth_primitives::{proofs::EMPTY_ROOT, ChainSpec, ChainSpecBuilder, H256, MAINNET}; + use reth_primitives::{proofs::EMPTY_ROOT, ChainSpecBuilder, H256, MAINNET}; use reth_provider::{ - insert_block, post_state::PostState, test_utils::blocks::BlockChainTestData, BlockExecutor, - StateProvider, + insert_block, post_state::PostState, test_utils::blocks::BlockChainTestData, }; use std::{collections::HashSet, sync::Arc}; - #[derive(Clone, Debug)] - struct TestFactory { - exec_result: Arc>>, - chain_spec: Arc, - } - - impl TestFactory { - fn new(chain_spec: Arc) -> Self { - Self { exec_result: Arc::new(Mutex::new(Vec::new())), chain_spec } - } - - fn extend(&self, exec_res: Vec) { - self.exec_result.lock().extend(exec_res.into_iter()); - } - } - - struct TestExecutor(Option); - - impl BlockExecutor for TestExecutor { - fn execute( - &mut self, - _block: &reth_primitives::Block, - _total_difficulty: reth_primitives::U256, - _senders: Option>, - ) -> Result { - self.0.clone().ok_or(ExecError::VerificationFailed) - } - - fn execute_and_verify_receipt( - &mut self, - _block: &reth_primitives::Block, - _total_difficulty: reth_primitives::U256, - _senders: Option>, - ) -> Result { - self.0.clone().ok_or(ExecError::VerificationFailed) - } - } - - impl ExecutorFactory for TestFactory { - type Executor = TestExecutor; - - fn with_sp(&self, _sp: SP) -> Self::Executor { - let exec_res = self.exec_result.lock().pop(); - TestExecutor(exec_res) - } - - fn chain_spec(&self) -> &ChainSpec { - self.chain_spec.as_ref() - } - } - fn setup_externals( exec_res: Vec, - ) -> TreeExternals>, Arc, TestFactory> { + ) -> TreeExternals>, Arc, TestExecutorFactory> { let db = create_test_rw_db(); let consensus = Arc::new(TestConsensus::default()); let chain_spec = Arc::new( @@ -707,7 +655,7 @@ mod tests { .shanghai_activated() .build(), ); - let executor_factory = TestFactory::new(chain_spec.clone()); + let executor_factory = TestExecutorFactory::new(chain_spec.clone()); executor_factory.extend(exec_res); TreeExternals::new(db, consensus, executor_factory, chain_spec) diff --git a/crates/executor/src/lib.rs b/crates/executor/src/lib.rs index 5bbd34a3b8..fbdb1cc173 100644 --- a/crates/executor/src/lib.rs +++ b/crates/executor/src/lib.rs @@ -21,3 +21,7 @@ pub mod executor; /// ExecutorFactory impl pub mod factory; pub use factory::Factory; + +#[cfg(any(test, feature = "test-utils"))] +/// Common test helpers for mocking out executor and executor factory +pub mod test_utils; diff --git a/crates/executor/src/test_utils/executor.rs b/crates/executor/src/test_utils/executor.rs new file mode 100644 index 0000000000..d09338fd5e --- /dev/null +++ b/crates/executor/src/test_utils/executor.rs @@ -0,0 +1,26 @@ +use reth_interfaces::executor::Error as ExecutionError; +use reth_primitives::{Address, Block, U256}; +use reth_provider::{post_state::PostState, BlockExecutor, StateProvider}; + +/// Test executor with mocked result. +pub struct TestExecutor(pub Option); + +impl BlockExecutor for TestExecutor { + fn execute( + &mut self, + _block: &Block, + _total_difficulty: U256, + _senders: Option>, + ) -> Result { + self.0.clone().ok_or(ExecutionError::VerificationFailed) + } + + fn execute_and_verify_receipt( + &mut self, + _block: &Block, + _total_difficulty: U256, + _senders: Option>, + ) -> Result { + self.0.clone().ok_or(ExecutionError::VerificationFailed) + } +} diff --git a/crates/executor/src/test_utils/factory.rs b/crates/executor/src/test_utils/factory.rs new file mode 100644 index 0000000000..50e4360ad1 --- /dev/null +++ b/crates/executor/src/test_utils/factory.rs @@ -0,0 +1,37 @@ +use super::TestExecutor; +use parking_lot::Mutex; +use reth_primitives::ChainSpec; +use reth_provider::{post_state::PostState, ExecutorFactory, StateProvider}; +use std::sync::Arc; + +/// Executor factory with pre-set execution results. +#[derive(Clone, Debug)] +pub struct TestExecutorFactory { + exec_results: Arc>>, + chain_spec: Arc, +} + +impl TestExecutorFactory { + /// Create new instance of test factory. + pub fn new(chain_spec: Arc) -> Self { + Self { exec_results: Arc::new(Mutex::new(Vec::new())), chain_spec } + } + + /// Extend the mocked execution results + pub fn extend(&self, results: Vec) { + self.exec_results.lock().extend(results.into_iter()); + } +} + +impl ExecutorFactory for TestExecutorFactory { + type Executor = TestExecutor; + + fn with_sp(&self, _sp: SP) -> Self::Executor { + let exec_res = self.exec_results.lock().pop(); + TestExecutor(exec_res) + } + + fn chain_spec(&self) -> &ChainSpec { + self.chain_spec.as_ref() + } +} diff --git a/crates/executor/src/test_utils/mod.rs b/crates/executor/src/test_utils/mod.rs new file mode 100644 index 0000000000..86ef2f53ae --- /dev/null +++ b/crates/executor/src/test_utils/mod.rs @@ -0,0 +1,5 @@ +mod executor; +pub use executor::*; + +mod factory; +pub use factory::*;