use {
crate::{
GroupKey,
discovery::SignedPeerEntry,
groups::{ConsensusConfig, GroupId, StateMachine, StateSync},
tickets::{Expiration, InvalidTicket, TicketValidator},
},
core::time::Duration,
derive_builder::Builder,
};
#[derive(Builder, Debug, Clone)]
#[builder(pattern = "owned", setter(prefix = "with"), derive(Debug, Clone))]
#[builder_struct_attr(doc(hidden))]
pub struct Config {
#[builder(default = "Duration::from_secs(2)")]
pub handshake_timeout: Duration,
}
impl Config {
pub fn builder() -> ConfigBuilder {
ConfigBuilder::default()
}
}
pub struct GroupConfig {
id: GroupId,
key: GroupKey,
consensus: ConsensusConfig,
auth: Vec<Box<dyn TicketValidator>>,
}
impl GroupConfig {
pub fn new(
key: GroupKey,
consensus: ConsensusConfig,
state_machine: &impl StateMachine,
auth: Vec<Box<dyn TicketValidator>>,
) -> Self {
let mut id = key
.secret()
.hashed()
.derive(consensus.digest())
.derive(state_machine.signature())
.derive(state_machine.state_sync().signature());
for validator in &auth {
id = id.derive(validator.signature());
}
Self {
id,
key,
consensus,
auth,
}
}
pub const fn group_id(&self) -> &GroupId {
&self.id
}
pub const fn key(&self) -> &GroupKey {
&self.key
}
pub const fn consensus(&self) -> &ConsensusConfig {
&self.consensus
}
pub fn auth(&self) -> &[Box<dyn TicketValidator>] {
&self.auth
}
pub fn authorize_peer(
&self,
peer: &SignedPeerEntry,
) -> Result<Option<Expiration>, InvalidTicket> {
peer.validate_tickets(&self.auth)
}
}