Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions crates/consensus/consensus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,18 @@ pub trait Consensus<B: Block>: HeaderValidator<B::Header> {
/// Note: validating blocks does not include other validations of the Consensus
fn validate_block_pre_execution(&self, block: &SealedBlock<B>) -> Result<(), ConsensusError>;

/// Returns `true` if the given consensus error is transient and may resolve on its own.
///
/// On fast chains, clock skew between nodes can cause a valid block's timestamp to
/// appear briefly in the future. Caching such blocks as permanently invalid would
/// prevent them from being re-validated once the local clock catches up.
///
/// Transient errors will not cause the block hash to be cached as permanently invalid,
/// allowing the block to be re-validated later.
fn is_transient_error(&self, _error: &ConsensusError) -> bool {
false
}

/// Validate a block disregarding world state using an optional pre-computed transaction root.
///
/// If `transaction_root` is provided, the implementation should use the pre-computed
Expand Down
12 changes: 9 additions & 3 deletions crates/engine/tree/src/tree/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use alloy_primitives::B256;
use alloy_rpc_types_engine::{
ForkchoiceState, PayloadStatus, PayloadStatusEnum, PayloadValidationError,
};
use error::{InsertBlockError, InsertBlockFatalError};
use error::{InsertBlockError, InsertBlockFatalError, InsertBlockValidationError};
use reth_chain_state::{
CanonicalInMemoryState, ComputedTrieData, ExecutedBlock, ExecutionTimingStats,
MemoryOverlayStateProvider, NewCanonicalChain,
Expand Down Expand Up @@ -3019,8 +3019,14 @@ where
);
let latest_valid_hash = self.latest_valid_hash_for_invalid_payload(block.parent_hash())?;

// keep track of the invalid header
self.state.invalid_headers.insert(block.block_with_parent());
// keep track of the invalid header unless the consensus impl considers it transient
let is_transient = match &validation_err {
InsertBlockValidationError::Consensus(err) => self.consensus.is_transient_error(err),
_ => false,
};
if !is_transient {
self.state.invalid_headers.insert(block.block_with_parent());
}
self.emit_event(EngineApiEvent::BeaconConsensus(ConsensusEngineEvent::InvalidBlock(
Box::new(block),
)));
Expand Down
Loading