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