1mod addr;
2mod connection;
3mod metrics;
4mod msg;
5mod net;
6mod queue;
7mod time;
8mod util;
9
10pub mod error;
11pub mod noise;
12pub mod x25519;
13
14use std::{collections::BTreeMap, fmt, num::NonZeroUsize, sync::Arc, time::Duration};
15
16pub use addr::NetAddr;
17use bon::Builder;
18pub use error::NetworkError;
19pub use metrics::Metrics;
20pub use msg::Slot;
21pub use net::{
22 Network, NetworkController, NetworkReceiver, RetryPolicy, SendAction, SendCommand,
23 SendCommandBuilder,
24};
25
26use crate::{
27 util::nonempty::NonEmpty,
28 x25519::{Keypair, PublicKey},
29};
30
31#[derive(Builder)]
32#[builder(finish_fn(vis = "", name = "internal_build"))]
33#[non_exhaustive]
34pub struct Config {
35 #[builder(with = |s: impl Into<String>| Arc::new(s.into()))]
37 name: Arc<String>,
38
39 #[builder(with = |it: impl IntoIterator<Item = (Version, noise::Protocol)>| {
48 NonEmpty::assert_non_empty_map(it)
49 })]
50 noise_protocols: NonEmpty<BTreeMap<Version, noise::Protocol>>,
51
52 keypair: Keypair,
54
55 bind: NetAddr,
57
58 #[builder(with = <_>::from_iter)]
60 parties: Vec<(PublicKey, NetAddr)>,
61
62 #[builder(default = NonZeroUsize::new(100).expect("100 > 0"))]
63 peer_budget: NonZeroUsize,
64
65 #[builder(default = NonZeroUsize::new(10485760).expect("10485760 > 0"))]
67 max_message_size: NonZeroUsize,
68
69 #[builder(
71 default = NonEmpty::new(1, [3, 5, 15, 30]),
72 with = |it: impl IntoIterator<Item = u8>| NonEmpty::assert_non_empty_vec(it)
73 )]
74 connect_retry_delays: NonEmpty<Vec<u8>>,
75
76 #[builder(
78 default = NonEmpty::new(5, [15, 30]),
79 with = |it: impl IntoIterator<Item = u8>| NonEmpty::assert_non_empty_vec(it)
80 )]
81 send_retry_delays: NonEmpty<Vec<u8>>,
82
83 #[builder(default = true)]
85 random_connect_delay: bool,
86
87 #[builder(default = Duration::from_secs(30))]
89 connect_timeout: Duration,
90
91 #[builder(default = Duration::from_secs(10))]
93 handshake_timeout: Duration,
94
95 #[builder(default = Duration::from_secs(30))]
99 receive_timeout: Duration,
100
101 #[builder(default = Duration::from_secs(30))]
105 backoff_duration: Duration,
106
107 metrics: Option<Arc<dyn Metrics>>,
109}
110
111impl<S: config_builder::IsComplete> ConfigBuilder<S> {
112 pub fn build(self) -> Config {
113 let conf = self.internal_build();
114
115 let v1 = conf.noise_protocols.iter().map(|(k, _)| k);
116 let v2 = conf.noise_protocols.iter().map(|(k, _)| k).skip(1);
117 assert! {
118 v1.zip(v2).all(|(a, b)| u16::from(*a) + 1 == u16::from(*b)),
119 "cliquenet configuration requires consecutive noise protocol versions"
120 }
121
122 conf
123 }
124}
125
126impl fmt::Debug for Config {
127 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128 f.debug_struct("Config")
129 .field("name", &self.name)
130 .field("key", &self.keypair.public_key())
131 .field("bind", &self.bind)
132 .field("parties", &self.parties)
133 .field("peer_budget", &self.peer_budget)
134 .field("max_message_size", &self.max_message_size)
135 .field("connect_retry_delays", &self.connect_retry_delays)
136 .field("send_retry_delays", &self.send_retry_delays)
137 .field("random_connect_delay", &self.random_connect_delay)
138 .field("connect_timeout", &self.connect_timeout)
139 .field("handshake_timeout", &self.handshake_timeout)
140 .field("receive_timeout", &self.receive_timeout)
141 .field("backoff_duration", &self.backoff_duration)
142 .finish()
143 }
144}
145
146impl Config {
147 pub fn public_key(&self) -> PublicKey {
148 self.keypair.public_key()
149 }
150
151 pub fn with_metrics<M: Metrics + 'static>(mut self, m: M) -> Self {
152 self.metrics = Some(Arc::new(m));
153 self
154 }
155}
156
157#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
159pub enum Role {
160 Active,
162 Passive,
167}
168
169impl Role {
170 pub fn is_active(self) -> bool {
171 matches!(self, Self::Active)
172 }
173}
174
175impl fmt::Display for Role {
176 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177 match self {
178 Self::Active => f.write_str("active"),
179 Self::Passive => f.write_str("passive"),
180 }
181 }
182}
183
184#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
185pub struct Version(u16);
186
187impl From<u16> for Version {
188 fn from(v: u16) -> Self {
189 Self(v)
190 }
191}
192
193impl From<Version> for u16 {
194 fn from(v: Version) -> Self {
195 v.0
196 }
197}
198
199impl fmt::Display for Version {
200 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201 self.0.fmt(f)
202 }
203}