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-primitives",
"reth-provider", "reth-provider",
"tokio", "tokio",
"tracing",
] ]
[[package]] [[package]]

View File

@ -13,12 +13,15 @@ normal = [
] ]
[dependencies] [dependencies]
# reth # reth
reth-primitives = { path = "../primitives" } reth-primitives = { path = "../primitives" }
reth-interfaces = { path = "../interfaces" } reth-interfaces = { path = "../interfaces" }
reth-db = { path = "../storage/db" } reth-db = { path = "../storage/db" }
reth-provider = { path = "../storage/provider" } reth-provider = { path = "../storage/provider" }
# tracing
tracing = "0.1"
# common # common
parking_lot = { version = "0.12"} parking_lot = { version = "0.12"}

View File

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

View File

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

View File

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

View File

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