1use crate::codec::{TransferCodec, MessageCodec};
4use crate::protocol::{TransferRequest, TransferResponse, PROTOCOL_NAME};
5use crate::messaging::{MessageRequest, MessageResponse, MESSAGING_PROTOCOL};
6use libp2p::{
7 dcutr, relay,
8 gossipsub::{self, MessageAuthenticity, ValidationMode},
9 identify, kad, mdns, ping,
10 request_response::{self, ProtocolSupport},
11 swarm::NetworkBehaviour,
12 PeerId,
13};
14use std::time::Duration;
15
16#[derive(NetworkBehaviour)]
18#[behaviour(to_swarm = "FireCloudEvent")]
19pub struct FireCloudBehaviour {
20 pub mdns: mdns::tokio::Behaviour,
22 pub kademlia: kad::Behaviour<kad::store::MemoryStore>,
24 pub gossipsub: gossipsub::Behaviour,
26 pub identify: identify::Behaviour,
28 pub ping: ping::Behaviour,
30 pub transfer: request_response::Behaviour<TransferCodec>,
32 pub messaging: request_response::Behaviour<MessageCodec>,
34 pub dcutr: dcutr::Behaviour,
36 pub relay_client: relay::client::Behaviour,
38}
39
40#[derive(Debug)]
42pub enum FireCloudEvent {
43 Mdns(mdns::Event),
44 Kademlia(kad::Event),
45 Gossipsub(gossipsub::Event),
46 Identify(identify::Event),
47 Ping(ping::Event),
48 Transfer(request_response::Event<TransferRequest, TransferResponse>),
49 Messaging(request_response::Event<MessageRequest, MessageResponse>),
50 Dcutr(dcutr::Event),
51 RelayClient(relay::client::Event),
52}
53
54impl From<mdns::Event> for FireCloudEvent {
55 fn from(event: mdns::Event) -> Self {
56 FireCloudEvent::Mdns(event)
57 }
58}
59
60impl From<kad::Event> for FireCloudEvent {
61 fn from(event: kad::Event) -> Self {
62 FireCloudEvent::Kademlia(event)
63 }
64}
65
66impl From<gossipsub::Event> for FireCloudEvent {
67 fn from(event: gossipsub::Event) -> Self {
68 FireCloudEvent::Gossipsub(event)
69 }
70}
71
72impl From<identify::Event> for FireCloudEvent {
73 fn from(event: identify::Event) -> Self {
74 FireCloudEvent::Identify(event)
75 }
76}
77
78impl From<ping::Event> for FireCloudEvent {
79 fn from(event: ping::Event) -> Self {
80 FireCloudEvent::Ping(event)
81 }
82}
83
84impl From<request_response::Event<TransferRequest, TransferResponse>> for FireCloudEvent {
85 fn from(event: request_response::Event<TransferRequest, TransferResponse>) -> Self {
86 FireCloudEvent::Transfer(event)
87 }
88}
89
90impl From<request_response::Event<MessageRequest, MessageResponse>> for FireCloudEvent {
91 fn from(event: request_response::Event<MessageRequest, MessageResponse>) -> Self {
92 FireCloudEvent::Messaging(event)
93 }
94}
95
96impl From<dcutr::Event> for FireCloudEvent {
97 fn from(event: dcutr::Event) -> Self {
98 FireCloudEvent::Dcutr(event)
99 }
100}
101
102impl From<relay::client::Event> for FireCloudEvent {
103 fn from(event: relay::client::Event) -> Self {
104 FireCloudEvent::RelayClient(event)
105 }
106}
107
108impl FireCloudBehaviour {
109 pub fn new_with_relay(
111 local_peer_id: PeerId,
112 local_key: &libp2p::identity::Keypair,
113 relay_client: relay::client::Behaviour,
114 ) -> anyhow::Result<Self> {
115 let mdns = mdns::tokio::Behaviour::new(
117 mdns::Config::default(),
118 local_peer_id,
119 )?;
120
121 let mut kad_config = kad::Config::new(kad::PROTOCOL_NAME);
123 kad_config.set_query_timeout(Duration::from_secs(60));
124
125 let kad_store = kad::store::MemoryStore::new(local_peer_id);
126 let kademlia = kad::Behaviour::with_config(local_peer_id, kad_store, kad_config);
127
128 let gossipsub_config = gossipsub::ConfigBuilder::default()
130 .heartbeat_interval(Duration::from_secs(1))
131 .validation_mode(ValidationMode::Strict)
132 .build()
133 .map_err(|e| anyhow::anyhow!("GossipSub config error: {}", e))?;
134
135 let gossipsub = gossipsub::Behaviour::new(
136 MessageAuthenticity::Signed(local_key.clone()),
137 gossipsub_config,
138 )
139 .map_err(|e| anyhow::anyhow!("GossipSub error: {}", e))?;
140
141 let identify = identify::Behaviour::new(identify::Config::new(
143 "/firecloud/1.0.0".to_string(),
144 local_key.public(),
145 ));
146
147 let ping = ping::Behaviour::new(ping::Config::new());
149
150 let protocols = vec![(PROTOCOL_NAME, ProtocolSupport::Full)];
152 let transfer_config = request_response::Config::default()
153 .with_request_timeout(Duration::from_secs(60));
154 let transfer = request_response::Behaviour::with_codec(
155 TransferCodec,
156 protocols,
157 transfer_config,
158 );
159
160 let messaging_protocols = vec![(MESSAGING_PROTOCOL, ProtocolSupport::Full)];
162 let messaging_config = request_response::Config::default()
163 .with_request_timeout(Duration::from_secs(30)); let messaging = request_response::Behaviour::with_codec(
165 MessageCodec,
166 messaging_protocols,
167 messaging_config,
168 );
169
170 let dcutr = dcutr::Behaviour::new(local_peer_id);
172
173 Ok(Self {
174 mdns,
175 kademlia,
176 gossipsub,
177 identify,
178 ping,
179 transfer,
180 messaging,
181 dcutr,
182 relay_client,
183 })
184 }
185
186 pub fn new(local_peer_id: PeerId, local_key: &libp2p::identity::Keypair) -> anyhow::Result<Self> {
188 let mdns = mdns::tokio::Behaviour::new(
190 mdns::Config::default(),
191 local_peer_id,
192 )?;
193
194 let mut kad_config = kad::Config::new(kad::PROTOCOL_NAME);
196 kad_config.set_query_timeout(Duration::from_secs(60));
197
198 let kad_store = kad::store::MemoryStore::new(local_peer_id);
199 let kademlia = kad::Behaviour::with_config(local_peer_id, kad_store, kad_config);
200
201 let gossipsub_config = gossipsub::ConfigBuilder::default()
203 .heartbeat_interval(Duration::from_secs(1))
204 .validation_mode(ValidationMode::Strict)
205 .build()
206 .map_err(|e| anyhow::anyhow!("GossipSub config error: {}", e))?;
207
208 let gossipsub = gossipsub::Behaviour::new(
209 MessageAuthenticity::Signed(local_key.clone()),
210 gossipsub_config,
211 )
212 .map_err(|e| anyhow::anyhow!("GossipSub error: {}", e))?;
213
214 let identify = identify::Behaviour::new(identify::Config::new(
216 "/firecloud/1.0.0".to_string(),
217 local_key.public(),
218 ));
219
220 let ping = ping::Behaviour::new(ping::Config::new());
222
223 let protocols = vec![(PROTOCOL_NAME, ProtocolSupport::Full)];
225 let transfer_config = request_response::Config::default()
226 .with_request_timeout(Duration::from_secs(60));
227 let transfer = request_response::Behaviour::with_codec(
228 TransferCodec,
229 protocols,
230 transfer_config,
231 );
232
233 let messaging_protocols = vec![(MESSAGING_PROTOCOL, ProtocolSupport::Full)];
235 let messaging_config = request_response::Config::default()
236 .with_request_timeout(Duration::from_secs(30));
237 let messaging = request_response::Behaviour::with_codec(
238 MessageCodec,
239 messaging_protocols,
240 messaging_config,
241 );
242
243 let dcutr = dcutr::Behaviour::new(local_peer_id);
245
246 let (_relay_transport, relay_client) = relay::client::new(local_peer_id);
248
249 Ok(Self {
250 mdns,
251 kademlia,
252 gossipsub,
253 identify,
254 ping,
255 transfer,
256 messaging,
257 dcutr,
258 relay_client,
259 })
260 }
261}