1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// SPDX-License-Identifier: MIT OR Apache-2.0
use std::collections::HashSet;
use p2panda_core::SigningKey;
use ractor::thread_local::{ThreadLocalActor, ThreadLocalActorSpawner};
use crate::address_book::AddressBook;
use crate::iroh_endpoint::actors::{IrohEndpoint, IrohEndpointArgs};
use crate::iroh_endpoint::api::{Endpoint, EndpointError};
use crate::iroh_endpoint::config::IrohConfig;
use crate::{DEFAULT_NETWORK_ID, NetworkId};
pub struct Builder {
network_id: Option<NetworkId>,
signing_key: Option<SigningKey>,
config: Option<IrohConfig>,
relay_urls: HashSet<iroh::RelayUrl>,
address_book: AddressBook,
}
impl Builder {
pub fn new(address_book: AddressBook) -> Self {
Self {
network_id: None,
signing_key: None,
config: None,
address_book,
relay_urls: HashSet::new(),
}
}
pub fn network_id(mut self, network_id: NetworkId) -> Self {
self.network_id = Some(network_id);
self
}
pub fn signing_key(mut self, signing_key: SigningKey) -> Self {
self.signing_key = Some(signing_key);
self
}
pub fn config(mut self, config: IrohConfig) -> Self {
self.config = Some(config);
self
}
/// Adds iroh relay server to assist in establishing direct connections.
///
/// Multiple relays can be added, iroh will automatically choose a "home relay" based on
/// latency.
///
/// Relays fullfil multiple functions:
///
/// 1. The relay server helps establish connections by temporarily routing encrypted traffic
/// until a direct, P2P connection is feasible. This allows nodes to immediately get
/// started, without waiting for holepunching / STUN to complete first.
/// 2. Handle learning a node's public addresses (via QUIC address discovery), signalling and
/// hole-punching to establish direct connections between two nodes. This set of methods is
/// also understood as STUN. After this point the relay is not required anymore.
/// 3. Relayed and encrypted fallback using the server when establishing a direct connection
/// failed (TURN).
///
/// If no relay is given other nodes can only connect to us if a directly reachable IP address
/// is available and known to them.
pub fn relay_url(mut self, url: iroh::RelayUrl) -> Self {
self.relay_urls.insert(url);
self
}
pub(crate) fn build_args(self) -> IrohEndpointArgs {
let network_id = self.network_id.unwrap_or(DEFAULT_NETWORK_ID);
let signing_key = self.signing_key.unwrap_or_default();
let config = self.config.unwrap_or_default();
let relay_map = iroh::RelayMap::from_iter(self.relay_urls);
(
network_id,
signing_key,
config,
relay_map,
self.address_book,
)
}
pub async fn spawn(self) -> Result<Endpoint, EndpointError> {
let args = self.build_args();
let (actor_ref, _) = {
let thread_pool = ThreadLocalActorSpawner::new();
IrohEndpoint::spawn(None, args.clone(), thread_pool).await?
};
Ok(Endpoint::new(Some(actor_ref), args))
}
}