chore(executor): extract test utils (#1841)

This commit is contained in:
Roman Krasiuk
2023-03-19 16:35:31 +02:00
committed by GitHub
parent 25ac1370fd
commit 02cb1e3257
6 changed files with 81 additions and 57 deletions

View File

@ -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"]

View File

@ -631,73 +631,21 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
#[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<Mutex<Vec<PostState>>>,
chain_spec: Arc<ChainSpec>,
}
impl TestFactory {
fn new(chain_spec: Arc<ChainSpec>) -> Self {
Self { exec_result: Arc::new(Mutex::new(Vec::new())), chain_spec }
}
fn extend(&self, exec_res: Vec<PostState>) {
self.exec_result.lock().extend(exec_res.into_iter());
}
}
struct TestExecutor(Option<PostState>);
impl<SP: StateProvider> BlockExecutor<SP> for TestExecutor {
fn execute(
&mut self,
_block: &reth_primitives::Block,
_total_difficulty: reth_primitives::U256,
_senders: Option<Vec<reth_primitives::Address>>,
) -> Result<PostState, ExecError> {
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<Vec<reth_primitives::Address>>,
) -> Result<PostState, ExecError> {
self.0.clone().ok_or(ExecError::VerificationFailed)
}
}
impl ExecutorFactory for TestFactory {
type Executor<T: StateProvider> = TestExecutor;
fn with_sp<SP: StateProvider>(&self, _sp: SP) -> Self::Executor<SP> {
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<PostState>,
) -> TreeExternals<Arc<Env<WriteMap>>, Arc<TestConsensus>, TestFactory> {
) -> TreeExternals<Arc<Env<WriteMap>>, Arc<TestConsensus>, 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)

View File

@ -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;

View File

@ -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<PostState>);
impl<SP: StateProvider> BlockExecutor<SP> for TestExecutor {
fn execute(
&mut self,
_block: &Block,
_total_difficulty: U256,
_senders: Option<Vec<Address>>,
) -> Result<PostState, ExecutionError> {
self.0.clone().ok_or(ExecutionError::VerificationFailed)
}
fn execute_and_verify_receipt(
&mut self,
_block: &Block,
_total_difficulty: U256,
_senders: Option<Vec<Address>>,
) -> Result<PostState, ExecutionError> {
self.0.clone().ok_or(ExecutionError::VerificationFailed)
}
}

View File

@ -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<Mutex<Vec<PostState>>>,
chain_spec: Arc<ChainSpec>,
}
impl TestExecutorFactory {
/// Create new instance of test factory.
pub fn new(chain_spec: Arc<ChainSpec>) -> Self {
Self { exec_results: Arc::new(Mutex::new(Vec::new())), chain_spec }
}
/// Extend the mocked execution results
pub fn extend(&self, results: Vec<PostState>) {
self.exec_results.lock().extend(results.into_iter());
}
}
impl ExecutorFactory for TestExecutorFactory {
type Executor<T: StateProvider> = TestExecutor;
fn with_sp<SP: StateProvider>(&self, _sp: SP) -> Self::Executor<SP> {
let exec_res = self.exec_results.lock().pop();
TestExecutor(exec_res)
}
fn chain_spec(&self) -> &ChainSpec {
self.chain_spec.as_ref()
}
}

View File

@ -0,0 +1,5 @@
mod executor;
pub use executor::*;
mod factory;
pub use factory::*;