Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: some tree doc cleanup #5423

Merged
merged 1 commit into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 41 additions & 53 deletions crates/blockchain-tree/src/blockchain_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<DB: Database, EF: ExecutorFactory> {
/// The state of the tree
Expand Down Expand Up @@ -142,14 +137,13 @@ impl<DB: Database, EF: ExecutorFactory> BlockchainTree<DB, EF> {
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.
Expand Down Expand Up @@ -244,7 +238,7 @@ impl<DB: Database, EF: ExecutorFactory> BlockchainTree<DB, EF> {
/// * `BundleState` changes that happened at the asked `block_hash`
/// * `BTreeMap<BlockNumber,BlockHash>` 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<BundleStateData> {
trace!(target: "blockchain_tree", ?block_hash, "Searching for post state data");
// if it is part of the chain
Expand Down Expand Up @@ -287,7 +281,7 @@ impl<DB: Database, EF: ExecutorFactory> BlockchainTree<DB, EF> {
/// 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,
Expand Down Expand Up @@ -564,12 +558,12 @@ impl<DB: Database, EF: ExecutorFactory> BlockchainTree<DB, EF> {
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<ForkBlock> {
let mut chain_id = chain_id;
let mut fork;
Expand Down Expand Up @@ -603,7 +597,7 @@ impl<DB: Database, EF: ExecutorFactory> BlockchainTree<DB, EF> {
self.state.lowest_buffered_ancestor(hash)
}

/// Insert a new block in the tree.
/// Insert a new block into the tree.
///
/// # Note
///
Expand Down Expand Up @@ -677,7 +671,7 @@ impl<DB: Database, EF: ExecutorFactory> BlockchainTree<DB, EF> {
None
}

/// Insert a block (with senders recovered) in the tree.
/// Insert a block (with recovered senders) into the tree.
///
/// Returns the [BlockStatus] on success:
///
Expand All @@ -686,14 +680,14 @@ impl<DB: Database, EF: ExecutorFactory> BlockchainTree<DB, EF> {
/// - 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
///
Expand Down Expand Up @@ -813,9 +807,9 @@ impl<DB: Database, EF: ExecutorFactory> BlockchainTree<DB, EF> {

/// 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");
Expand Down Expand Up @@ -1127,9 +1121,10 @@ impl<DB: Database, EF: ExecutorFactory> BlockchainTree<DB, EF> {
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,
Expand Down Expand Up @@ -1185,16 +1180,6 @@ impl<DB: Database, EF: ExecutorFactory> BlockchainTree<DB, EF> {
}
}

/// 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<BlockChainId, AppendableChain>,
/// The block indices for all chains.
pub indices: &'a BlockIndices,
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -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<BundleStateWithReceipts>,
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions crates/blockchain-tree/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
15 changes: 8 additions & 7 deletions crates/storage/provider/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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,
},
}
Expand Down
Loading