commonware_p2p/authenticated/discovery/
network.rs1use super::{
4 actors::{dialer, listener, router, spawner, tracker},
5 channels::{self, Channels},
6 config::Config,
7 types,
8};
9use crate::{authenticated::discovery::types::InfoVerifier, Channel};
10use commonware_cryptography::Signer;
11use commonware_macros::select;
12use commonware_runtime::{
13 spawn_cell, BufferPooler, Clock, ContextCell, Handle, Metrics, Network as RNetwork, Quota,
14 Resolver, Spawner,
15};
16use commonware_stream::encrypted::Config as StreamConfig;
17use commonware_utils::union;
18use rand_core::CryptoRng;
19use tracing::{debug, info};
20
21const TRACKER_SUFFIX: &[u8] = b"_TRACKER";
23
24const STREAM_SUFFIX: &[u8] = b"_STREAM";
26
27pub struct Network<
29 E: Spawner + BufferPooler + Clock + CryptoRng + RNetwork + Resolver + Metrics,
30 C: Signer,
31> {
32 context: ContextCell<E>,
33 cfg: Config<C>,
34
35 channels: Channels<C::PublicKey>,
36 tracker: tracker::Actor<E, C>,
37 tracker_mailbox: tracker::Mailbox<C::PublicKey>,
38 router: router::Actor<E, C::PublicKey>,
39 router_mailbox: router::Mailbox<C::PublicKey>,
40 info_verifier: InfoVerifier<C::PublicKey>,
41}
42
43impl<E: Spawner + BufferPooler + Clock + CryptoRng + RNetwork + Resolver + Metrics, C: Signer>
44 Network<E, C>
45{
46 pub fn new(context: E, cfg: Config<C>) -> (Self, tracker::Oracle<C::PublicKey>) {
57 let (tracker, tracker_mailbox, oracle, info_verifier) = tracker::Actor::new(
58 context.child("tracker"),
59 tracker::Config {
60 crypto: cfg.crypto.clone(),
61 namespace: union(&cfg.namespace, TRACKER_SUFFIX),
62 address: cfg.dialable.clone(),
63 bootstrappers: cfg.bootstrappers.clone(),
64 allow_private_ips: cfg.allow_private_ips,
65 allow_dns: cfg.allow_dns,
66 synchrony_bound: cfg.synchrony_bound,
67 mailbox_size: cfg.mailbox_size,
68 tracked_peer_sets: cfg.tracked_peer_sets,
69 peer_connection_cooldown: cfg.peer_connection_cooldown,
70 peer_gossip_max_count: cfg.peer_gossip_max_count,
71 max_peer_set_size: cfg.max_peer_set_size,
72 dial_fail_limit: cfg.dial_fail_limit,
73 block_duration: cfg.block_duration,
74 },
75 );
76 let (router, router_mailbox, messenger) = router::Actor::new(
77 context.child("router"),
78 router::Config {
79 mailbox_size: cfg.mailbox_size,
80 },
81 );
82 let channels = Channels::new(messenger, cfg.max_message_size);
83
84 (
85 Self {
86 context: ContextCell::new(context),
87 cfg,
88
89 channels,
90 tracker,
91 tracker_mailbox,
92 router,
93 router_mailbox,
94 info_verifier,
95 },
96 oracle,
97 )
98 }
99
100 #[allow(clippy::type_complexity)]
114 pub fn register(
115 &mut self,
116 channel: Channel,
117 rate: Quota,
118 backlog: usize,
119 ) -> (
120 channels::Sender<C::PublicKey, E>,
121 channels::Receiver<C::PublicKey>,
122 ) {
123 let context = self
124 .context
125 .child("channel")
126 .with_attribute("index", channel);
127 self.channels.register(channel, rate, backlog, context)
128 }
129
130 pub fn start(mut self) -> Handle<()> {
134 spawn_cell!(self.context, self.run())
135 }
136
137 async fn run(self) {
138 let mut tracker_task = self.tracker.start();
140
141 let mut router_task = self.router.start(self.channels);
143
144 let (spawner, spawner_mailbox) = spawner::Actor::new(
146 self.context.child("spawner"),
147 spawner::Config {
148 mailbox_size: self.cfg.mailbox_size,
149 send_batch_size: self.cfg.send_batch_size,
150 gossip_bit_vec_frequency: self.cfg.gossip_bit_vec_frequency,
151 max_peer_set_size: self.cfg.max_peer_set_size,
152 peer_gossip_max_count: self.cfg.peer_gossip_max_count,
153 info_verifier: self.info_verifier,
154 },
155 );
156 let mut spawner_task =
157 spawner.start(self.tracker_mailbox.clone(), self.router_mailbox.clone());
158
159 let stream_cfg = StreamConfig {
161 signing_key: self.cfg.crypto,
162 namespace: union(&self.cfg.namespace, STREAM_SUFFIX),
163 max_message_size: self
164 .cfg
165 .max_message_size
166 .saturating_add(types::MAX_PAYLOAD_DATA_OVERHEAD),
167 synchrony_bound: self.cfg.synchrony_bound,
168 max_handshake_age: self.cfg.max_handshake_age,
169 handshake_timeout: self.cfg.handshake_timeout,
170 };
171 let listener = listener::Actor::new(
172 self.context.child("listener"),
173 listener::Config {
174 address: self.cfg.listen,
175 stream_cfg: stream_cfg.clone(),
176 allow_private_ips: self.cfg.allow_private_ips,
177 max_concurrent_handshakes: self.cfg.max_concurrent_handshakes,
178 allowed_handshake_rate_per_ip: self.cfg.allowed_handshake_rate_per_ip,
179 allowed_handshake_rate_per_subnet: self.cfg.allowed_handshake_rate_per_subnet,
180 },
181 );
182 let mut listener_task =
183 listener.start(self.tracker_mailbox.clone(), spawner_mailbox.clone());
184
185 let dialer = dialer::Actor::new(
187 self.context.child("dialer"),
188 dialer::Config {
189 stream_cfg,
190 dial_frequency: self.cfg.dial_frequency,
191 peer_connection_cooldown: self.cfg.peer_connection_cooldown,
192 allow_private_ips: self.cfg.allow_private_ips,
193 },
194 );
195 let mut dialer_task = dialer.start(self.tracker_mailbox, spawner_mailbox);
196
197 let mut shutdown = self.context.stopped();
198
199 info!("network started");
201 select! {
202 _ = &mut shutdown => {
203 debug!("context shutdown, stopping network");
204 },
205 tracker = &mut tracker_task => {
206 debug!(?tracker, "tracker stopped, shutting down network");
207 },
208 router = &mut router_task => {
209 debug!(?router, "router stopped, shutting down network");
210 },
211 spawner = &mut spawner_task => {
212 debug!(?spawner, "spawner stopped, shutting down network");
213 },
214 listener = &mut listener_task => {
215 debug!(?listener, "listener stopped, shutting down network");
216 },
217 dialer = &mut dialer_task => {
218 debug!(?dialer, "dialer stopped, shutting down network");
219 },
220 }
221 }
222}