//! P2P resolver plumbing reused by the standard and coding marshal variants. use crate::marshal::resolver::handler::{self, Annotation, Key, Receiver as HandlerReceiver}; use commonware_actor::mailbox; use commonware_cryptography::{Digest, PublicKey}; use commonware_p2p::{Blocker, Provider, Receiver as P2pReceiver, Sender}; use commonware_resolver::p2p; use commonware_runtime::{Clock, Metrics, Spawner}; use commonware_utils::NonZeroDuration; use rand_core::Rng; use std::{num::NonZeroUsize, time::Duration}; /// Configuration for the P2P [Resolver](commonware_resolver::Resolver). pub struct Config where P: PublicKey, C: Provider, B: Blocker, { /// The public key to identify this node. pub public_key: P, /// The provider of the peer set that fetches are sent to. /// /// A fetch without targets may be sent to any peer of the latest set, primary or secondary. /// A fetch with targets, such as one from /// [`hint_finalized`](crate::marshal::core::Mailbox::hint_finalized), is sent only to its /// targets in that set. pub peer_provider: C, /// The blocker that will be used to block peers that send invalid responses. pub blocker: B, /// The size of the request mailbox backlog. pub mailbox_size: NonZeroUsize, /// Timeout for requests. pub fetch_timeout: NonZeroDuration, /// Delay after an unresolved attempt before retrying its fetch. /// Zero permits immediate retries, subject to the sender's rate limit. pub fetch_retry_delay: Duration, /// Whether requests are sent with priority over other network messages pub priority_requests: bool, /// Whether responses are sent with priority over other network messages pub priority_responses: bool, } /// Mailbox for issuing marshal backfill requests. pub type Mailbox = p2p::Mailbox, P, Annotation>; /// Initialize a P2P resolver. pub fn init( context: E, config: Config, backfill: (S, R), ) -> (HandlerReceiver, Mailbox) where E: Rng + Spawner + Clock + Metrics, C: Provider, B: Blocker, D: Digest, S: Sender, R: P2pReceiver, P: PublicKey, { // Every handler entry is one message the network admitted on the backfill channel, and peer // requests are dropped once the ready queue is full, so hold as many as the channel. let (sender, receiver) = mailbox::new(context.child("handler"), backfill.1.capacity()); let handler = handler::Handler::new(sender); let (resolver_engine, resolver) = p2p::Engine::new( context.child("resolver"), p2p::Config { peer_provider: config.peer_provider, blocker: config.blocker, consumer: handler.clone(), producer: handler, mailbox_size: config.mailbox_size, me: Some(config.public_key), fetch_timeout: config.fetch_timeout, fetch_retry_delay: config.fetch_retry_delay, priority_requests: config.priority_requests, priority_responses: config.priority_responses, }, ); resolver_engine.start(backfill); (HandlerReceiver::new(receiver), resolver) }