calimero_network/handlers/commands/
dial.rs1use std::collections::hash_map::Entry;
2
3use actix::{Context, Handler, Message, Response};
4use calimero_network_primitives::messages::Dial;
5use eyre::eyre;
6use multiaddr::Protocol;
7use tokio::sync::oneshot;
8
9use crate::NetworkManager;
10
11impl Handler<Dial> for NetworkManager {
12 type Result = Response<<Dial as Message>::Result>;
13
14 fn handle(&mut self, Dial(mut peer_addr): Dial, _ctx: &mut Context<Self>) -> Self::Result {
15 let Some(Protocol::P2p(peer_id)) = peer_addr.pop() else {
16 return Response::reply(Err(eyre!("No peer ID in address: {}", peer_addr)));
17 };
18
19 let (sender, receiver) = oneshot::channel();
20
21 match self.pending_dial.entry(peer_id) {
22 Entry::Occupied(_) => {
23 return Response::reply(Ok(()));
25 }
26 Entry::Vacant(entry) => {
27 let _ignored = self
28 .swarm
29 .behaviour_mut()
30 .kad
31 .add_address(&peer_id, peer_addr.clone());
32
33 match self.swarm.dial(peer_addr) {
34 Ok(()) => {
35 let _ignored = entry.insert(sender);
36 }
37 Err(e) => {
38 return Response::reply(Err(eyre!(e)));
39 }
40 }
41 }
42 }
43
44 Response::fut(async { receiver.await.expect("Sender not to be dropped.") })
45 }
46}