pulse_candidates.rs

Overview

This file defines the PulseCandidateBlocks struct and its associated methods, which are responsible for managing timing and broadcasting logic related to "pulse" events in the context of block finalization within a networked node. The main functionality revolves around detecting when block finalization has stalled or not progressed and triggering broadcast events to re-announce candidate blocks to the network in order to maintain synchronization and liveness.

Key responsibilities include tracking the last finalized block, detecting timing conditions that require rebroadcasting, and interfacing with network message senders to propagate these candidate blocks.

Struct: PulseCandidateBlocks

PulseCandidateBlocks maintains state and timing information relevant to the pulse mechanism for candidate blocks. It is designed to be instantiated with specific node and thread identifiers, network senders, and timeout configurations.

Fields

Construction

PulseCandidateBlocks is constructed using the TypedBuilder pattern, which allows setting most fields explicitly, while some fields like last_finalized_block, last_pulse, and last_broadcast_timestamp have default initializations.

Methods

pulse(&mut self, last_finalized_block: BlockSeqNo) -> anyhow::Result<()>

Updates the internal state when a new block is finalized, resetting relevant timers and updating the last finalized block sequence number.

Parameters

Behavior

Usage Example

let mut pulse_candidates = PulseCandidateBlocks::builder()
    .node_id(node_id)
    .thread_identifier(thread_id)
    .broadcast_tx(broadcast_sender)
    .direct_send_tx(direct_sender)
    .resend_timeout(Duration::from_secs(10))
    .resend_extra_timeout_per_candidate(Duration::from_secs(1))
    .trigger_by_finalization_stopped_timer(Duration::from_secs(30))
    .trigger_by_no_finalized_since_start_timer(Duration::from_secs(300))
    .build();

pulse_candidates.pulse(new_finalized_block_seq_no)?;

evaluate(&mut self, candidates: &UnfinalizedBlocksSnapshot, blocks_repository: &RepositoryImpl) -> anyhow::Result<()>

Evaluates whether a rebroadcast should be triggered based on timing conditions and the current state of candidate blocks. If conditions are met, it initiates broadcasting of candidate blocks.

Parameters

Behavior

Usage Example

pulse_candidates.evaluate(&unfinalized_blocks_snapshot, &repository_impl)?;

Implementation Notes

Implementation Details and Algorithms

Interaction with Other Parts


Diagram: PulseCandidateBlocks Structure and Workflow

classDiagram
class PulseCandidateBlocks {
-node_id: NodeIdentifier
-thread_identifier: ThreadIdentifier
-broadcast_tx: NetBroadcastSender
-direct_send_tx: NetDirectSender
-last_finalized_block: Option<BlockSeqNo>
-last_pulse: Instant
-last_broadcast_timestamp: Instant
-resend_timeout: Duration
-resend_extra_timeout_per_candidate: Duration
-trigger_by_finalization_stopped_timer: Duration
-trigger_by_no_finalized_since_start_timer: Duration
+pulse()
+evaluate()
}
PulseCandidateBlocks ..> NodeIdentifier : uses
PulseCandidateBlocks ..> ThreadIdentifier : uses
PulseCandidateBlocks ..> NetBroadcastSender : sends messages
PulseCandidateBlocks ..> NetDirectSender : sends messages
PulseCandidateBlocks ..> UnfinalizedBlocksSnapshot : reads candidate blocks
PulseCandidateBlocks ..> RepositoryImpl : queries block repository

This diagram illustrates PulseCandidateBlocks' internal structure, key methods, and its relationships with external entities such as identifiers, network senders, and data sources.