ferripfs_network/
behavior.rs1use libp2p::{autonat, dcutr, identify, kad, mdns, ping, relay, swarm::NetworkBehaviour, PeerId};
11
12#[derive(NetworkBehaviour)]
23pub struct FerripfsBehavior {
24 pub identify: identify::Behaviour,
26 pub ping: ping::Behaviour,
28 pub kademlia: kad::Behaviour<kad::store::MemoryStore>,
30 pub mdns: mdns::tokio::Behaviour,
32 pub autonat: autonat::Behaviour,
34 pub relay_client: relay::client::Behaviour,
36 pub dcutr: dcutr::Behaviour,
38}
39
40impl FerripfsBehavior {
41 pub fn new(
43 local_peer_id: PeerId,
44 local_public_key: libp2p::identity::PublicKey,
45 relay_client: relay::client::Behaviour,
46 ) -> Result<Self, Box<dyn std::error::Error>> {
47 let identify_config = identify::Config::new(
49 crate::PROTOCOL_VERSION.to_string(),
50 local_public_key.clone(),
51 )
52 .with_agent_version(crate::AGENT_VERSION.to_string());
53 let identify = identify::Behaviour::new(identify_config);
54
55 let ping = ping::Behaviour::new(ping::Config::new());
57
58 let kad_store = kad::store::MemoryStore::new(local_peer_id);
60 let mut kad_config = kad::Config::new(libp2p::StreamProtocol::new("/ipfs/kad/1.0.0"));
61 kad_config.set_query_timeout(std::time::Duration::from_secs(60));
62 let kademlia = kad::Behaviour::with_config(local_peer_id, kad_store, kad_config);
63
64 let mdns = mdns::tokio::Behaviour::new(mdns::Config::default(), local_peer_id)?;
66
67 let autonat = autonat::Behaviour::new(local_peer_id, autonat::Config::default());
69
70 let dcutr = dcutr::Behaviour::new(local_peer_id);
72
73 Ok(Self {
74 identify,
75 ping,
76 kademlia,
77 mdns,
78 autonat,
79 relay_client,
80 dcutr,
81 })
82 }
83
84 pub fn add_address(&mut self, peer_id: &PeerId, addr: libp2p::Multiaddr) {
86 self.kademlia.add_address(peer_id, addr);
87 }
88
89 pub fn bootstrap(&mut self) -> Result<kad::QueryId, kad::NoKnownPeers> {
91 self.kademlia.bootstrap()
92 }
93
94 pub fn get_providers(&mut self, key: kad::RecordKey) -> kad::QueryId {
96 self.kademlia.get_providers(key)
97 }
98
99 pub fn start_providing(
101 &mut self,
102 key: kad::RecordKey,
103 ) -> Result<kad::QueryId, kad::store::Error> {
104 self.kademlia.start_providing(key)
105 }
106
107 pub fn get_closest_peers(&mut self, peer_id: PeerId) -> kad::QueryId {
109 self.kademlia.get_closest_peers(peer_id)
110 }
111
112 pub fn put_value(&mut self, key: kad::RecordKey, value: Vec<u8>) -> kad::QueryId {
114 self.kademlia
115 .put_record(kad::Record::new(key, value), kad::Quorum::One)
116 .expect("put_record should not fail with Quorum::One")
117 }
118
119 pub fn get_value(&mut self, key: kad::RecordKey) -> kad::QueryId {
121 self.kademlia.get_record(key)
122 }
123
124 pub fn set_mode(&mut self, mode: Option<kad::Mode>) {
126 self.kademlia.set_mode(mode);
127 }
128
129 pub fn get_routing_table_info(&mut self) -> (usize, usize) {
131 let mut total_peers = 0;
132 let mut total_buckets = 0;
133 for bucket in self.kademlia.kbuckets() {
134 total_buckets += 1;
135 total_peers += bucket.num_entries();
136 }
137 (total_buckets, total_peers)
138 }
139}