diff --git a/bin/reth/src/chain/import.rs b/bin/reth/src/chain/import.rs index f93228a3f6a..967ea2fa183 100644 --- a/bin/reth/src/chain/import.rs +++ b/bin/reth/src/chain/import.rs @@ -27,6 +27,7 @@ use reth_staged_sync::{ use reth_stages::{ prelude::*, stages::{ExecutionStage, SenderRecoveryStage, TotalDifficultyStage}, + DefaultDB, }; use std::sync::Arc; use tracing::{debug, info}; @@ -156,9 +157,11 @@ impl ImportCommand { .set(SenderRecoveryStage { commit_threshold: config.stages.sender_recovery.commit_threshold, }) - .set(ExecutionStage { - chain_spec: self.chain.clone(), - commit_threshold: config.stages.execution.commit_threshold, + .set({ + let mut stage: ExecutionStage<'_, DefaultDB<'_>> = + ExecutionStage::from(self.chain.clone()); + stage.commit_threshold = config.stages.execution.commit_threshold; + stage }), ) .with_max_block(0) diff --git a/bin/reth/src/dump_stage/execution.rs b/bin/reth/src/dump_stage/execution.rs index 49d6de7de35..5a5ae04decb 100644 --- a/bin/reth/src/dump_stage/execution.rs +++ b/bin/reth/src/dump_stage/execution.rs @@ -7,8 +7,9 @@ use eyre::Result; use reth_db::{ cursor::DbCursorRO, database::Database, table::TableImporter, tables, transaction::DbTx, }; +use reth_primitives::MAINNET; use reth_provider::Transaction; -use reth_stages::{stages::ExecutionStage, Stage, StageId, UnwindInput}; +use reth_stages::{stages::ExecutionStage, DefaultDB, Stage, StageId, UnwindInput}; use std::ops::DerefMut; use tracing::info; @@ -96,7 +97,7 @@ async fn unwind_and_copy( output_db: &reth_db::mdbx::Env, ) -> eyre::Result<()> { let mut unwind_tx = Transaction::new(db_tool.db)?; - let mut exec_stage = ExecutionStage::default(); + let mut exec_stage: ExecutionStage<'_, DefaultDB<'_>> = ExecutionStage::from(MAINNET.clone()); exec_stage .unwind( @@ -125,7 +126,7 @@ async fn dry_run( info!(target: "reth::cli", "Executing stage. [dry-run]"); let mut tx = Transaction::new(&output_db)?; - let mut exec_stage = ExecutionStage::default(); + let mut exec_stage: ExecutionStage<'_, DefaultDB<'_>> = ExecutionStage::from(MAINNET.clone()); exec_stage .execute( diff --git a/bin/reth/src/node/mod.rs b/bin/reth/src/node/mod.rs index 55a4a9ef368..082d2c5cbba 100644 --- a/bin/reth/src/node/mod.rs +++ b/bin/reth/src/node/mod.rs @@ -50,6 +50,7 @@ use reth_staged_sync::{ use reth_stages::{ prelude::*, stages::{ExecutionStage, SenderRecoveryStage, TotalDifficultyStage, FINISH}, + DefaultDB, }; use reth_tasks::TaskExecutor; use std::{net::SocketAddr, path::PathBuf, sync::Arc}; @@ -448,9 +449,11 @@ impl Command { .set(SenderRecoveryStage { commit_threshold: stage_conf.sender_recovery.commit_threshold, }) - .set(ExecutionStage { - chain_spec: self.chain.clone(), - commit_threshold: stage_conf.execution.commit_threshold, + .set({ + let mut stage: ExecutionStage<'_, DefaultDB<'_>> = + ExecutionStage::from(self.chain.clone()); + stage.commit_threshold = stage_conf.execution.commit_threshold; + stage }), ) .build(); diff --git a/bin/reth/src/stage/mod.rs b/bin/reth/src/stage/mod.rs index 8153567a4fd..27f82e25d95 100644 --- a/bin/reth/src/stage/mod.rs +++ b/bin/reth/src/stage/mod.rs @@ -17,7 +17,7 @@ use reth_staged_sync::{ }; use reth_stages::{ stages::{BodyStage, ExecutionStage, SenderRecoveryStage}, - ExecInput, Stage, StageId, UnwindInput, + DefaultDB, ExecInput, Stage, StageId, UnwindInput, }; use std::{net::SocketAddr, sync::Arc}; use tracing::*; @@ -171,8 +171,8 @@ impl Command { stage.execute(&mut tx, input).await?; } StageEnum::Execution => { - let mut stage = - ExecutionStage { chain_spec: self.chain.clone(), commit_threshold: num_blocks }; + let mut stage = ExecutionStage::>::from(self.chain.clone()); + stage.commit_threshold = num_blocks; if !self.skip_unwind { stage.unwind(&mut tx, unwind).await?; } diff --git a/bin/reth/src/test_eth_chain/runner.rs b/bin/reth/src/test_eth_chain/runner.rs index 45c1225bf26..2e1b2f99238 100644 --- a/bin/reth/src/test_eth_chain/runner.rs +++ b/bin/reth/src/test_eth_chain/runner.rs @@ -15,7 +15,7 @@ use reth_primitives::{ }; use reth_provider::Transaction; use reth_rlp::Decodable; -use reth_stages::{stages::ExecutionStage, ExecInput, Stage, StageId}; +use reth_stages::{stages::ExecutionStage, DefaultDB, ExecInput, Stage, StageId}; use std::{ collections::HashMap, ffi::OsStr, @@ -193,7 +193,7 @@ pub async fn run_test(path: PathBuf) -> eyre::Result { // Initialize the execution stage // Hardcode the chain_id to Ethereum 1. - let mut stage = ExecutionStage::new(chain_spec, 1000); + let mut stage = ExecutionStage::>::from(chain_spec); // Call execution stage let input = ExecInput { diff --git a/crates/executor/src/executor.rs b/crates/executor/src/executor.rs index f383d84e0bc..ab27c6c639e 100644 --- a/crates/executor/src/executor.rs +++ b/crates/executor/src/executor.rs @@ -21,26 +21,47 @@ use revm::{ primitives::{Account as RevmAccount, AccountInfo, Bytecode, ResultAndState}, EVM, }; -use std::collections::{BTreeMap, HashMap}; +use std::{ + collections::{BTreeMap, HashMap}, + sync::Arc, +}; /// Main block executor pub struct Executor<'a, DB> where DB: StateProvider, { - chain_spec: &'a ChainSpec, + /// The configured chain-spec + pub chain_spec: Arc, evm: EVM<&'a mut SubState>, stack: InspectorStack, } +impl<'a, DB> From for Executor<'a, DB> +where + DB: StateProvider, +{ + /// Instantiates a new executor from the chainspec. Must call + /// `with_db` to set the database before executing. + fn from(chain_spec: ChainSpec) -> Self { + let evm = EVM::new(); + Executor { + chain_spec: Arc::new(chain_spec), + evm, + stack: InspectorStack::new(InspectorStackConfig::default()), + } + } +} + impl<'a, DB> Executor<'a, DB> where DB: StateProvider, { /// Creates a new executor from the given chain spec and database. - pub fn new(chain_spec: &'a ChainSpec, db: &'a mut SubState) -> Self { + pub fn new(chain_spec: Arc, db: &'a mut SubState) -> Self { let mut evm = EVM::new(); evm.database(db); + Executor { chain_spec, evm, stack: InspectorStack::new(InspectorStackConfig::default()) } } @@ -50,10 +71,21 @@ where self } - fn db(&mut self) -> &mut SubState { + /// Gives a reference to the database + pub fn db(&mut self) -> &mut SubState { self.evm.db().expect("db to not be moved") } + /// Overrides the database + pub fn with_db( + &self, + db: &'a mut SubState, + ) -> Executor<'a, OtherDB> { + let mut evm = EVM::new(); + evm.database(db); + Executor { chain_spec: self.chain_spec.clone(), evm, stack: self.stack.clone() } + } + fn recover_senders( &self, body: &[TransactionSigned], @@ -75,7 +107,7 @@ where fill_cfg_and_block_env( &mut self.evm.env.cfg, &mut self.evm.env.block, - self.chain_spec, + &self.chain_spec, header, total_difficulty, ); @@ -341,6 +373,30 @@ where } } + /// Execute and verify block + pub fn execute_and_verify_receipt( + &mut self, + block: &Block, + total_difficulty: U256, + senders: Option>, + ) -> Result { + let execution_result = self.execute(block, total_difficulty, senders)?; + + let receipts_iter = + execution_result.tx_changesets.iter().map(|changeset| &changeset.receipt); + + if self.chain_spec.fork(Hardfork::Byzantium).active_at_block(block.header.number) { + verify_receipt(block.header.receipts_root, block.header.logs_bloom, receipts_iter)?; + } + + // TODO Before Byzantium, receipts contained state root that would mean that expensive + // operation as hashing that is needed for state root got calculated in every + // transaction This was replaced with is_success flag. + // See more about EIP here: https://eips.ethereum.org/EIPS/eip-658 + + Ok(execution_result) + } + /// Runs a single transaction in the configured environment and proceeds /// to return the result and state diff (without applying it). /// @@ -464,30 +520,6 @@ where } } -/// Execute and verify block -pub fn execute_and_verify_receipt( - block: &Block, - total_difficulty: U256, - senders: Option>, - chain_spec: &ChainSpec, - db: &mut SubState, -) -> Result { - let execution_result = execute(block, total_difficulty, senders, chain_spec, db)?; - - let receipts_iter = execution_result.tx_changesets.iter().map(|changeset| &changeset.receipt); - - if chain_spec.fork(Hardfork::Byzantium).active_at_block(block.header.number) { - verify_receipt(block.header.receipts_root, block.header.logs_bloom, receipts_iter)?; - } - - // TODO Before Byzantium, receipts contained state root that would mean that expensive operation - // as hashing that is needed for state root got calculated in every transaction - // This was replaced with is_success flag. - // See more about EIP here: https://eips.ethereum.org/EIPS/eip-658 - - Ok(execution_result) -} - /// Verify receipts pub fn verify_receipt<'a>( expected_receipts_root: H256, @@ -511,22 +543,6 @@ pub fn verify_receipt<'a>( Ok(()) } -/// Verify block. Execute all transaction and compare results. -/// Returns ChangeSet on transaction granularity. -/// NOTE: If block reward is still active (Before Paris/Merge) we would return -/// additional TransactionStatechangeset for account that receives the reward. -pub fn execute( - block: &Block, - total_difficulty: U256, - senders: Option>, - chain_spec: &ChainSpec, - db: &mut SubState, -) -> Result { - let mut executor = Executor::new(chain_spec, db) - .with_stack(InspectorStack::new(InspectorStackConfig::default())); - executor.execute(block, total_difficulty, senders) -} - #[cfg(test)] mod tests { use super::*; @@ -640,13 +656,13 @@ mod tests { ); // spec at berlin fork - let chain_spec = ChainSpecBuilder::mainnet().berlin_activated().build(); + let chain_spec = Arc::new(ChainSpecBuilder::mainnet().berlin_activated().build()); let mut db = SubState::new(State::new(db)); // execute chain and verify receipts - let out = - execute_and_verify_receipt(&block, U256::ZERO, None, &chain_spec, &mut db).unwrap(); + let mut executor = Executor::new(chain_spec, &mut db); + let out = executor.execute_and_verify_receipt(&block, U256::ZERO, None).unwrap(); assert_eq!(out.tx_changesets.len(), 1, "Should executed one transaction"); @@ -765,21 +781,23 @@ mod tests { beneficiary_balance += i; } - let chain_spec = ChainSpecBuilder::from(&*MAINNET) - .homestead_activated() - .with_fork(Hardfork::Dao, ForkCondition::Block(1)) - .build(); + let chain_spec = Arc::new( + ChainSpecBuilder::from(&*MAINNET) + .homestead_activated() + .with_fork(Hardfork::Dao, ForkCondition::Block(1)) + .build(), + ); let mut db = SubState::new(State::new(db)); // execute chain and verify receipts - let out = execute_and_verify_receipt( - &Block { header, body: vec![], ommers: vec![], withdrawals: None }, - U256::ZERO, - None, - &chain_spec, - &mut db, - ) - .unwrap(); + let mut executor = Executor::new(chain_spec, &mut db); + let out = executor + .execute_and_verify_receipt( + &Block { header, body: vec![], ommers: vec![], withdrawals: None }, + U256::ZERO, + None, + ) + .unwrap(); assert_eq!(out.tx_changesets.len(), 0, "No tx"); // Check if cache is set @@ -858,13 +876,13 @@ mod tests { ); // spec at berlin fork - let chain_spec = ChainSpecBuilder::mainnet().berlin_activated().build(); + let chain_spec = Arc::new(ChainSpecBuilder::mainnet().berlin_activated().build()); let mut db = SubState::new(State::new(db)); // execute chain and verify receipts - let out = - execute_and_verify_receipt(&block, U256::ZERO, None, &chain_spec, &mut db).unwrap(); + let mut executor = Executor::new(chain_spec, &mut db); + let out = executor.execute_and_verify_receipt(&block, U256::ZERO, None).unwrap(); assert_eq!(out.tx_changesets.len(), 1, "Should executed one transaction"); @@ -907,17 +925,17 @@ mod tests { Address::from_str("c94f5374fce5edbc8e2a8697c15331677e6ebf0b").unwrap(); // spec at shanghai fork - let chain_spec = ChainSpecBuilder::mainnet().shanghai_activated().build(); + let chain_spec = Arc::new(ChainSpecBuilder::mainnet().shanghai_activated().build()); let mut db = SubState::new(State::new(StateProviderTest::default())); // execute chain and verify receipts - let out = - execute_and_verify_receipt(&block, U256::ZERO, None, &chain_spec, &mut db).unwrap(); + let mut executor = Executor::new(chain_spec, &mut db); + let out = executor.execute_and_verify_receipt(&block, U256::ZERO, None).unwrap(); assert_eq!(out.tx_changesets.len(), 0, "No tx"); let withdrawal_sum = withdrawals.iter().fold(U256::ZERO, |sum, w| sum + w.amount_wei()); - let beneficiary_account = db.accounts.get(&withdrawal_beneficiary).unwrap(); + let beneficiary_account = executor.db().accounts.get(&withdrawal_beneficiary).unwrap(); assert_eq!(beneficiary_account.info.balance, withdrawal_sum); assert_eq!(beneficiary_account.info.nonce, 0); assert_eq!(beneficiary_account.account_state, AccountState::StorageCleared); @@ -931,8 +949,7 @@ mod tests { ); // Execute same block again - let out = - execute_and_verify_receipt(&block, U256::ZERO, None, &chain_spec, &mut db).unwrap(); + let out = executor.execute_and_verify_receipt(&block, U256::ZERO, None).unwrap(); assert_eq!(out.tx_changesets.len(), 0, "No tx"); assert_eq!(out.block_changesets.len(), 1); diff --git a/crates/revm/revm-inspectors/src/stack.rs b/crates/revm/revm-inspectors/src/stack.rs index 12e3df4050a..042dd339f9b 100644 --- a/crates/revm/revm-inspectors/src/stack.rs +++ b/crates/revm/revm-inspectors/src/stack.rs @@ -10,7 +10,7 @@ use revm::{ /// - Block: Hook on block execution /// - BlockWithIndex: Hook on block execution transaction index /// - Transaction: Hook on a specific transaction hash -#[derive(Default)] +#[derive(Default, Clone)] pub enum Hook { #[default] /// No hook. @@ -23,7 +23,7 @@ pub enum Hook { All, } -#[derive(Default)] +#[derive(Default, Clone)] /// An inspector that calls multiple inspectors in sequence. /// /// If a call to an inspector returns a value other than [InstructionResult::Continue] (or diff --git a/crates/revm/src/lib.rs b/crates/revm/src/lib.rs index 21cc3790af8..781ae36c332 100644 --- a/crates/revm/src/lib.rs +++ b/crates/revm/src/lib.rs @@ -12,3 +12,6 @@ pub mod database; /// reexport for convenience pub use reth_revm_primitives::*; + +/// Re-export everything +pub use revm; diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index c5e8df1d3f2..d52daa3033e 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -1,6 +1,5 @@ use crate::{message::EngineApiMessageVersion, EngineApiError, EngineApiMessage, EngineApiResult}; use futures::StreamExt; -use reth_executor::executor; use reth_interfaces::consensus::ForkchoiceState; use reth_primitives::{ proofs::{self, EMPTY_LIST_HASH}, @@ -17,6 +16,7 @@ use reth_rpc_types::engine::{ use std::{ future::Future, pin::Pin, + sync::Arc, task::{ready, Context, Poll}, }; use tokio::sync::{mpsc, oneshot, watch}; @@ -37,7 +37,7 @@ const MAX_PAYLOAD_BODIES_LIMIT: u64 = 1024; pub struct EngineApi { client: Client, /// Consensus configuration - chain_spec: ChainSpec, + chain_spec: Arc, message_rx: UnboundedReceiverStream, forkchoice_state_tx: watch::Sender, // TODO: Placeholder for storing future blocks. Make cache bounded. Use lru @@ -57,7 +57,7 @@ impl Self { Self { client, - chain_spec, + chain_spec: Arc::new(chain_spec), message_rx: UnboundedReceiverStream::new(message_rx), forkchoice_state_tx, } @@ -304,13 +304,10 @@ impl Ok(PayloadStatus::new(PayloadStatusEnum::Valid, block_hash)), Err(err) => Ok(PayloadStatus::new( PayloadStatusEnum::Invalid { validation_error: err.to_string() }, @@ -443,7 +440,7 @@ mod tests { }; fn setup_engine_api() -> (EngineApiTestHandle, EngineApi>) { - let chain_spec = MAINNET.clone(); + let chain_spec = Arc::new(MAINNET.clone()); let client = Arc::new(MockEthProvider::default()); let (msg_tx, msg_rx) = unbounded_channel(); let (forkchoice_state_tx, forkchoice_state_rx) = watch::channel(ForkchoiceState::default()); @@ -458,7 +455,7 @@ mod tests { } struct EngineApiTestHandle { - chain_spec: ChainSpec, + chain_spec: Arc, client: Arc, msg_tx: UnboundedSender, forkchoice_state_rx: WatchReceiver, diff --git a/crates/stages/src/lib.rs b/crates/stages/src/lib.rs index 139bc314d1c..59e6c075e86 100644 --- a/crates/stages/src/lib.rs +++ b/crates/stages/src/lib.rs @@ -56,6 +56,11 @@ mod stage; mod trie; mod util; +/// The real database type we use in Reth using MDBX. +pub type DefaultDB<'a> = LatestStateProviderRef<'a, 'a, Tx<'a, RW, WriteMap>>; +use reth_db::mdbx::{tx::Tx, WriteMap, RW}; +use reth_provider::LatestStateProviderRef; + #[allow(missing_docs)] #[cfg(any(test, feature = "test-utils"))] pub mod test_utils; diff --git a/crates/stages/src/sets.rs b/crates/stages/src/sets.rs index 6b2d70031fe..dd86ef121ca 100644 --- a/crates/stages/src/sets.rs +++ b/crates/stages/src/sets.rs @@ -170,7 +170,7 @@ impl StageSet for ExecutionStages { fn builder(self) -> StageSetBuilder { StageSetBuilder::default() .add_stage(SenderRecoveryStage::default()) - .add_stage(ExecutionStage { chain_spec: self.chain_spec, ..Default::default() }) + .add_stage(ExecutionStage::>::from(self.chain_spec)) } } diff --git a/crates/stages/src/stages/execution.rs b/crates/stages/src/stages/execution.rs index 62490016b15..f7b58eb9b81 100644 --- a/crates/stages/src/stages/execution.rs +++ b/crates/stages/src/stages/execution.rs @@ -1,6 +1,6 @@ use crate::{ - exec_or_return, ExecAction, ExecInput, ExecOutput, Stage, StageError, StageId, UnwindInput, - UnwindOutput, + exec_or_return, DefaultDB, ExecAction, ExecInput, ExecOutput, Stage, StageError, StageId, + UnwindInput, UnwindOutput, }; use reth_db::{ cursor::{DbCursorRO, DbCursorRW, DbDupCursorRO}, @@ -9,12 +9,11 @@ use reth_db::{ tables, transaction::{DbTx, DbTxMut}, }; -use reth_executor::execution_result::AccountChangeSet; +use reth_executor::{execution_result::AccountChangeSet, executor::Executor}; use reth_interfaces::provider::ProviderError; -use reth_primitives::{Address, Block, ChainSpec, Hardfork, StorageEntry, H256, MAINNET, U256}; -use reth_provider::{LatestStateProviderRef, Transaction}; +use reth_primitives::{Address, Block, ChainSpec, Hardfork, StorageEntry, H256, U256}; +use reth_provider::{LatestStateProviderRef, StateProvider, Transaction}; use reth_revm::database::{State, SubState}; -use std::fmt::Debug; use tracing::*; /// The [`StageId`] of the execution stage. @@ -48,24 +47,35 @@ pub const EXECUTION: StageId = StageId("Execution"); /// - [tables::AccountHistory] to remove change set and apply old values to /// - [tables::PlainAccountState] [tables::StorageHistory] to remove change set and apply old values /// to [tables::PlainStorageState] -#[derive(Debug)] -pub struct ExecutionStage { - /// Executor configuration. - pub chain_spec: ChainSpec, +// false positive, we cannot derive it if !DB: Debug. +#[allow(missing_debug_implementations)] +pub struct ExecutionStage<'a, DB = DefaultDB<'a>> +where + DB: StateProvider, +{ + /// The stage's internal executor + pub executor: Executor<'a, DB>, /// Commit threshold pub commit_threshold: u64, } -impl Default for ExecutionStage { - fn default() -> Self { - Self { chain_spec: MAINNET.clone(), commit_threshold: 1_000 } +impl<'a, DB: StateProvider> From> for ExecutionStage<'a, DB> { + fn from(executor: Executor<'a, DB>) -> Self { + Self { executor, commit_threshold: 1_000 } } } -impl ExecutionStage { +impl<'a, DB: StateProvider> From for ExecutionStage<'a, DB> { + fn from(chain_spec: ChainSpec) -> Self { + let executor = Executor::from(chain_spec); + Self::from(executor) + } +} + +impl<'a, S: StateProvider> ExecutionStage<'a, S> { /// Execute the stage. pub fn execute_inner( - &self, + &mut self, tx: &mut Transaction<'_, DB>, input: ExecInput, ) -> Result { @@ -87,7 +97,6 @@ impl ExecutionStage { let mut tx_cursor = tx.cursor_read::()?; // Skip sender recovery and load signer from database. let mut tx_sender = tx.cursor_read::()?; - // Get block headers and bodies let block_batch = headers_cursor .walk_range(start_block..=end_block)? @@ -106,6 +115,7 @@ impl ExecutionStage { .collect::, _>>()?; // Create state provider with cached state + let mut state_provider = SubState::new(State::new(LatestStateProviderRef::new(&**tx))); // Fetch transactions, execute them and generate results @@ -143,14 +153,15 @@ impl ExecutionStage { trace!(target: "sync::stages::execution", number = block_number, txs = transactions.len(), "Executing block"); - let changeset = reth_executor::executor::execute_and_verify_receipt( - &Block { header, body: transactions, ommers, withdrawals }, - td, - Some(signers), - &self.chain_spec, - &mut state_provider, - ) - .map_err(|error| StageError::ExecutionError { block: block_number, error })?; + // Configure the executor to use the current state. + let mut executor = self.executor.with_db(&mut state_provider); + let changeset = executor + .execute_and_verify_receipt( + &Block { header, body: transactions, ommers, withdrawals }, + td, + Some(signers), + ) + .map_err(|error| StageError::ExecutionError { block: block_number, error })?; block_change_patches.push((changeset, block_number)); } @@ -160,8 +171,11 @@ impl ExecutionStage { // apply changes to plain database. for (results, block_number) in block_change_patches.into_iter() { - let spurious_dragon_active = - self.chain_spec.fork(Hardfork::SpuriousDragon).active_at_block(block_number); + let spurious_dragon_active = self + .executor + .chain_spec + .fork(Hardfork::SpuriousDragon) + .active_at_block(block_number); // insert state change set for result in results.tx_changesets.into_iter() { for (address, account_change_set) in result.changeset.into_iter() { @@ -266,15 +280,15 @@ impl ExecutionStage { } } -impl ExecutionStage { +impl<'a, DB: StateProvider> ExecutionStage<'a, DB> { /// Create new execution stage with specified config. - pub fn new(chain_spec: ChainSpec, commit_threshold: u64) -> Self { - Self { chain_spec, commit_threshold } + pub fn new(executor: Executor<'a, DB>, commit_threshold: u64) -> Self { + Self { executor, commit_threshold } } } #[async_trait::async_trait] -impl Stage for ExecutionStage { +impl Stage for ExecutionStage<'_, State> { /// Return the id of the stage fn id(&self) -> StageId { EXECUTION @@ -392,20 +406,18 @@ impl Stage for ExecutionStage { #[cfg(test)] mod tests { - use std::ops::{Deref, DerefMut}; - - use crate::test_utils::{TestTransaction, PREV_STAGE_ID}; - use super::*; + use crate::test_utils::{TestTransaction, PREV_STAGE_ID}; use reth_db::{ mdbx::{test_utils::create_test_db, EnvKind, WriteMap}, models::AccountBeforeTx, }; use reth_primitives::{ - hex_literal::hex, keccak256, Account, ChainSpecBuilder, SealedBlock, H160, U256, + hex_literal::hex, keccak256, Account, ChainSpecBuilder, SealedBlock, H160, MAINNET, U256, }; use reth_provider::insert_canonical_block; use reth_rlp::Decodable; + use std::ops::{Deref, DerefMut}; #[tokio::test] async fn sanity_execution_of_block() { @@ -448,11 +460,8 @@ mod tests { db_tx.put::(code_hash, code.to_vec()).unwrap(); tx.commit().unwrap(); - // execute - let mut execution_stage = ExecutionStage { - chain_spec: ChainSpecBuilder::mainnet().berlin_activated().build(), - ..Default::default() - }; + let chain_spec = ChainSpecBuilder::mainnet().berlin_activated().build(); + let mut execution_stage = ExecutionStage::>::from(chain_spec); let output = execution_stage.execute(&mut tx, input).await.unwrap(); tx.commit().unwrap(); assert_eq!(output, ExecOutput { stage_progress: 1, done: true }); @@ -536,14 +545,12 @@ mod tests { tx.commit().unwrap(); // execute - let mut execution_stage = ExecutionStage { - chain_spec: ChainSpecBuilder::mainnet().berlin_activated().build(), - ..Default::default() - }; + let chain_spec = ChainSpecBuilder::mainnet().berlin_activated().build(); + let mut execution_stage = ExecutionStage::>::from(chain_spec); let _ = execution_stage.execute(&mut tx, input).await.unwrap(); tx.commit().unwrap(); - let o = ExecutionStage::default() + let o = ExecutionStage::>::from(MAINNET.clone()) .unwind(&mut tx, UnwindInput { stage_progress: 1, unwind_to: 0, bad_block: None }) .await .unwrap(); @@ -624,10 +631,8 @@ mod tests { tx.commit().unwrap(); // execute - let mut execution_stage = ExecutionStage { - chain_spec: ChainSpecBuilder::mainnet().berlin_activated().build(), - ..Default::default() - }; + let chain_spec = ChainSpecBuilder::mainnet().berlin_activated().build(); + let mut execution_stage = ExecutionStage::>::from(chain_spec); let _ = execution_stage.execute(&mut tx, input).await.unwrap(); tx.commit().unwrap();