acki_nacki.rs

Overview

This file implements the handling of acknowledgment (Ack) and negative acknowledgment (Nack) messages within the consensus mechanism of a node. It provides methods to process incoming Ack and Nack messages, manage their caching and validation, and maintain consistency in block finalization states. The implementation resides as part of the generic Node struct, parameterized over a state synchronization service and a random number generator, facilitating pluggable components in the consensus workflow.

Processing acknowledgments and negative acknowledgments is critical for consensus finality and block validation. The file focuses on verifying signatures, caching messages when necessary, updating internal state repositories, and interacting with validation services. Some methods related to detailed Nack validation are stubbed or commented out, indicating ongoing or planned enhancements.

Classes and Implementations

impl<TStateSyncService, TRandomGenerator> Node<TStateSyncService, TRandomGenerator>

This implementation block adds acknowledgment and negative acknowledgment handling functionality to the Node struct. The generics constrain the node to use a StateSyncService with a RepositoryImpl and a random number generator implementing the rand::Rng trait.

Methods


on_ack(&mut self, ack: &<Self as NodeAssociatedTypes>::Ack) -> anyhow::Result<()>

Processes an incoming acknowledgment message.

let ack_message = ...; // some ack message
node.on_ack(&ack_message)?;

on_nack(&mut self, nack: &<Self as NodeAssociatedTypes>::Nack) -> anyhow::Result<()>

Processes an incoming negative acknowledgment message.

let nack_message = ...; // some nack message
node.on_nack(&nack_message)?;

_check_cached_acks_and_nacks(&mut self, last_processed_block: &<Self as NodeAssociatedTypes>::CandidateBlock) -> anyhow::Result<()>

Checks and processes any cached acknowledgments or negative acknowledgments related to a recently processed block.

node._check_cached_acks_and_nacks(&last_block)?;

_clear_old_acks_and_nacks(&mut self, finalized_block_seq_no: &BlockSeqNo) -> anyhow::Result<()>

Clears cached acknowledgments and negative acknowledgments up to and including a given finalized block sequence number.

node._clear_old_acks_and_nacks(&finalized_seq_no)?;

Important Implementation Details and Algorithms

Interaction with Other System Components

Visual Diagram: Structure of Node Ack/Nack Handling

flowchart TD
A[Node]
A --> B(on_ack)
A --> C(on_nack)
A --> D(_check_cached_acks_and_nacks)
A --> E(_clear_old_acks_and_nacks)
B --> F{Retrieve pubkeys}
F -- Success --> G[Verify signatures]
F -- Fail --> H[Cache ack]
G -- Valid --> I[Add ack to received_acks]
G -- Invalid --> J[Ignore]
C --> K{NackReason}
K -- BadBlock/TooComplex --> L[Mark block suspicious]
L --> M[Send to validation_service]
K -- Other --> N[Warn unimplemented]
D --> O[Get cached acks for block]
O --> P[Process first matching ack]
D --> Q[Get cached nacks for block]
Q --> R[Process first matching nack]
E --> S[Remove cached acks <= finalized seq]
E --> T[Remove cached nacks <= finalized seq]
E --> U[Prune received_acks]
E --> V[Prune received_nacks]

The diagram captures the flow of acknowledgment and negative acknowledgment processing within the node, highlighting caching, verification, suspicious block handling, and cleanup operations.