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 pretty_assertions::Comparison;
|
||||||
use reth_chainspec::{EthChainSpec, EthereumHardforks};
|
use reth_chainspec::{EthChainSpec, EthereumHardforks};
|
||||||
use reth_engine_primitives::InvalidBlockHook;
|
use reth_engine_primitives::InvalidBlockHook;
|
||||||
use reth_evm::{
|
use reth_evm::execute::{BlockExecutorProvider, Executor};
|
||||||
state_change::post_block_balance_increments, system_calls::SystemCaller, ConfigureEvmFor, Evm,
|
|
||||||
};
|
|
||||||
use reth_primitives::{NodePrimitives, RecoveredBlock, SealedHeader};
|
use reth_primitives::{NodePrimitives, RecoveredBlock, SealedHeader};
|
||||||
use reth_provider::{BlockExecutionOutput, ChainSpecProvider, StateProviderFactory};
|
use reth_provider::{BlockExecutionOutput, ChainSpecProvider, StateProviderFactory};
|
||||||
use reth_revm::{
|
use reth_revm::database::StateProviderDatabase;
|
||||||
database::StateProviderDatabase,
|
|
||||||
db::{states::bundle_state::BundleRetention, StateBuilder},
|
|
||||||
};
|
|
||||||
use reth_rpc_api::DebugApiClient;
|
use reth_rpc_api::DebugApiClient;
|
||||||
use reth_tracing::tracing::warn;
|
use reth_tracing::tracing::warn;
|
||||||
use reth_trie::{updates::TrieUpdates, HashedStorage};
|
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.
|
/// Generates a witness for the given block and saves it to a file.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct InvalidBlockWitnessHook<P, EvmConfig> {
|
pub struct InvalidBlockWitnessHook<P, E> {
|
||||||
/// The provider to read the historical state and do the EVM execution.
|
/// The provider to read the historical state and do the EVM execution.
|
||||||
provider: P,
|
provider: P,
|
||||||
/// The EVM configuration to use for the execution.
|
/// 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
|
/// The directory to write the witness to. Additionally, diff files will be written to this
|
||||||
/// directory in case of failed sanity checks.
|
/// directory in case of failed sanity checks.
|
||||||
output_directory: PathBuf,
|
output_directory: PathBuf,
|
||||||
@ -33,27 +28,29 @@ pub struct InvalidBlockWitnessHook<P, EvmConfig> {
|
|||||||
healthy_node_client: Option<jsonrpsee::http_client::HttpClient>,
|
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.
|
/// Creates a new witness hook.
|
||||||
pub const fn new(
|
pub const fn new(
|
||||||
provider: P,
|
provider: P,
|
||||||
evm_config: EvmConfig,
|
executor: E,
|
||||||
output_directory: PathBuf,
|
output_directory: PathBuf,
|
||||||
healthy_node_client: Option<jsonrpsee::http_client::HttpClient>,
|
healthy_node_client: Option<jsonrpsee::http_client::HttpClient>,
|
||||||
) -> Self {
|
) -> 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
|
where
|
||||||
P: StateProviderFactory
|
P: StateProviderFactory
|
||||||
+ ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
|
+ ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
|
||||||
+ Send
|
+ Send
|
||||||
+ Sync
|
+ Sync
|
||||||
+ 'static,
|
+ 'static,
|
||||||
|
E: BlockExecutorProvider<Primitives = N>,
|
||||||
|
N: NodePrimitives,
|
||||||
{
|
{
|
||||||
fn on_invalid_block<N>(
|
fn on_invalid_block(
|
||||||
&self,
|
&self,
|
||||||
parent_header: &SealedHeader<N::BlockHeader>,
|
parent_header: &SealedHeader<N::BlockHeader>,
|
||||||
block: &RecoveredBlock<N::Block>,
|
block: &RecoveredBlock<N::Block>,
|
||||||
@ -62,46 +59,17 @@ where
|
|||||||
) -> eyre::Result<()>
|
) -> eyre::Result<()>
|
||||||
where
|
where
|
||||||
N: NodePrimitives,
|
N: NodePrimitives,
|
||||||
EvmConfig: ConfigureEvmFor<N>,
|
|
||||||
{
|
{
|
||||||
// TODO(alexey): unify with `DebugApi::debug_execution_witness`
|
// TODO(alexey): unify with `DebugApi::debug_execution_witness`
|
||||||
|
|
||||||
// Setup database.
|
let mut executor = self.executor.executor(StateProviderDatabase::new(
|
||||||
let mut db = StateBuilder::new()
|
self.provider.state_by_block_hash(parent_header.hash())?,
|
||||||
.with_database(StateProviderDatabase::new(
|
));
|
||||||
self.provider.state_by_block_hash(parent_header.hash())?,
|
|
||||||
))
|
|
||||||
.with_bundle_update()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// Setup EVM
|
executor.execute_one(block)?;
|
||||||
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);
|
|
||||||
|
|
||||||
// Take the bundle state
|
// Take the bundle state
|
||||||
|
let mut db = executor.into_state();
|
||||||
let mut bundle_state = db.take_bundle();
|
let mut bundle_state = db.take_bundle();
|
||||||
|
|
||||||
// Initialize a map of preimages.
|
// 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
|
where
|
||||||
N: NodePrimitives,
|
|
||||||
P: StateProviderFactory
|
P: StateProviderFactory
|
||||||
+ ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
|
+ ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
|
||||||
+ Send
|
+ Send
|
||||||
+ Sync
|
+ Sync
|
||||||
+ 'static,
|
+ 'static,
|
||||||
EvmConfig: ConfigureEvmFor<N>,
|
E: BlockExecutorProvider<Primitives = N>,
|
||||||
{
|
{
|
||||||
fn on_invalid_block(
|
fn on_invalid_block(
|
||||||
&self,
|
&self,
|
||||||
@ -295,7 +262,7 @@ where
|
|||||||
output: &BlockExecutionOutput<N::Receipt>,
|
output: &BlockExecutionOutput<N::Receipt>,
|
||||||
trie_updates: Option<(&TrieUpdates, B256)>,
|
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");
|
warn!(target: "engine::invalid_block_hooks::witness", %err, "Failed to invoke hook");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -895,7 +895,7 @@ where
|
|||||||
Ok(match hook {
|
Ok(match hook {
|
||||||
InvalidBlockHookType::Witness => Box::new(InvalidBlockWitnessHook::new(
|
InvalidBlockHookType::Witness => Box::new(InvalidBlockWitnessHook::new(
|
||||||
self.blockchain_db().clone(),
|
self.blockchain_db().clone(),
|
||||||
self.components().evm_config().clone(),
|
self.components().block_executor().clone(),
|
||||||
output_directory,
|
output_directory,
|
||||||
healthy_node_rpc_client.clone(),
|
healthy_node_rpc_client.clone(),
|
||||||
)),
|
)),
|
||||||
|
|||||||
Reference in New Issue
Block a user