mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(eecutor): send EvmState in state hook (#13025)
This commit is contained in:
@ -48,7 +48,7 @@ use reth_revm::database::StateProviderDatabase;
|
|||||||
use reth_stages_api::ControlFlow;
|
use reth_stages_api::ControlFlow;
|
||||||
use reth_trie::{updates::TrieUpdates, HashedPostState, TrieInput};
|
use reth_trie::{updates::TrieUpdates, HashedPostState, TrieInput};
|
||||||
use reth_trie_parallel::root::{ParallelStateRoot, ParallelStateRootError};
|
use reth_trie_parallel::root::{ParallelStateRoot, ParallelStateRootError};
|
||||||
use revm_primitives::ResultAndState;
|
use revm_primitives::EvmState;
|
||||||
use std::{
|
use std::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
collections::{btree_map, hash_map, BTreeMap, VecDeque},
|
collections::{btree_map, hash_map, BTreeMap, VecDeque},
|
||||||
@ -2212,7 +2212,7 @@ where
|
|||||||
|
|
||||||
// TODO: create StateRootTask with the receiving end of a channel and
|
// TODO: create StateRootTask with the receiving end of a channel and
|
||||||
// pass the sending end of the channel to the state hook.
|
// pass the sending end of the channel to the state hook.
|
||||||
let noop_state_hook = |_result_and_state: &ResultAndState| {};
|
let noop_state_hook = |_state: &EvmState| {};
|
||||||
let output = self.metrics.executor.execute_metered(
|
let output = self.metrics.executor.execute_metered(
|
||||||
executor,
|
executor,
|
||||||
(&block, U256::MAX).into(),
|
(&block, U256::MAX).into(),
|
||||||
|
|||||||
@ -193,7 +193,7 @@ where
|
|||||||
error: Box::new(new_err),
|
error: Box::new(new_err),
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
self.system_caller.on_state(&result_and_state);
|
self.system_caller.on_state(&result_and_state.state);
|
||||||
let ResultAndState { result, state } = result_and_state;
|
let ResultAndState { result, state } = result_and_state;
|
||||||
evm.db_mut().commit(state);
|
evm.db_mut().commit(state);
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ use metrics::{Counter, Gauge, Histogram};
|
|||||||
use reth_execution_types::{BlockExecutionInput, BlockExecutionOutput};
|
use reth_execution_types::{BlockExecutionInput, BlockExecutionOutput};
|
||||||
use reth_metrics::Metrics;
|
use reth_metrics::Metrics;
|
||||||
use reth_primitives::BlockWithSenders;
|
use reth_primitives::BlockWithSenders;
|
||||||
use revm_primitives::ResultAndState;
|
use revm_primitives::EvmState;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
/// Wrapper struct that combines metrics and state hook
|
/// Wrapper struct that combines metrics and state hook
|
||||||
@ -18,13 +18,11 @@ struct MeteredStateHook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl OnStateHook for MeteredStateHook {
|
impl OnStateHook for MeteredStateHook {
|
||||||
fn on_state(&mut self, result_and_state: &ResultAndState) {
|
fn on_state(&mut self, state: &EvmState) {
|
||||||
// Update the metrics for the number of accounts, storage slots and bytecodes loaded
|
// Update the metrics for the number of accounts, storage slots and bytecodes loaded
|
||||||
let accounts = result_and_state.state.keys().len();
|
let accounts = state.keys().len();
|
||||||
let storage_slots =
|
let storage_slots = state.values().map(|account| account.storage.len()).sum::<usize>();
|
||||||
result_and_state.state.values().map(|account| account.storage.len()).sum::<usize>();
|
let bytecodes = state
|
||||||
let bytecodes = result_and_state
|
|
||||||
.state
|
|
||||||
.values()
|
.values()
|
||||||
.filter(|account| !account.info.is_empty_code_hash())
|
.filter(|account| !account.info.is_empty_code_hash())
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
@ -35,7 +33,7 @@ impl OnStateHook for MeteredStateHook {
|
|||||||
self.metrics.bytecodes_loaded_histogram.record(bytecodes as f64);
|
self.metrics.bytecodes_loaded_histogram.record(bytecodes as f64);
|
||||||
|
|
||||||
// Call the original state hook
|
// Call the original state hook
|
||||||
self.inner_hook.on_state(result_and_state);
|
self.inner_hook.on_state(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,14 +154,13 @@ mod tests {
|
|||||||
use metrics_util::debugging::{DebugValue, DebuggingRecorder, Snapshotter};
|
use metrics_util::debugging::{DebugValue, DebuggingRecorder, Snapshotter};
|
||||||
use revm::db::BundleState;
|
use revm::db::BundleState;
|
||||||
use revm_primitives::{
|
use revm_primitives::{
|
||||||
Account, AccountInfo, AccountStatus, Bytes, EvmState, EvmStorage, EvmStorageSlot,
|
Account, AccountInfo, AccountStatus, EvmState, EvmStorage, EvmStorageSlot, B256, U256,
|
||||||
ExecutionResult, Output, SuccessReason, B256, U256,
|
|
||||||
};
|
};
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|
||||||
/// A mock executor that simulates state changes
|
/// A mock executor that simulates state changes
|
||||||
struct MockExecutor {
|
struct MockExecutor {
|
||||||
result_and_state: ResultAndState,
|
state: EvmState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Executor<()> for MockExecutor {
|
impl Executor<()> for MockExecutor {
|
||||||
@ -206,7 +203,7 @@ mod tests {
|
|||||||
F: OnStateHook + 'static,
|
F: OnStateHook + 'static,
|
||||||
{
|
{
|
||||||
// Call hook with our mock state
|
// Call hook with our mock state
|
||||||
hook.on_state(&self.result_and_state);
|
hook.on_state(&self.state);
|
||||||
|
|
||||||
Ok(BlockExecutionOutput {
|
Ok(BlockExecutionOutput {
|
||||||
state: BundleState::default(),
|
state: BundleState::default(),
|
||||||
@ -223,7 +220,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl OnStateHook for ChannelStateHook {
|
impl OnStateHook for ChannelStateHook {
|
||||||
fn on_state(&mut self, _result_and_state: &ResultAndState) {
|
fn on_state(&mut self, _state: &EvmState) {
|
||||||
let _ = self.sender.send(self.output);
|
let _ = self.sender.send(self.output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,35 +246,26 @@ mod tests {
|
|||||||
let expected_output = 42;
|
let expected_output = 42;
|
||||||
let state_hook = Box::new(ChannelStateHook { sender: tx, output: expected_output });
|
let state_hook = Box::new(ChannelStateHook { sender: tx, output: expected_output });
|
||||||
|
|
||||||
let result_and_state = ResultAndState {
|
let state = {
|
||||||
result: ExecutionResult::Success {
|
let mut state = EvmState::default();
|
||||||
reason: SuccessReason::Stop,
|
let storage =
|
||||||
gas_used: 100,
|
EvmStorage::from_iter([(U256::from(1), EvmStorageSlot::new(U256::from(2)))]);
|
||||||
output: Output::Call(Bytes::default()),
|
state.insert(
|
||||||
logs: vec![],
|
Default::default(),
|
||||||
gas_refunded: 0,
|
Account {
|
||||||
},
|
info: AccountInfo {
|
||||||
state: {
|
balance: U256::from(100),
|
||||||
let mut state = EvmState::default();
|
nonce: 10,
|
||||||
let storage =
|
code_hash: B256::random(),
|
||||||
EvmStorage::from_iter([(U256::from(1), EvmStorageSlot::new(U256::from(2)))]);
|
code: Default::default(),
|
||||||
state.insert(
|
|
||||||
Default::default(),
|
|
||||||
Account {
|
|
||||||
info: AccountInfo {
|
|
||||||
balance: U256::from(100),
|
|
||||||
nonce: 10,
|
|
||||||
code_hash: B256::random(),
|
|
||||||
code: Default::default(),
|
|
||||||
},
|
|
||||||
storage,
|
|
||||||
status: AccountStatus::Loaded,
|
|
||||||
},
|
},
|
||||||
);
|
storage,
|
||||||
state
|
status: AccountStatus::Loaded,
|
||||||
},
|
},
|
||||||
|
);
|
||||||
|
state
|
||||||
};
|
};
|
||||||
let executor = MockExecutor { result_and_state };
|
let executor = MockExecutor { state };
|
||||||
let _result = metrics.execute_metered(executor, input, state_hook).unwrap();
|
let _result = metrics.execute_metered(executor, input, state_hook).unwrap();
|
||||||
|
|
||||||
let snapshot = snapshotter.snapshot().into_vec();
|
let snapshot = snapshotter.snapshot().into_vec();
|
||||||
@ -311,11 +299,9 @@ mod tests {
|
|||||||
let expected_output = 42;
|
let expected_output = 42;
|
||||||
let state_hook = Box::new(ChannelStateHook { sender: tx, output: expected_output });
|
let state_hook = Box::new(ChannelStateHook { sender: tx, output: expected_output });
|
||||||
|
|
||||||
let result_and_state = ResultAndState {
|
let state = EvmState::default();
|
||||||
result: ExecutionResult::Revert { gas_used: 0, output: Default::default() },
|
|
||||||
state: EvmState::default(),
|
let executor = MockExecutor { state };
|
||||||
};
|
|
||||||
let executor = MockExecutor { result_and_state };
|
|
||||||
let _result = metrics.execute_metered(executor, input, state_hook).unwrap();
|
let _result = metrics.execute_metered(executor, input, state_hook).unwrap();
|
||||||
|
|
||||||
let actual_output = rx.try_recv().unwrap();
|
let actual_output = rx.try_recv().unwrap();
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use reth_chainspec::EthereumHardforks;
|
|||||||
use reth_execution_errors::BlockExecutionError;
|
use reth_execution_errors::BlockExecutionError;
|
||||||
use reth_primitives::Block;
|
use reth_primitives::Block;
|
||||||
use revm::{Database, DatabaseCommit, Evm};
|
use revm::{Database, DatabaseCommit, Evm};
|
||||||
use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, ResultAndState, B256};
|
use revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, EnvWithHandlerCfg, EvmState, B256};
|
||||||
|
|
||||||
mod eip2935;
|
mod eip2935;
|
||||||
mod eip4788;
|
mod eip4788;
|
||||||
@ -19,15 +19,15 @@ mod eip7251;
|
|||||||
|
|
||||||
/// A hook that is called after each state change.
|
/// A hook that is called after each state change.
|
||||||
pub trait OnStateHook {
|
pub trait OnStateHook {
|
||||||
/// Invoked with the result and state after each system call.
|
/// Invoked with the state after each system call.
|
||||||
fn on_state(&mut self, state: &ResultAndState);
|
fn on_state(&mut self, state: &EvmState);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F> OnStateHook for F
|
impl<F> OnStateHook for F
|
||||||
where
|
where
|
||||||
F: FnMut(&ResultAndState),
|
F: FnMut(&EvmState),
|
||||||
{
|
{
|
||||||
fn on_state(&mut self, state: &ResultAndState) {
|
fn on_state(&mut self, state: &EvmState) {
|
||||||
self(state)
|
self(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -38,7 +38,7 @@ where
|
|||||||
pub struct NoopHook;
|
pub struct NoopHook;
|
||||||
|
|
||||||
impl OnStateHook for NoopHook {
|
impl OnStateHook for NoopHook {
|
||||||
fn on_state(&mut self, _state: &ResultAndState) {}
|
fn on_state(&mut self, _state: &EvmState) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An ephemeral helper type for executing system calls.
|
/// An ephemeral helper type for executing system calls.
|
||||||
@ -182,7 +182,7 @@ where
|
|||||||
|
|
||||||
if let Some(res) = result_and_state {
|
if let Some(res) = result_and_state {
|
||||||
if let Some(ref mut hook) = self.hook {
|
if let Some(ref mut hook) = self.hook {
|
||||||
hook.on_state(&res);
|
hook.on_state(&res.state);
|
||||||
}
|
}
|
||||||
evm.context.evm.db.commit(res.state);
|
evm.context.evm.db.commit(res.state);
|
||||||
}
|
}
|
||||||
@ -237,7 +237,7 @@ where
|
|||||||
|
|
||||||
if let Some(res) = result_and_state {
|
if let Some(res) = result_and_state {
|
||||||
if let Some(ref mut hook) = self.hook {
|
if let Some(ref mut hook) = self.hook {
|
||||||
hook.on_state(&res);
|
hook.on_state(&res.state);
|
||||||
}
|
}
|
||||||
evm.context.evm.db.commit(res.state);
|
evm.context.evm.db.commit(res.state);
|
||||||
}
|
}
|
||||||
@ -276,7 +276,7 @@ where
|
|||||||
eip7002::transact_withdrawal_requests_contract_call(&self.evm_config.clone(), evm)?;
|
eip7002::transact_withdrawal_requests_contract_call(&self.evm_config.clone(), evm)?;
|
||||||
|
|
||||||
if let Some(ref mut hook) = self.hook {
|
if let Some(ref mut hook) = self.hook {
|
||||||
hook.on_state(&result_and_state);
|
hook.on_state(&result_and_state.state);
|
||||||
}
|
}
|
||||||
evm.context.evm.db.commit(result_and_state.state);
|
evm.context.evm.db.commit(result_and_state.state);
|
||||||
|
|
||||||
@ -314,7 +314,7 @@ where
|
|||||||
eip7251::transact_consolidation_requests_contract_call(&self.evm_config.clone(), evm)?;
|
eip7251::transact_consolidation_requests_contract_call(&self.evm_config.clone(), evm)?;
|
||||||
|
|
||||||
if let Some(ref mut hook) = self.hook {
|
if let Some(ref mut hook) = self.hook {
|
||||||
hook.on_state(&result_and_state);
|
hook.on_state(&result_and_state.state);
|
||||||
}
|
}
|
||||||
evm.context.evm.db.commit(result_and_state.state);
|
evm.context.evm.db.commit(result_and_state.state);
|
||||||
|
|
||||||
@ -322,7 +322,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Delegate to stored `OnStateHook`, noop if hook is `None`.
|
/// Delegate to stored `OnStateHook`, noop if hook is `None`.
|
||||||
pub fn on_state(&mut self, state: &ResultAndState) {
|
pub fn on_state(&mut self, state: &EvmState) {
|
||||||
if let Some(ref mut hook) = &mut self.hook {
|
if let Some(ref mut hook) = &mut self.hook {
|
||||||
hook.on_state(state);
|
hook.on_state(state);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -221,7 +221,7 @@ where
|
|||||||
?transaction,
|
?transaction,
|
||||||
"Executed transaction"
|
"Executed transaction"
|
||||||
);
|
);
|
||||||
self.system_caller.on_state(&result_and_state);
|
self.system_caller.on_state(&result_and_state.state);
|
||||||
let ResultAndState { result, state } = result_and_state;
|
let ResultAndState { result, state } = result_and_state;
|
||||||
evm.db_mut().commit(state);
|
evm.db_mut().commit(state);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user