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_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, { /// Subscribe to the probe artifact (see [`Mailbox::subscribe`]). Subscribe { /// Channel used to resolve the subscriber. response: oneshot::Sender>, }, /// Attach marshal to serve boundary requests (see [`Mailbox::attach`]). Attach { /// Marshal mailbox used to serve boundary requests. marshal: MarshalMailbox, }, } impl Policy for Message where S: Scheme, V: Variant, V::ApplicationBlock: ReshareBlock, { 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, { sender: Sender>, } impl Mailbox where S: Scheme, V: Variant, V::ApplicationBlock: ReshareBlock, { pub(crate) const fn new(sender: Sender>) -> Self { Self { sender } } /// Subscribes to the probe artifact. /// /// The first live subscriber starts discovery. Dropping the returned /// receiver cancels the subscription. If discovery has already resolved, the /// receiver gets the cached artifact immediately. If the actor has stopped, /// or is serving without an artifact, the receiver closes without a value. pub fn subscribe(&self) -> oneshot::Receiver> { let (response, receiver) = oneshot::channel(); let _ = self.sender.enqueue(Message::Subscribe { response }); receiver } /// Attaches marshal so the actor can serve peers' requests. /// /// If subscribers are pending, the actor starts serving once they are /// resolved or dropped. A source node can attach marshal without ever /// subscribing, so it serves without sending discovery requests. pub fn attach(&self, marshal: MarshalMailbox) { let _ = self.sender.enqueue(Message::Attach { marshal }); } }