use super::ActorArtifact; use crate::dkg::ReshareBlock; use commonware_actor::mailbox::{Policy, Sender}; use commonware_consensus::{ marshal::core::{Mailbox as MarshalMailbox, Variant}, simplex::scheme::Scheme, }; use commonware_cryptography::Signer; use commonware_utils::channel::oneshot; use std::collections::VecDeque; /// Messages sent to the DKG probe actor. pub(crate) enum Message where S: Scheme, V: Variant, V::ApplicationBlock: ReshareBlock, ::Signer: Signer, { /// Subscribe to the probe artifact. Subscribe { /// Channel used to resolve the subscriber. response: oneshot::Sender>, }, /// Attach marshal and transition to boundary-serving mode once discovery no /// no longer has pending subscribers. Attach { /// Marshal mailbox used to serve boundary requests. marshal: MarshalMailbox, }, } impl Policy for Message where S: Scheme, V: Variant, V::ApplicationBlock: ReshareBlock, ::Signer: Signer, { type Overflow = VecDeque; fn handle(overflow: &mut Self::Overflow, message: Self) { overflow.push_back(message); } } /// Mailbox for a running DKG probe actor. #[derive(Clone)] pub struct Mailbox where S: Scheme, V: Variant, V::ApplicationBlock: ReshareBlock, ::Signer: Signer, { sender: Sender>, } impl Mailbox where S: Scheme, V: Variant, V::ApplicationBlock: ReshareBlock, ::Signer: Signer, { pub(crate) const fn new(sender: Sender>) -> Self { Self { sender } } /// Subscribe to the probe artifact. /// /// The first live subscriber causes discovery to solicit the configured /// bootstrap committee. Dropping the returned receiver cancels the /// subscription. If discovery has already resolved, late subscribers receive /// the cached artifact immediately. pub fn subscribe(&self) -> oneshot::Receiver> { let (response, receiver) = oneshot::channel(); let _ = self.sender.enqueue(Message::Subscribe { response }); receiver } /// Attach marshal so the actor can serve peers' boundary requests. /// /// If discovery has pending subscribers, the actor waits until they are /// resolved or dropped before entering serving. A source node can attach /// marshal without ever subscribing, causing it to serve boundaries without /// issuing discovery requests. pub fn attach(&self, marshal: MarshalMailbox) { let _ = self.sender.enqueue(Message::Attach { marshal }); } }