commonware_p2p/authenticated/lookup/
network.rs1use super::{
4 actors::{dialer, listener, router, spawner, tracker},
5 channels::{self, Channels},
6 config::Config,
7 types,
8};
9use crate::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 STREAM_SUFFIX: &[u8] = b"_STREAM";
23
24pub struct Network<E: Spawner + BufferPooler + Clock + CryptoRng + RNetwork + Metrics, C: Signer> {
26 context: ContextCell<E>,
27 cfg: Config<C>,
28
29 channels: Channels<C::PublicKey>,
30 tracker: tracker::Actor<E, C>,
31 tracker_mailbox: tracker::Mailbox<C::PublicKey>,
32 router: router::Actor<E, C::PublicKey>,
33 router_mailbox: router::Mailbox<C::PublicKey>,
34 listener: listener::Updates,
35}
36
37impl<E: Spawner + BufferPooler + Clock + CryptoRng + RNetwork + Resolver + Metrics, C: Signer>
38 Network<E, C>
39{
40 pub fn new(context: E, cfg: Config<C>) -> (Self, tracker::Oracle<C::PublicKey>) {
51 let (listener_mailbox, listener) = listener::Mailbox::new();
52 let (tracker, tracker_mailbox, oracle) = tracker::Actor::new(
53 context.child("tracker"),
54 tracker::Config {
55 crypto: cfg.crypto.clone(),
56 mailbox_size: cfg.mailbox_size,
57 tracked_peer_sets: cfg.tracked_peer_sets,
58 peer_connection_cooldown: cfg.peer_connection_cooldown,
59 allow_private_ips: cfg.allow_private_ips,
60 allow_dns: cfg.allow_dns,
61 bypass_ip_check: cfg.bypass_ip_check,
62 listener: listener_mailbox,
63 block_duration: cfg.block_duration,
64 },
65 );
66 let (router, router_mailbox, messenger) = router::Actor::new(
67 context.child("router"),
68 router::Config {
69 mailbox_size: cfg.mailbox_size,
70 },
71 );
72 let channels = Channels::new(messenger, cfg.max_message_size);
73
74 (
75 Self {
76 context: ContextCell::new(context),
77 cfg,
78
79 channels,
80 tracker,
81 tracker_mailbox,
82 router,
83 router_mailbox,
84 listener,
85 },
86 oracle,
87 )
88 }
89
90 #[allow(clippy::type_complexity)]
104 pub fn register(
105 &mut self,
106 channel: Channel,
107 rate: Quota,
108 backlog: usize,
109 ) -> (
110 channels::Sender<C::PublicKey, E>,
111 channels::Receiver<C::PublicKey>,
112 ) {
113 let context = self
114 .context
115 .child("channel")
116 .with_attribute("index", channel);
117 self.channels.register(channel, rate, backlog, context)
118 }
119
120 pub fn start(mut self) -> Handle<()> {
124 spawn_cell!(self.context, self.run())
125 }
126
127 async fn run(self) {
128 let mut tracker_task = self.tracker.start();
130
131 let mut router_task = self.router.start(self.channels);
133
134 let (spawner, spawner_mailbox) = spawner::Actor::new(
136 self.context.child("spawner"),
137 spawner::Config {
138 mailbox_size: self.cfg.mailbox_size,
139 send_batch_size: self.cfg.send_batch_size,
140 ping_frequency: self.cfg.ping_frequency,
141 },
142 );
143 let mut spawner_task =
144 spawner.start(self.tracker_mailbox.clone(), self.router_mailbox.clone());
145
146 let stream_cfg = StreamConfig {
148 signing_key: self.cfg.crypto,
149 namespace: union(&self.cfg.namespace, STREAM_SUFFIX),
150 max_message_size: self
151 .cfg
152 .max_message_size
153 .saturating_add(types::MAX_PAYLOAD_DATA_OVERHEAD),
154 synchrony_bound: self.cfg.synchrony_bound,
155 max_handshake_age: self.cfg.max_handshake_age,
156 handshake_timeout: self.cfg.handshake_timeout,
157 };
158 let listener = listener::Actor::new(
159 self.context.child("listener"),
160 listener::Config {
161 address: self.cfg.listen,
162 stream_cfg: stream_cfg.clone(),
163 allow_private_ips: self.cfg.allow_private_ips,
164 bypass_ip_check: self.cfg.bypass_ip_check,
165 max_concurrent_handshakes: self.cfg.max_concurrent_handshakes,
166 allowed_handshake_rate_per_ip: self.cfg.allowed_handshake_rate_per_ip,
167 allowed_handshake_rate_per_subnet: self.cfg.allowed_handshake_rate_per_subnet,
168 },
169 self.listener,
170 );
171 let mut listener_task =
172 listener.start(self.tracker_mailbox.clone(), spawner_mailbox.clone());
173
174 let dialer = dialer::Actor::new(
176 self.context.child("dialer"),
177 dialer::Config {
178 stream_cfg,
179 dial_frequency: self.cfg.dial_frequency,
180 peer_connection_cooldown: self.cfg.peer_connection_cooldown,
181 allow_private_ips: self.cfg.allow_private_ips,
182 },
183 );
184 let mut dialer_task = dialer.start(self.tracker_mailbox, spawner_mailbox);
185
186 let mut shutdown = self.context.stopped();
187
188 info!("network started");
190 select! {
191 _ = &mut shutdown => {
192 debug!("context shutdown, stopping network");
193 },
194 tracker = &mut tracker_task => {
195 debug!(?tracker, "tracker stopped, shutting down network");
196 },
197 router = &mut router_task => {
198 debug!(?router, "router stopped, shutting down network");
199 },
200 spawner = &mut spawner_task => {
201 debug!(?spawner, "spawner stopped, shutting down network");
202 },
203 listener = &mut listener_task => {
204 debug!(?listener, "listener stopped, shutting down network");
205 },
206 dialer = &mut dialer_task => {
207 debug!(?dialer, "dialer stopped, shutting down network");
208 },
209 }
210 }
211}