refactor: change latest block == parent hash by block window distance check (#13961)

This commit is contained in:
Léa Narzis
2025-01-24 10:43:06 +01:00
committed by GitHub
parent 8a3d9b3899
commit 1296bacb87
2 changed files with 33 additions and 8 deletions

View File

@ -106,7 +106,10 @@ impl RethRpcServerConfig for RpcServerArgs {
} }
fn flashbots_config(&self) -> ValidationApiConfig { fn flashbots_config(&self) -> ValidationApiConfig {
ValidationApiConfig { disallow: self.builder_disallow.clone().unwrap_or_default() } ValidationApiConfig {
disallow: self.builder_disallow.clone().unwrap_or_default(),
validation_window: self.rpc_eth_proof_window,
}
} }
fn state_cache_config(&self) -> EthStateCacheConfig { fn state_cache_config(&self) -> EthStateCacheConfig {

View File

@ -51,7 +51,7 @@ where
dyn PayloadValidator<Block = <E::Primitives as NodePrimitives>::Block>, dyn PayloadValidator<Block = <E::Primitives as NodePrimitives>::Block>,
>, >,
) -> Self { ) -> Self {
let ValidationApiConfig { disallow } = config; let ValidationApiConfig { disallow, validation_window } = config;
let inner = Arc::new(ValidationApiInner { let inner = Arc::new(ValidationApiInner {
provider, provider,
@ -59,6 +59,7 @@ where
payload_validator, payload_validator,
executor_provider, executor_provider,
disallow, disallow,
validation_window,
cached_state: Default::default(), cached_state: Default::default(),
task_spawner, task_spawner,
}); });
@ -130,11 +131,13 @@ where
let latest_header = let latest_header =
self.provider.latest_header()?.ok_or_else(|| ValidationApiError::MissingLatestBlock)?; self.provider.latest_header()?.ok_or_else(|| ValidationApiError::MissingLatestBlock)?;
if latest_header.hash() != block.parent_hash() { let parent_header = self
return Err(ConsensusError::ParentHashMismatch( .provider
GotExpected { got: block.parent_hash(), expected: latest_header.hash() }.into(), .header(&block.parent_hash())?
) .ok_or_else(|| ValidationApiError::MissingParentBlock)?;
.into())
if latest_header.number().saturating_sub(parent_header.number()) > self.validation_window {
return Err(ValidationApiError::BlockTooOld)
} }
self.consensus.validate_header_against_parent(block.sealed_header(), &latest_header)?; self.consensus.validate_header_against_parent(block.sealed_header(), &latest_header)?;
self.validate_gas_limit(registered_gas_limit, &latest_header, block.sealed_header())?; self.validate_gas_limit(registered_gas_limit, &latest_header, block.sealed_header())?;
@ -466,6 +469,8 @@ pub struct ValidationApiInner<Provider, E: BlockExecutorProvider> {
executor_provider: E, executor_provider: E,
/// Set of disallowed addresses /// Set of disallowed addresses
disallow: HashSet<Address>, disallow: HashSet<Address>,
/// The maximum block distance - parent to latest - allowed for validation
validation_window: u64,
/// Cached state reads to avoid redundant disk I/O across multiple validation attempts /// Cached state reads to avoid redundant disk I/O across multiple validation attempts
/// targeting the same state. Stores a tuple of (`block_hash`, `cached_reads`) for the /// targeting the same state. Stores a tuple of (`block_hash`, `cached_reads`) for the
/// latest head block state. Uses async `RwLock` to safely handle concurrent validation /// latest head block state. Uses async `RwLock` to safely handle concurrent validation
@ -476,10 +481,23 @@ pub struct ValidationApiInner<Provider, E: BlockExecutorProvider> {
} }
/// Configuration for validation API. /// Configuration for validation API.
#[derive(Debug, Clone, Default, Eq, PartialEq, Serialize, Deserialize)] #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct ValidationApiConfig { pub struct ValidationApiConfig {
/// Disallowed addresses. /// Disallowed addresses.
pub disallow: HashSet<Address>, pub disallow: HashSet<Address>,
/// The maximum block distance - parent to latest - allowed for validation
pub validation_window: u64,
}
impl ValidationApiConfig {
/// Default validation blocks window of 3 blocks
pub const DEFAULT_VALIDATION_WINDOW: u64 = 3;
}
impl Default for ValidationApiConfig {
fn default() -> Self {
Self { disallow: Default::default(), validation_window: Self::DEFAULT_VALIDATION_WINDOW }
}
} }
/// Errors thrown by the validation API. /// Errors thrown by the validation API.
@ -495,6 +513,10 @@ pub enum ValidationApiError {
BlockHashMismatch(GotExpected<B256>), BlockHashMismatch(GotExpected<B256>),
#[error("missing latest block in database")] #[error("missing latest block in database")]
MissingLatestBlock, MissingLatestBlock,
#[error("parent block not found")]
MissingParentBlock,
#[error("block is too old, outside validation window")]
BlockTooOld,
#[error("could not verify proposer payment")] #[error("could not verify proposer payment")]
ProposerPayment, ProposerPayment,
#[error("invalid blobs bundle")] #[error("invalid blobs bundle")]