network_message.rs
Overview
This file defines the core message types and data structures used for managing consensus rounds and authority switching in a distributed network protocol. It primarily handles the communication and data involved in transitioning block production authority between nodes during consensus rounds, including success, failure, and rejection scenarios. The message structures encapsulate cryptographic proofs, attestations, and locking mechanisms crucial for the protocol's correctness and safety.
The file contains data types representing lock states, round requests, round results (success/failure), rejection messages, and the enumeration of all possible authority switch messages exchanged between nodes. These messages facilitate coordination and verification of block production and finalization in the consensus process.
Data Structures and Enumerations
Lock
Represents the locked state for a particular round in the consensus protocol.
Fields
parent_block: BlockIdentifier
Identifier of the parent block for the locked round.height: BlockHeight
The height of the block in the blockchain.next_auth_node_id: NodeIdentifier
The identifier of the node authorized to produce the next block.locked_round: BlockRound
The round number that is currently locked.locked_block: Option<BlockIdentifier>
Optional identifier of the locked block if one exists.nack_bad_block: HashSet<BlockIdentifier>
Set of blocks at this height identified as invalid, confirmed via negative acknowledgments (NACKs).
Usage
Lock is used to represent and propagate the locked state across nodes. The lock ensures that all nodes agree on a particular block and round, helping to prevent conflicting blocks being finalized. The handling of invalid blocks using nack_bad_block supports network robustness by tracking and excluding known bad blocks.
Implementation Details
The lock is updated based on round results; both success and failure responses update the lock for all nodes.
A lock update requires a proof that the locked block is valid.
The lock state supports the protocol’s quorum logic, ensuring that at least 51% agreement is collected before finalizing or switching blocks.
NextRound
Represents a request message to initiate or continue a consensus round.
Fields
lock: Envelope<GoshBLS, Lock>
The lock state wrapped in an envelope with cryptographic signatures.locked_block_attestation: Option<Envelope<GoshBLS, AttestationData>>
Optional attestation proving the validity of the locked block.attestations_for_ancestors: Vec<Envelope<GoshBLS, AttestationData>>
Attestations for blocks not yet finalized; necessary when no locked block exists.
Usage
Sent by nodes to signal the start or continuation of a round, including the current lock and relevant attestations. This message is essential for nodes to synchronize their view of the blockchain state and locked rounds.
NextRoundSuccess
Indicates a successful consensus round with a proposed block.
Fields
node_identifier: NodeIdentifier
Node that produced this success message.round: BlockRound
Round number this success corresponds to.block_height: BlockHeight
Block height associated with this round.proposed_block: NetBlock
The block proposed in this round.attestations_aggregated: Option<Envelope<GoshBLS, AttestationData>>
Optional aggregated attestations proving the block's validity; must exist if the block is a voting winner.requests_aggregated: Vec<Envelope<GoshBLS, Lock>>
Collection of lock messages used as proof that the round was successful.
Usage
Conveys that a consensus round has completed successfully with a block proposed and validated by a quorum of nodes.
NextRoundFailed
Represents a failed consensus round, including the best known block and proofs.
Fields
node_identifier: NodeIdentifier
Node that produced the failure message.round: BlockRound
Round number for the failed attempt.block_height: BlockHeight
Block height related to this round.proposed_block: NetBlock
The best block known despite failure.attestations_aggregated: Option<Envelope<GoshBLS, AttestationData>>
Optional aggregated attestations associated with the block.requests_aggregated: Vec<Envelope<GoshBLS, Lock>>
Proofs and locks collected during the failed round attempt.
Usage
Used when a round fails to produce a final block but nodes still share information about the best known block and proof of efforts made.
NextRoundReject
Sent to reject a NextRound request due to a prefinalized block existing at the requested height.
Fields
thread_identifier: ThreadIdentifier
Identifier of the thread to which this rejection applies.prefinalized_block: NetBlock
The block that has been prefinalized, causing the rejection.proof_of_prefinalization: Envelope<GoshBLS, AttestationData>
Cryptographic proof that the block is prefinalized.
Usage
Prevents unnecessary processing of rounds for blocks that have already been prefinalized, maintaining protocol efficiency.
AuthoritySwitch (Enum)
Enumerates all possible messages related to switching block production authority.
Variants
Request(NextRound)
Initiates authority switching by requesting the next consensus round. Must be signed by an authorized node.Reject(NextRoundReject)
Rejects a request due to the presence of a prefinalized block.RejectTooOld(ThreadIdentifier)
Rejects a request because the requested block height is outdated compared to finalized blocks.Switched(Envelope<GoshBLS, NextRoundSuccess>)
Confirms a successful switch in authority, including proof of the round's success.Failed(Envelope<GoshBLS, NextRoundFailed>)
Indicates that the node failed to collect enough requests for a quorum and provides the best known block information.
Usage
This enum serves as the comprehensive message type for all authority switch communication scenarios in the protocol.
Important Implementation Details
The locking mechanism ensures that all nodes have a consistent view of the locked round and block, crucial to preventing forks.
The protocol requires 51%+ consensus for certain decisions, such as finalizing a block or switching authority.
Messages are wrapped in cryptographic envelopes (
Envelope<GoshBLS, T>) to ensure authenticity and integrity, leveraging the BLS signature scheme (GoshBLS).The design supports failure scenarios and recovery, with messages to indicate failed rounds and provide evidence of attempts.
The
NextRoundmessage supports attestations for ancestor blocks, enabling validation of chains even when no locked block exists.Reject messages prevent redundant processing by nodes when blocks are already prefinalized or requests are outdated.
Interactions with Other Components
Envelope and Signatures: The file depends on the
Envelopetype from the BLS cryptographic module (crate::bls::envelope::Envelope) for message signing and verification, integrating cryptographic proofs into consensus messages.Node Identification: Uses
NodeIdentifierto identify nodes involved in the consensus, defined elsewhere in the system (crate::node::NodeIdentifier).Block and Round Types: Relies on types such as
BlockIdentifier,BlockHeight, andBlockRoundfrom shared type definitions (crate::types), ensuring consistent block and round references across the system.Attestations: Uses
AttestationDatato include cryptographic attestations proving block validity, linking to the attestation handling in the node module (crate::node::associated_types::AttestationData).NetBlock: Represents the network block structure (crate::node::NetBlock), which encapsulates blocks transferred between nodes.
Consensus Protocol Logic: Messages defined here are exchanged between nodes during consensus rounds, linking to higher-level consensus management modules that process these messages to drive block production and finalization.
Usage Examples
Creating a Lock
use std::collections::HashSet;
use crate::types::{BlockIdentifier, BlockHeight, BlockRound};
use crate::node::NodeIdentifier;
let lock = Lock::builder()
.parent_block(parent_block_id)
.height(current_height)
.next_auth_node_id(next_node_id)
.locked_round(current_round)
.locked_block(Some(locked_block_id))
.nack_bad_block(HashSet::new())
.build();
Sending a NextRound Request
let next_round_msg = NextRound::builder()
.lock(lock_envelope)
.locked_block_attestation(Some(attestation_envelope))
.attestations_for_ancestors(vec![/* additional attestations */])
.build();
let authority_switch_request = AuthoritySwitch::Request(next_round_msg);
Handling a Successful Round
match received_message {
AuthoritySwitch::Switched(success_envelope) => {
let success = success_envelope.content();
// Process the proposed block and aggregated attestations
}
_ => {}
}
Mermaid Diagram: Structure of network_message.rs
classDiagram
class Lock {
-parent_block: BlockIdentifier
-height: BlockHeight
-next_auth_node_id: NodeIdentifier
-locked_round: BlockRound
-locked_block: Option<BlockIdentifier>
-nack_bad_block: HashSet<BlockIdentifier>
}
class NextRound {
-lock: Envelope<GoshBLS, Lock>
-locked_block_attestation: Option<Envelope<GoshBLS, AttestationData>>
-attestations_for_ancestors: Vec<Envelope<GoshBLS, AttestationData>>
}
class NextRoundSuccess {
-node_identifier: NodeIdentifier
-round: BlockRound
-block_height: BlockHeight
-proposed_block: NetBlock
-attestations_aggregated: Option<Envelope<GoshBLS, AttestationData>>
-requests_aggregated: Vec<Envelope<GoshBLS, Lock>>
}
class NextRoundFailed {
-node_identifier: NodeIdentifier
-round: BlockRound
-block_height: BlockHeight
-proposed_block: NetBlock
-attestations_aggregated: Option<Envelope<GoshBLS, AttestationData>>
-requests_aggregated: Vec<Envelope<GoshBLS, Lock>>
}
class NextRoundReject {
-thread_identifier: ThreadIdentifier
-prefinalized_block: NetBlock
-proof_of_prefinalization: Envelope<GoshBLS, AttestationData>
}
class AuthoritySwitch {
<<enumeration>>
Request
Reject
RejectTooOld
Switched
Failed
}
AuthoritySwitch --> NextRound : Request
AuthoritySwitch --> NextRoundReject : Reject
AuthoritySwitch --> ThreadIdentifier : RejectTooOld
AuthoritySwitch --> NextRoundSuccess : Switched
AuthoritySwitch --> NextRoundFailed : Failed
NextRoundSuccess --> NetBlock
NextRoundFailed --> NetBlock
NextRoundReject --> NetBlock
Lock <.. Envelope
NextRound <.. Envelope
NextRoundSuccess <.. Envelope
NextRoundFailed <.. Envelope
NextRoundReject <.. Envelope
This diagram illustrates the main data structures and their relationships, highlighting the central role of the AuthoritySwitch enum in message handling. The use of Envelope for cryptographic wrapping is indicated via dependencies. The diagram provides a high-level view of message types involved in consensus round management.