mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
chore: add blockchain tree and state provider traces (#2418)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -4692,6 +4692,7 @@ dependencies = [
|
|||||||
"reth-primitives",
|
"reth-primitives",
|
||||||
"reth-provider",
|
"reth-provider",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@ -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"}
|
||||||
|
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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))
|
||||||
|
|||||||
Reference in New Issue
Block a user