From 1b75c95d688c715a0244d7f337c728c6dd4f75f3 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 14 Nov 2023 16:03:20 +0100 Subject: [PATCH] docs: some tree doc clenaup --- crates/blockchain-tree/src/blockchain_tree.rs | 94 ++++++++----------- .../src/{post_state_data.rs => bundle.rs} | 6 +- crates/blockchain-tree/src/lib.rs | 6 +- crates/storage/provider/src/chain.rs | 15 +-- 4 files changed, 55 insertions(+), 66 deletions(-) rename crates/blockchain-tree/src/{post_state_data.rs => bundle.rs} (89%) diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 345a9fe34916..565d6801aebd 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -27,27 +27,24 @@ use reth_provider::{ DatabaseProvider, DisplayBlocksChain, ExecutorFactory, HeaderProvider, }; use reth_stages::{MetricEvent, MetricEventsSender}; -use std::{ - collections::{BTreeMap, HashMap}, - sync::Arc, -}; +use std::{collections::BTreeMap, sync::Arc}; use tracing::{debug, error, info, instrument, trace, warn}; #[cfg_attr(doc, aquamarine::aquamarine)] -/// Tree of chains and its identifications. +/// A Tree of chains. /// -/// Mermaid flowchart represent all blocks that can appear in blockchain. -/// Green blocks belong to canonical chain and are saved inside database table, they are our main +/// Mermaid flowchart represents all the states a block can have inside the blockchaintree. +/// Green blocks belong to canonical chain and are saved inside then database, they are our main /// chain. Pending blocks and sidechains are found in memory inside [`BlockchainTree`]. -/// Both pending and sidechains have same mechanisms only difference is when they got committed to -/// database. For pending it is just append operation but for sidechains they need to move current -/// canonical blocks to BlockchainTree flush sidechain to the database to become canonical chain. -/// ```mermaid +/// Both pending and sidechains have same mechanisms only difference is when they get committed to +/// the database. For pending it is an append operation but for sidechains they need to move current +/// canonical blocks to BlockchainTree and commit the sidechain to the database to become canonical +/// chain (reorg). ```mermaid /// flowchart BT /// subgraph canonical chain /// CanonState:::state -/// block0canon:::canon -->block1canon:::canon -->block2canon:::canon -->block3canon:::canon --> block4canon:::canon --> block5canon:::canon -/// end +/// block0canon:::canon -->block1canon:::canon -->block2canon:::canon -->block3canon:::canon --> +/// block4canon:::canon --> block5canon:::canon end /// block5canon --> block6pending1:::pending /// block5canon --> block6pending2:::pending /// subgraph sidechain2 @@ -56,23 +53,21 @@ use tracing::{debug, error, info, instrument, trace, warn}; /// end /// subgraph sidechain1 /// S1State:::state -/// block2canon --> block3s1:::sidechain --> block4s1:::sidechain --> block5s1:::sidechain --> block6s1:::sidechain -/// end +/// block2canon --> block3s1:::sidechain --> block4s1:::sidechain --> block5s1:::sidechain --> +/// block6s1:::sidechain end /// classDef state fill:#1882C4 /// classDef canon fill:#8AC926 /// classDef pending fill:#FFCA3A /// classDef sidechain fill:#FF595E /// ``` -/// +/// /// /// main functions: /// * [BlockchainTree::insert_block]: Connect block to chain, execute it and if valid insert block -/// inside tree. -/// * [BlockchainTree::finalize_block]: Remove chains that join to now finalized block, as chain -/// becomes invalid. -/// * [BlockchainTree::make_canonical]: Check if we have the hash of block that we want to finalize -/// and commit it to db. If we don't have the block, pipeline syncing should start to fetch the -/// blocks from p2p. Do reorg in tables if canonical chain if needed. +/// into the tree. +/// * [BlockchainTree::finalize_block]: Remove chains that are branch off the now finalized block. +/// * [BlockchainTree::make_canonical]: Check if we have the hash of block that is the current +/// canonical head and commit it to db. #[derive(Debug)] pub struct BlockchainTree { /// The state of the tree @@ -142,14 +137,13 @@ impl BlockchainTree { self } - /// Check if then block is known to blockchain tree or database and return its status. + /// Check if the block is known to blockchain tree or database and return its status. /// /// Function will check: - /// * if block is inside database and return [BlockStatus::Valid] if it is. - /// * if block is inside buffer and return [BlockStatus::Disconnected] if it is. - /// * if block is part of the side chain and return [BlockStatus::Accepted] if it is. - /// * if block is part of the canonical chain that tree knows, return [BlockStatus::Valid], if - /// it is. + /// * if block is inside database returns [BlockStatus::Valid]. + /// * if block is inside buffer returns [BlockStatus::Disconnected]. + /// * if block is part of a side chain returns [BlockStatus::Accepted]. + /// * if block is part of the canonical returns [BlockStatus::Valid]. /// /// Returns an error if /// - an error occurred while reading from the database. @@ -244,7 +238,7 @@ impl BlockchainTree { /// * `BundleState` changes that happened at the asked `block_hash` /// * `BTreeMap` list of past pending and canonical hashes, That are /// needed for evm `BLOCKHASH` opcode. - /// Return none if block is not known. + /// Return none if block unknown. pub fn post_state_data(&self, block_hash: BlockHash) -> Option { trace!(target: "blockchain_tree", ?block_hash, "Searching for post state data"); // if it is part of the chain @@ -287,7 +281,7 @@ impl BlockchainTree { /// Try inserting a validated [Self::validate_block] block inside the tree. /// /// If the block's parent block is unknown, this returns [`BlockStatus::Disconnected`] and the - /// block will be buffered until the parent block is inserted and then attached. + /// block will be buffered until the parent block is inserted and then attached to sidechain #[instrument(level = "trace", skip_all, fields(block = ?block.num_hash()), target = "blockchain_tree", ret)] fn try_insert_validated_block( &mut self, @@ -564,12 +558,12 @@ impl BlockchainTree { hashes } - /// Get the block at which the given chain forked from the current canonical chain. + /// Get the block at which the given chain forks off the current canonical chain. /// /// This is used to figure out what kind of state provider the executor should use to execute - /// the block. + /// the block on /// - /// Returns `None` if the chain is not known. + /// Returns `None` if the chain is unknown. fn canonical_fork(&self, chain_id: BlockChainId) -> Option { let mut chain_id = chain_id; let mut fork; @@ -603,7 +597,7 @@ impl BlockchainTree { self.state.lowest_buffered_ancestor(hash) } - /// Insert a new block in the tree. + /// Insert a new block into the tree. /// /// # Note /// @@ -677,7 +671,7 @@ impl BlockchainTree { None } - /// Insert a block (with senders recovered) in the tree. + /// Insert a block (with recovered senders) into the tree. /// /// Returns the [BlockStatus] on success: /// @@ -686,14 +680,14 @@ impl BlockchainTree { /// - The parent is part of a sidechain in the tree, and we can fork at this block, or /// - The parent is part of the canonical chain, and we can fork at this block /// - /// Otherwise, and error is returned, indicating that neither the block nor its parent is part + /// Otherwise, an error is returned, indicating that neither the block nor its parent are part /// of the chain or any sidechains. /// /// This means that if the block becomes canonical, we need to fetch the missing blocks over /// P2P. /// - /// If the [BlockValidationKind::SkipStateRootValidation] is provided the state root is not - /// validated. + /// If the [BlockValidationKind::SkipStateRootValidation] variant is provided the state root is + /// not validated. /// /// # Note /// @@ -813,9 +807,9 @@ impl BlockchainTree { /// Connect unconnected (buffered) blocks if the new block closes a gap. /// - /// This will try to insert all children of the new block, extending the chain. + /// This will try to insert all children of the new block, extending its chain. /// - /// If all children are valid, then this essentially moves appends all children blocks to the + /// If all children are valid, then this essentially appends all child blocks to the /// new block's chain. fn try_connect_buffered_blocks(&mut self, new_block: BlockNumHash) { trace!(target: "blockchain_tree", ?new_block, "try_connect_buffered_blocks"); @@ -1127,9 +1121,10 @@ impl BlockchainTree { Ok(()) } - /// Revert canonical blocks from the database and return them. + /// Reverts the canonical chain down to the given block from the database and returns the + /// unwound chain. /// - /// The block, `revert_until`, is non-inclusive, i.e. `revert_until` stays in the database. + /// The block, `revert_until`, is __non-inclusive__, i.e. `revert_until` stays in the database. fn revert_canonical_from_database( &mut self, revert_until: BlockNumber, @@ -1185,16 +1180,6 @@ impl BlockchainTree { } } -/// A container that wraps chains and block indices to allow searching for block hashes across all -/// sidechains. -#[derive(Debug)] -pub struct BlockHashes<'a> { - /// The current tracked chains. - pub chains: &'a mut HashMap, - /// The block indices for all chains. - pub indices: &'a BlockIndices, -} - #[cfg(test)] mod tests { use super::*; @@ -1215,7 +1200,10 @@ mod tests { test_utils::{blocks::BlockChainTestData, TestExecutorFactory}, BlockWriter, BundleStateWithReceipts, ProviderFactory, }; - use std::{collections::HashSet, sync::Arc}; + use std::{ + collections::{HashMap, HashSet}, + sync::Arc, + }; fn setup_externals( exec_res: Vec, diff --git a/crates/blockchain-tree/src/post_state_data.rs b/crates/blockchain-tree/src/bundle.rs similarity index 89% rename from crates/blockchain-tree/src/post_state_data.rs rename to crates/blockchain-tree/src/bundle.rs index b03f25e1556b..1e7eb3182004 100644 --- a/crates/blockchain-tree/src/post_state_data.rs +++ b/crates/blockchain-tree/src/bundle.rs @@ -1,10 +1,10 @@ -//! Substate for blockchain trees +//! [BundleStateDataProvider] implementations used by the tree. use reth_primitives::{BlockHash, BlockNumber, ForkBlock}; use reth_provider::{BundleStateDataProvider, BundleStateWithReceipts}; use std::collections::BTreeMap; -/// Structure that bundles references of data needs to implement [`BundleStateDataProvider`] +/// Structure that combines references of required data to be a [`BundleStateDataProvider`]. #[derive(Clone, Debug)] pub struct BundleStateDataRef<'a> { /// The wrapped state after execution of one or more transactions and/or blocks. @@ -36,7 +36,7 @@ impl<'a> BundleStateDataProvider for BundleStateDataRef<'a> { } } -/// Structure that contains data needs to implement [`BundleStateDataProvider`] +/// Structure that owns the relevant data needs to be a [`BundleStateDataProvider`] #[derive(Clone, Debug)] pub struct BundleStateData { /// Post state with changes diff --git a/crates/blockchain-tree/src/lib.rs b/crates/blockchain-tree/src/lib.rs index 38ed99f82b7e..b825ce5beaa1 100644 --- a/crates/blockchain-tree/src/lib.rs +++ b/crates/blockchain-tree/src/lib.rs @@ -20,7 +20,7 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] pub mod blockchain_tree; -pub use blockchain_tree::{BlockHashes, BlockchainTree}; +pub use blockchain_tree::BlockchainTree; pub mod block_indices; pub use block_indices::BlockIndices; @@ -37,8 +37,8 @@ pub use externals::TreeExternals; pub mod shareable; pub use shareable::ShareableBlockchainTree; -pub mod post_state_data; -pub use post_state_data::{BundleStateData, BundleStateDataRef}; +mod bundle; +pub use bundle::{BundleStateData, BundleStateDataRef}; /// Buffer of not executed blocks. pub mod block_buffer; diff --git a/crates/storage/provider/src/chain.rs b/crates/storage/provider/src/chain.rs index 95bf68b3b24e..ab269b680ad6 100644 --- a/crates/storage/provider/src/chain.rs +++ b/crates/storage/provider/src/chain.rs @@ -328,7 +328,7 @@ pub struct BlockReceipts { pub tx_receipts: Vec<(TxHash, Receipt)>, } -/// The target block of the chain split. +/// The target block where the chain should be split. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum ChainSplitTarget { /// Split at block number. @@ -347,16 +347,17 @@ pub enum ChainSplit { /// Chain is not split. Canonical chain is returned. /// Given block split is lower than first block. NoSplitCanonical(Chain), - /// Chain is split into two. - /// Given block split is contained in first chain. + /// Chain is split into two: `[canonical]` and `[pending]` + /// The target of this chain split [ChainSplitTarget] belongs to the `canonical` chain. Split { - /// Left contains lower block numbers that are considered canonicalized. It ends with - /// the [ChainSplitTarget] block. The substate of this chain is now empty and not usable. + /// Contains lower block numbers that are considered canonicalized. It ends with + /// the [ChainSplitTarget] block. The state of this chain is now empty and no longer + /// usable. canonical: Chain, - /// Right contains all subsequent blocks after the [ChainSplitTarget] that are still + /// Right contains all subsequent blocks __after__ the [ChainSplitTarget] that are still /// pending. /// - /// The substate of the original chain is moved here. + /// The state of the original chain is moved here. pending: Chain, }, }