feat(provider): HeaderProvider::sealed_headers_while (#5470)

This commit is contained in:
Roman Krasiuk
2023-11-17 02:21:35 -08:00
committed by GitHub
parent 7312ada852
commit eadbe5dce9
9 changed files with 109 additions and 67 deletions

View File

@ -214,6 +214,10 @@ impl<DB: Database> HeaderProvider for ProviderFactory<DB> {
self.provider()?.headers_range(range)
}
fn sealed_header(&self, number: BlockNumber) -> RethResult<Option<SealedHeader>> {
self.provider()?.sealed_header(number)
}
fn sealed_headers_range(
&self,
range: impl RangeBounds<BlockNumber>,
@ -221,8 +225,12 @@ impl<DB: Database> HeaderProvider for ProviderFactory<DB> {
self.provider()?.sealed_headers_range(range)
}
fn sealed_header(&self, number: BlockNumber) -> RethResult<Option<SealedHeader>> {
self.provider()?.sealed_header(number)
fn sealed_headers_while(
&self,
range: impl RangeBounds<BlockNumber>,
predicate: impl FnMut(&SealedHeader) -> bool,
) -> RethResult<Vec<SealedHeader>> {
self.provider()?.sealed_headers_while(range, predicate)
}
}

View File

@ -911,21 +911,6 @@ impl<TX: DbTx> HeaderProvider for DatabaseProvider<TX> {
.collect::<RethResult<Vec<_>>>()
}
fn sealed_headers_range(
&self,
range: impl RangeBounds<BlockNumber>,
) -> RethResult<Vec<SealedHeader>> {
let mut headers = vec![];
for entry in self.tx.cursor_read::<tables::Headers>()?.walk_range(range)? {
let (number, header) = entry?;
let hash = self
.block_hash(number)?
.ok_or_else(|| ProviderError::HeaderNotFound(number.into()))?;
headers.push(header.seal(hash));
}
Ok(headers)
}
fn sealed_header(&self, number: BlockNumber) -> RethResult<Option<SealedHeader>> {
if let Some(header) = self.header_by_number(number)? {
let hash = self
@ -936,6 +921,26 @@ impl<TX: DbTx> HeaderProvider for DatabaseProvider<TX> {
Ok(None)
}
}
fn sealed_headers_while(
&self,
range: impl RangeBounds<BlockNumber>,
mut predicate: impl FnMut(&SealedHeader) -> bool,
) -> RethResult<Vec<SealedHeader>> {
let mut headers = vec![];
for entry in self.tx.cursor_read::<tables::Headers>()?.walk_range(range)? {
let (number, header) = entry?;
let hash = self
.block_hash(number)?
.ok_or_else(|| ProviderError::HeaderNotFound(number.into()))?;
let sealed = header.seal(hash);
if !predicate(&sealed) {
break
}
headers.push(sealed);
}
Ok(headers)
}
}
impl<TX: DbTx> BlockHashReader for DatabaseProvider<TX> {
@ -1055,9 +1060,7 @@ impl<TX: DbTx> BlockReader for DatabaseProvider<TX> {
id: BlockHashOrNumber,
transaction_kind: TransactionVariant,
) -> RethResult<Option<BlockWithSenders>> {
let Some(block_number) = self.convert_hash_or_number(id)? else {
return Ok(None);
};
let Some(block_number) = self.convert_hash_or_number(id)? else { return Ok(None) };
let Some(header) = self.header_by_number(block_number)? else { return Ok(None) };

View File

@ -140,6 +140,10 @@ where
self.database.provider()?.headers_range(range)
}
fn sealed_header(&self, number: BlockNumber) -> RethResult<Option<SealedHeader>> {
self.database.provider()?.sealed_header(number)
}
fn sealed_headers_range(
&self,
range: impl RangeBounds<BlockNumber>,
@ -147,8 +151,12 @@ where
self.database.provider()?.sealed_headers_range(range)
}
fn sealed_header(&self, number: BlockNumber) -> RethResult<Option<SealedHeader>> {
self.database.provider()?.sealed_header(number)
fn sealed_headers_while(
&self,
range: impl RangeBounds<BlockNumber>,
predicate: impl FnMut(&SealedHeader) -> bool,
) -> RethResult<Vec<SealedHeader>> {
self.database.provider()?.sealed_headers_while(range, predicate)
}
}

View File

@ -95,9 +95,17 @@ impl<'a> HeaderProvider for SnapshotJarProvider<'a> {
Ok(headers)
}
fn sealed_headers_range(
fn sealed_header(&self, number: BlockNumber) -> RethResult<Option<SealedHeader>> {
Ok(self
.cursor()?
.get_two::<HeaderMask<Header, BlockHash>>(number.into())?
.map(|(header, hash)| header.seal(hash)))
}
fn sealed_headers_while(
&self,
range: impl RangeBounds<BlockNumber>,
mut predicate: impl FnMut(&SealedHeader) -> bool,
) -> RethResult<Vec<SealedHeader>> {
let range = to_range(range);
@ -108,18 +116,15 @@ impl<'a> HeaderProvider for SnapshotJarProvider<'a> {
if let Some((header, hash)) =
cursor.get_two::<HeaderMask<Header, BlockHash>>(number.into())?
{
headers.push(header.seal(hash))
let sealed = header.seal(hash);
if !predicate(&sealed) {
break
}
headers.push(sealed);
}
}
Ok(headers)
}
fn sealed_header(&self, number: BlockNumber) -> RethResult<Option<SealedHeader>> {
Ok(self
.cursor()?
.get_two::<HeaderMask<Header, BlockHash>>(number.into())?
.map(|(header, hash)| header.seal(hash)))
}
}
impl<'a> BlockHashReader for SnapshotJarProvider<'a> {

View File

@ -113,7 +113,7 @@ impl SnapshotProvider {
})?)
.and_then(|(parsed_segment, block_range, tx_range)| {
if parsed_segment == segment {
return Some((block_range, tx_range));
return Some((block_range, tx_range))
}
None
})
@ -123,7 +123,7 @@ impl SnapshotProvider {
// Return cached `LoadedJar` or insert it for the first time, and then, return it.
if let Some((block_range, tx_range)) = snapshot_ranges {
return Ok(Some(self.get_or_create_jar_provider(segment, &block_range, &tx_range)?));
return Ok(Some(self.get_or_create_jar_provider(segment, &block_range, &tx_range)?))
}
Ok(None)
@ -171,7 +171,7 @@ impl SnapshotProvider {
let block_start =
snapshots_rev_iter.peek().map(|(block_end, _)| *block_end + 1).unwrap_or(0);
if block_start <= block {
return Some((block_start..=*block_end, tx_range.clone()));
return Some((block_start..=*block_end, tx_range.clone()))
}
}
None
@ -194,7 +194,7 @@ impl SnapshotProvider {
while let Some((tx_end, block_range)) = snapshots_rev_iter.next() {
let tx_start = snapshots_rev_iter.peek().map(|(tx_end, _)| *tx_end + 1).unwrap_or(0);
if tx_start <= tx {
return Some((block_range.clone(), tx_start..=*tx_end));
return Some((block_range.clone(), tx_start..=*tx_end))
}
}
None
@ -278,17 +278,18 @@ impl HeaderProvider for SnapshotProvider {
todo!();
}
fn sealed_headers_range(
&self,
_range: impl RangeBounds<BlockNumber>,
) -> RethResult<Vec<SealedHeader>> {
todo!();
}
fn sealed_header(&self, num: BlockNumber) -> RethResult<Option<SealedHeader>> {
self.get_segment_provider_from_block(SnapshotSegment::Headers, num, None)?
.sealed_header(num)
}
fn sealed_headers_while(
&self,
_range: impl RangeBounds<BlockNumber>,
_predicate: impl FnMut(&SealedHeader) -> bool,
) -> RethResult<Vec<SealedHeader>> {
todo!()
}
}
impl BlockHashReader for SnapshotProvider {

View File

@ -162,16 +162,22 @@ impl HeaderProvider for MockEthProvider {
Ok(headers)
}
fn sealed_headers_range(
&self,
range: impl RangeBounds<BlockNumber>,
) -> RethResult<Vec<SealedHeader>> {
Ok(self.headers_range(range)?.into_iter().map(|h| h.seal_slow()).collect())
}
fn sealed_header(&self, number: BlockNumber) -> RethResult<Option<SealedHeader>> {
Ok(self.header_by_number(number)?.map(|h| h.seal_slow()))
}
fn sealed_headers_while(
&self,
range: impl RangeBounds<BlockNumber>,
mut predicate: impl FnMut(&SealedHeader) -> bool,
) -> RethResult<Vec<SealedHeader>> {
Ok(self
.headers_range(range)?
.into_iter()
.map(|h| h.seal_slow())
.take_while(|h| predicate(h))
.collect())
}
}
impl ChainSpecProvider for MockEthProvider {

View File

@ -235,16 +235,17 @@ impl HeaderProvider for NoopProvider {
Ok(vec![])
}
fn sealed_headers_range(
&self,
_range: impl RangeBounds<BlockNumber>,
) -> RethResult<Vec<SealedHeader>> {
Ok(vec![])
}
fn sealed_header(&self, _number: BlockNumber) -> RethResult<Option<SealedHeader>> {
Ok(None)
}
fn sealed_headers_while(
&self,
_range: impl RangeBounds<BlockNumber>,
_predicate: impl FnMut(&SealedHeader) -> bool,
) -> RethResult<Vec<SealedHeader>> {
Ok(vec![])
}
}
impl AccountReader for NoopProvider {

View File

@ -37,12 +37,21 @@ pub trait HeaderProvider: Send + Sync {
/// Get headers in range of block numbers
fn headers_range(&self, range: impl RangeBounds<BlockNumber>) -> RethResult<Vec<Header>>;
/// Get headers in range of block numbers
/// Get a single sealed header by block number.
fn sealed_header(&self, number: BlockNumber) -> RethResult<Option<SealedHeader>>;
/// Get headers in range of block numbers.
fn sealed_headers_range(
&self,
range: impl RangeBounds<BlockNumber>,
) -> RethResult<Vec<SealedHeader>>;
) -> RethResult<Vec<SealedHeader>> {
self.sealed_headers_while(range, |_| true)
}
/// Get a single sealed header by block number
fn sealed_header(&self, number: BlockNumber) -> RethResult<Option<SealedHeader>>;
/// Get sealed headers while `predicate` returns `true` or the range is exhausted.
fn sealed_headers_while(
&self,
range: impl RangeBounds<BlockNumber>,
predicate: impl FnMut(&SealedHeader) -> bool,
) -> RethResult<Vec<SealedHeader>>;
}