Skip to main content

rings_core/swarm/
builder.rs

1#![warn(missing_docs)]
2//! This module provider [SwarmBuilder] and it's interface for
3//! [Swarm]
4
5use std::sync::Arc;
6use std::sync::RwLock;
7
8use rings_transport::webrtc_config::WebrtcUdpPortRange;
9
10use crate::chunk::ReassemblyLimits;
11use crate::dht::EntryStorage;
12use crate::dht::PeerRing;
13use crate::dht::DEFAULT_FINGER_TABLE_SIZE;
14use crate::measure::MeasureImpl;
15use crate::session::SessionSk;
16use crate::swarm::callback::SharedSwarmCallback;
17use crate::swarm::callback::SwarmCallback;
18use crate::swarm::transport::SwarmTransport;
19use crate::swarm::transport::SwarmTransportSettings;
20use crate::swarm::transport::SwarmWebrtcConfig;
21use crate::swarm::Swarm;
22
23struct DefaultCallback;
24impl SwarmCallback for DefaultCallback {}
25
26/// Creates a SwarmBuilder to configure a Swarm.
27pub struct SwarmBuilder {
28    network_id: u32,
29    ice_servers: String,
30    external_address: Option<String>,
31    webrtc_udp_port_range: Option<WebrtcUdpPortRange>,
32    dht_succ_max: u8,
33    dht_finger_table_size: usize,
34    dht_storage_redundancy: u16,
35    reassembly_limits: ReassemblyLimits,
36    dht_storage: EntryStorage,
37    session_sk: SessionSk,
38    session_ttl: Option<usize>,
39    measure: Option<MeasureImpl>,
40    callback: Option<SharedSwarmCallback>,
41}
42
43impl SwarmBuilder {
44    /// Creates new instance of [SwarmBuilder]
45    pub fn new(
46        network_id: u32,
47        ice_servers: &str,
48        dht_storage: EntryStorage,
49        session_sk: SessionSk,
50    ) -> Self {
51        SwarmBuilder {
52            network_id,
53            ice_servers: ice_servers.to_string(),
54            external_address: None,
55            webrtc_udp_port_range: None,
56            dht_succ_max: 3,
57            dht_finger_table_size: DEFAULT_FINGER_TABLE_SIZE,
58            dht_storage_redundancy: 1,
59            reassembly_limits: ReassemblyLimits::production(),
60            dht_storage,
61            session_sk,
62            session_ttl: None,
63            measure: None,
64            callback: None,
65        }
66    }
67
68    /// Sets up the maximum length of successors in the DHT.
69    pub fn dht_succ_max(mut self, succ_max: u8) -> Self {
70        self.dht_succ_max = succ_max;
71        self
72    }
73
74    /// Sets up the number of slots in the DHT finger table.
75    ///
76    /// `Did` is 160-bit, so values above `DEFAULT_FINGER_TABLE_SIZE` are clamped
77    /// by `FingerTable::new`. A size of zero disables finger maintenance.
78    pub fn dht_finger_table_size(mut self, size: usize) -> Self {
79        self.dht_finger_table_size = size;
80        self
81    }
82
83    /// Sets up the redundancy used by storage repair and anti-entropy.
84    pub fn dht_storage_redundancy(mut self, redundancy: u16) -> Self {
85        self.dht_storage_redundancy = redundancy;
86        self
87    }
88
89    /// Sets inbound chunk reassembly limits.
90    pub fn reassembly_limits(mut self, limits: ReassemblyLimits) -> Self {
91        self.reassembly_limits = limits;
92        self
93    }
94
95    /// Sets up the external address for swarm transport.
96    /// This will be used to configure the transport to listen for WebRTC connections in "HOST" mode.
97    pub fn external_address(mut self, external_address: String) -> Self {
98        self.external_address = Some(external_address);
99        self
100    }
101
102    /// Sets the native WebRTC UDP port range used during ICE gathering.
103    ///
104    /// Invariant: a present range has already proven `1 <= min <= max`.
105    /// Browser transports ignore this native deployment setting.
106    pub fn webrtc_udp_port_range(mut self, range: WebrtcUdpPortRange) -> Self {
107        self.webrtc_udp_port_range = Some(range);
108        self
109    }
110
111    /// Setup timeout for session.
112    pub fn session_ttl(mut self, ttl: usize) -> Self {
113        self.session_ttl = Some(ttl);
114        self
115    }
116
117    /// Bind measurement function for Swarm.
118    pub fn measure(mut self, implement: MeasureImpl) -> Self {
119        self.measure = Some(implement);
120        self
121    }
122
123    /// Bind callback for Swarm.
124    pub fn callback(mut self, callback: SharedSwarmCallback) -> Self {
125        self.callback = Some(callback);
126        self
127    }
128
129    /// Try build for `Swarm`.
130    pub fn build(self) -> Swarm {
131        let dht_did = self.session_sk.account_did();
132
133        let dht = Arc::new(PeerRing::new_with_storage_and_finger_table_size(
134            dht_did,
135            self.dht_succ_max,
136            self.dht_storage,
137            self.dht_finger_table_size,
138        ));
139
140        let callback = RwLock::new(
141            self.callback
142                .unwrap_or_else(|| Arc::new(DefaultCallback {})),
143        );
144
145        let transport = Arc::new(SwarmTransport::new(
146            self.network_id,
147            SwarmWebrtcConfig::new(
148                self.ice_servers,
149                self.external_address,
150                self.webrtc_udp_port_range,
151            ),
152            self.session_sk,
153            dht.clone(),
154            self.measure,
155            SwarmTransportSettings::new(self.dht_storage_redundancy, self.reassembly_limits),
156        ));
157
158        Swarm {
159            dht,
160            transport,
161            callback,
162        }
163    }
164}