diff --git a/crates/rpc/rpc-eth-api/src/helpers/fee.rs b/crates/rpc/rpc-eth-api/src/helpers/fee.rs index e3e513c9ce..b8e98db1fc 100644 --- a/crates/rpc/rpc-eth-api/src/helpers/fee.rs +++ b/crates/rpc/rpc-eth-api/src/helpers/fee.rs @@ -13,7 +13,9 @@ use reth_rpc_eth_types::{ fee_history::calculate_reward_percentiles_for_block, utils::checked_blob_gas_used_ratio, EthApiError, FeeHistoryCache, FeeHistoryEntry, GasPriceOracle, RpcInvalidTransactionError, }; -use reth_storage_api::{BlockIdReader, BlockReaderIdExt, HeaderProvider, ProviderHeader}; +use reth_storage_api::{ + BlockIdReader, BlockNumReader, BlockReaderIdExt, HeaderProvider, ProviderHeader, +}; use tracing::debug; /// Fee related functions for the [`EthApiServer`](crate::EthApiServer) trait in the @@ -92,6 +94,17 @@ pub trait EthFees: newest_block = BlockNumberOrTag::Latest; } + // For explicit block numbers, validate against chain head before resolution + if let BlockNumberOrTag::Number(requested) = newest_block { + let latest_block = + self.provider().best_block_number().map_err(Self::Error::from_eth_err)?; + if requested > latest_block { + return Err( + EthApiError::RequestBeyondHead { requested, head: latest_block }.into() + ) + } + } + let end_block = self .provider() .block_number_for_id(newest_block.into()) diff --git a/crates/rpc/rpc-eth-types/src/error/mod.rs b/crates/rpc/rpc-eth-types/src/error/mod.rs index 3cbd4116af..b2dcc12cea 100644 --- a/crates/rpc/rpc-eth-types/src/error/mod.rs +++ b/crates/rpc/rpc-eth-types/src/error/mod.rs @@ -92,6 +92,14 @@ pub enum EthApiError { /// When an invalid block range is provided #[error("invalid block range")] InvalidBlockRange, + /// Requested block number is beyond the head block + #[error("request beyond head block: requested {requested}, head {head}")] + RequestBeyondHead { + /// The requested block number + requested: u64, + /// The current head block number + head: u64, + }, /// Thrown when the target block for proof computation exceeds the maximum configured window. #[error("distance to target block exceeds maximum proof window")] ExceedsMaxProofWindow, @@ -268,6 +276,7 @@ impl From for jsonrpsee_types::error::ErrorObject<'static> { EthApiError::InvalidTransactionSignature | EthApiError::EmptyRawTransactionData | EthApiError::InvalidBlockRange | + EthApiError::RequestBeyondHead { .. } | EthApiError::ExceedsMaxProofWindow | EthApiError::ConflictingFeeFieldsInRequest | EthApiError::Signing(_) |