//! Consensus-relay plumbing shared by the marshal application wrappers. use crate::{ marshal::{ application::gates::{Gates, Staged}, core::{Mailbox, Variant}, }, simplex::Plan, }; use commonware_actor::Feedback; use commonware_cryptography::certificate::Scheme; use commonware_p2p::Recipients; use tracing::debug; /// Relays a consensus broadcast [`Plan`] through marshal for a proposal staged in `gates`. /// /// A prepare plan sends the staged candidate to all peers, at most once, and keeps /// it staged without storing it. A propose plan locks the staged proposal in: it sends /// the proposal to all peers unless a prepare plan already did, and persists /// it either way, delivering the durable-sync handle through the staged ack. A /// forward plan re-sends a stored block to the requested recipients. /// /// A propose plan that finds nothing staged sends nothing. Certification claims our own /// proposal only after a notarization, which needs our vote, and consensus casts that vote /// only after the propose plan. Within a process, a proposal is therefore missing only when /// its round is decided, and a prepare plan may already have sent the block. Prepare and /// propose plans send nothing for a round at or below the decided cutoff of [`Gates`]. pub(crate) fn broadcast( gates: &Gates, marshal: &Mailbox, commitment: V::Commitment, plan: Plan, ) -> Feedback where S: Scheme, V: Variant, { match plan { Plan::Prepare { round } => { let Some(block) = gates.send_staged(round, commitment) else { debug!(%round, %commitment, "no unsent staged candidate to relay early"); return Feedback::Ok; }; marshal.prepared(round, block, Recipients::All) } Plan::Propose { round } => { let Some((Staged { block, ack }, sent)) = gates.take_staged(round, commitment) else { debug!(%round, %commitment, "no staged proposal to relay"); return Feedback::Ok; }; if sent { marshal.verified_deferred(round, block, ack); return Feedback::Ok; } marshal.proposed(round, block, Recipients::All, ack) } Plan::Forward { round, recipients } => marshal.forward(round, commitment, recipients), } }