From 337579176daa9a1150351b7f34d371df76b91db4 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 22 May 2023 15:30:00 +0200 Subject: [PATCH] feat: add sealed headers range (#2769) --- crates/consensus/common/src/validation.rs | 7 ++++ .../provider/src/providers/database.rs | 38 ++++++++++++++++++- crates/storage/provider/src/providers/mod.rs | 7 ++++ .../storage/provider/src/test_utils/mock.rs | 12 ++++-- .../storage/provider/src/test_utils/noop.rs | 7 ++++ crates/storage/provider/src/traits/header.rs | 8 +++- 6 files changed, 72 insertions(+), 7 deletions(-) diff --git a/crates/consensus/common/src/validation.rs b/crates/consensus/common/src/validation.rs index 81a4b9136f..172d8965ba 100644 --- a/crates/consensus/common/src/validation.rs +++ b/crates/consensus/common/src/validation.rs @@ -467,6 +467,13 @@ mod tests { fn headers_range(&self, _range: impl RangeBounds) -> Result> { Ok(vec![]) } + + fn sealed_headers_range( + &self, + _range: impl RangeBounds, + ) -> Result> { + Ok(vec![]) + } } impl WithdrawalsProvider for Provider { diff --git a/crates/storage/provider/src/providers/database.rs b/crates/storage/provider/src/providers/database.rs index 80ec98855e..89de00d610 100644 --- a/crates/storage/provider/src/providers/database.rs +++ b/crates/storage/provider/src/providers/database.rs @@ -8,8 +8,8 @@ use reth_db::{cursor::DbCursorRO, database::Database, tables, transaction::DbTx} use reth_interfaces::Result; use reth_primitives::{ Block, BlockHash, BlockHashOrNumber, BlockNumber, ChainInfo, ChainSpec, Hardfork, Head, Header, - Receipt, SealedBlock, TransactionMeta, TransactionSigned, TxHash, TxNumber, Withdrawal, H256, - U256, + Receipt, SealedBlock, SealedHeader, TransactionMeta, TransactionSigned, TxHash, TxNumber, + Withdrawal, H256, U256, }; use reth_revm_primitives::{ config::revm_spec, @@ -129,6 +129,23 @@ impl HeaderProvider for ShareableDatabase { })? .map_err(Into::into) } + + fn sealed_headers_range( + &self, + range: impl RangeBounds, + ) -> Result> { + self.db + .view(|tx| -> Result<_> { + let mut headers = vec![]; + for entry in tx.cursor_read::()?.walk_range(range)? { + let (num, header) = entry?; + let hash = read_header_hash(tx, num)?; + headers.push(header.seal(hash)); + } + Ok(headers) + })? + .map_err(Into::into) + } } impl BlockHashProvider for ShareableDatabase { @@ -481,6 +498,23 @@ impl EvmEnvProvider for ShareableDatabase { } } +/// Reads the hash for the given block number +/// +/// Returns an error if no matching entry is found. +#[inline] +fn read_header_hash<'a, TX>( + tx: &TX, + number: u64, +) -> std::result::Result +where + TX: DbTx<'a> + Send + Sync, +{ + match tx.get::(number)? { + Some(hash) => Ok(hash), + None => Err(ProviderError::HeaderNotFound(number.into()).into()), + } +} + /// Fetches Header and its hash #[inline] fn read_sealed_header<'a, TX>( diff --git a/crates/storage/provider/src/providers/mod.rs b/crates/storage/provider/src/providers/mod.rs index d19f86eeb3..1958a4695c 100644 --- a/crates/storage/provider/src/providers/mod.rs +++ b/crates/storage/provider/src/providers/mod.rs @@ -99,6 +99,13 @@ where fn headers_range(&self, range: impl RangeBounds) -> Result> { self.database.headers_range(range) } + + fn sealed_headers_range( + &self, + range: impl RangeBounds, + ) -> Result> { + self.database.sealed_headers_range(range) + } } impl BlockHashProvider for BlockchainProvider diff --git a/crates/storage/provider/src/test_utils/mock.rs b/crates/storage/provider/src/test_utils/mock.rs index 59b4d9b1a8..873c102040 100644 --- a/crates/storage/provider/src/test_utils/mock.rs +++ b/crates/storage/provider/src/test_utils/mock.rs @@ -135,10 +135,7 @@ impl HeaderProvider for MockEthProvider { Ok(Some(sum)) } - fn headers_range( - &self, - range: impl RangeBounds, - ) -> Result> { + fn headers_range(&self, range: impl RangeBounds) -> Result> { let lock = self.headers.lock(); let mut headers: Vec<_> = @@ -147,6 +144,13 @@ impl HeaderProvider for MockEthProvider { Ok(headers) } + + fn sealed_headers_range( + &self, + range: impl RangeBounds, + ) -> Result> { + Ok(self.headers_range(range)?.into_iter().map(|h| h.seal_slow()).collect()) + } } impl TransactionsProvider for MockEthProvider { diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index 318dbaee89..cd7f5f6f21 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -166,6 +166,13 @@ impl HeaderProvider for NoopProvider { fn headers_range(&self, _range: impl RangeBounds) -> Result> { Ok(vec![]) } + + fn sealed_headers_range( + &self, + _range: impl RangeBounds, + ) -> Result> { + Ok(vec![]) + } } impl AccountProvider for NoopProvider { diff --git a/crates/storage/provider/src/traits/header.rs b/crates/storage/provider/src/traits/header.rs index 9f1c741e9c..06fe5846c3 100644 --- a/crates/storage/provider/src/traits/header.rs +++ b/crates/storage/provider/src/traits/header.rs @@ -1,6 +1,6 @@ use auto_impl::auto_impl; use reth_interfaces::Result; -use reth_primitives::{BlockHash, BlockHashOrNumber, BlockNumber, Header, U256}; +use reth_primitives::{BlockHash, BlockHashOrNumber, BlockNumber, Header, SealedHeader, U256}; use std::ops::RangeBounds; /// Client trait for fetching `Header` related data. @@ -33,4 +33,10 @@ pub trait HeaderProvider: Send + Sync { /// Get headers in range of block numbers fn headers_range(&self, range: impl RangeBounds) -> Result>; + + /// Get headers in range of block numbers + fn sealed_headers_range( + &self, + range: impl RangeBounds, + ) -> Result>; }