use super::{
elector::Config as Elector,
types::{Activity, Context},
};
use crate::{
types::{Epoch, ViewDelta},
CertifiableAutomaton, Relay, Reporter,
};
use commonware_cryptography::{certificate::Scheme, Digest};
use commonware_p2p::Blocker;
use commonware_parallel::Strategy;
use commonware_runtime::buffer::paged::CacheRef;
use std::{num::NonZeroUsize, time::Duration};
#[derive(Debug, Clone, Copy)]
pub enum ForwardingPolicy {
Disabled,
SilentVoters,
SilentLeader,
}
impl ForwardingPolicy {
pub const fn is_enabled(&self) -> bool {
!matches!(self, Self::Disabled)
}
}
pub struct Config<S, L, B, D, A, R, F, T>
where
S: Scheme,
L: Elector<S>,
B: Blocker<PublicKey = S::PublicKey>,
D: Digest,
A: CertifiableAutomaton<Context = Context<D, S::PublicKey>>,
R: Relay,
F: Reporter<Activity = Activity<S, D>>,
T: Strategy,
{
pub scheme: S,
pub elector: L,
pub blocker: B,
pub automaton: A,
pub relay: R,
pub reporter: F,
pub strategy: T,
pub partition: String,
pub mailbox_size: usize,
pub epoch: Epoch,
pub replay_buffer: NonZeroUsize,
pub write_buffer: NonZeroUsize,
pub page_cache: CacheRef,
pub leader_timeout: Duration,
pub certification_timeout: Duration,
pub timeout_retry: Duration,
pub activity_timeout: ViewDelta,
pub skip_timeout: ViewDelta,
pub fetch_timeout: Duration,
pub fetch_concurrent: usize,
pub forwarding: ForwardingPolicy,
}
impl<
S: Scheme,
L: Elector<S>,
B: Blocker<PublicKey = S::PublicKey>,
D: Digest,
A: CertifiableAutomaton<Context = Context<D, S::PublicKey>>,
R: Relay,
F: Reporter<Activity = Activity<S, D>>,
T: Strategy,
> Config<S, L, B, D, A, R, F, T>
{
pub fn assert(&self) {
assert!(
!self.scheme.participants().is_empty(),
"there must be at least one participant"
);
assert!(
self.leader_timeout > Duration::default(),
"leader timeout must be greater than zero"
);
assert!(
self.certification_timeout > Duration::default(),
"certification timeout must be greater than zero"
);
assert!(
self.leader_timeout <= self.certification_timeout,
"leader timeout must be less than or equal to certification timeout"
);
assert!(
self.timeout_retry > Duration::default(),
"timeout retry broadcast must be greater than zero"
);
assert!(
!self.activity_timeout.is_zero(),
"activity timeout must be greater than zero"
);
assert!(
!self.skip_timeout.is_zero(),
"skip timeout must be greater than zero"
);
assert!(
self.skip_timeout <= self.activity_timeout,
"skip timeout must be less than or equal to activity timeout"
);
assert!(
self.fetch_timeout > Duration::default(),
"fetch timeout must be greater than zero"
);
assert!(
self.fetch_concurrent > 0,
"it must be possible to fetch from at least one peer at a time"
);
}
}