1
- use crate :: p2p:: { AvailableNodes , P2P_PROTOCOL_STRING } ;
1
+ use crate :: p2p:: AvailableNodes ;
2
2
use crate :: DRIA_COMPUTE_NODE_VERSION ;
3
3
use libp2p:: futures:: StreamExt ;
4
4
use libp2p:: gossipsub:: {
@@ -14,7 +14,11 @@ use semver::Version;
14
14
use tokio:: time:: Duration ;
15
15
use tokio:: time:: Instant ;
16
16
17
- use super :: { DriaBehaviour , DriaBehaviourEvent , P2P_KADEMLIA_PROTOCOL } ;
17
+ use super :: { DriaBehaviour , DriaBehaviourEvent } ;
18
+
19
+ /// Used as default for unparsable versions.
20
+ /// Will not match with any valid version.
21
+ const ZERO_VERSION : Version = Version :: new ( 0 , 0 , 0 ) ;
18
22
19
23
/// Underlying libp2p client.
20
24
pub struct P2PClient {
@@ -247,67 +251,55 @@ impl P2PClient {
247
251
///
248
252
/// - For Kademlia, we check the kademlia protocol and then add the address to the Kademlia routing table.
249
253
fn handle_identify_event ( & mut self , peer_id : PeerId , info : identify:: Info ) {
254
+ // we only care about the observed address, although there may be other addresses at `info.listen_addrs`
250
255
let addr = info. observed_addr ;
251
256
252
257
// check protocol string
253
- let ( left , right ) = info. protocol_version . split_at ( 5 ) ; // equals " dria/".len()
254
- if left != "dria/" {
258
+ let protocol_ok = self . check_version_with_prefix ( & info. protocol_version , "/ dria/") ;
259
+ if !protocol_ok {
255
260
log:: warn!(
256
- "Identify: Peer {} is from different protocol: (have {}, want {})" ,
261
+ "Identify: Peer {} has different Identify protocol: (have {}, want {})" ,
257
262
peer_id,
258
263
info. protocol_version,
259
- P2P_PROTOCOL_STRING
264
+ self . version
260
265
) ;
261
266
return ;
262
267
}
263
268
264
- // check version
265
- match semver:: Version :: parse ( right) {
266
- Ok ( peer_version) => {
267
- if peer_version. minor != self . version . minor {
268
- log:: warn!(
269
- "Identify: Peer {} has different version: (have {}, want {})" ,
270
- peer_id,
271
- peer_version,
272
- self . version
273
- ) ;
274
- return ;
275
- }
276
- }
277
- Err ( err) => {
278
- log:: error!(
279
- "Identify: Peer {} version could not be parsed: {}" ,
280
- peer_id,
281
- err,
282
- ) ;
283
- return ;
284
- }
285
- }
269
+ // check kademlia protocol
270
+ if let Some ( kad_protocol) = info
271
+ . protocols
272
+ . iter ( )
273
+ . find ( |p| p. to_string ( ) . starts_with ( "/dria/kad/" ) )
274
+ {
275
+ let protocol_ok =
276
+ self . check_version_with_prefix ( & kad_protocol. to_string ( ) , "/dria/kad/" ) ;
286
277
287
- // we only care about the observed address, although there may be other addresses at `info.listen_addrs`
288
- if info. protocols . iter ( ) . any ( |p| * p == P2P_KADEMLIA_PROTOCOL ) {
289
278
// if it matches our protocol, add it to the Kademlia routing table
290
- log:: info!(
291
- "Identify: {} peer {} identified at {}" ,
292
- info. protocol_version,
293
- peer_id,
294
- addr
295
- ) ;
279
+ if protocol_ok {
280
+ log:: info!(
281
+ "Identify: {} peer {} identified at {}" ,
282
+ kad_protocol,
283
+ peer_id,
284
+ addr
285
+ ) ;
296
286
297
- self . swarm
298
- . behaviour_mut ( )
299
- . kademlia
300
- . add_address ( & peer_id, addr) ;
301
- } else {
302
- log:: trace!(
303
- "Identify: Incoming from different protocol, address {}. PeerID is {}" ,
304
- addr,
305
- peer_id
306
- ) ;
287
+ self . swarm
288
+ . behaviour_mut ( )
289
+ . kademlia
290
+ . add_address ( & peer_id, addr) ;
291
+ } else {
292
+ log:: warn!(
293
+ "Identify: Peer {} has different Kademlia version: (have {}, want {})" ,
294
+ peer_id,
295
+ kad_protocol,
296
+ self . version
297
+ ) ;
298
+ }
307
299
}
308
300
}
309
301
310
- /// Handles the results of a Kademlia closest peers search, either adding peers to Gossipsub or logging timeout errors .
302
+ /// Handles the results of a Kademlia closest peers search, simply logs it .
311
303
fn handle_closest_peers_result (
312
304
& mut self ,
313
305
result : Result < GetClosestPeersOk , GetClosestPeersError > ,
@@ -373,4 +365,22 @@ impl P2PClient {
373
365
}
374
366
}
375
367
}
368
+
369
+ /// Generic function to split a string such as `prefix || version` and check that the major & minor versions are the same.
370
+ ///
371
+ /// Some examples:
372
+ /// - `self.check_version_with_prefix("dria/")` for identity
373
+ /// - `self.check_version_with_prefix("dria/kad/")` for Kademlia
374
+ ///
375
+ /// Returns whether the version is ok.
376
+ fn check_version_with_prefix ( & self , p : & str , prefix : & str ) -> bool {
377
+ let parsed_version = p
378
+ . strip_prefix ( prefix)
379
+ . and_then ( |v| Version :: parse ( v) . ok ( ) )
380
+ . unwrap_or ( ZERO_VERSION ) ;
381
+
382
+ p. starts_with ( prefix)
383
+ && parsed_version. major == self . version . major
384
+ && parsed_version. minor == self . version . minor
385
+ }
376
386
}
0 commit comments