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 {
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 {

View File

@ -51,7 +51,7 @@ where
dyn PayloadValidator<Block = <E::Primitives as NodePrimitives>::Block>,
>,
) -> Self {
let ValidationApiConfig { disallow } = config;
let ValidationApiConfig { disallow, validation_window } = config;
let inner = Arc::new(ValidationApiInner {
provider,
@ -59,6 +59,7 @@ where
payload_validator,
executor_provider,
disallow,
validation_window,
cached_state: Default::default(),
task_spawner,
});
@ -130,11 +131,13 @@ where
let latest_header =
self.provider.latest_header()?.ok_or_else(|| ValidationApiError::MissingLatestBlock)?;
if latest_header.hash() != block.parent_hash() {
return Err(ConsensusError::ParentHashMismatch(
GotExpected { got: block.parent_hash(), expected: latest_header.hash() }.into(),
)
.into())
let parent_header = self
.provider
.header(&block.parent_hash())?
.ok_or_else(|| ValidationApiError::MissingParentBlock)?;
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.validate_gas_limit(registered_gas_limit, &latest_header, block.sealed_header())?;
@ -466,6 +469,8 @@ pub struct ValidationApiInner<Provider, E: BlockExecutorProvider> {
executor_provider: E,
/// Set of disallowed addresses
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
/// 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
@ -476,10 +481,23 @@ pub struct ValidationApiInner<Provider, E: BlockExecutorProvider> {
}
/// Configuration for validation API.
#[derive(Debug, Clone, Default, Eq, PartialEq, Serialize, Deserialize)]
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct ValidationApiConfig {
/// Disallowed addresses.
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.
@ -495,6 +513,10 @@ pub enum ValidationApiError {
BlockHashMismatch(GotExpected<B256>),
#[error("missing latest block in database")]
MissingLatestBlock,
#[error("parent block not found")]
MissingParentBlock,
#[error("block is too old, outside validation window")]
BlockTooOld,
#[error("could not verify proposer payment")]
ProposerPayment,
#[error("invalid blobs bundle")]