chore: add blockchain tree and state provider traces (#2418)

This commit is contained in:
Dan Cline
2023-04-27 12:01:54 -04:00
committed by GitHub
parent 2b7b14ab8c
commit 5d76e6513d
6 changed files with 40 additions and 1 deletions

1
Cargo.lock generated
View File

@ -4692,6 +4692,7 @@ dependencies = [
"reth-primitives",
"reth-provider",
"tokio",
"tracing",
]
[[package]]

View File

@ -19,6 +19,9 @@ reth-interfaces = { path = "../interfaces" }
reth-db = { path = "../storage/db" }
reth-provider = { path = "../storage/provider" }
# tracing
tracing = "0.1"
# common
parking_lot = { version = "0.12"}

View File

@ -16,6 +16,7 @@ use std::{
collections::{BTreeMap, HashMap},
sync::Arc,
};
use tracing::trace;
use crate::{
chain::BlockChainId, AppendableChain, BlockIndices, BlockchainTreeConfig, PostStateData,
@ -177,8 +178,10 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
/// needed for evm `BLOCKHASH` opcode.
/// Return none if block is not known.
pub fn post_state_data(&self, block_hash: BlockHash) -> Option<PostStateData> {
trace!(target: "blockchain_tree", ?block_hash, "Searching for post state data");
// if it is part of the chain
if let Some(chain_id) = self.block_indices.get_blocks_chain_id(&block_hash) {
trace!(target: "blockchain_tree", ?block_hash, "Constructing post state data based on non-canonical chain");
// get block state
let chain = self.chains.get(&chain_id).expect("Chain should be present");
let block_number = chain.block_number(block_hash)?;
@ -206,6 +209,7 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
if let Some(canonical_fork) =
self.block_indices().canonical_chain().iter().find(|(_, value)| **value == block_hash)
{
trace!(target: "blockchain_tree", ?block_hash, "Constructing post state data based on canonical chain");
return Some(PostStateData {
canonical_fork: ForkBlock { number: *canonical_fork.0, hash: *canonical_fork.1 },
state: PostState::new(),
@ -535,6 +539,7 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTree<DB, C, EF>
pub fn make_canonical(&mut self, block_hash: &BlockHash) -> Result<(), Error> {
// If block is already canonical don't return error.
if self.block_indices.is_block_hash_canonical(block_hash) {
trace!(target: "blockchain_tree", ?block_hash, "Block is already canonical");
let td = self
.externals
.shareable_db()

View File

@ -16,6 +16,7 @@ use std::{
collections::{BTreeMap, HashSet},
sync::Arc,
};
use tracing::trace;
/// Shareable blockchain tree that is behind tokio::RwLock
#[derive(Clone)]
@ -36,6 +37,7 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTreeEngine
{
/// Recover senders and call [`BlockchainTreeEngine::insert_block_with_senders`].
fn insert_block(&self, block: SealedBlock) -> Result<BlockStatus, Error> {
trace!(target: "blockchain_tree", ?block, "Inserting block");
let mut tree = self.tree.write();
tree.ensure_block_is_in_range(&block)?;
let block = block
@ -48,22 +50,27 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTreeEngine
&self,
block: SealedBlockWithSenders,
) -> Result<BlockStatus, Error> {
trace!(target: "blockchain_tree", ?block, "Inserting block with senders");
self.tree.write().insert_block_with_senders(block)
}
fn finalize_block(&self, finalized_block: BlockNumber) {
trace!(target: "blockchain_tree", ?finalized_block, "Finalizing block");
self.tree.write().finalize_block(finalized_block)
}
fn restore_canonical_hashes(&self, last_finalized_block: BlockNumber) -> Result<(), Error> {
trace!(target: "blockchain_tree", ?last_finalized_block, "Restoring canonical hashes for last finalized block");
self.tree.write().restore_canonical_hashes(last_finalized_block)
}
fn make_canonical(&self, block_hash: &BlockHash) -> Result<(), Error> {
trace!(target: "blockchain_tree", ?block_hash, "Making block canonical");
self.tree.write().make_canonical(block_hash)
}
fn unwind(&self, unwind_to: BlockNumber) -> Result<(), Error> {
trace!(target: "blockchain_tree", ?unwind_to, "Unwinding to block number");
self.tree.write().unwind(unwind_to)
}
}
@ -72,26 +79,32 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTreeViewer
for ShareableBlockchainTree<DB, C, EF>
{
fn blocks(&self) -> BTreeMap<BlockNumber, HashSet<BlockHash>> {
trace!(target: "blockchain_tree", "Returning all blocks in blockchain tree");
self.tree.read().block_indices().index_of_number_to_pending_blocks().clone()
}
fn block_by_hash(&self, block_hash: BlockHash) -> Option<SealedBlock> {
trace!(target: "blockchain_tree", ?block_hash, "Returning block by hash");
self.tree.read().block_by_hash(block_hash).cloned()
}
fn canonical_blocks(&self) -> BTreeMap<BlockNumber, BlockHash> {
trace!(target: "blockchain_tree", "Returning canonical blocks in tree");
self.tree.read().block_indices().canonical_chain().clone()
}
fn canonical_tip(&self) -> BlockNumHash {
trace!(target: "blockchain_tree", "Returning canonical tip");
self.tree.read().block_indices().canonical_tip()
}
fn pending_blocks(&self) -> (BlockNumber, Vec<BlockHash>) {
trace!(target: "blockchain_tree", "Returning all pending blocks");
self.tree.read().block_indices().pending_blocks()
}
fn pending_block(&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 })
}
@ -104,6 +117,7 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> BlockchainTreePendingState
&self,
block_hash: BlockHash,
) -> Option<Box<dyn PostStateDataProvider>> {
trace!(target: "blockchain_tree", ?block_hash, "Finding pending state provider");
let provider = self.tree.read().post_state_data(block_hash)?;
Some(Box::new(provider))
}
@ -113,6 +127,7 @@ impl<DB: Database, C: Consensus, EF: ExecutorFactory> CanonStateSubscriptions
for ShareableBlockchainTree<DB, C, EF>
{
fn subscribe_to_canonical_state(&self) -> reth_provider::CanonStateNotifications {
trace!(target: "blockchain_tree", "Registered subscriber for canonical state");
self.tree.read().subscribe_canon_state()
}
}

View File

@ -16,6 +16,7 @@ use reth_revm_primitives::{
primitives::{BlockEnv, CfgEnv, SpecId},
};
use std::{ops::RangeBounds, sync::Arc};
use tracing::trace;
/// A common provider that fetches data from a database.
///
@ -44,6 +45,7 @@ impl<DB: Clone> Clone for ShareableDatabase<DB> {
impl<DB: Database> ShareableDatabase<DB> {
/// Storage provider for latest block
pub fn latest(&self) -> Result<StateProviderBox<'_>> {
trace!(target: "providers::db", "Returning latest state provider");
Ok(Box::new(LatestStateProvider::new(self.db.tx()?)))
}
@ -61,6 +63,7 @@ impl<DB: Database> ShareableDatabase<DB> {
// +1 as the changeset that we want is the one that was applied after this block.
block_number += 1;
trace!(target: "providers::db", ?block_number, "Returning historical state provider for block number");
Ok(Box::new(HistoricalStateProvider::new(tx, block_number)))
}
@ -80,6 +83,7 @@ impl<DB: Database> ShareableDatabase<DB> {
// as the changeset contains old values.
block_number += 1;
trace!(target: "providers::db", ?block_hash, "Returning historical state provider for block hash");
Ok(Box::new(HistoricalStateProvider::new(tx, block_number)))
}
}

View File

@ -23,6 +23,7 @@ use std::{
collections::{BTreeMap, HashSet},
ops::RangeBounds,
};
use tracing::trace;
mod database;
mod post_state_provider;
@ -283,20 +284,26 @@ where
{
/// Storage provider for latest block
fn latest(&self) -> Result<StateProviderBox<'_>> {
trace!(target: "providers::blockchain", "Getting latest block state provider");
self.database.latest()
}
fn history_by_block_number(&self, block_number: BlockNumber) -> Result<StateProviderBox<'_>> {
trace!(target: "providers::blockchain", ?block_number, "Getting history by block number");
self.database.history_by_block_number(block_number)
}
fn history_by_block_hash(&self, block_hash: BlockHash) -> Result<StateProviderBox<'_>> {
trace!(target: "providers::blockchain", ?block_hash, "Getting history by block hash");
self.database.history_by_block_hash(block_hash)
}
fn state_by_block_hash(&self, block: BlockHash) -> Result<StateProviderBox<'_>> {
trace!(target: "providers::blockchain", ?block, "Getting state by block hash");
// check tree first
if let Some(pending) = self.tree.find_pending_state_provider(block) {
trace!(target: "providers::blockchain", "Returning pending state provider");
return self.pending_with_provider(pending)
}
// not found in tree, check database
@ -305,6 +312,8 @@ where
/// Storage provider for pending state.
fn pending(&self) -> Result<StateProviderBox<'_>> {
trace!(target: "providers::blockchain", "Getting provider for pending state");
if let Some(block) = self.tree.pending_block() {
let pending = self.tree.pending_state_provider(block.hash)?;
return self.pending_with_provider(pending)
@ -317,6 +326,8 @@ where
post_state_data: Box<dyn PostStateDataProvider>,
) -> Result<StateProviderBox<'_>> {
let canonical_fork = post_state_data.canonical_fork();
trace!(target: "providers::blockchain", ?canonical_fork, "Returning post state provider");
let state_provider = self.history_by_block_hash(canonical_fork.hash)?;
let post_state_provider = PostStateProvider::new(state_provider, post_state_data);
Ok(Box::new(post_state_provider))