mod.rs
Overview
This file implements the core logic for the block finalization process within the blockchain system. It continuously monitors unprocessed candidate blocks, attempts to finalize eligible blocks based on their attestations and parent-child relationships, and updates the system state accordingly. The finalization process ensures that blocks are confirmed and finalized in a consistent order, updating relevant metrics, notifying other system components, and broadcasting finalized blocks.
The primary functionality revolves around the finalization_loop function, which runs continuously, and helper functions such as try_finalize that apply the finalization logic to individual blocks, and on_block_finalized which performs all necessary state updates and side-effects once a block is finalized.
This file interacts closely with:
The block state repository (
BlockStateRepository) for accessing and updating block states.The repository implementation (
RepositoryImpl) for persisting finalized blocks.Shared services (
SharedServices) that coordinate application-wide state updates.The unprocessed blocks cache (
UnfinalizedCandidateBlockCollection) for retrieving candidate blocks awaiting finalization.Messaging components for broadcasting blocks (
InstrumentedSender).The authority lock (
Authority) for thread-specific authority management.The state synchronization service (
StateSyncService) that manages cross-node state sharing.Attestation collections (
CollectedAttestations) tracking block attestations.
The overall design follows an event-driven approach, waiting on notifications of new candidate blocks and processing them in a loop until shutdown conditions are met.
Functions and Their Details
finalization_loop
pub fn finalization_loop(
mut repository: RepositoryImpl,
block_state_repository: BlockStateRepository,
mut shared_services: SharedServices,
mut raw_block_tx: InstrumentedSender<(NodeIdentifier, Vec<u8>)>,
state_sync_service: impl StateSyncService<Repository = RepositoryImpl>,
metrics: Option<BlockProductionMetrics>,
_message_db: MessageDurableStorage,
node_id: &NodeIdentifier,
authority: Arc<Mutex<Authority>>,
unprocessed_blocks_cache: UnfinalizedCandidateBlockCollection,
last_block_attestations: Arc<Mutex<CollectedAttestations>>,
chain_pulse_monitor: Sender<ChainPulseEvent>,
thread_identifier: ThreadIdentifier,
)
Description
Runs the continuous block finalization loop for a specific thread within the blockchain. It listens for updates to the unprocessed blocks cache, attempts to finalize blocks in order, and updates the repository and related services accordingly.
Parameters
repository: Mutable instance of the block repository used for persisting finalized blocks.block_state_repository: Repository providing access to block states.shared_services: Shared services instance used for cross-component coordination.raw_block_tx: Instrumented sender channel for broadcasting finalized blocks to peers.state_sync_service: Service responsible for state synchronization across nodes.metrics: Optional metrics collector to report finalization statistics._message_db: Durable storage for messages (unused in this function).node_id: Identifier of the current node.authority: Thread-safe lock managing authority state per thread.unprocessed_blocks_cache: Cache holding candidate blocks not yet finalized.last_block_attestations: Shared mutex-protected object holding attestations of the last block.chain_pulse_monitor: Sender for notifying about block finalization events.thread_identifier: Identifier for the thread this loop processes.
Behavior
Continuously runs until the shutdown flag
SHUTDOWN_FINALIZATION_FLAGis set.Waits for notifications on new unprocessed candidate blocks.
Retrieves the last finalized block and its children for the current thread.
Calculates a
height_cutoffbased on attestation deadlines and finalized heights to limit processing scope.Iterates over unprocessed blocks up to the cutoff, attempting to finalize each by calling
try_finalize.Updates the cutoff height dynamically based on new finalizations.
Waits with timeout for new notifications if no blocks are ready to finalize.
Usage Example
finalization_loop(
repository_impl,
block_state_repo,
shared_services,
raw_block_sender,
state_sync_service_instance,
Some(block_metrics),
message_storage,
&node_identifier,
authority_arc_mutex,
unprocessed_blocks_collection,
last_block_attestations_arc_mutex,
chain_pulse_event_sender,
thread_id,
);
try_finalize
fn try_finalize(
block_state: &BlockState,
repository: &mut RepositoryImpl,
block_state_repository: &BlockStateRepository,
shared_services: &mut SharedServices,
raw_block_tx: &mut InstrumentedSender<(NodeIdentifier, Vec<u8>)>,
metrics: &Option<BlockProductionMetrics>,
node_id: &NodeIdentifier,
authority: Arc<Mutex<Authority>>,
state_sync_service: Arc<impl StateSyncService<Repository = RepositoryImpl>>,
last_block_attestations: Arc<Mutex<CollectedAttestations>>,
unprocessed_blocks_cache: &UnfinalizedCandidateBlockCollection,
chain_pulse_monitor: &Sender<ChainPulseEvent>,
) -> anyhow::Result<Option<u64>>
Description
Attempts to finalize a single block if it meets the criteria such as having enough attestations and finalized parent blocks. Performs necessary state updates, notifications, and metrics reporting upon successful finalization.
Parameters
block_state: Reference to the current block's state to attempt finalization on.repository: Mutable repository instance for persisting finalized blocks.block_state_repository: Repository for querying block states.shared_services: Mutable reference to shared services handling application-level updates.raw_block_tx: Sender to broadcast finalized blocks.metrics: Optional metrics collector.node_id: Identifier of the current node.authority: Thread-safe lock managing authority.state_sync_service: Arc-wrapped state synchronization service.last_block_attestations: Shared attestations collection.unprocessed_blocks_cache: Cache of candidate blocks.chain_pulse_monitor: Sender for block finalization events.
Return Value
Returns
Result<Option<u64>>where theOption<u64>represents a new height cutoff border if block finalization advanced it.Noneindicates no change.
Important Implementation Details
Retrieves the parent block state to verify finalization dependencies.
Checks if cross-thread reference data is prepared for the block.
Collects blocks finalized by the parent and sorts them by sequence number.
For each block that can be finalized, calls
on_block_finalizedto perform finalization side effects.Updates the authority state and metrics accordingly.
Invalidates branches of blocks that are no longer valid due to finalization.
Uses internal tracing for debug and monitoring purposes.
Usage Example
let new_cutoff = try_finalize(
&block_state,
&mut repository,
&block_state_repo,
&mut shared_services,
&mut raw_block_sender,
&Some(metrics),
&node_id,
authority.clone(),
state_sync_service.clone(),
last_block_attestations.clone(),
&unprocessed_blocks_cache,
&chain_pulse_monitor,
)?;
on_block_finalized
pub fn on_block_finalized(
shared_services: &mut SharedServices,
block: &Envelope<GoshBLS, AckiNackiBlock>,
repository: &mut RepositoryImpl,
block_state_repository: &BlockStateRepository,
raw_block_tx: &mut InstrumentedSender<(NodeIdentifier, Vec<u8>)>,
state_sync_service: Arc<impl StateSyncService<Repository = RepositoryImpl>>,
last_block_attestations: Arc<Mutex<CollectedAttestations>>,
) -> anyhow::Result<()>
Description
Performs all necessary operations once a block is finalized:
Marks the block as finalized in the repository.
Updates attestation cutoffs.
Broadcasts the finalized block.
Notifies shared services.
Updates child block states to reflect finalized parent status.
Reports metrics and tracing information.
Parameters
shared_services: Mutable reference to shared services for system coordination.block: Reference to the finalized block envelope.repository: Mutable repository instance for marking blocks finalized.block_state_repository: Repository for querying block states.raw_block_tx: Sender channel for broadcasting finalized blocks.state_sync_service: Arc-wrapped state synchronization service.last_block_attestations: Shared mutex-protected collection for attestation updates.
Return Value
Returns
Result<()>representing success or failure of finalization operations.
Important Implementation Details
Uses a tracing span
"on_block_finalized"for scoped instrumentation.Moves attestation cutoffs if present in the block state.
Serializes the block with
bincodefor broadcasting.Handles possible errors when sending on the broadcasting channel, taking into account shutdown flags.
Invokes
shared_services.on_block_finalizedwith the block data and optimistic state.Updates child blocks to mark that their parent is finalized.
Usage Example
on_block_finalized(
&mut shared_services,
&finalized_block,
&mut repository,
&block_state_repo,
&mut raw_block_sender,
state_sync_service.clone(),
last_block_attestations.clone(),
)?;
Important Implementation Details and Algorithms
Finalization Eligibility: A block is eligible for finalization if it has sufficient attestations and its parent block is finalized. This is verified in
try_finalize.Height Cutoff Computation: The
finalization_loopcalculates a cutoff height based on the maximum generation deadline of child blocks and the last finalized block height, enforcing a boundary to avoid processing blocks too far ahead.Parent-Child Block Connection: When processing the next block height, the loop attempts to connect the candidate block to its parent using the
connect!macro/function, establishing parent-child relationships.Branch Invalidation: Blocks that have a sequence number less than or equal to the maximum finalized block sequence number are invalidated to prevent forks or stale branches.
Metrics and Tracing: The system reports finalization events and metrics such as transaction count and sequence numbers for monitoring and performance evaluation.
Concurrency: Uses
Arc<Mutex<...>>synchronization primitives to safely share mutable state like authority and attestation collections across threads.Shutdown Handling: The loop and finalization gracefully exit if the shutdown flags (
SHUTDOWN_FLAG,SHUTDOWN_FINALIZATION_FLAG) are set.
Interactions with Other System Components
Repositories: Reads and modifies block states via
BlockStateRepositoryandRepositoryImpl. The repository is responsible for persistence of finalized blocks.Shared Services: Invokes shared services callbacks for finalized blocks to update application-wide state.
Messaging and Networking: Sends finalized blocks over a channel (
InstrumentedSender) to be broadcast to peer nodes.State Synchronization: Integrates with a state sync service to propagate finalized state changes.
Authority Lock: Updates thread-specific authority state upon block finalization.
Unprocessed Blocks Cache: Reads candidate blocks awaiting finalization from a shared cache with notification support.
Chain Pulse Monitor: Sends events to notify about block finalization to other components interested in chain progress.
Mermaid Diagram: Function Relationship Flowchart
flowchart TD
FL(finalization_loop)
TF(try_finalize)
OF(on_block_finalized)
FL -->|iterates over blocks| TF
TF -->|finalizes block| OF
OF -->|updates repository, broadcasts| FL
FL -->|checks shutdown flags| SHUTDOWN[Shutdown Flag Check]
TF -->|checks block state and parent| BS[Block State Repository]
OF -->|marks block finalized| REPO[RepositoryImpl]
OF -->|updates shared services| SHARED[SharedServices]
OF -->|sends via channel| BROADCAST[raw_block_tx]
TF -->|sends finalization events| PULSE[ChainPulseEvent Sender]
This diagram illustrates the flow of the finalization process:
finalization_loopcontinuously processes blocks by callingtry_finalize.try_finalizeattempts to finalize a block and callson_block_finalizedupon success.on_block_finalizedperforms repository updates, broadcasts, and shared service notifications.The loop checks shutdown flags to gracefully exit.
The block state repository and repository implementations are accessed for state and persistence.
Finalization events are sent to the chain pulse monitor.
The broadcasting channel is used to disseminate finalized blocks.
Summary of Key Types Used
RepositoryImpl: The concrete implementation of the block repository handling persistence.BlockStateRepository: Provides read access to block states with locking.SharedServices: Contains shared logic and state for the node.InstrumentedSender<(NodeIdentifier, Vec<u8>)>: Channel for sending serialized blocks over the network.StateSyncService: Trait defining state synchronization behavior.UnfinalizedCandidateBlockCollection: Cache holding candidate blocks pending finalization.Authority: Manages authority-related state per thread.CollectedAttestations: Tracks attestations related to blocks.ChainPulseEvent: Events related to chain progress and block finalization.
For further details on these types, refer to their respective modules and documentation.