mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
refactor: use BlockExecutorProvider in InvalidBlockWitnessHook (#14594)
This commit is contained in:
@ -4,15 +4,10 @@ use alloy_rpc_types_debug::ExecutionWitness;
|
||||
use pretty_assertions::Comparison;
|
||||
use reth_chainspec::{EthChainSpec, EthereumHardforks};
|
||||
use reth_engine_primitives::InvalidBlockHook;
|
||||
use reth_evm::{
|
||||
state_change::post_block_balance_increments, system_calls::SystemCaller, ConfigureEvmFor, Evm,
|
||||
};
|
||||
use reth_evm::execute::{BlockExecutorProvider, Executor};
|
||||
use reth_primitives::{NodePrimitives, RecoveredBlock, SealedHeader};
|
||||
use reth_provider::{BlockExecutionOutput, ChainSpecProvider, StateProviderFactory};
|
||||
use reth_revm::{
|
||||
database::StateProviderDatabase,
|
||||
db::{states::bundle_state::BundleRetention, StateBuilder},
|
||||
};
|
||||
use reth_revm::database::StateProviderDatabase;
|
||||
use reth_rpc_api::DebugApiClient;
|
||||
use reth_tracing::tracing::warn;
|
||||
use reth_trie::{updates::TrieUpdates, HashedStorage};
|
||||
@ -21,11 +16,11 @@ use std::{collections::HashMap, fmt::Debug, fs::File, io::Write, path::PathBuf};
|
||||
|
||||
/// Generates a witness for the given block and saves it to a file.
|
||||
#[derive(Debug)]
|
||||
pub struct InvalidBlockWitnessHook<P, EvmConfig> {
|
||||
pub struct InvalidBlockWitnessHook<P, E> {
|
||||
/// The provider to read the historical state and do the EVM execution.
|
||||
provider: P,
|
||||
/// The EVM configuration to use for the execution.
|
||||
evm_config: EvmConfig,
|
||||
executor: E,
|
||||
/// The directory to write the witness to. Additionally, diff files will be written to this
|
||||
/// directory in case of failed sanity checks.
|
||||
output_directory: PathBuf,
|
||||
@ -33,27 +28,29 @@ pub struct InvalidBlockWitnessHook<P, EvmConfig> {
|
||||
healthy_node_client: Option<jsonrpsee::http_client::HttpClient>,
|
||||
}
|
||||
|
||||
impl<P, EvmConfig> InvalidBlockWitnessHook<P, EvmConfig> {
|
||||
impl<P, E> InvalidBlockWitnessHook<P, E> {
|
||||
/// Creates a new witness hook.
|
||||
pub const fn new(
|
||||
provider: P,
|
||||
evm_config: EvmConfig,
|
||||
executor: E,
|
||||
output_directory: PathBuf,
|
||||
healthy_node_client: Option<jsonrpsee::http_client::HttpClient>,
|
||||
) -> Self {
|
||||
Self { provider, evm_config, output_directory, healthy_node_client }
|
||||
Self { provider, executor, output_directory, healthy_node_client }
|
||||
}
|
||||
}
|
||||
|
||||
impl<P, EvmConfig> InvalidBlockWitnessHook<P, EvmConfig>
|
||||
impl<P, E, N> InvalidBlockWitnessHook<P, E>
|
||||
where
|
||||
P: StateProviderFactory
|
||||
+ ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
E: BlockExecutorProvider<Primitives = N>,
|
||||
N: NodePrimitives,
|
||||
{
|
||||
fn on_invalid_block<N>(
|
||||
fn on_invalid_block(
|
||||
&self,
|
||||
parent_header: &SealedHeader<N::BlockHeader>,
|
||||
block: &RecoveredBlock<N::Block>,
|
||||
@ -62,46 +59,17 @@ where
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
N: NodePrimitives,
|
||||
EvmConfig: ConfigureEvmFor<N>,
|
||||
{
|
||||
// TODO(alexey): unify with `DebugApi::debug_execution_witness`
|
||||
|
||||
// Setup database.
|
||||
let mut db = StateBuilder::new()
|
||||
.with_database(StateProviderDatabase::new(
|
||||
self.provider.state_by_block_hash(parent_header.hash())?,
|
||||
))
|
||||
.with_bundle_update()
|
||||
.build();
|
||||
let mut executor = self.executor.executor(StateProviderDatabase::new(
|
||||
self.provider.state_by_block_hash(parent_header.hash())?,
|
||||
));
|
||||
|
||||
// Setup EVM
|
||||
let mut evm = self.evm_config.evm_for_block(&mut db, block.header());
|
||||
|
||||
let mut system_caller = SystemCaller::new(self.provider.chain_spec());
|
||||
|
||||
// Apply pre-block system contract calls.
|
||||
system_caller.apply_pre_execution_changes(block.header(), &mut evm)?;
|
||||
|
||||
// Re-execute all of the transactions in the block to load all touched accounts into
|
||||
// the cache DB.
|
||||
for tx in block.transactions_recovered() {
|
||||
evm.transact_commit(self.evm_config.tx_env(tx))?;
|
||||
}
|
||||
|
||||
drop(evm);
|
||||
|
||||
// use U256::MAX here for difficulty, because fetching it is annoying
|
||||
// NOTE: This is not mut because we are not doing the DAO irregular state change here
|
||||
let balance_increments =
|
||||
post_block_balance_increments(self.provider.chain_spec().as_ref(), block);
|
||||
|
||||
// increment balances
|
||||
db.increment_balances(balance_increments)?;
|
||||
|
||||
// Merge all state transitions
|
||||
db.merge_transitions(BundleRetention::Reverts);
|
||||
executor.execute_one(block)?;
|
||||
|
||||
// Take the bundle state
|
||||
let mut db = executor.into_state();
|
||||
let mut bundle_state = db.take_bundle();
|
||||
|
||||
// Initialize a map of preimages.
|
||||
@ -278,15 +246,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<P, EvmConfig, N> InvalidBlockHook<N> for InvalidBlockWitnessHook<P, EvmConfig>
|
||||
impl<P, E, N: NodePrimitives> InvalidBlockHook<N> for InvalidBlockWitnessHook<P, E>
|
||||
where
|
||||
N: NodePrimitives,
|
||||
P: StateProviderFactory
|
||||
+ ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
EvmConfig: ConfigureEvmFor<N>,
|
||||
E: BlockExecutorProvider<Primitives = N>,
|
||||
{
|
||||
fn on_invalid_block(
|
||||
&self,
|
||||
@ -295,7 +262,7 @@ where
|
||||
output: &BlockExecutionOutput<N::Receipt>,
|
||||
trie_updates: Option<(&TrieUpdates, B256)>,
|
||||
) {
|
||||
if let Err(err) = self.on_invalid_block::<N>(parent_header, block, output, trie_updates) {
|
||||
if let Err(err) = self.on_invalid_block(parent_header, block, output, trie_updates) {
|
||||
warn!(target: "engine::invalid_block_hooks::witness", %err, "Failed to invoke hook");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user