Skip to content

Commit e12a4fc

Browse files
authored
fix: prevent historical provider queries for block tags (#642)
Historical providers should only be used for specific block numbers or hashes, not for block tags like Latest, Safe, or Finalized. This fix ensures that block tag queries are always handled by the current provider to get the most up-to-date information. Changes: - Add should_use_historical_provider utility function to check block ID type - Update both rpc.rs and verifiable_api.rs to use the new utility - Ensure block tags (Latest, Safe, Finalized, etc.) bypass historical provider
1 parent 276b875 commit e12a4fc

File tree

4 files changed

+31
-21
lines changed

4 files changed

+31
-21
lines changed

Cargo.lock

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/src/execution/providers/rpc.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,9 @@ impl<N: NetworkSpec, B: BlockProvider<N>, H: HistoricalBlockProvider<N>> BlockPr
260260
return Ok(Some(block));
261261
}
262262

263-
// 2. Try historical provider if available and not requesting latest
263+
// 2. Try historical provider if available and only for block numbers or hashes (not tags)
264264
if let Some(historical) = &self.historical_provider {
265-
if block_id != BlockNumberOrTag::Latest.into() {
265+
if super::utils::should_use_historical_provider(&block_id) {
266266
if let Some(block) = historical
267267
.get_historical_block(block_id, full_tx, self)
268268
.await?
@@ -273,7 +273,6 @@ impl<N: NetworkSpec, B: BlockProvider<N>, H: HistoricalBlockProvider<N>> BlockPr
273273
}
274274
}
275275

276-
// 3. No historical block found
277276
Ok(None)
278277
}
279278

core/src/execution/providers/utils.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1-
use alloy::rpc::types::{Filter, Log};
1+
use alloy::rpc::types::{BlockId, BlockNumberOrTag, Filter, Log};
22
use eyre::Result;
33

44
use crate::execution::errors::ExecutionError;
55

6+
/// Determines if a block ID should be fetched from the historical provider.
7+
/// Historical providers should only be used for specific block numbers or hashes,
8+
/// never for block tags like Latest, Safe, Finalized, etc.
9+
pub fn should_use_historical_provider(block_id: &BlockId) -> bool {
10+
match block_id {
11+
BlockId::Number(BlockNumberOrTag::Number(_)) => true,
12+
BlockId::Hash(_) => true,
13+
_ => false, // Don't use for Latest, Safe, Finalized, Pending, Earliest
14+
}
15+
}
16+
617
pub fn ensure_logs_match_filter(logs: &[Log], filter: &Filter) -> Result<()> {
718
fn log_matches_filter(log: &Log, filter: &Filter) -> bool {
819
if let Some(block_hash) = filter.get_block_hash() {

core/src/execution/providers/verifiable_api.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::collections::{hash_map::Entry, HashMap, HashSet};
22

33
use alloy::{
44
consensus::BlockHeader,
5-
eips::{BlockId, BlockNumberOrTag},
5+
eips::BlockId,
66
network::{primitives::HeaderResponse, BlockResponse, ReceiptResponse, TransactionResponse},
77
primitives::{Address, B256, U256},
88
rlp,
@@ -150,9 +150,9 @@ impl<N: NetworkSpec, B: BlockProvider<N>, H: HistoricalBlockProvider<N>> BlockPr
150150
return Ok(Some(block));
151151
}
152152

153-
// 2. Try historical provider if available and not requesting latest
153+
// 2. Try historical provider if available and only for block numbers or hashes (not tags)
154154
if let Some(historical) = &self.historical_provider {
155-
if block_id != BlockNumberOrTag::Latest.into() {
155+
if super::utils::should_use_historical_provider(&block_id) {
156156
if let Some(block) = historical
157157
.get_historical_block(block_id, full_tx, self)
158158
.await?

0 commit comments

Comments
 (0)