diff --git a/crates/storage/provider/src/providers/database/chain.rs b/crates/storage/provider/src/providers/database/chain.rs index 24f4888ec397..b20741784212 100644 --- a/crates/storage/provider/src/providers/database/chain.rs +++ b/crates/storage/provider/src/providers/database/chain.rs @@ -23,6 +23,7 @@ where T: FullSignedTx, N: FullNodePrimitives< Block = reth_primitives::Block, + BlockHeader = alloy_consensus::Header, BlockBody = reth_primitives::BlockBody, SignedTx = T, >, diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index 12e33146c913..157922b50362 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -562,14 +562,29 @@ impl BlockBodyIndicesProvider for ProviderFactory { &self, number: BlockNumber, ) -> ProviderResult> { - self.provider()?.block_body_indices(number) + self.static_file_provider.get_with_static_file_or_database( + StaticFileSegment::BlockMeta, + number, + |static_file| static_file.block_body_indices(number), + || self.provider()?.block_body_indices(number), + ) } fn block_body_indices_range( &self, range: RangeInclusive, ) -> ProviderResult> { - self.provider()?.block_body_indices_range(range) + self.static_file_provider.get_range_with_static_file_or_database( + StaticFileSegment::BlockMeta, + *range.start()..*range.end() + 1, + |static_file, range, _| { + static_file.block_body_indices_range(range.start..=range.end.saturating_sub(1)) + }, + |range, _| { + self.provider()?.block_body_indices_range(range.start..=range.end.saturating_sub(1)) + }, + |_| true, + ) } } diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 6ac93454c865..31105c33665b 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -1574,14 +1574,21 @@ impl> Withdrawals ) -> ProviderResult> { if self.chain_spec.is_shanghai_active_at_timestamp(timestamp) { if let Some(number) = self.convert_hash_or_number(id)? { - // If we are past shanghai, then all blocks should have a withdrawal list, even if - // empty - let withdrawals = self - .tx - .get::(number) - .map(|w| w.map(|w| w.withdrawals))? - .unwrap_or_default(); - return Ok(Some(withdrawals)) + return self.static_file_provider.get_with_static_file_or_database( + StaticFileSegment::BlockMeta, + number, + |static_file| static_file.withdrawals_by_block(number.into(), timestamp), + || { + // If we are past shanghai, then all blocks should have a withdrawal list, + // even if empty + let withdrawals = self + .tx + .get::(number) + .map(|w| w.map(|w| w.withdrawals))? + .unwrap_or_default(); + Ok(Some(withdrawals)) + }, + ) } } Ok(None) @@ -1601,9 +1608,12 @@ impl OmmersProvider for DatabasePro return Ok(Some(Vec::new())) } - let ommers = - self.tx.get::>(number)?.map(|o| o.ommers); - return Ok(ommers) + return self.static_file_provider.get_with_static_file_or_database( + StaticFileSegment::BlockMeta, + number, + |static_file| static_file.ommers(id), + || Ok(self.tx.get::>(number)?.map(|o| o.ommers)), + ) } Ok(None) @@ -1614,19 +1624,27 @@ impl BlockBodyIndicesProvider for DatabaseProvider { fn block_body_indices(&self, num: u64) -> ProviderResult> { - Ok(self.tx.get::(num)?) + self.static_file_provider.get_with_static_file_or_database( + StaticFileSegment::BlockMeta, + num, + |static_file| static_file.block_body_indices(num), + || Ok(self.tx.get::(num)?), + ) } fn block_body_indices_range( &self, range: RangeInclusive, ) -> ProviderResult> { - Ok(self - .tx_ref() - .cursor_read::()? - .walk_range(range)? - .map(|r| r.map(|(_, b)| b)) - .collect::>()?) + self.static_file_provider.get_range_with_static_file_or_database( + StaticFileSegment::BlockMeta, + *range.start()..*range.end() + 1, + |static_file, range, _| { + static_file.block_body_indices_range(range.start..=range.end.saturating_sub(1)) + }, + |range, _| self.cursor_read_collect::(range), + |_| true, + ) } } diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index 11f768a07642..51b68f8f2cc6 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -17,8 +17,8 @@ use reth_chainspec::{ChainInfo, ChainSpecProvider}; use reth_db::{ lockfile::StorageLock, static_file::{ - iter_static_files, BlockHashMask, HeaderMask, HeaderWithHashMask, ReceiptMask, - StaticFileCursor, TDWithHashMask, TransactionMask, + iter_static_files, BlockHashMask, BodyIndicesMask, HeaderMask, HeaderWithHashMask, + ReceiptMask, StaticFileCursor, TDWithHashMask, TransactionMask, }, table::{Decompress, Value}, tables, @@ -1027,7 +1027,7 @@ impl StaticFileProvider { "Could not find block or tx number on a range request" ); - let err = if segment.is_headers() { + let err = if segment.is_block_based() { ProviderError::MissingStaticFileBlock(segment, number) } else { ProviderError::MissingStaticFileTx(segment, number) @@ -1732,10 +1732,14 @@ impl BlockBodyIndicesProvider for StaticFileProvider { fn block_body_indices_range( &self, - _range: RangeInclusive, + range: RangeInclusive, ) -> ProviderResult> { - // Required data not present in static_files - Err(ProviderError::UnsupportedProvider) + self.fetch_range_with_predicate( + StaticFileSegment::BlockMeta, + *range.start()..*range.end() + 1, + |cursor, number| cursor.get_one::(number.into()), + |_| true, + ) } } diff --git a/crates/storage/storage-api/src/chain.rs b/crates/storage/storage-api/src/chain.rs index 6306f418fee0..cb2b38dc7b41 100644 --- a/crates/storage/storage-api/src/chain.rs +++ b/crates/storage/storage-api/src/chain.rs @@ -1,4 +1,5 @@ -use crate::{DBProvider, StorageLocation}; +use crate::{DBProvider, OmmersProvider, StorageLocation}; +use alloy_consensus::Header; use alloy_primitives::BlockNumber; use reth_chainspec::{ChainSpecProvider, EthereumHardforks}; use reth_db::{ @@ -138,7 +139,9 @@ where impl BlockBodyReader for EthStorage where - Provider: DBProvider + ChainSpecProvider, + Provider: DBProvider + + ChainSpecProvider + + OmmersProvider
, T: SignedTransaction, { type Block = reth_primitives::Block; @@ -151,7 +154,6 @@ where // TODO: Ideally storage should hold its own copy of chain spec let chain_spec = provider.chain_spec(); - let mut ommers_cursor = provider.tx_ref().cursor_read::()?; let mut withdrawals_cursor = provider.tx_ref().cursor_read::()?; let mut bodies = Vec::with_capacity(inputs.len()); @@ -171,7 +173,7 @@ where let ommers = if chain_spec.final_paris_total_difficulty(header.number).is_some() { Vec::new() } else { - ommers_cursor.seek_exact(header.number)?.map(|(_, o)| o.ommers).unwrap_or_default() + provider.ommers(header.number.into())?.unwrap_or_default() }; bodies.push(reth_primitives::BlockBody { transactions, ommers, withdrawals });