@@ -157,6 +157,11 @@ export interface GossipsubOpts extends GossipsubOptsSpec, PubSubInit {
157
157
* If full it will throw and reject sending any more data.
158
158
*/
159
159
maxOutboundBufferSize ?: number
160
+
161
+ /**
162
+ * If provided, only allow topics in this list
163
+ */
164
+ allowedTopics ?: string [ ] | Set < string >
160
165
}
161
166
162
167
export interface GossipsubMessage {
@@ -339,6 +344,7 @@ export class GossipSub extends EventEmitter<GossipsubEvents> implements Initiali
339
344
private status : GossipStatus = { code : GossipStatusCode . stopped }
340
345
private maxInboundStreams ?: number
341
346
private maxOutboundStreams ?: number
347
+ private allowedTopics : Set < TopicStr > | null
342
348
343
349
private heartbeatTimer : {
344
350
_intervalId : ReturnType < typeof setInterval > | undefined
@@ -462,6 +468,8 @@ export class GossipSub extends EventEmitter<GossipsubEvents> implements Initiali
462
468
463
469
this . maxInboundStreams = options . maxInboundStreams
464
470
this . maxOutboundStreams = options . maxOutboundStreams
471
+
472
+ this . allowedTopics = opts . allowedTopics ? new Set ( opts . allowedTopics ) : null
465
473
}
466
474
467
475
getPeers ( ) : PeerId [ ] {
@@ -918,23 +926,29 @@ export class GossipSub extends EventEmitter<GossipsubEvents> implements Initiali
918
926
// Handle received subscriptions
919
927
if ( rpc . subscriptions && rpc . subscriptions . length > 0 ) {
920
928
// update peer subscriptions
929
+
930
+ const subscriptions : { topic : TopicStr ; subscribe : boolean } [ ] = [ ]
931
+
921
932
rpc . subscriptions . forEach ( ( subOpt ) => {
922
- this . handleReceivedSubscription ( from , subOpt )
933
+ const topic = subOpt . topic
934
+ const subscribe = subOpt . subscribe === true
935
+
936
+ if ( topic != null ) {
937
+ if ( this . allowedTopics && ! this . allowedTopics . has ( topic ) ) {
938
+ // Not allowed: subscription data-structures are not bounded by topic count
939
+ // TODO: Should apply behaviour penalties?
940
+ return
941
+ }
942
+
943
+ this . handleReceivedSubscription ( from , topic , subscribe )
944
+
945
+ subscriptions . push ( { topic, subscribe } )
946
+ }
923
947
} )
924
948
925
949
this . dispatchEvent (
926
950
new CustomEvent < SubscriptionChangeData > ( 'subscription-change' , {
927
- detail : {
928
- peerId : from ,
929
- subscriptions : rpc . subscriptions
930
- . filter ( ( sub ) => sub . topic !== null )
931
- . map ( ( sub ) => {
932
- return {
933
- topic : sub . topic ?? '' ,
934
- subscribe : Boolean ( sub . subscribe )
935
- }
936
- } )
937
- }
951
+ detail : { peerId : from , subscriptions }
938
952
} )
939
953
)
940
954
}
@@ -943,6 +957,12 @@ export class GossipSub extends EventEmitter<GossipsubEvents> implements Initiali
943
957
// TODO: (up to limit)
944
958
if ( rpc . messages ) {
945
959
for ( const message of rpc . messages ) {
960
+ if ( this . allowedTopics && ! this . allowedTopics . has ( message . topic ) ) {
961
+ // Not allowed: message cache data-structures are not bounded by topic count
962
+ // TODO: Should apply behaviour penalties?
963
+ continue
964
+ }
965
+
946
966
const handleReceivedMessagePromise = this . handleReceivedMessage ( from , message )
947
967
// Should never throw, but handle just in case
948
968
. catch ( ( err ) => this . log ( err ) )
@@ -962,20 +982,16 @@ export class GossipSub extends EventEmitter<GossipsubEvents> implements Initiali
962
982
/**
963
983
* Handles a subscription change from a peer
964
984
*/
965
- private handleReceivedSubscription ( from : PeerId , subOpt : RPC . ISubOpts ) : void {
966
- if ( subOpt . topic == null ) {
967
- return
968
- }
969
-
970
- this . log ( 'subscription update from %p topic %s' , from , subOpt . topic )
985
+ private handleReceivedSubscription ( from : PeerId , topic : TopicStr , subscribe : boolean ) : void {
986
+ this . log ( 'subscription update from %p topic %s' , from , topic )
971
987
972
- let topicSet = this . topics . get ( subOpt . topic )
988
+ let topicSet = this . topics . get ( topic )
973
989
if ( topicSet == null ) {
974
990
topicSet = new Set ( )
975
- this . topics . set ( subOpt . topic , topicSet )
991
+ this . topics . set ( topic , topicSet )
976
992
}
977
993
978
- if ( subOpt . subscribe ) {
994
+ if ( subscribe ) {
979
995
// subscribe peer to new topic
980
996
topicSet . add ( from . toString ( ) )
981
997
} else {
0 commit comments