Skip to content

Commit

Permalink
Use trace_executor instead
Browse files Browse the repository at this point in the history
  • Loading branch information
0x00101010 committed Sep 14, 2024
1 parent c256876 commit 0b38792
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 43 deletions.
27 changes: 19 additions & 8 deletions crates/ethereum/evm/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use reth_revm::{
BundleAccount, State,
},
state_change::post_block_balance_increments,
Evm, State
Evm,
};
use revm_primitives::{
db::{Database, DatabaseCommit},
Expand Down Expand Up @@ -79,6 +79,13 @@ where
State::builder().with_database(db).with_bundle_update().without_state_clear().build(),
)
}

fn block_access_list_executor<DB>(&self, db: DB) -> BlockAccessListExecutor<EvmConfig, DB>
where
DB: Database<Error: Into<ProviderError>>,
{
BlockAccessListExecutor { executor: self.eth_executor(db) }
}
}

impl<EvmConfig> BlockExecutorProvider for EthExecutorProvider<EvmConfig>
Expand All @@ -88,6 +95,9 @@ where
type Executor<DB: Database<Error: Into<ProviderError> + Display>> =
EthBlockExecutor<EvmConfig, DB>;

type BlockAccessListExecutor<DB: Database<Error: Into<ProviderError> + Display>> =
BlockAccessListExecutor<EvmConfig, DB>;

type BatchExecutor<DB: Database<Error: Into<ProviderError> + Display>> =
EthBatchExecutor<EvmConfig, DB>;

Expand All @@ -98,6 +108,13 @@ where
self.eth_executor(db)
}

fn trace_executor<DB>(&self, db: DB) -> Self::BlockAccessListExecutor<DB>
where
DB: Database<Error: Into<ProviderError> + Display>,
{
self.block_access_list_executor(db)
}

fn batch_executor<DB>(&self, db: DB) -> Self::BatchExecutor<DB>
where
DB: Database<Error: Into<ProviderError> + Display>,
Expand Down Expand Up @@ -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 })
}
}

Expand Down
4 changes: 1 addition & 3 deletions crates/evm/execution-types/src/execute.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down Expand Up @@ -30,8 +30,6 @@ impl<'a, Block> From<(&'a Block, U256)> for BlockExecutionInput<'a, Block> {
pub struct BlockExecutionOutput<T> {
/// 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<T>,
/// All the EIP-7685 requests of the transactions in the block.
Expand Down
13 changes: 13 additions & 0 deletions crates/evm/src/either.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ where
type Executor<DB: Database<Error: Into<ProviderError> + Display>> =
Either<A::Executor<DB>, B::Executor<DB>>;

type BlockAccessListExecutor<DB: Database<Error: Into<ProviderError> + Display>> =
Either<A::BlockAccessListExecutor<DB>, B::BlockAccessListExecutor<DB>>;

type BatchExecutor<DB: Database<Error: Into<ProviderError> + Display>> =
Either<A::BatchExecutor<DB>, B::BatchExecutor<DB>>;

Expand All @@ -34,6 +37,16 @@ where
}
}

fn trace_executor<DB>(&self, db: DB) -> Self::BlockAccessListExecutor<DB>
where
DB: Database<Error: Into<ProviderError> + Display>,
{
match self {
Self::Left(a) => Either::Left(a.trace_executor(db)),
Self::Right(b) => Either::Right(b.trace_executor(db)),
}
}

fn batch_executor<DB>(&self, db: DB) -> Self::BatchExecutor<DB>
where
DB: Database<Error: Into<ProviderError> + Display>,
Expand Down
24 changes: 24 additions & 0 deletions crates/evm/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<DB: Database<Error: Into<ProviderError> + Display>>: for<'a> Executor<
DB,
Input<'a> = BlockExecutionInput<'a, BlockWithSenders>,
Output = BlockExecutionOutput<Receipt>,
Error = BlockExecutionError,
>;

/// An executor that can execute a batch of blocks given a database.
type BatchExecutor<DB: Database<Error: Into<ProviderError> + Display>>: for<'a> BatchExecutor<
DB,
Expand All @@ -129,6 +138,12 @@ pub trait BlockExecutorProvider: Send + Sync + Clone + Unpin + 'static {
where
DB: Database<Error: Into<ProviderError> + Display>;

/// Creates a new executor which traces block execution, including any system calls or system
/// transactions pre- and post-block.
fn trace_executor<DB>(&self, db: DB) -> Self::BlockAccessListExecutor<DB>
where
DB: Database<Error: Into<ProviderError> + 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
Expand All @@ -151,6 +166,8 @@ mod tests {

impl BlockExecutorProvider for TestExecutorProvider {
type Executor<DB: Database<Error: Into<ProviderError> + Display>> = TestExecutor<DB>;
type BlockAccessListExecutor<DB: Database<Error: Into<ProviderError> + Display>> =
TestExecutor<DB>;
type BatchExecutor<DB: Database<Error: Into<ProviderError> + Display>> = TestExecutor<DB>;

fn executor<DB>(&self, _db: DB) -> Self::Executor<DB>
Expand All @@ -160,6 +177,13 @@ mod tests {
TestExecutor(PhantomData)
}

fn trace_executor<DB>(&self, _db: DB) -> Self::BlockAccessListExecutor<DB>
where
DB: Database<Error: Into<ProviderError> + Display>,
{
TestExecutor(PhantomData)
}

fn batch_executor<DB>(&self, _db: DB) -> Self::BatchExecutor<DB>
where
DB: Database<Error: Into<ProviderError> + Display>,
Expand Down
9 changes: 8 additions & 1 deletion crates/evm/src/noop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub struct NoopBlockExecutorProvider;

impl BlockExecutorProvider for NoopBlockExecutorProvider {
type Executor<DB: Database<Error: Into<ProviderError> + Display>> = Self;

type BlockAccessListExecutor<DB: Database<Error: Into<ProviderError> + Display>> = Self;
type BatchExecutor<DB: Database<Error: Into<ProviderError> + Display>> = Self;

fn executor<DB>(&self, _: DB) -> Self::Executor<DB>
Expand All @@ -30,6 +30,13 @@ impl BlockExecutorProvider for NoopBlockExecutorProvider {
Self
}

fn trace_executor<DB>(&self, _db: DB) -> Self::BlockAccessListExecutor<DB>
where
DB: Database<Error: Into<ProviderError> + Display>,
{
Self
}

fn batch_executor<DB>(&self, _: DB) -> Self::BatchExecutor<DB>
where
DB: Database<Error: Into<ProviderError> + Display>,
Expand Down
10 changes: 8 additions & 2 deletions crates/evm/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl MockExecutorProvider {

impl BlockExecutorProvider for MockExecutorProvider {
type Executor<DB: Database<Error: Into<ProviderError> + Display>> = Self;

type BlockAccessListExecutor<DB: Database<Error: Into<ProviderError> + Display>> = Self;
type BatchExecutor<DB: Database<Error: Into<ProviderError> + Display>> = Self;

fn executor<DB>(&self, _: DB) -> Self::Executor<DB>
Expand All @@ -37,6 +37,13 @@ impl BlockExecutorProvider for MockExecutorProvider {
self.clone()
}

fn trace_executor<DB>(&self, _db: DB) -> Self::BlockAccessListExecutor<DB>
where
DB: Database<Error: Into<ProviderError> + Display>,
{
self.clone()
}

fn batch_executor<DB>(&self, _: DB) -> Self::BatchExecutor<DB>
where
DB: Database<Error: Into<ProviderError> + Display>,
Expand All @@ -55,7 +62,6 @@ impl<DB> Executor<DB> 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,
Expand Down
1 change: 0 additions & 1 deletion crates/optimism/evm/src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
65 changes: 38 additions & 27 deletions crates/rpc/rpc/src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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<revm_primitives::FixedBytes<32>, Bytes> =
Expand All @@ -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 =
Expand Down
1 change: 0 additions & 1 deletion examples/rpc-db/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down

0 comments on commit 0b38792

Please sign in to comment.