From 6c21295b782dff69c48777aa5520b3bf6f66600c Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 4 May 2023 18:29:21 +0200 Subject: [PATCH] docs: add a few additional tree docs (#2557) --- crates/blockchain-tree/src/block_indices.rs | 41 ++++++++++++------- crates/blockchain-tree/src/blockchain_tree.rs | 4 +- crates/blockchain-tree/src/shareable.rs | 2 +- crates/interfaces/src/blockchain_tree.rs | 18 ++++---- 4 files changed, 41 insertions(+), 24 deletions(-) diff --git a/crates/blockchain-tree/src/block_indices.rs b/crates/blockchain-tree/src/block_indices.rs index f9902d7e6a..621537a53e 100644 --- a/crates/blockchain-tree/src/block_indices.rs +++ b/crates/blockchain-tree/src/block_indices.rs @@ -21,13 +21,19 @@ pub struct BlockIndices { /// `number_to_block` as those are chain specific indices. canonical_chain: CanonicalChain, /// Index needed when discarding the chain, so we can remove connected chains from tree. - /// NOTE: It contains just a blocks that are forks as a key and not all blocks. + /// NOTE: It contains just blocks that are forks as a key and not all blocks. fork_to_child: HashMap>, + /// Utility index for Block number to block hash(s). + /// + /// This maps all blocks with same block number to their hash. + /// + /// Can be used for RPC fetch block(s) in chain by its number. + /// + /// Note: This is a bijection: at all times `blocks_to_chain` and this map contain the block + /// hashes. + block_number_to_block_hashes: BTreeMap>, /// Block hashes and side chain they belong blocks_to_chain: HashMap, - /// Utility index. Block number to block hash. Can be used for - /// RPC to fetch all pending block in chain by its number. - index_number_to_block: BTreeMap>, } impl BlockIndices { @@ -41,13 +47,16 @@ impl BlockIndices { canonical_chain: CanonicalChain::new(canonical_chain), fork_to_child: Default::default(), blocks_to_chain: Default::default(), - index_number_to_block: Default::default(), + block_number_to_block_hashes: Default::default(), } } - /// Return internal index that maps all pending block number to their hash. - pub fn index_of_number_to_pending_blocks(&self) -> &BTreeMap> { - &self.index_number_to_block + /// Return internal index that maps all pending block number to their hashes. + /// + /// This essentially contains all possible branches. Given a parent block, then the child block + /// number as the key has all possible block hashes as the value. + pub fn block_number_to_block_hashes(&self) -> &BTreeMap> { + &self.block_number_to_block_hashes } /// Return fork to child indices @@ -62,14 +71,16 @@ impl BlockIndices { /// 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 { + pub(crate) fn pending_block_num_hash(&self) -> Option { 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. + /// Returns all pending block hashes. + /// + /// Pending blocks are considered blocks that are extending the canonical tip by one block + /// number and have their parent hash set to the canonical tip. pub fn pending_blocks(&self) -> (BlockNumber, Vec) { let canonical_tip = self.canonical_tip(); let pending_blocks = self @@ -99,7 +110,7 @@ impl BlockIndices { block_hash: BlockHash, chain_id: BlockChainId, ) { - self.index_number_to_block.entry(block_number).or_default().insert(block_hash); + self.block_number_to_block_hashes.entry(block_number).or_default().insert(block_hash); self.blocks_to_chain.insert(block_hash, chain_id); } @@ -109,7 +120,7 @@ impl BlockIndices { // add block -> chain_id index self.blocks_to_chain.insert(block.hash(), chain_id); // add number -> block - self.index_number_to_block.entry(*number).or_default().insert(block.hash()); + self.block_number_to_block_hashes.entry(*number).or_default().insert(block.hash()); } let first = chain.first(); // add parent block -> block index @@ -213,7 +224,7 @@ impl BlockIndices { ) -> BTreeSet { // rm number -> block if let btree_map::Entry::Occupied(mut entry) = - self.index_number_to_block.entry(block_number) + self.block_number_to_block_hashes.entry(block_number) { let set = entry.get_mut(); set.remove(&block_hash); @@ -260,7 +271,7 @@ impl BlockIndices { // rm number -> block if let btree_map::Entry::Occupied(mut entry) = - self.index_number_to_block.entry(number) + self.block_number_to_block_hashes.entry(number) { let set = entry.get_mut(); set.remove(&hash); diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 53d8a2a94d..678d5dc95b 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -195,7 +195,9 @@ impl BlockchainTree self.block_indices.canonical_chain() } - /// Returns the block with matching hash. + /// Returns the block with matching hash from any side-chain. + /// + /// Caution: This will not return blocks from the canonical chain. pub fn block_by_hash(&self, block_hash: BlockHash) -> Option<&SealedBlock> { let id = self.block_indices.get_blocks_chain_id(&block_hash)?; let chain = self.chains.get(&id)?; diff --git a/crates/blockchain-tree/src/shareable.rs b/crates/blockchain-tree/src/shareable.rs index 7d03b7ea13..4cb792d1ea 100644 --- a/crates/blockchain-tree/src/shareable.rs +++ b/crates/blockchain-tree/src/shareable.rs @@ -82,7 +82,7 @@ impl BlockchainTreeViewer { fn blocks(&self) -> BTreeMap> { trace!(target: "blockchain_tree", "Returning all blocks in blockchain tree"); - self.tree.read().block_indices().index_of_number_to_pending_blocks().clone() + self.tree.read().block_indices().block_number_to_block_hashes().clone() } fn block_by_hash(&self, block_hash: BlockHash) -> Option { diff --git a/crates/interfaces/src/blockchain_tree.rs b/crates/interfaces/src/blockchain_tree.rs index 3121c23db2..ee37c16551 100644 --- a/crates/interfaces/src/blockchain_tree.rs +++ b/crates/interfaces/src/blockchain_tree.rs @@ -43,7 +43,7 @@ pub trait BlockchainTreeEngine: BlockchainTreeViewer + Send + Sync { /// [`BlockchainTreeEngine::finalize_block`]). fn restore_canonical_hashes(&self, last_finalized_block: BlockNumber) -> Result<(), Error>; - /// Make a block and its parent part of the canonical chain. + /// Make a block and its parent part of the canonical chain by committing it to the database. /// /// # Note /// @@ -85,10 +85,14 @@ pub enum BlockStatus { /// * Pending blocks that extend the canonical chain but are not yet included. /// * Future pending blocks that extend the pending blocks. pub trait BlockchainTreeViewer: Send + Sync { - /// Returns both pending and sidechain block numbers and their hashes. + /// Returns both pending and side-chain block numbers and their hashes. + /// + /// Caution: This will not return blocks from the canonical chain. fn blocks(&self) -> BTreeMap>; - /// Returns the block with matching hash. + /// Returns the block with matching hash from the tree, if it exists. + /// + /// Caution: This will not return blocks from the canonical chain. fn block_by_hash(&self, hash: BlockHash) -> Option; /// Canonical block number and hashes best known by the tree. @@ -96,8 +100,8 @@ pub trait BlockchainTreeViewer: Send + Sync { /// Given a hash, this tries to find the last ancestor that is part of the canonical chain. /// - /// In other words, this will walk up the chain starting with the given hash and return the - /// first block that's canonical. + /// In other words, this will walk up the (side) chain starting with the given hash and return + /// the first block that's canonical. fn find_canonical_ancestor(&self, hash: BlockHash) -> Option; /// Return BlockchainTree best known canonical chain tip (BlockHash, BlockNumber) @@ -108,9 +112,9 @@ pub trait BlockchainTreeViewer: Send + Sync { /// has best chance to become canonical. fn pending_blocks(&self) -> (BlockNumber, Vec); - /// Return block hashes that extends the canonical chain tip by one. + /// Return block number and hash that extends the canonical chain tip by one. /// - /// If there is no such block, return `None`. + /// If there is no such block, this returns `None`. fn pending_block_num_hash(&self) -> Option; /// Returns the pending block if there is one.