diff --git a/crates/ethereum/evm/src/execute.rs b/crates/ethereum/evm/src/execute.rs index 66856f9ac3f6e..e722b23cf7d43 100644 --- a/crates/ethereum/evm/src/execute.rs +++ b/crates/ethereum/evm/src/execute.rs @@ -31,7 +31,7 @@ use reth_revm::{ BundleAccount, State, }, state_change::post_block_balance_increments, - Evm, State + Evm, }; use revm_primitives::{ db::{Database, DatabaseCommit}, @@ -79,6 +79,13 @@ where State::builder().with_database(db).with_bundle_update().without_state_clear().build(), ) } + + fn block_access_list_executor(&self, db: DB) -> BlockAccessListExecutor + where + DB: Database>, + { + BlockAccessListExecutor { executor: self.eth_executor(db) } + } } impl BlockExecutorProvider for EthExecutorProvider @@ -88,6 +95,9 @@ where type Executor + Display>> = EthBlockExecutor; + type BlockAccessListExecutor + Display>> = + BlockAccessListExecutor; + type BatchExecutor + Display>> = EthBatchExecutor; @@ -98,6 +108,13 @@ where self.eth_executor(db) } + fn trace_executor(&self, db: DB) -> Self::BlockAccessListExecutor + where + DB: Database + Display>, + { + self.block_access_list_executor(db) + } + fn batch_executor(&self, db: DB) -> Self::BatchExecutor where DB: Database + Display>, @@ -382,13 +399,7 @@ where // NOTE: we need to merge keep the reverts for the bundle retention self.state.merge_transitions(BundleRetention::Reverts); - Ok(BlockExecutionOutput { - state: self.state.take_bundle(), - cache: core::mem::take(&mut self.state.cache), - receipts, - requests, - gas_used, - }) + Ok(BlockExecutionOutput { state: self.state.take_bundle(), receipts, requests, gas_used }) } } diff --git a/crates/evm/execution-types/src/execute.rs b/crates/evm/execution-types/src/execute.rs index d197cb5001c10..2933fd59815f8 100644 --- a/crates/evm/execution-types/src/execute.rs +++ b/crates/evm/execution-types/src/execute.rs @@ -1,5 +1,5 @@ use reth_primitives::{Request, U256}; -use revm::{db::BundleState, CacheState}; +use revm::db::BundleState; /// A helper type for ethereum block inputs that consists of a block and the total difficulty. #[derive(Debug)] @@ -30,8 +30,6 @@ impl<'a, Block> From<(&'a Block, U256)> for BlockExecutionInput<'a, Block> { pub struct BlockExecutionOutput { /// The changed state of the block after execution. pub state: BundleState, - /// cache state of the block after execution. - pub cache: CacheState, /// All the receipts of the transactions in the block. pub receipts: Vec, /// All the EIP-7685 requests of the transactions in the block. diff --git a/crates/evm/src/either.rs b/crates/evm/src/either.rs index 84e1733e4812f..971bf9c867665 100644 --- a/crates/evm/src/either.rs +++ b/crates/evm/src/either.rs @@ -21,6 +21,9 @@ where type Executor + Display>> = Either, B::Executor>; + type BlockAccessListExecutor + Display>> = + Either, B::BlockAccessListExecutor>; + type BatchExecutor + Display>> = Either, B::BatchExecutor>; @@ -34,6 +37,16 @@ where } } + fn trace_executor(&self, db: DB) -> Self::BlockAccessListExecutor + where + DB: Database + Display>, + { + match self { + Self::Left(a) => Either::Left(a.trace_executor(db)), + Self::Right(b) => Either::Right(b.trace_executor(db)), + } + } + fn batch_executor(&self, db: DB) -> Self::BatchExecutor where DB: Database + Display>, diff --git a/crates/evm/src/execute.rs b/crates/evm/src/execute.rs index 2109d557f8ec9..634d16e372e6b 100644 --- a/crates/evm/src/execute.rs +++ b/crates/evm/src/execute.rs @@ -114,6 +114,15 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static { Error = BlockExecutionError, >; + /// An executor that returns not only the changes in the block, but all state accessed in the + /// block. + type BlockAccessListExecutor + Display>>: for<'a> Executor< + DB, + Input<'a> = BlockExecutionInput<'a, BlockWithSenders>, + Output = BlockExecutionOutput, + Error = BlockExecutionError, + >; + /// An executor that can execute a batch of blocks given a database. type BatchExecutor + Display>>: for<'a> BatchExecutor< DB, @@ -129,6 +138,12 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static { where DB: Database + Display>; + /// Creates a new executor which traces block execution, including any system calls or system + /// transactions pre- and post-block. + fn trace_executor(&self, db: DB) -> Self::BlockAccessListExecutor + where + DB: Database + Display>; + /// Creates a new batch executor with the given database and pruning modes. /// /// Batch executor is used to execute multiple blocks in sequence and keep track of the state @@ -151,6 +166,8 @@ mod tests { impl BlockExecutorProvider for TestExecutorProvider { type Executor + Display>> = TestExecutor; + type BlockAccessListExecutor + Display>> = + TestExecutor; type BatchExecutor + Display>> = TestExecutor; fn executor(&self, _db: DB) -> Self::Executor @@ -160,6 +177,13 @@ mod tests { TestExecutor(PhantomData) } + fn trace_executor(&self, _db: DB) -> Self::BlockAccessListExecutor + where + DB: Database + Display>, + { + TestExecutor(PhantomData) + } + fn batch_executor(&self, _db: DB) -> Self::BatchExecutor where DB: Database + Display>, diff --git a/crates/evm/src/noop.rs b/crates/evm/src/noop.rs index ff8e893b2b6ba..76753fdb0e238 100644 --- a/crates/evm/src/noop.rs +++ b/crates/evm/src/noop.rs @@ -20,7 +20,7 @@ pub struct NoopBlockExecutorProvider; impl BlockExecutorProvider for NoopBlockExecutorProvider { type Executor + Display>> = Self; - + type BlockAccessListExecutor + Display>> = Self; type BatchExecutor + Display>> = Self; fn executor(&self, _: DB) -> Self::Executor @@ -30,6 +30,13 @@ impl BlockExecutorProvider for NoopBlockExecutorProvider { Self } + fn trace_executor(&self, _db: DB) -> Self::BlockAccessListExecutor + where + DB: Database + Display>, + { + Self + } + fn batch_executor(&self, _: DB) -> Self::BatchExecutor where DB: Database + Display>, diff --git a/crates/evm/src/test_utils.rs b/crates/evm/src/test_utils.rs index f535e7840eb4c..7602f18e5377b 100644 --- a/crates/evm/src/test_utils.rs +++ b/crates/evm/src/test_utils.rs @@ -27,7 +27,7 @@ impl MockExecutorProvider { impl BlockExecutorProvider for MockExecutorProvider { type Executor + Display>> = Self; - + type BlockAccessListExecutor + Display>> = Self; type BatchExecutor + Display>> = Self; fn executor(&self, _: DB) -> Self::Executor @@ -37,6 +37,13 @@ impl BlockExecutorProvider for MockExecutorProvider { self.clone() } + fn trace_executor(&self, _db: DB) -> Self::BlockAccessListExecutor + where + DB: Database + Display>, + { + self.clone() + } + fn batch_executor(&self, _: DB) -> Self::BatchExecutor where DB: Database + Display>, @@ -55,7 +62,6 @@ impl Executor for MockExecutorProvider { self.exec_results.lock().pop().unwrap(); Ok(BlockExecutionOutput { state: bundle, - cache: Default::default(), receipts: receipts.into_iter().flatten().flatten().collect(), requests: requests.into_iter().flatten().collect(), gas_used: 0, diff --git a/crates/optimism/evm/src/execute.rs b/crates/optimism/evm/src/execute.rs index 2d9bbc10ead6e..d921b817659ea 100644 --- a/crates/optimism/evm/src/execute.rs +++ b/crates/optimism/evm/src/execute.rs @@ -364,7 +364,6 @@ where Ok(BlockExecutionOutput { state: self.state.take_bundle(), - cache: core::mem::take(&mut self.state.cache), receipts, requests: vec![], gas_used, diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index 2352b866c335b..2f2532291c34d 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -30,7 +30,7 @@ use reth_rpc_types::{ Block as RpcBlock, BlockError, Bundle, StateContext, TransactionRequest, }; use reth_tasks::pool::BlockingTaskGuard; -use reth_trie::{HashedPostState, HashedStorage}; +use reth_trie::HashedPostState; use revm::{ db::CacheDB, primitives::{db::DatabaseCommit, BlockEnv, CfgEnvWithHandlerCfg, Env, EnvWithHandlerCfg}, @@ -588,13 +588,12 @@ where .eth_api .spawn_with_state_at_block(block.parent_hash.into(), move |state| { let db = StateProviderDatabase::new(&state); - let block_executor = this.inner.block_executor.executor(db); + let block_executor = this.inner.block_executor.trace_executor(db); let block_execution_output = block_executor .execute((&block.clone().unseal(), block.difficulty).into()) .map_err(|err| EthApiError::Internal(err.into()))?; let bundle_state = block_execution_output.state; - let cache_state = block_execution_output.cache; // Initialize a map of preimages. let mut state_preimages: HashMap, Bytes> = @@ -604,36 +603,48 @@ where // // Note: We grab *all* accounts in the cache here, as the `BundleState` prunes // referenced accounts + storage slots. - let mut hashed_state = HashedPostState::from_bundle_state(&bundle_state.state); - for (address, account) in cache_state.accounts { - let hashed_address = keccak256(address); - hashed_state.accounts.insert( - hashed_address, - account.account.as_ref().map(|a| a.info.clone().into()), - ); - - let storage = hashed_state - .storages - .entry(hashed_address) - .or_insert_with(|| HashedStorage::new(account.status.was_destroyed())); - - if let Some(account) = account.account { - if include_preimages { - state_preimages - .insert(hashed_address, alloy_rlp::encode(address).into()); - } + let hashed_state = HashedPostState::from_bundle_state(&bundle_state.state); + if include_preimages { + for (address, account) in bundle_state.state { + let hashed_address = keccak256(address); + state_preimages.insert(hashed_address, alloy_rlp::encode(address).into()); - for (slot, value) in account.storage { + for (slot, _) in account.storage { let slot = B256::from(slot); let hashed_slot = keccak256(slot); - storage.storage.insert(hashed_slot, value); - - if include_preimages { - state_preimages.insert(hashed_slot, alloy_rlp::encode(slot).into()); - } + state_preimages.insert(hashed_slot, alloy_rlp::encode(slot).into()); } } } + // for (address, account) in bundle_state.state { + // let hashed_address = keccak256(address); + // hashed_state.accounts.insert( + // hashed_address, + // account.account.as_ref().map(|a| a.info.clone().into()), + // ); + + // let storage = hashed_state + // .storages + // .entry(hashed_address) + // .or_insert_with(|| HashedStorage::new(account.status.was_destroyed())); + + // if let Some(account) = account.account { + // if include_preimages { + // state_preimages + // .insert(hashed_address, alloy_rlp::encode(address).into()); + // } + + // for (slot, value) in account.storage { + // let slot = B256::from(slot); + // let hashed_slot = keccak256(slot); + // storage.storage.insert(hashed_slot, value); + + // if include_preimages { + // state_preimages.insert(hashed_slot, + // alloy_rlp::encode(slot).into()); } + // } + // } + // } // Generate an execution witness for the aggregated state of accessed accounts. let witness = diff --git a/examples/rpc-db/src/main.rs b/examples/rpc-db/src/main.rs index 892dd99812363..1b2899a6485ba 100644 --- a/examples/rpc-db/src/main.rs +++ b/examples/rpc-db/src/main.rs @@ -69,7 +69,6 @@ async fn main() -> eyre::Result<()> { .with_evm_config(EthEvmConfig::new(spec)) .with_events(TestCanonStateSubscriptions::default()) .with_block_executor(EthExecutorProvider::ethereum(provider.chain_spec())); ->>>>>>> 7d9b7e746 (Add block_executor to debug_execution_witness to execute blocks) // Pick which namespaces to expose. let config = TransportRpcModuleConfig::default().with_http([RethRpcModule::Eth]);