feat: add helper for accessing pending block object (#2465)

This commit is contained in:
Matthias Seitz
2023-05-01 21:08:43 +02:00
committed by GitHub
parent 7ea801f456
commit 7b1aee2d9c
5 changed files with 37 additions and 9 deletions

View File

@ -59,6 +59,14 @@ impl BlockIndices {
&self.blocks_to_chain
}
/// Returns the hash and number of the pending block (the first block in the
/// [Self::pending_blocks]) set.
pub fn pending_block_num_hash(&self) -> Option<BlockNumHash> {
let canonical_tip = self.canonical_tip();
let hash = self.fork_to_child.get(&canonical_tip.hash)?.iter().next().copied()?;
Some(BlockNumHash { number: canonical_tip.number + 1, hash })
}
/// Return all pending block hashes. Pending blocks are considered blocks
/// that are extending that canonical tip by one block number.
pub fn pending_blocks(&self) -> (BlockNumber, Vec<BlockHash>) {

View File

@ -163,6 +163,12 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
chain.block(block_hash)
}
/// Returns the block that's considered the `Pending` block, if it exists.
pub fn pending_block(&self) -> Option<&SealedBlock> {
let b = self.block_indices.pending_block_num_hash()?;
self.block_by_hash(b.hash)
}
/// Return items needed to execute on the pending state.
/// This includes:
/// * `BlockHash` of canonical block that chain connects to. Needed for creating database

View File

@ -102,10 +102,14 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTreeViewer
self.tree.read().block_indices().pending_blocks()
}
fn pending_block(&self) -> Option<BlockNumHash> {
fn pending_block_num_hash(&self) -> Option<BlockNumHash> {
trace!(target: "blockchain_tree", "Returning first pending block");
let (number, blocks) = self.tree.read().block_indices().pending_blocks();
blocks.first().map(|&hash| BlockNumHash { number, hash })
self.tree.read().block_indices().pending_block_num_hash()
}
fn pending_block(&self) -> Option<SealedBlock> {
trace!(target: "blockchain_tree", "Returning first pending block");
self.tree.read().pending_block().cloned()
}
}

View File

@ -105,5 +105,10 @@ pub trait BlockchainTreeViewer: Send + Sync {
/// Return block hashes that extends the canonical chain tip by one.
///
/// If there is no such block, return `None`.
fn pending_block(&self) -> Option<BlockNumHash>;
fn pending_block_num_hash(&self) -> Option<BlockNumHash>;
/// Returns the pending block if there is one.
fn pending_block(&self) -> Option<SealedBlock> {
self.block_by_hash(self.pending_block_num_hash()?.hash)
}
}

View File

@ -109,7 +109,9 @@ where
let num = match num {
BlockNumberOrTag::Latest => self.chain_info()?.best_number,
BlockNumberOrTag::Number(num) => num,
BlockNumberOrTag::Pending => return Ok(self.tree.pending_block().map(|b| b.number)),
BlockNumberOrTag::Pending => {
return Ok(self.tree.pending_block_num_hash().map(|b| b.number))
}
BlockNumberOrTag::Finalized => return Ok(self.chain_info()?.last_finalized),
BlockNumberOrTag::Safe => return Ok(self.chain_info()?.safe_finalized),
BlockNumberOrTag::Earliest => 0,
@ -122,7 +124,7 @@ where
BlockId::Hash(hash) => Ok(Some(hash.into())),
BlockId::Number(num) => match num {
BlockNumberOrTag::Latest => Ok(Some(self.chain_info()?.best_hash)),
BlockNumberOrTag::Pending => Ok(self.tree.pending_block().map(|b| b.hash)),
BlockNumberOrTag::Pending => Ok(self.tree.pending_block_num_hash().map(|b| b.hash)),
_ => self
.convert_block_number(num)?
.map(|num| self.block_hash(num))
@ -162,6 +164,9 @@ where
}
fn block(&self, id: BlockId) -> Result<Option<Block>> {
if id.is_pending() {
return Ok(self.tree.pending_block().map(SealedBlock::unseal))
}
self.database.block(id)
}
@ -314,7 +319,7 @@ where
fn pending(&self) -> Result<StateProviderBox<'_>> {
trace!(target: "providers::blockchain", "Getting provider for pending state");
if let Some(block) = self.tree.pending_block() {
if let Some(block) = self.tree.pending_block_num_hash() {
let pending = self.tree.pending_state_provider(block.hash)?;
return self.pending_with_provider(pending)
}
@ -389,8 +394,8 @@ where
self.tree.pending_blocks()
}
fn pending_block(&self) -> Option<BlockNumHash> {
self.tree.pending_block()
fn pending_block_num_hash(&self) -> Option<BlockNumHash> {
self.tree.pending_block_num_hash()
}
}