link_parent_child.rs
Overview
This file provides mechanisms to establish and manage parent-child relationships between blocks in a blockchain-like structure through their BlockState representations. It focuses on linking a child block to its parent block within a BlockStateRepository, ensuring consistency and integrity of the block states. The core functionality is encapsulated in the do_link function and the Link struct, complemented by a macro connect! to simplify the linking syntax.
The linking process updates the parent block to include the child in its list of children and sets the child's parent identifier accordingly. It also handles special cases where the parent block is invalidated or finalized, triggering branch invalidation or propagation of the finalized status.
Key Components
Struct: Link
Represents a connection between two blocks: a parent and a child.
pub struct Link {
pub parent: BlockState,
pub child: BlockState,
}
Fields:
parent: TheBlockStateof the parent block.child: TheBlockStateof the child block.
Usage Example:
let link = Link {
parent: parent_block_state,
child: child_block_state,
};
do_link(link, &block_state_repository);
Macro: connect!
A convenience macro that wraps the creation of a Link and calls do_link.
macro_rules! connect {
(parent = $parent:ident,child = $child:ident, $block_state_repository:expr) => {
$crate::node::block_state::tools::link_parent_child::do_link(
$crate::node::block_state::tools::link_parent_child::Link {
parent: crate::node::block_state::repository::BlockState::clone(&$parent),
child: crate::node::block_state::repository::BlockState::clone(&$child),
},
$block_state_repository,
);
};
}
Parameters:
parent: Identifier for the parent block state.child: Identifier for the child block state.A reference to the
BlockStateRepository.
Usage Example:
connect!(parent = parent_block, child = child_block, &block_state_repository);
This macro clones the provided block states and invokes do_link.
Function: do_link
Establishes the parent-child relationship between two blocks and maintains block state consistency.
pub fn do_link(link: Link, block_state_repository: &BlockStateRepository)
Parameters:
link: ALinkstruct containing the parent and childBlockStates.block_state_repository: Reference to theBlockStateRepositorymanaging block states.
Functionality:
Extracts the thread identifier from the child block. The thread identifier must be set; otherwise, the function panics.
Adds the child block to the parent's children list, keyed by the thread identifier.
Retrieves the parent's finalized and invalidated statuses.
If the parent is both finalized and invalidated simultaneously, the function panics as this represents an inconsistent state.
If the parent is invalidated, the function triggers invalidation of the child's branch by calling
invalidate_branchwith a filter that excludes prehistoric blocks.Sets the child's parent block identifier.
If the parent is finalized, it marks the child block as having a finalized parent.
Return Value:
None.
Important Notes:
Uses guarded accessors (
guarded,guarded_mut) to safely access and mutate the internal state of block states, ensuring thread safety and consistency.The function relies on
invalidate_branchfrom the sibling module to propagate invalidation downstream.The
FilterPrehistoricis used to filter blocks when invalidating branches, referencing block sequence numbers.
Usage Example:
let link = Link { parent, child };
do_link(link, &block_state_repository);
Implementation Details and Algorithms
The linking process ensures the integrity of the blockchain state by:
Enforcing that a child must have a thread identifier before it can be linked.
Updating the parent's children map atomically.
Validating that the parent block is not simultaneously finalized and invalidated, which would be a critical error.
The branch invalidation algorithm uses
invalidate_branchwith a filter that excludes prehistoric blocks by default (BlockSeqNo::default()).The use of
GuardedandGuardedMuttypes wraps internal data mutations with controlled access, reducing race conditions or inconsistent mutations.Panic conditions are used to catch critical state inconsistencies early during development or runtime.
Interactions with Other Modules
invalidate_branch(super module)
Called when the parent is invalidated to recursively invalidate the child's branch.BlockStateandBlockStateRepository(crate::node::block_state and crate::node::block_state::repository)
The fundamental entities representing blocks and their storage; this file manipulates these states to maintain parent-child relationships.GuardedandGuardedMut(crate::utilities::guarded)
Used to safely access and mutate block states under concurrency or controlled conditions.FilterPrehistoric(crate::node::unprocessed_blocks_collection)
Provides filtering criteria when invalidating branches.BlockSeqNo(crate::types)
Represents block sequence numbers used in filtering prehistoric blocks.
Diagram: Structure and Workflow of link_parent_child.rs
flowchart TD
A[Link struct] -->|contains| B[BlockState parent]
A -->|contains| C[BlockState child]
D[connect! macro] -->|creates| A
D -->|calls| E[do_link function]
E -->|reads| C[child]
E -->|updates| B[parent]
E -->|may call| F[invalidate_branch]
E -->|updates| C[child]
subgraph BlockState Access
direction LR
G["guarded()"] -- read --> C
H["guarded_mut()"] -- mutate --> B
H -- mutate --> C
end
This diagram illustrates how the Link struct encapsulates the parent and child BlockState instances. The connect! macro simplifies the creation of a Link and invokes do_link. The do_link function reads and updates the parent and child block states, invoking invalidate_branch when necessary. Access to block states is managed via guarded methods to ensure safe reads and mutations.
For detailed information about BlockState, BlockStateRepository, invalidate_branch, and guarded utilities, refer to their respective topics: BlockState, BlockStateRepository, invalidate_branch, and Guarded.