pub struct BlockchainTree<N: NodeTypesWithDB, E> { /* private fields */ }
Expand description
A Tree of chains.
The flowchart represents all the states a block can have inside the tree.
- Green blocks belong to the canonical chain and are saved inside the database.
- Pending blocks and sidechains are found in-memory inside
BlockchainTree
.
Both pending chains and sidechains have the same mechanisms, the only difference is when they get committed to the database.
For pending, it is an append operation, but for sidechains they need to move the current canonical blocks to the tree (by removing them from the database), and commit the sidechain blocks to the database to become the canonical chain (reorg).
include_mmd!("docs/mermaid/tree.mmd
“)
§Main functions
BlockchainTree::insert_block
: Connect a block to a chain, execute it, and if valid, insert the block into the tree.BlockchainTree::finalize_block
: Remove chains that branch off of the now finalized block.BlockchainTree::make_canonical
: Check if we have the hash of a block that is the current canonical head and commit it to db.
Implementations§
Source§impl<N: NodeTypesWithDB, E> BlockchainTree<N, E>
impl<N: NodeTypesWithDB, E> BlockchainTree<N, E>
Sourcepub fn subscribe_canon_state(&self) -> CanonStateNotifications
pub fn subscribe_canon_state(&self) -> CanonStateNotifications
Subscribe to new blocks events.
Note: Only canonical blocks are emitted by the tree.
Sourcepub fn canon_state_notification_sender(&self) -> CanonStateNotificationSender
pub fn canon_state_notification_sender(&self) -> CanonStateNotificationSender
Returns a clone of the sender for the canonical state notifications.
Source§impl<N, E> BlockchainTree<N, E>where
N: ProviderNodeTypes,
E: BlockExecutorProvider,
impl<N, E> BlockchainTree<N, E>where
N: ProviderNodeTypes,
E: BlockExecutorProvider,
Sourcepub fn new(
externals: TreeExternals<N, E>,
config: BlockchainTreeConfig,
) -> ProviderResult<Self>
pub fn new( externals: TreeExternals<N, E>, config: BlockchainTreeConfig, ) -> ProviderResult<Self>
Builds the blockchain tree for the node.
This method configures the blockchain tree, which is a critical component of the node, responsible for managing the blockchain state, including blocks, transactions, and receipts. It integrates with the consensus mechanism and the EVM for executing transactions.
§Parameters
externals
: External components required by the blockchain tree:provider_factory
: A factory for creating various blockchain-related providers, such as for accessing the database or static files.consensus
: The consensus configuration, which defines how the node reaches agreement on the blockchain state with other nodes.evm_config
: The EVM (Ethereum Virtual Machine) configuration, which affects how smart contracts and transactions are executed. Proper validation of this configuration is crucial for the correct execution of transactions.
tree_config
: Configuration for the blockchain tree, including any parameters that affect its structure or performance.
Sourcepub fn with_sync_metrics_tx(self, metrics_tx: MetricEventsSender) -> Self
pub fn with_sync_metrics_tx(self, metrics_tx: MetricEventsSender) -> Self
Set the sync metric events sender.
A transmitter for sending synchronization metrics. This is used for monitoring the node’s synchronization process with the blockchain network.
Sourcepub const fn block_indices(&self) -> &BlockIndices
pub const fn block_indices(&self) -> &BlockIndices
Expose internal indices of the BlockchainTree
.
Sourcepub fn sidechain_block_by_hash(
&self,
block_hash: BlockHash,
) -> Option<&SealedBlock>
pub fn sidechain_block_by_hash( &self, block_hash: BlockHash, ) -> Option<&SealedBlock>
Returns the block with matching hash from any side-chain.
Caution: This will not return blocks from the canonical chain.
Sourcepub fn block_with_senders_by_hash(
&self,
block_hash: BlockHash,
) -> Option<&SealedBlockWithSenders>
pub fn block_with_senders_by_hash( &self, block_hash: BlockHash, ) -> Option<&SealedBlockWithSenders>
Returns the block with matching hash from any side-chain.
Caution: This will not return blocks from the canonical chain.
Sourcepub fn receipts_by_block_hash(
&self,
block_hash: BlockHash,
) -> Option<Vec<&Receipt>>
pub fn receipts_by_block_hash( &self, block_hash: BlockHash, ) -> Option<Vec<&Receipt>>
Returns the block’s receipts with matching hash from any side-chain.
Caution: This will not return blocks from the canonical chain.
Sourcepub fn pending_block(&self) -> Option<&SealedBlock>
pub fn pending_block(&self) -> Option<&SealedBlock>
Returns the block that’s considered the Pending
block, if it exists.
Sourcepub fn post_state_data(&self, block_hash: BlockHash) -> Option<ExecutionData>
pub fn post_state_data(&self, block_hash: BlockHash) -> Option<ExecutionData>
Return items needed to execute on the pending state.
This includes:
* BlockHash
of canonical block that chain connects to. Needed for creating database
provider for the rest of the state.
* 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 unknown.
* chain_id
not present in state.
* there are no parent hashes stored.
Sourcepub fn get_buffered_block(
&self,
hash: &BlockHash,
) -> Option<&SealedBlockWithSenders>
pub fn get_buffered_block( &self, hash: &BlockHash, ) -> Option<&SealedBlockWithSenders>
Checks the block buffer for the given block.
Sourcepub fn lowest_buffered_ancestor(
&self,
hash: &BlockHash,
) -> Option<&SealedBlockWithSenders>
pub fn lowest_buffered_ancestor( &self, hash: &BlockHash, ) -> Option<&SealedBlockWithSenders>
Gets the lowest ancestor for the given block in the block buffer.
Sourcepub fn insert_block_without_senders(
&mut self,
block: SealedBlock,
) -> Result<InsertPayloadOk, InsertBlockError>
pub fn insert_block_without_senders( &mut self, block: SealedBlock, ) -> Result<InsertPayloadOk, InsertBlockError>
Insert a new block into the tree.
§Note
This recovers transaction signers (unlike BlockchainTree::insert_block
).
Sourcepub fn buffer_block(
&mut self,
block: SealedBlockWithSenders,
) -> Result<(), InsertBlockError>
pub fn buffer_block( &mut self, block: SealedBlockWithSenders, ) -> Result<(), InsertBlockError>
Insert block for future execution.
Returns an error if the block is invalid.
Sourcepub fn insert_block(
&mut self,
block: SealedBlockWithSenders,
block_validation_kind: BlockValidationKind,
) -> Result<InsertPayloadOk, InsertBlockError>
pub fn insert_block( &mut self, block: SealedBlockWithSenders, block_validation_kind: BlockValidationKind, ) -> Result<InsertPayloadOk, InsertBlockError>
Insert a block (with recovered senders) into the tree.
Returns the BlockStatus
on success:
- The block is already part of a sidechain in the tree, or
- The block is already part of the canonical chain, or
- 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, 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
variant is provided the state root
is not validated.
§Note
If the senders have not already been recovered, call
BlockchainTree::insert_block_without_senders
instead.
Sourcepub fn remove_old_blocks(&mut self, block: BlockNumber)
pub fn remove_old_blocks(&mut self, block: BlockNumber)
Discard all blocks that precede block number from the buffer.
Sourcepub fn finalize_block(
&mut self,
finalized_block: BlockNumber,
) -> ProviderResult<()>
pub fn finalize_block( &mut self, finalized_block: BlockNumber, ) -> ProviderResult<()>
Finalize blocks up until and including finalized_block
, and remove them from the tree.
Sourcepub fn connect_buffered_blocks_to_canonical_hashes_and_finalize(
&mut self,
last_finalized_block: BlockNumber,
) -> ProviderResult<()>
pub fn connect_buffered_blocks_to_canonical_hashes_and_finalize( &mut self, last_finalized_block: BlockNumber, ) -> ProviderResult<()>
Reads the last N
canonical hashes from the database and updates the block indices of the
tree by attempting to connect the buffered blocks to canonical hashes.
N
is the maximum of max_reorg_depth
and the number of block hashes needed to satisfy the
BLOCKHASH
opcode in the EVM.
§Note
This finalizes last_finalized_block
prior to reading the canonical hashes (using
BlockchainTree::finalize_block
).
Sourcepub fn update_block_hashes(
&mut self,
) -> ProviderResult<BTreeMap<BlockNumber, B256>>
pub fn update_block_hashes( &mut self, ) -> ProviderResult<BTreeMap<BlockNumber, B256>>
Update all block hashes. iterate over present and new list of canonical hashes and compare them. Remove all mismatches, disconnect them and removes all chains.
Sourcepub fn update_block_hashes_and_clear_buffered(
&mut self,
) -> ProviderResult<BTreeMap<BlockNumber, BlockHash>>
pub fn update_block_hashes_and_clear_buffered( &mut self, ) -> ProviderResult<BTreeMap<BlockNumber, BlockHash>>
Update all block hashes. iterate over present and new list of canonical hashes and compare them. Remove all mismatches, disconnect them, removes all chains and clears all buffered blocks before the tip.
Sourcepub fn connect_buffered_blocks_to_canonical_hashes(
&mut self,
) -> ProviderResult<()>
pub fn connect_buffered_blocks_to_canonical_hashes( &mut self, ) -> ProviderResult<()>
Reads the last N
canonical hashes from the database and updates the block indices of the
tree by attempting to connect the buffered blocks to canonical hashes.
N
is the maximum of max_reorg_depth
and the number of block hashes needed to satisfy the
BLOCKHASH
opcode in the EVM.
Sourcepub fn find_canonical_header(
&self,
hash: &BlockHash,
) -> Result<Option<SealedHeader>, ProviderError>
pub fn find_canonical_header( &self, hash: &BlockHash, ) -> Result<Option<SealedHeader>, ProviderError>
Attempts to find the header for the given block hash if it is canonical.
Returns Ok(None)
if the block hash is not canonical (block hash does not exist, or is
included in a sidechain).
Note: this does not distinguish between a block that is finalized and a block that is not finalized yet, only whether it is part of the canonical chain or not.
Sourcepub fn is_block_hash_canonical(
&self,
hash: &BlockHash,
) -> Result<bool, ProviderError>
pub fn is_block_hash_canonical( &self, hash: &BlockHash, ) -> Result<bool, ProviderError>
Determines whether or not a block is canonical, checking the db if necessary.
Note: this does not distinguish between a block that is finalized and a block that is not finalized yet, only whether it is part of the canonical chain or not.
Sourcepub fn make_canonical(
&mut self,
block_hash: BlockHash,
) -> Result<CanonicalOutcome, CanonicalError>
pub fn make_canonical( &mut self, block_hash: BlockHash, ) -> Result<CanonicalOutcome, CanonicalError>
Sourcepub fn unwind(&mut self, unwind_to: BlockNumber) -> Result<(), CanonicalError>
pub fn unwind(&mut self, unwind_to: BlockNumber) -> Result<(), CanonicalError>
Unwind tables and put it inside state
Trait Implementations§
Auto Trait Implementations§
impl<N, E> Freeze for BlockchainTree<N, E>
impl<N, E> !RefUnwindSafe for BlockchainTree<N, E>
impl<N, E> Send for BlockchainTree<N, E>where
E: Send,
impl<N, E> Sync for BlockchainTree<N, E>where
E: Sync,
impl<N, E> Unpin for BlockchainTree<N, E>where
E: Unpin,
impl<N, E> !UnwindSafe for BlockchainTree<N, E>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.§impl<T> TryConv for T
impl<T> TryConv for T
§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where
S: Into<Dispatch>,
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where
S: Into<Dispatch>,
§fn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
Source§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
Source§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where
S: Into<Dispatch>,
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where
S: Into<Dispatch>,
Source§fn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
impl<T> ErasedDestructor for Twhere
T: 'static,
impl<T> MaybeDebug for Twhere
T: Debug,
impl<T> MaybeSendSync for T
Layout§
Note: Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.