mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-02-08 05:55:21 -05:00
feat: re-introduce debug.reorg logic (#14676)
This commit is contained in:
@@ -5,6 +5,7 @@ use reth_chainspec::EthChainSpec;
|
||||
use reth_db::{test_utils::TempDatabase, DatabaseEnv};
|
||||
use reth_engine_local::LocalPayloadAttributesBuilder;
|
||||
use reth_network_api::test_utils::PeersHandleProvider;
|
||||
use reth_node_api::NodePrimitives;
|
||||
use reth_node_builder::{
|
||||
components::NodeComponentsBuilder,
|
||||
rpc::{EngineValidatorAddOn, RethRpcAddOns},
|
||||
@@ -52,6 +53,10 @@ pub async fn setup<N>(
|
||||
) -> eyre::Result<(Vec<NodeHelperType<N>>, TaskManager, Wallet)>
|
||||
where
|
||||
N: Default + Node<TmpNodeAdapter<N>> + NodeTypesForProvider + NodeTypesWithEngine,
|
||||
N::Primitives: NodePrimitives<
|
||||
BlockHeader = alloy_consensus::Header,
|
||||
BlockBody = alloy_consensus::BlockBody<<N::Primitives as NodePrimitives>::SignedTx>,
|
||||
>,
|
||||
N::ComponentsBuilder: NodeComponentsBuilder<
|
||||
TmpNodeAdapter<N>,
|
||||
Components: NodeComponents<TmpNodeAdapter<N>, Network: PeersHandleProvider>,
|
||||
@@ -123,6 +128,10 @@ where
|
||||
+ Node<TmpNodeAdapter<N, BlockchainProvider<NodeTypesWithDBAdapter<N, TmpDB>>>>
|
||||
+ NodeTypesWithEngine
|
||||
+ NodeTypesForProvider,
|
||||
N::Primitives: NodePrimitives<
|
||||
BlockHeader = alloy_consensus::Header,
|
||||
BlockBody = alloy_consensus::BlockBody<<N::Primitives as NodePrimitives>::SignedTx>,
|
||||
>,
|
||||
N::ComponentsBuilder: NodeComponentsBuilder<
|
||||
TmpNodeAdapter<N, BlockchainProvider<NodeTypesWithDBAdapter<N, TmpDB>>>,
|
||||
Components: NodeComponents<
|
||||
|
||||
@@ -12,6 +12,7 @@ workspace = true
|
||||
|
||||
[dependencies]
|
||||
# reth
|
||||
reth-ethereum-primitives.workspace = true
|
||||
reth-primitives.workspace = true
|
||||
reth-primitives-traits.workspace = true
|
||||
reth-errors.workspace = true
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use futures::Stream;
|
||||
use reth_engine_primitives::{BeaconEngineMessage, EngineTypes};
|
||||
use reth_payload_validator::ExecutionPayloadValidator;
|
||||
use std::path::PathBuf;
|
||||
use tokio_util::either::Either;
|
||||
|
||||
@@ -94,14 +93,14 @@ pub trait EngineMessageStreamExt<Engine: EngineTypes>:
|
||||
}
|
||||
|
||||
/// Creates reorgs with specified frequency.
|
||||
fn reorg<Provider, Evm, Spec>(
|
||||
fn reorg<Provider, Evm, Validator>(
|
||||
self,
|
||||
provider: Provider,
|
||||
evm_config: Evm,
|
||||
payload_validator: ExecutionPayloadValidator<Spec>,
|
||||
payload_validator: Validator,
|
||||
frequency: usize,
|
||||
depth: Option<usize>,
|
||||
) -> EngineReorg<Self, Engine, Provider, Evm, Spec>
|
||||
) -> EngineReorg<Self, Engine, Provider, Evm, Validator>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
@@ -117,14 +116,14 @@ pub trait EngineMessageStreamExt<Engine: EngineTypes>:
|
||||
|
||||
/// If frequency is [Some], returns the stream that creates reorgs with
|
||||
/// specified frequency. Otherwise, returns `Self`.
|
||||
fn maybe_reorg<Provider, Evm, Spec>(
|
||||
fn maybe_reorg<Provider, Evm, Validator>(
|
||||
self,
|
||||
provider: Provider,
|
||||
evm_config: Evm,
|
||||
payload_validator: ExecutionPayloadValidator<Spec>,
|
||||
payload_validator: Validator,
|
||||
frequency: Option<usize>,
|
||||
depth: Option<usize>,
|
||||
) -> Either<EngineReorg<Self, Engine, Provider, Evm, Spec>, Self>
|
||||
) -> Either<EngineReorg<Self, Engine, Provider, Evm, Validator>, Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
|
||||
@@ -1,31 +1,26 @@
|
||||
//! Stream wrapper that simulates reorgs.
|
||||
|
||||
use alloy_consensus::{Header, Transaction};
|
||||
use alloy_rpc_types_engine::{
|
||||
CancunPayloadFields, ExecutionData, ExecutionPayload, ExecutionPayloadSidecar, ForkchoiceState,
|
||||
PayloadStatus,
|
||||
};
|
||||
use alloy_consensus::{BlockHeader, Header, TxReceipt};
|
||||
use alloy_rpc_types_engine::{ForkchoiceState, PayloadStatus};
|
||||
use futures::{stream::FuturesUnordered, Stream, StreamExt, TryFutureExt};
|
||||
use itertools::Either;
|
||||
use reth_chainspec::EthChainSpec;
|
||||
use reth_engine_primitives::{
|
||||
BeaconEngineMessage, BeaconOnNewPayloadError, EngineTypes, OnForkChoiceUpdated,
|
||||
BeaconEngineMessage, BeaconOnNewPayloadError, EngineTypes, ExecutionPayload as _,
|
||||
OnForkChoiceUpdated, PayloadValidator,
|
||||
};
|
||||
use reth_errors::{BlockExecutionError, RethError, RethResult};
|
||||
use reth_ethereum_forks::EthereumHardforks;
|
||||
use reth_evm::{
|
||||
state_change::post_block_withdrawals_balance_increments, system_calls::SystemCaller,
|
||||
ConfigureEvm, Evm, EvmError,
|
||||
use reth_errors::{BlockExecutionError, BlockValidationError, RethError, RethResult};
|
||||
use reth_evm::execute::{BlockExecutionStrategy, BlockExecutionStrategyFactory};
|
||||
use reth_payload_primitives::{BuiltPayload, EngineApiMessageVersion};
|
||||
use reth_primitives::{BlockBody, NodePrimitives, SealedBlock};
|
||||
use reth_primitives_traits::{block::Block as _, proofs, BlockBody as _, SignedTransaction};
|
||||
use reth_provider::{
|
||||
BlockExecutionResult, BlockReader, ChainSpecProvider, ExecutionOutcome, ProviderError,
|
||||
StateProviderFactory,
|
||||
};
|
||||
use reth_payload_primitives::EngineApiMessageVersion;
|
||||
use reth_payload_validator::ExecutionPayloadValidator;
|
||||
use reth_primitives::{Block, BlockBody, Receipt};
|
||||
use reth_primitives_traits::{block::Block as _, proofs, SignedTransaction};
|
||||
use reth_provider::{BlockReader, ExecutionOutcome, ProviderError, StateProviderFactory};
|
||||
use reth_revm::{
|
||||
database::StateProviderDatabase,
|
||||
db::{states::bundle_state::BundleRetention, State},
|
||||
DatabaseCommit,
|
||||
};
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
@@ -52,7 +47,7 @@ type ReorgResponseFut = Pin<Box<dyn Future<Output = EngineReorgResponse> + Send
|
||||
/// Engine API stream wrapper that simulates reorgs with specified frequency.
|
||||
#[derive(Debug)]
|
||||
#[pin_project::pin_project]
|
||||
pub struct EngineReorg<S, Engine: EngineTypes, Provider, Evm, Spec> {
|
||||
pub struct EngineReorg<S, Engine: EngineTypes, Provider, Evm, Validator> {
|
||||
/// Underlying stream
|
||||
#[pin]
|
||||
stream: S,
|
||||
@@ -61,7 +56,7 @@ pub struct EngineReorg<S, Engine: EngineTypes, Provider, Evm, Spec> {
|
||||
/// Evm configuration.
|
||||
evm_config: Evm,
|
||||
/// Payload validator.
|
||||
payload_validator: ExecutionPayloadValidator<Spec>,
|
||||
payload_validator: Validator,
|
||||
/// The frequency of reorgs.
|
||||
frequency: usize,
|
||||
/// The depth of reorgs.
|
||||
@@ -77,13 +72,15 @@ pub struct EngineReorg<S, Engine: EngineTypes, Provider, Evm, Spec> {
|
||||
reorg_responses: FuturesUnordered<ReorgResponseFut>,
|
||||
}
|
||||
|
||||
impl<S, Engine: EngineTypes, Provider, Evm, Spec> EngineReorg<S, Engine, Provider, Evm, Spec> {
|
||||
impl<S, Engine: EngineTypes, Provider, Evm, Validator>
|
||||
EngineReorg<S, Engine, Provider, Evm, Validator>
|
||||
{
|
||||
/// Creates new [`EngineReorg`] stream wrapper.
|
||||
pub fn new(
|
||||
stream: S,
|
||||
provider: Provider,
|
||||
evm_config: Evm,
|
||||
payload_validator: ExecutionPayloadValidator<Spec>,
|
||||
payload_validator: Validator,
|
||||
frequency: usize,
|
||||
depth: usize,
|
||||
) -> Self {
|
||||
@@ -102,13 +99,22 @@ impl<S, Engine: EngineTypes, Provider, Evm, Spec> EngineReorg<S, Engine, Provide
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, Engine, Provider, Evm, Spec> Stream for EngineReorg<S, Engine, Provider, Evm, Spec>
|
||||
impl<S, Engine, Provider, Evm, Validator, N, T> Stream
|
||||
for EngineReorg<S, Engine, Provider, Evm, Validator>
|
||||
where
|
||||
T: SignedTransaction,
|
||||
N: NodePrimitives<
|
||||
BlockHeader = alloy_consensus::Header,
|
||||
SignedTx = T,
|
||||
BlockBody = alloy_consensus::BlockBody<T>,
|
||||
>,
|
||||
S: Stream<Item = BeaconEngineMessage<Engine>>,
|
||||
Engine: EngineTypes<ExecutionData = ExecutionData>,
|
||||
Provider: BlockReader<Block = reth_primitives::Block> + StateProviderFactory,
|
||||
Evm: ConfigureEvm<Header = Header, Transaction = reth_primitives::TransactionSigned>,
|
||||
Spec: EthChainSpec + EthereumHardforks,
|
||||
Engine: EngineTypes<BuiltPayload: BuiltPayload<Primitives = N>>,
|
||||
Provider: BlockReader<Header = N::BlockHeader, Block = N::Block>
|
||||
+ StateProviderFactory
|
||||
+ ChainSpecProvider,
|
||||
Evm: BlockExecutionStrategyFactory<Primitives = N>,
|
||||
Validator: PayloadValidator<ExecutionData = Engine::ExecutionData, Block = N::Block>,
|
||||
{
|
||||
type Item = S::Item;
|
||||
|
||||
@@ -163,7 +169,7 @@ where
|
||||
// forkchoice state. We will rely on CL to reorg us back to canonical chain.
|
||||
// TODO: This is an expensive blocking operation, ideally it's spawned as a task
|
||||
// so that the stream could yield the control back.
|
||||
let reorg_payload = match create_reorg_head(
|
||||
let reorg_block = match create_reorg_head(
|
||||
this.provider,
|
||||
this.evm_config,
|
||||
this.payload_validator,
|
||||
@@ -184,7 +190,7 @@ where
|
||||
let reorg_forkchoice_state = ForkchoiceState {
|
||||
finalized_block_hash: last_forkchoice_state.finalized_block_hash,
|
||||
safe_block_hash: last_forkchoice_state.safe_block_hash,
|
||||
head_block_hash: reorg_payload.block_hash(),
|
||||
head_block_hash: reorg_block.hash(),
|
||||
};
|
||||
|
||||
let (reorg_payload_tx, reorg_payload_rx) = oneshot::channel();
|
||||
@@ -199,7 +205,7 @@ where
|
||||
BeaconEngineMessage::NewPayload { payload, tx },
|
||||
// Reorg payload
|
||||
BeaconEngineMessage::NewPayload {
|
||||
payload: reorg_payload,
|
||||
payload: Engine::block_to_payload(reorg_block),
|
||||
tx: reorg_payload_tx,
|
||||
},
|
||||
// Reorg forkchoice state
|
||||
@@ -241,19 +247,27 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn create_reorg_head<Provider, Evm, Spec>(
|
||||
fn create_reorg_head<Provider, Evm, Validator, N, T>(
|
||||
provider: &Provider,
|
||||
evm_config: &Evm,
|
||||
payload_validator: &ExecutionPayloadValidator<Spec>,
|
||||
payload_validator: &Validator,
|
||||
mut depth: usize,
|
||||
next_payload: ExecutionData,
|
||||
) -> RethResult<ExecutionData>
|
||||
next_payload: Validator::ExecutionData,
|
||||
) -> RethResult<SealedBlock<N::Block>>
|
||||
where
|
||||
Provider: BlockReader<Block = reth_primitives::Block> + StateProviderFactory,
|
||||
Evm: ConfigureEvm<Header = Header, Transaction = reth_primitives::TransactionSigned>,
|
||||
Spec: EthChainSpec + EthereumHardforks,
|
||||
T: SignedTransaction,
|
||||
N: NodePrimitives<
|
||||
BlockHeader = alloy_consensus::Header,
|
||||
SignedTx = T,
|
||||
BlockBody = alloy_consensus::BlockBody<T>,
|
||||
>,
|
||||
Provider: BlockReader<Header = N::BlockHeader, Block = N::Block>
|
||||
+ StateProviderFactory
|
||||
+ ChainSpecProvider<ChainSpec: EthChainSpec>,
|
||||
Evm: BlockExecutionStrategyFactory<Primitives = N>,
|
||||
Validator: PayloadValidator<Block = N::Block>,
|
||||
{
|
||||
let chain_spec = payload_validator.chain_spec();
|
||||
let chain_spec = provider.chain_spec();
|
||||
|
||||
// Ensure next payload is valid.
|
||||
let next_block =
|
||||
@@ -268,93 +282,72 @@ where
|
||||
.block_by_hash(previous_hash)?
|
||||
.ok_or_else(|| ProviderError::HeaderNotFound(previous_hash.into()))?;
|
||||
if depth == 0 {
|
||||
break 'target reorg_target
|
||||
break 'target reorg_target.seal_slow()
|
||||
}
|
||||
|
||||
depth -= 1;
|
||||
previous_hash = reorg_target.parent_hash;
|
||||
candidate_transactions = reorg_target.body.transactions;
|
||||
previous_hash = reorg_target.header().parent_hash();
|
||||
candidate_transactions = reorg_target.into_body().into_transactions();
|
||||
}
|
||||
};
|
||||
let reorg_target_parent = provider
|
||||
.block_by_hash(reorg_target.parent_hash)?
|
||||
.ok_or_else(|| ProviderError::HeaderNotFound(reorg_target.parent_hash.into()))?;
|
||||
.block_by_hash(reorg_target.header().parent_hash)?
|
||||
.ok_or_else(|| ProviderError::HeaderNotFound(reorg_target.header().parent_hash.into()))?;
|
||||
|
||||
debug!(target: "engine::stream::reorg", number = reorg_target.number, hash = %previous_hash, "Selected reorg target");
|
||||
debug!(target: "engine::stream::reorg", number = reorg_target.header().number, hash = %previous_hash, "Selected reorg target");
|
||||
|
||||
// Configure state
|
||||
let state_provider = provider.state_by_block_hash(reorg_target.parent_hash)?;
|
||||
let state_provider = provider.state_by_block_hash(reorg_target.header().parent_hash)?;
|
||||
let mut state = State::builder()
|
||||
.with_database_ref(StateProviderDatabase::new(&state_provider))
|
||||
.with_bundle_update()
|
||||
.build();
|
||||
|
||||
// Configure EVM
|
||||
let mut evm = evm_config.evm_for_block(&mut state, &reorg_target.header);
|
||||
let mut strategy = evm_config.create_strategy(&mut state, &reorg_target);
|
||||
|
||||
// apply eip-4788 pre block contract call
|
||||
let mut system_caller = SystemCaller::new(chain_spec.clone());
|
||||
|
||||
system_caller
|
||||
.apply_beacon_root_contract_call(reorg_target.parent_beacon_block_root, &mut evm)?;
|
||||
strategy.apply_pre_execution_changes()?;
|
||||
|
||||
let mut cumulative_gas_used = 0;
|
||||
let mut sum_blob_gas_used = 0;
|
||||
let mut transactions = Vec::new();
|
||||
let mut receipts = Vec::new();
|
||||
let mut versioned_hashes = Vec::new();
|
||||
for tx in candidate_transactions {
|
||||
// ensure we still have capacity for this transaction
|
||||
if cumulative_gas_used + tx.gas_limit() > reorg_target.gas_limit {
|
||||
continue
|
||||
}
|
||||
|
||||
// Configure the environment for the block.
|
||||
let tx_recovered =
|
||||
tx.try_clone_into_recovered().map_err(|_| ProviderError::SenderRecoveryError)?;
|
||||
let tx_env = evm_config.tx_env(tx_recovered);
|
||||
let exec_result = match evm.transact(tx_env) {
|
||||
Ok(result) => result,
|
||||
Err(err) if err.is_invalid_tx_err() => {
|
||||
trace!(target: "engine::stream::reorg", hash = %tx.tx_hash(), ?err, "Error executing transaction from next block");
|
||||
let gas_used = match strategy.execute_transaction(tx_recovered.as_recovered_ref()) {
|
||||
Ok(gas_used) => gas_used,
|
||||
Err(BlockExecutionError::Validation(BlockValidationError::InvalidTx {
|
||||
hash,
|
||||
error,
|
||||
})) => {
|
||||
trace!(target: "engine::stream::reorg", hash = %hash, ?error, "Error executing transaction from next block");
|
||||
continue
|
||||
}
|
||||
// Treat error as fatal
|
||||
Err(error) => return Err(RethError::Execution(BlockExecutionError::other(error))),
|
||||
Err(error) => return Err(RethError::Execution(error)),
|
||||
};
|
||||
evm.db_mut().commit(exec_result.state);
|
||||
|
||||
if let Some(blob_tx) = tx.as_eip4844() {
|
||||
sum_blob_gas_used += blob_tx.blob_gas();
|
||||
versioned_hashes.extend(blob_tx.blob_versioned_hashes.clone());
|
||||
if tx.is_eip4844() {
|
||||
sum_blob_gas_used += tx.blob_gas_used().unwrap_or_default();
|
||||
}
|
||||
|
||||
cumulative_gas_used += exec_result.result.gas_used();
|
||||
receipts.push(Receipt {
|
||||
tx_type: tx.tx_type(),
|
||||
success: exec_result.result.is_success(),
|
||||
cumulative_gas_used,
|
||||
logs: exec_result.result.into_logs().into_iter().collect(),
|
||||
});
|
||||
cumulative_gas_used += gas_used;
|
||||
|
||||
// append transaction to the list of executed transactions
|
||||
transactions.push(tx);
|
||||
}
|
||||
drop(evm);
|
||||
|
||||
if let Some(withdrawals) = &reorg_target.body.withdrawals {
|
||||
state.increment_balances(post_block_withdrawals_balance_increments(
|
||||
chain_spec,
|
||||
reorg_target.timestamp,
|
||||
withdrawals,
|
||||
))?;
|
||||
}
|
||||
let BlockExecutionResult { receipts, .. } = strategy.apply_post_execution_changes()?;
|
||||
|
||||
// merge all transitions into bundle state, this would apply the withdrawal balance changes
|
||||
// and 4788 contract call
|
||||
state.merge_transitions(BundleRetention::PlainState);
|
||||
|
||||
let outcome: ExecutionOutcome = ExecutionOutcome::new(
|
||||
let outcome = ExecutionOutcome::new(
|
||||
state.take_bundle(),
|
||||
vec![receipts],
|
||||
reorg_target.number,
|
||||
@@ -364,62 +357,48 @@ where
|
||||
|
||||
let (blob_gas_used, excess_blob_gas) =
|
||||
if let Some(blob_params) = chain_spec.blob_params_at_timestamp(reorg_target.timestamp) {
|
||||
(Some(sum_blob_gas_used), reorg_target_parent.next_block_excess_blob_gas(blob_params))
|
||||
(
|
||||
Some(sum_blob_gas_used),
|
||||
reorg_target_parent.header().next_block_excess_blob_gas(blob_params),
|
||||
)
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
|
||||
let reorg_block = Block {
|
||||
header: Header {
|
||||
let (header, body) = reorg_target.split_header_body();
|
||||
|
||||
let reorg_block = N::Block::new(
|
||||
Header {
|
||||
// Set same fields as the reorg target
|
||||
parent_hash: reorg_target.header.parent_hash,
|
||||
ommers_hash: reorg_target.header.ommers_hash,
|
||||
beneficiary: reorg_target.header.beneficiary,
|
||||
difficulty: reorg_target.header.difficulty,
|
||||
number: reorg_target.header.number,
|
||||
gas_limit: reorg_target.header.gas_limit,
|
||||
timestamp: reorg_target.header.timestamp,
|
||||
extra_data: reorg_target.header.extra_data,
|
||||
mix_hash: reorg_target.header.mix_hash,
|
||||
nonce: reorg_target.header.nonce,
|
||||
base_fee_per_gas: reorg_target.header.base_fee_per_gas,
|
||||
parent_beacon_block_root: reorg_target.header.parent_beacon_block_root,
|
||||
withdrawals_root: reorg_target.header.withdrawals_root,
|
||||
parent_hash: header.parent_hash,
|
||||
ommers_hash: header.ommers_hash,
|
||||
beneficiary: header.beneficiary,
|
||||
difficulty: header.difficulty,
|
||||
number: header.number,
|
||||
gas_limit: header.gas_limit,
|
||||
timestamp: header.timestamp,
|
||||
extra_data: header.extra_data,
|
||||
mix_hash: header.mix_hash,
|
||||
nonce: header.nonce,
|
||||
base_fee_per_gas: header.base_fee_per_gas,
|
||||
parent_beacon_block_root: header.parent_beacon_block_root,
|
||||
withdrawals_root: header.withdrawals_root,
|
||||
|
||||
// Compute or add new fields
|
||||
transactions_root: proofs::calculate_transaction_root(&transactions),
|
||||
receipts_root: outcome.ethereum_receipts_root(reorg_target.header.number).unwrap(),
|
||||
logs_bloom: outcome.block_logs_bloom(reorg_target.header.number).unwrap(),
|
||||
receipts_root: proofs::calculate_receipt_root(
|
||||
&outcome.receipts()[0].iter().map(|r| r.with_bloom_ref()).collect::<Vec<_>>(),
|
||||
),
|
||||
logs_bloom: outcome.block_logs_bloom(header.number).unwrap(),
|
||||
gas_used: cumulative_gas_used,
|
||||
blob_gas_used,
|
||||
excess_blob_gas,
|
||||
state_root: state_provider.state_root(hashed_state)?,
|
||||
requests_hash: None, // TODO(prague)
|
||||
},
|
||||
body: BlockBody {
|
||||
transactions,
|
||||
ommers: reorg_target.body.ommers,
|
||||
withdrawals: reorg_target.body.withdrawals,
|
||||
},
|
||||
}
|
||||
BlockBody { transactions, ommers: body.ommers, withdrawals: body.withdrawals },
|
||||
)
|
||||
.seal_slow();
|
||||
|
||||
Ok(ExecutionData {
|
||||
payload: ExecutionPayload::from_block_unchecked(
|
||||
reorg_block.hash(),
|
||||
&reorg_block.into_block(),
|
||||
)
|
||||
.0,
|
||||
// todo(onbjerg): how do we support execution requests?
|
||||
sidecar: reorg_target
|
||||
.header
|
||||
.parent_beacon_block_root
|
||||
.map(|root| {
|
||||
ExecutionPayloadSidecar::v3(CancunPayloadFields {
|
||||
parent_beacon_block_root: root,
|
||||
versioned_hashes,
|
||||
})
|
||||
})
|
||||
.unwrap_or_else(ExecutionPayloadSidecar::none),
|
||||
})
|
||||
Ok(reorg_block)
|
||||
}
|
||||
|
||||
@@ -20,9 +20,7 @@ use reth_evm::{
|
||||
ConfigureEvm, Database, Evm, EvmEnv, EvmFactory, TransactionEnv,
|
||||
};
|
||||
use reth_execution_types::BlockExecutionResult;
|
||||
use reth_primitives::{
|
||||
EthPrimitives, Receipt, Recovered, RecoveredBlock, SealedBlock, TransactionSigned,
|
||||
};
|
||||
use reth_primitives::{EthPrimitives, Receipt, Recovered, SealedBlock, TransactionSigned};
|
||||
use reth_primitives_traits::NodePrimitives;
|
||||
use reth_revm::{
|
||||
context_interface::result::ResultAndState, db::State, specification::hardfork::SpecId,
|
||||
@@ -40,15 +38,15 @@ where
|
||||
type Primitives = EthPrimitives;
|
||||
|
||||
fn create_strategy<'a, DB>(
|
||||
&'a mut self,
|
||||
&'a self,
|
||||
db: &'a mut State<DB>,
|
||||
block: &'a RecoveredBlock<<Self::Primitives as NodePrimitives>::Block>,
|
||||
block: &'a SealedBlock<<Self::Primitives as NodePrimitives>::Block>,
|
||||
) -> impl BlockExecutionStrategy<Primitives = Self::Primitives, Error = BlockExecutionError> + 'a
|
||||
where
|
||||
DB: Database,
|
||||
{
|
||||
let evm = self.evm_for_block(db, block.header());
|
||||
EthExecutionStrategy::new(evm, block.sealed_block(), &self.chain_spec)
|
||||
EthExecutionStrategy::new(evm, block, &self.chain_spec)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,7 +281,7 @@ mod tests {
|
||||
use reth_chainspec::{ChainSpecBuilder, ForkCondition, MAINNET};
|
||||
use reth_evm::execute::{BasicBlockExecutorProvider, BlockExecutorProvider, Executor};
|
||||
use reth_execution_types::BlockExecutionResult;
|
||||
use reth_primitives::{Account, Block, BlockBody, Transaction};
|
||||
use reth_primitives::{Account, Block, BlockBody, RecoveredBlock, Transaction};
|
||||
use reth_primitives_traits::{crypto::secp256k1::public_key_to_address, Block as _};
|
||||
use reth_revm::{
|
||||
database::StateProviderDatabase,
|
||||
|
||||
@@ -13,7 +13,7 @@ pub use reth_execution_errors::{
|
||||
};
|
||||
use reth_execution_types::BlockExecutionResult;
|
||||
pub use reth_execution_types::{BlockExecutionOutput, ExecutionOutcome};
|
||||
use reth_primitives::{NodePrimitives, Receipt, Recovered, RecoveredBlock};
|
||||
use reth_primitives::{NodePrimitives, Receipt, Recovered, RecoveredBlock, SealedBlock};
|
||||
pub use reth_storage_errors::provider::ProviderError;
|
||||
use revm::state::{Account, AccountStatus, EvmState};
|
||||
use revm_database::{states::bundle_state::BundleRetention, State};
|
||||
@@ -197,9 +197,9 @@ pub trait BlockExecutionStrategyFactory: ConfigureEvmFor<Self::Primitives> {
|
||||
|
||||
/// Creates a strategy using the given database.
|
||||
fn create_strategy<'a, DB>(
|
||||
&'a mut self,
|
||||
&'a self,
|
||||
db: &'a mut State<DB>,
|
||||
block: &'a RecoveredBlock<<Self::Primitives as NodePrimitives>::Block>,
|
||||
block: &'a SealedBlock<<Self::Primitives as NodePrimitives>::Block>,
|
||||
) -> impl BlockExecutionStrategy<Primitives = Self::Primitives, Error = BlockExecutionError> + 'a
|
||||
where
|
||||
DB: Database;
|
||||
|
||||
@@ -16,13 +16,13 @@ use reth_exex::ExExManagerHandle;
|
||||
use reth_network::{NetworkSyncUpdater, SyncState};
|
||||
use reth_network_api::BlockDownloaderProvider;
|
||||
use reth_node_api::{
|
||||
BeaconConsensusEngineHandle, BuiltPayload, FullNodeTypes, NodeTypesWithDBAdapter,
|
||||
NodeTypesWithEngine, PayloadAttributesBuilder, PayloadTypes,
|
||||
BeaconConsensusEngineHandle, BuiltPayload, FullNodeTypes, NodePrimitives,
|
||||
NodeTypesWithDBAdapter, NodeTypesWithEngine, PayloadAttributesBuilder, PayloadTypes,
|
||||
};
|
||||
use reth_node_core::{
|
||||
dirs::{ChainPath, DataDirPath},
|
||||
exit::NodeExitFuture,
|
||||
primitives::Head,
|
||||
primitives::{Head, SignedTransaction},
|
||||
};
|
||||
use reth_node_events::{cl::ConsensusLayerHealthEvents, node};
|
||||
use reth_primitives::EthereumHardforks;
|
||||
@@ -65,9 +65,18 @@ impl EngineNodeLauncher {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Types, DB, T, CB, AO> LaunchNode<NodeBuilderWithComponents<T, CB, AO>> for EngineNodeLauncher
|
||||
impl<Types, DB, T, CB, AO, Tx> LaunchNode<NodeBuilderWithComponents<T, CB, AO>>
|
||||
for EngineNodeLauncher
|
||||
where
|
||||
Types: NodeTypesForProvider + NodeTypesWithEngine,
|
||||
Tx: SignedTransaction,
|
||||
Types: NodeTypesForProvider
|
||||
+ NodeTypesWithEngine<
|
||||
Primitives: NodePrimitives<
|
||||
SignedTx = Tx,
|
||||
BlockHeader = alloy_consensus::Header,
|
||||
BlockBody = alloy_consensus::BlockBody<Tx>,
|
||||
>,
|
||||
>,
|
||||
DB: Database + DatabaseMetrics + Clone + Unpin + 'static,
|
||||
T: FullNodeTypes<
|
||||
Types = Types,
|
||||
@@ -143,20 +152,6 @@ where
|
||||
let (consensus_engine_tx, consensus_engine_rx) = unbounded_channel();
|
||||
|
||||
let node_config = ctx.node_config();
|
||||
let consensus_engine_stream = UnboundedReceiverStream::from(consensus_engine_rx)
|
||||
.maybe_skip_fcu(node_config.debug.skip_fcu)
|
||||
.maybe_skip_new_payload(node_config.debug.skip_new_payload)
|
||||
// .maybe_reorg(
|
||||
// ctx.blockchain_db().clone(),
|
||||
// ctx.components().evm_config().clone(),
|
||||
// reth_payload_validator::ExecutionPayloadValidator::new(ctx.chain_spec()),
|
||||
// node_config.debug.reorg_frequency,
|
||||
// node_config.debug.reorg_depth,
|
||||
// )
|
||||
// Store messages _after_ skipping so that `replay-engine` command
|
||||
// would replay only the messages that were observed by the engine
|
||||
// during this run.
|
||||
.maybe_store_messages(node_config.debug.engine_api_store.clone());
|
||||
|
||||
let max_block = ctx.max_block(network_client.clone()).await?;
|
||||
|
||||
@@ -213,6 +208,21 @@ where
|
||||
};
|
||||
let engine_payload_validator = add_ons.engine_validator(&add_ons_ctx).await?;
|
||||
|
||||
let consensus_engine_stream = UnboundedReceiverStream::from(consensus_engine_rx)
|
||||
.maybe_skip_fcu(node_config.debug.skip_fcu)
|
||||
.maybe_skip_new_payload(node_config.debug.skip_new_payload)
|
||||
.maybe_reorg(
|
||||
ctx.blockchain_db().clone(),
|
||||
ctx.components().evm_config().clone(),
|
||||
engine_payload_validator.clone(),
|
||||
node_config.debug.reorg_frequency,
|
||||
node_config.debug.reorg_depth,
|
||||
)
|
||||
// Store messages _after_ skipping so that `replay-engine` command
|
||||
// would replay only the messages that were observed by the engine
|
||||
// during this run.
|
||||
.maybe_store_messages(node_config.debug.engine_api_store.clone());
|
||||
|
||||
let mut engine_service = if ctx.is_dev() {
|
||||
let eth_service = LocalEngineService::new(
|
||||
consensus.clone(),
|
||||
|
||||
@@ -24,9 +24,7 @@ use reth_execution_types::BlockExecutionResult;
|
||||
use reth_optimism_chainspec::OpChainSpec;
|
||||
use reth_optimism_forks::OpHardforks;
|
||||
use reth_optimism_primitives::{transaction::signed::OpTransaction, DepositReceipt};
|
||||
use reth_primitives_traits::{
|
||||
Block, NodePrimitives, RecoveredBlock, SealedBlock, SignedTransaction,
|
||||
};
|
||||
use reth_primitives_traits::{Block, NodePrimitives, SealedBlock, SignedTransaction};
|
||||
use revm::{context::TxEnv, context_interface::result::ResultAndState, DatabaseCommit};
|
||||
use revm_database::State;
|
||||
use revm_primitives::{Address, B256};
|
||||
@@ -41,20 +39,15 @@ where
|
||||
type Primitives = N;
|
||||
|
||||
fn create_strategy<'a, DB>(
|
||||
&'a mut self,
|
||||
&'a self,
|
||||
db: &'a mut State<DB>,
|
||||
block: &'a RecoveredBlock<<Self::Primitives as NodePrimitives>::Block>,
|
||||
block: &'a SealedBlock<<Self::Primitives as NodePrimitives>::Block>,
|
||||
) -> impl BlockExecutionStrategy<Primitives = Self::Primitives, Error = BlockExecutionError> + 'a
|
||||
where
|
||||
DB: Database,
|
||||
{
|
||||
let evm = self.evm_for_block(db, block.header());
|
||||
OpExecutionStrategy::new(
|
||||
evm,
|
||||
block.sealed_block(),
|
||||
&self.chain_spec,
|
||||
self.receipt_builder.as_ref(),
|
||||
)
|
||||
OpExecutionStrategy::new(evm, block, &self.chain_spec, self.receipt_builder.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,7 +299,7 @@ mod tests {
|
||||
use reth_evm::execute::{BasicBlockExecutorProvider, BlockExecutorProvider, Executor};
|
||||
use reth_optimism_chainspec::OpChainSpecBuilder;
|
||||
use reth_optimism_primitives::{OpReceipt, OpTransactionSigned};
|
||||
use reth_primitives_traits::Account;
|
||||
use reth_primitives_traits::{Account, RecoveredBlock};
|
||||
use reth_revm::{database::StateProviderDatabase, test_utils::StateProviderTest};
|
||||
use revm_optimism::constants::L1_BLOCK_CONTRACT;
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
Reference in New Issue
Block a user