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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use super::*;
use libp2p::{
core::{muxing::StreamMuxerBox, transport, upgrade},
identity,
mplex::MplexConfig,
noise::{self, AuthenticKeypair, X25519Spec},
pnet::PnetConfig,
PeerId, Transport,
};
use std::{borrow::Borrow, time::Duration};
pub type P2PTransport = (PeerId, StreamMuxerBox);
pub type BoxedP2PTransport = transport::Boxed<P2PTransport>;
#[derive(Clone)]
pub struct TransportBuilder {
pnet_config: PnetConfig,
mplex_config: MplexConfig,
noise_keys: AuthenticKeypair<X25519Spec>,
timeout: Duration,
peer_id: PeerId,
}
impl TransportBuilder {
pub fn new() -> Self {
let keypair = identity::Keypair::generate_ed25519();
Self::new_with_key(keypair)
}
pub fn new_with_key(keypair: identity::Keypair) -> Self {
Self::new_with_key_and_config(keypair, TransportConfig::default().borrow())
}
pub fn new_with_key_and_config(keypair: identity::Keypair, config: &TransportConfig) -> Self {
let peer_id = PeerId::from(keypair.public());
let shared_key = config.get_shared_key();
let pnet_config = PnetConfig::new(shared_key);
let mplex_config = config.get_mplex_config();
let noise_keys = noise::Keypair::<noise::X25519Spec>::new()
.into_authentic(&keypair)
.expect("Signing libp2p-noise static DH keypair failed.");
Self {
pnet_config,
mplex_config,
noise_keys,
timeout: Duration::from_secs(60),
peer_id,
}
}
pub fn with_config(mut self, config: &TransportConfig) -> Self {
let shared_key = config.get_shared_key();
self.pnet_config = PnetConfig::new(shared_key);
self.mplex_config = config.get_mplex_config();
self
}
pub fn with_mainnet_config(self) -> Self {
self.with_config(&MAINNET_CONFIG)
}
pub fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;
self
}
pub fn build(self) -> Result<(BoxedP2PTransport, PeerId), std::io::Error> {
let transport = {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
use libp2p::wasm_ext;
wasm_ext::ExtTransport::new(wasm_ext::ffi::websocket_transport())
} else {
use libp2p::{dns::TokioDnsConfig as DnsConfig, tcp::TokioTcpConfig as TcpConfig, websocket::WsConfig};
let tcp = TcpConfig::new().nodelay(true);
let dns_tcp = DnsConfig::system(tcp)?;
let ws_dns_tcp = WsConfig::new(dns_tcp.clone());
dns_tcp.or_transport(ws_dns_tcp)
}
}
};
Ok((
transport
.and_then(move |socket, _| self.pnet_config.handshake(socket))
.upgrade(upgrade::Version::V1)
.authenticate(noise::NoiseConfig::xx(self.noise_keys).into_authenticated())
.multiplex(self.mplex_config)
.timeout(self.timeout)
.boxed(),
self.peer_id,
))
}
}
impl Default for TransportBuilder {
fn default() -> Self {
Self::new()
}
}