invalidate_branch.rs
Overview
The invalidate_branch.rs file provides functionality to traverse and invalidate a blockchain branch starting from a specified root block state. The primary function, invalidate_branch, marks the entire branch as invalidated if it meets certain conditions related to the block sequence numbers, ensuring that branches older than a given cutoff are not processed unnecessarily. This operation is critical in maintaining the integrity and correctness of the blockchain state by preventing finalized or already invalidated blocks from being reprocessed.
Function: invalidate_branch
pub fn invalidate_branch(
branch_root_block_state: BlockState,
block_state_repository: &BlockStateRepository,
filter: &FilterPrehistoric,
)
Purpose
Traverses through a branch of blocks starting at branch_root_block_state and marks each block in the branch as invalidated unless the branch is newer or equal to a given filter sequence number. The function ensures that blocks which are finalized or already invalidated are not processed again to avoid redundant operations or corrupting finalized data.
Parameters
branch_root_block_state: BlockStateThe starting point of the branch to be invalidated. It represents the block state of the root block of the branch.
block_state_repository: &BlockStateRepositoryA reference to the repository holding all block states. It is used to retrieve child block states during traversal.
filter: &FilterPrehistoricA filter object that provides a cutoff sequence number. Branches with a root block sequence number greater than or equal to this cutoff are not invalidated.
Behavior and Implementation Details
Filter Check:
The function first checks the sequence number (
block_seq_no()) of the root block state. If the filter's sequence number is greater than or equal to the root block's sequence number, the function returns early without processing. This prevents invalidation of branches that are not prehistoric relative to the filter.Breadth-First Traversal:
The function uses a
VecDequeas a queue to perform a breadth-first traversal of the branch starting from the root block.Invalidation Logic:
For each block state dequeued:
It asserts that the block is not finalized, as finalized blocks should never be invalidated.
If the block is already invalidated, it skips further processing for that block.
Otherwise, it marks the block as invalidated by calling
set_invalidated().It collects all children of the current block from the
known_childrenmap and adds them to the queue for subsequent processing.
Child Block Retrieval:
Child blocks are retrieved from the
block_state_repositoryusing their identifiers. The function panics if a child block is not found (unwrap()), implying that the repository must be consistent and contain all referenced children.
Return Value
The function returns nothing (()); the operation modifies the internal state of BlockState instances by marking them invalidated.
Usage Example
// Assuming `root_block_state` is a BlockState instance representing the branch root,
// `block_repo` is a BlockStateRepository reference,
// and `filter` is a FilterPrehistoric instance:
invalidate_branch(root_block_state, &block_repo, &filter);
This will traverse the branch starting at root_block_state and invalidate all blocks in that branch which are older than the filter's cutoff sequence number.
Important Types and Components
BlockState
Represents the state of a block. It provides guarded accessors (
guardedandguarded_mut) to safely read or mutate internal fields such as sequence number, finalization status, invalidation status, and known children blocks.BlockStateRepository
Repository interface to fetch
BlockStateinstances by their identifiers. It supports retrieval operations essential for branch traversal.FilterPrehistoric
Provides a method to get a sequence number cutoff (
block_seq_no()). Branches with root sequence numbers not exceeding this cutoff are skipped during invalidation.Guarded and GuardedMut
Utility wrappers that ensure safe concurrent access or encapsulation of mutable and immutable references within
BlockState.
Algorithmic Flow
The function implements a Breadth-First Search (BFS) over the blockchain branch starting from the root block state. It ensures that:
No finalized blocks are invalidated.
Each block is invalidated once.
Children of invalidated blocks are recursively invalidated.
This approach guarantees a complete and efficient invalidation of the entire branch.
Interaction with Other System Components
BlockStateRepository
The function relies on this repository to fetch child block states during traversal. The repository must maintain an up-to-date map of all blocks for accurate invalidation.
BlockState
The function operates directly on block states, invoking guarded methods to safely read and mutate block attributes. The invalidation state is a critical component of the block lifecycle management.
FilterPrehistoric
Acts as a pruning mechanism to prevent unnecessary invalidation of recent or valid branches, optimizing system performance.
Mermaid Diagram: Function Workflow
flowchart TD
A[Start: invalidate_branch] --> B{Check root block seq_no vs filter}
B -- seq_no >= filter --> C[Return early]
B -- seq_no < filter --> D[Initialize queue with root block]
D --> E[Pop next block from queue]
E --> F{Is block finalized?}
F -- Yes --> G[Assert failure]
F -- No --> H{Is block invalidated?}
H -- Yes --> I[Skip processing]
H -- No --> J[Set block invalidated]
J --> K[Collect children from known_children]
K --> L{Are there children?}
L -- Yes --> M[Enqueue all children]
L -- No --> N[Continue]
M & N --> O{Queue empty?}
O -- No --> E
O -- Yes --> P[End]
Notes
The function assumes that all child blocks referenced in
known_childrenexist in theBlockStateRepository. Missing children will cause a panic at runtime.The assertion that blocks are not finalized before invalidation enforces blockchain consensus rules.
The use of HashSet for children ensures no duplicate child processing.
The function does not return any status, so callers must rely on side effects or other mechanisms to confirm invalidation.