helia_utils/
libp2p_behaviour.rs1use helia_bitswap::BitswapBehaviour;
4use libp2p::identity::Keypair;
5use libp2p::{
6 autonat, dcutr, gossipsub, identify, kad, mdns, noise, ping, relay, swarm::NetworkBehaviour,
7 tcp, yamux, StreamProtocol, Swarm, SwarmBuilder,
8};
9use std::collections::hash_map::DefaultHasher;
10use std::hash::{Hash, Hasher};
11use std::time::Duration;
12
13#[derive(NetworkBehaviour)]
15pub struct HeliaBehaviour {
16 pub ping: ping::Behaviour,
18 pub identify: identify::Behaviour,
20 pub kademlia: kad::Behaviour<kad::store::MemoryStore>,
22 pub gossipsub: gossipsub::Behaviour,
24 pub mdns: mdns::tokio::Behaviour,
26 pub autonat: autonat::Behaviour,
28 pub relay: relay::Behaviour,
30 pub dcutr: dcutr::Behaviour,
32 pub bitswap: BitswapBehaviour,
34}
35
36pub async fn create_swarm() -> Result<Swarm<HeliaBehaviour>, Box<dyn std::error::Error>> {
38 let local_key = Keypair::generate_ed25519();
40 let local_peer_id = local_key.public().to_peer_id();
41
42 let behaviour = create_behaviour(local_key.clone(), local_peer_id).await?;
44
45 let swarm = SwarmBuilder::with_existing_identity(local_key)
47 .with_tokio()
48 .with_tcp(
49 tcp::Config::default(),
50 noise::Config::new,
51 yamux::Config::default,
52 )?
53 .with_behaviour(|_| behaviour)?
54 .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(60)))
55 .build();
56
57 Ok(swarm)
58}
59
60pub async fn create_swarm_with_keypair(
62 keypair: Keypair,
63) -> Result<Swarm<HeliaBehaviour>, Box<dyn std::error::Error>> {
64 let local_peer_id = keypair.public().to_peer_id();
65
66 let behaviour = create_behaviour(keypair.clone(), local_peer_id).await?;
68
69 let swarm = SwarmBuilder::with_existing_identity(keypair)
71 .with_tokio()
72 .with_tcp(
73 tcp::Config::default(),
74 noise::Config::new,
75 yamux::Config::default,
76 )?
77 .with_behaviour(|_| behaviour)?
78 .with_swarm_config(|c| c.with_idle_connection_timeout(Duration::from_secs(60)))
79 .build();
80
81 Ok(swarm)
82}
83
84async fn create_behaviour(
85 local_key: Keypair,
86 local_peer_id: libp2p::PeerId,
87) -> Result<HeliaBehaviour, Box<dyn std::error::Error>> {
88 let ping = ping::Behaviour::new(ping::Config::new());
90
91 let identify = identify::Behaviour::new(identify::Config::new(
93 "/helia/1.0.0".to_string(),
94 local_key.public(),
95 ));
96
97 let mut kademlia_config = kad::Config::default();
99 kademlia_config.set_protocol_names(vec![StreamProtocol::new("/ipfs/kad/1.0.0")]);
100 let store = kad::store::MemoryStore::new(local_peer_id);
101 let kademlia = kad::Behaviour::with_config(local_peer_id, store, kademlia_config);
102
103 let gossipsub_config = gossipsub::ConfigBuilder::default()
105 .heartbeat_interval(Duration::from_secs(10))
106 .validation_mode(gossipsub::ValidationMode::Strict)
107 .build()
108 .expect("Valid config");
109
110 let _message_id_fn = |message: &gossipsub::Message| {
112 let mut s = DefaultHasher::new();
113 message.data.hash(&mut s);
114 gossipsub::MessageId::from(s.finish().to_string())
115 };
116 let gossipsub = gossipsub::Behaviour::new(
117 gossipsub::MessageAuthenticity::Signed(local_key.clone()),
118 gossipsub_config,
119 )
120 .expect("Correct configuration");
121
122 let mdns = mdns::tokio::Behaviour::new(mdns::Config::default(), local_peer_id)?;
124
125 let autonat = autonat::Behaviour::new(local_peer_id, autonat::Config::default());
127
128 let relay = relay::Behaviour::new(local_peer_id, relay::Config::default());
130
131 let dcutr = dcutr::Behaviour::new(local_peer_id);
133
134 let bitswap = BitswapBehaviour::new();
136
137 Ok(HeliaBehaviour {
138 ping,
139 identify,
140 kademlia,
141 gossipsub,
142 mdns,
143 autonat,
144 relay,
145 dcutr,
146 bitswap,
147 })
148}
149
150#[cfg(test)]
151mod tests {
152 use super::*;
153
154 #[tokio::test]
155 async fn test_create_swarm() {
156 let swarm = create_swarm().await;
157 assert!(swarm.is_ok());
158 }
159
160 #[tokio::test]
161 async fn test_create_swarm_with_keypair() {
162 let keypair = Keypair::generate_ed25519();
163 let swarm = create_swarm_with_keypair(keypair).await;
164 assert!(swarm.is_ok());
165 }
166}