1
1
import type { PeerId } from "@libp2p/interface/peer-id" ;
2
2
import type { PeerInfo } from "@libp2p/interface/peer-info" ;
3
3
import type { Peer } from "@libp2p/interface/peer-store" ;
4
+ import type { PeerStore } from "@libp2p/interface/peer-store" ;
4
5
import { CustomEvent , EventEmitter } from "@libp2p/interfaces/events" ;
6
+ import { decodeRelayShard } from "@waku/enr" ;
5
7
import {
6
8
ConnectionManagerOptions ,
7
9
EPeersByDiscoveryEvents ,
8
10
IConnectionManager ,
9
11
IPeersByDiscoveryEvents ,
10
12
IRelay ,
11
13
KeepAliveOptions ,
12
- PeersByDiscoveryResult
14
+ PeersByDiscoveryResult ,
15
+ PubSubTopic ,
16
+ ShardInfo
13
17
} from "@waku/interfaces" ;
14
18
import { Libp2p , Tags } from "@waku/interfaces" ;
19
+ import { shardInfoToPubSubTopics } from "@waku/utils" ;
15
20
import debug from "debug" ;
16
21
17
22
import { KeepAliveManager } from "./keep_alive_manager.js" ;
@@ -40,6 +45,7 @@ export class ConnectionManager
40
45
peerId : string ,
41
46
libp2p : Libp2p ,
42
47
keepAliveOptions : KeepAliveOptions ,
48
+ pubSubTopics : PubSubTopic [ ] ,
43
49
relay ?: IRelay ,
44
50
options ?: ConnectionManagerOptions
45
51
) : ConnectionManager {
@@ -48,6 +54,7 @@ export class ConnectionManager
48
54
instance = new ConnectionManager (
49
55
libp2p ,
50
56
keepAliveOptions ,
57
+ pubSubTopics ,
51
58
relay ,
52
59
options
53
60
) ;
@@ -104,11 +111,13 @@ export class ConnectionManager
104
111
private constructor (
105
112
libp2p : Libp2p ,
106
113
keepAliveOptions : KeepAliveOptions ,
114
+ private configuredPubSubTopics : PubSubTopic [ ] ,
107
115
relay ?: IRelay ,
108
116
options ?: Partial < ConnectionManagerOptions >
109
117
) {
110
118
super ( ) ;
111
119
this . libp2p = libp2p ;
120
+ this . configuredPubSubTopics = configuredPubSubTopics ;
112
121
this . options = {
113
122
maxDialAttemptsForPeer : DEFAULT_MAX_DIAL_ATTEMPTS_FOR_PEER ,
114
123
maxBootstrapPeersAllowed : DEFAULT_MAX_BOOTSTRAP_PEERS_ALLOWED ,
@@ -314,6 +323,20 @@ export class ConnectionManager
314
323
void ( async ( ) => {
315
324
const { id : peerId } = evt . detail ;
316
325
326
+ if ( ! ( await this . isPeerTopicConfigured ( peerId ) ) ) {
327
+ const shardInfo = await this . getPeerShardInfo (
328
+ peerId ,
329
+ this . libp2p . peerStore
330
+ ) ;
331
+ log (
332
+ `Discovered peer ${ peerId . toString ( ) } with ShardInfo ${ shardInfo } is not part of any of the configured pubsub topics (${
333
+ this . configuredPubSubTopics
334
+ } ).
335
+ Not dialing.`
336
+ ) ;
337
+ return ;
338
+ }
339
+
317
340
const isBootstrap = ( await this . getTagNamesForPeer ( peerId ) ) . includes (
318
341
Tags . BOOTSTRAP
319
342
) ;
@@ -430,4 +453,31 @@ export class ConnectionManager
430
453
return [ ] ;
431
454
}
432
455
}
456
+
457
+ private async isPeerTopicConfigured ( peerId : PeerId ) : Promise < boolean > {
458
+ const shardInfo = await this . getPeerShardInfo (
459
+ peerId ,
460
+ this . libp2p . peerStore
461
+ ) ;
462
+
463
+ // If there's no shard information, simply return true
464
+ if ( ! shardInfo ) return true ;
465
+
466
+ const pubSubTopics = shardInfoToPubSubTopics ( shardInfo ) ;
467
+
468
+ const isTopicConfigured = pubSubTopics . some ( ( topic ) =>
469
+ this . configuredPubSubTopics . includes ( topic )
470
+ ) ;
471
+ return isTopicConfigured ;
472
+ }
473
+
474
+ private async getPeerShardInfo (
475
+ peerId : PeerId ,
476
+ peerStore : PeerStore
477
+ ) : Promise < ShardInfo | undefined > {
478
+ const peer = await peerStore . get ( peerId ) ;
479
+ const shardInfoBytes = peer . metadata . get ( "shardInfo" ) ;
480
+ if ( ! shardInfoBytes ) return undefined ;
481
+ return decodeRelayShard ( shardInfoBytes ) ;
482
+ }
433
483
}
0 commit comments