//! Communicate with authenticated peers over encrypted connections.
//!
//! # Status
//!
//! Stability varies by primitive. See [README](https://github.com/commonwarexyz/monorepo#stability) for details.
#![doc(
html_logo_url = "https://commonware.xyz/imgs/rustdoc_logo.svg",
html_favicon_url = "https://commonware.xyz/favicon.ico"
)]
use commonware_macros::{stability_mod, stability_scope};
stability_mod!(ALPHA, pub mod simulated);
stability_scope!(BETA {
use commonware_actor::{Feedback, Unreliable};
use commonware_cryptography::PublicKey;
use commonware_runtime::{IoBuf, IoBufs};
use commonware_utils::{
channel::mpsc,
ordered::{Map, Set},
};
use std::{error::Error as StdError, fmt::Debug, future::Future, time::SystemTime};
pub mod authenticated;
pub mod types;
pub mod utils;
pub use types::{Address, Ingress};
/// Tuple representing a message received from a given public key.
///
/// This message is guaranteed to adhere to the configuration of the channel and
/// will already be decrypted and authenticated.
pub type Message
= (P, IoBuf);
/// Alias for identifying communication channels.
pub type Channel = u64;
/// Enum indicating the set of recipients to send a message to.
#[derive(Clone, Debug)]
pub enum Recipients {
All,
Some(Vec),
One(P),
}
/// Interface for sending messages to a set of recipients without rate-limiting restrictions.
pub trait UnlimitedSender: Clone + Send + Sync + 'static {
/// Public key type used to identify recipients.
type PublicKey: PublicKey;
/// Sends a message to a set of recipients.
///
/// # Offline Recipients
///
/// If a recipient is offline at the time a message is sent, the message
/// will be dropped. It is up to the application to handle retries (if
/// necessary).
///
/// # Returns
///
/// Feedback from submitting the message for delivery.
/// [`Unreliable`] indicates that local submission may be rejected under backpressure.
/// [`Feedback::accepted`] does not guarantee that the recipient will receive the message.
fn send(
&mut self,
recipients: Recipients,
message: impl Into + Send,
priority: bool,
) -> Unreliable;
}
/// Interface for constructing a [`CheckedSender`] from a set of [`Recipients`],
/// filtering out any that are currently rate-limited.
pub trait LimitedSender: Clone + Send + Sync + 'static {
/// Public key type used to identify recipients.
type PublicKey: PublicKey;
/// The type of [`CheckedSender`] returned after checking recipients.
type Checked<'a>: CheckedSender + Send
where
Self: 'a;
/// Checks which recipients are within their rate limit and returns a
/// [`CheckedSender`] for sending to them.
///
/// # Rate Limiting
///
/// Recipients that exceed their rate limit will be filtered out. The
/// returned [`CheckedSender`] will only send to non-limited recipients.
///
/// # Returns
///
/// A [`CheckedSender`] containing only the recipients that are not
/// currently rate-limited, or an error with the earliest instant at which
/// all recipients will be available if all are rate-limited.
fn check(
&mut self,
recipients: Recipients,
) -> Result, SystemTime>;
}
/// Interface for sending messages to [`Recipients`] that are not currently rate-limited.
pub trait CheckedSender: Send {
/// Public key type used to identify [`Recipients`].
type PublicKey: PublicKey;
/// Returns the recipients retained by the check.
fn recipients(&self) -> Vec;
/// Sends a message to the pre-checked recipients.
///
/// # Offline Recipients
///
/// If a recipient is offline at the time a message is sent, the message
/// will be dropped. It is up to the application to handle retries (if
/// necessary).
///
/// # Returns
///
/// Feedback from submitting the message for delivery.
/// [`Unreliable`] indicates that local submission may be rejected under backpressure.
/// [`Feedback::accepted`] does not guarantee that the recipient will receive the message.
fn send(self, message: impl Into + Send, priority: bool) -> Unreliable;
}
/// Interface for sending messages to a set of recipients.
pub trait Sender: LimitedSender {
/// Sends a message to a set of recipients.
///
/// # Offline Recipients
///
/// If a recipient is offline at the time a message is sent, the message
/// will be dropped. It is up to the application to handle retries (if
/// necessary).
///
/// # Rate Limiting
///
/// Recipients that exceed their rate limit will be skipped. The message is
/// still sent to non-limited recipients.
///
/// # Returns
///
/// The recipients we will attempt to send to. Returns an
/// empty list if all recipients are rate-limited, the sender has closed, or the send is
/// not accepted.
fn send(
&mut self,
recipients: Recipients,
message: impl Into + Send,
priority: bool,
) -> Vec {
self.check(recipients).map_or_else(
|_| Vec::new(),
|checked_sender| {
let recipients = checked_sender.recipients();
let feedback = checked_sender.send(message, priority);
if feedback.accepted() {
recipients
} else {
Vec::new()
}
},
)
}
}
// Blanket implementation of `Sender` for all `LimitedSender`s.
impl Sender for S {}
/// Interface for receiving messages from arbitrary recipients.
pub trait Receiver: Debug + Send + 'static {
/// Error that can occur when receiving a message.
type Error: Debug + StdError + Send + Sync;
/// Public key type used to identify recipients.
type PublicKey: PublicKey;
/// Receive a message from an arbitrary recipient.
fn recv(
&mut self,
) -> impl Future