55 "context"
66 "crypto/ecdsa"
77 "encoding/hex"
8+ "fmt"
9+ "strings"
810 "sync"
911
1012 "github.com/pkg/errors"
@@ -162,6 +164,8 @@ func (f *FiltersManager) InitCommunityFilters(communityFiltersToInitialize []Com
162164
163165 topics := make ([]string , 0 )
164166 topics = append (topics , wakuv2 .DefaultNonProtectedPubsubTopic ())
167+ topics = append (topics , wakuv2 .GlobalCommunityControlPubsubTopic ())
168+ topics = append (topics , wakuv2 .GlobalCommunityContentPubsubTopic ())
165169 topics = append (topics , communityFilter .Shard .PubsubTopic ())
166170
167171 for _ , pubsubTopic := range topics {
@@ -220,7 +224,16 @@ func (f *FiltersManager) Filters() (result []*Filter) {
220224func (f * FiltersManager ) Filter (chatID string ) * Filter {
221225 f .mutex .Lock ()
222226 defer f .mutex .Unlock ()
223- return f .filters [chatID ]
227+
228+ // find the first filter that matches this chat ID
229+ // TODO this is temporary so not changing the return type, otherwise we should return a slice
230+ for key , filter := range f .filters {
231+ if strings .HasPrefix (key , chatID ) {
232+ return filter
233+ }
234+ }
235+
236+ return nil
224237}
225238
226239// FilterByFilterID returns a Filter with a given Whisper filter ID.
@@ -276,19 +289,23 @@ func (f *FiltersManager) FilterByChatID(chatID string) *Filter {
276289 return f .filters [chatID ]
277290}
278291
279- // Remove remove all the filters associated with a chat/identity
280- func (f * FiltersManager ) Remove (ctx context.Context , filters ... * Filter ) error {
292+ // Remove removes all the filtersToRemove
293+ func (f * FiltersManager ) Remove (ctx context.Context , filtersToRemove ... * Filter ) error {
281294 f .mutex .Lock ()
282295 defer f .mutex .Unlock ()
283296
284- for _ , filter := range filters {
297+ for _ , filter := range filtersToRemove {
285298 if err := f .service .Unsubscribe (ctx , filter .FilterID ); err != nil {
286299 return err
287300 }
288301 if filter .SymKeyID != "" {
289302 f .service .DeleteSymKey (filter .SymKeyID )
290303 }
291- delete (f .filters , filter .ChatID )
304+ for k , v := range f .filters {
305+ if filter .FilterID == v .FilterID {
306+ delete (f .filters , k )
307+ }
308+ }
292309 }
293310
294311 return nil
@@ -301,10 +318,10 @@ func (f *FiltersManager) RemoveNoListenFilters() error {
301318 var filterIDs []string
302319 var filters []* Filter
303320
304- for _ , f := range filters {
305- if ! f .Listen {
306- filterIDs = append (filterIDs , f .FilterID )
307- filters = append (filters , f )
321+ for _ , v := range f . filters {
322+ if ! v .Listen {
323+ filterIDs = append (filterIDs , v .FilterID )
324+ filters = append (filters , v )
308325 }
309326 }
310327 if err := f .service .UnsubscribeMany (filterIDs ); err != nil {
@@ -315,30 +332,40 @@ func (f *FiltersManager) RemoveNoListenFilters() error {
315332 if filter .SymKeyID != "" {
316333 f .service .DeleteSymKey (filter .SymKeyID )
317334 }
318- delete (f .filters , filter .ChatID )
335+ for k , v := range f .filters {
336+ if filter .FilterID == v .FilterID {
337+ delete (f .filters , k )
338+ }
339+ }
319340 }
320341
321342 return nil
322343}
323344
324- // Remove remove all the filters associated with a chat/identity
345+ // RemoveFilterByChatID removes the filters associated with a chat/identity
325346func (f * FiltersManager ) RemoveFilterByChatID (chatID string ) (* Filter , error ) {
326347 // TODO: remove subscriptions from waku2 if required. Might need to be implemented in transport
327348
349+ toRemove := make ([]* Filter , 0 )
328350 f .mutex .Lock ()
329- filter , ok := f .filters [chatID ]
351+ for _ , filter := range f .filters {
352+ if filter .ChatID == chatID {
353+ toRemove = append (toRemove , filter )
354+ }
355+ }
330356 f .mutex .Unlock ()
331357
332- if ! ok {
358+ if len ( toRemove ) == 0 {
333359 return nil , nil
334360 }
335361
336- err := f .Remove (context .Background (), filter )
362+ err := f .Remove (context .Background (), toRemove ... )
337363 if err != nil {
338364 return nil , err
339365 }
340366
341- return filter , nil
367+ // TODO temporary so not changing the return type, otherwise we should return a slice
368+ return toRemove [0 ], nil
342369}
343370
344371// LoadPartitioned creates a filter for a partitioned topic.
@@ -514,12 +541,14 @@ func (f *FiltersManager) PersonalTopicFilter() *Filter {
514541 return f .filters [personalDiscoveryTopic ]
515542}
516543
517- // LoadPublic adds a filter for a public chat.
544+ // LoadPublic adds a filter for a public chat with specific pubsubTopic
518545func (f * FiltersManager ) LoadPublic (chatID string , pubsubTopic string ) (* Filter , error ) {
519546 f .mutex .Lock ()
520547 defer f .mutex .Unlock ()
521548
522- if chat , ok := f .filters [chatID ]; ok {
549+ filterKey := toFilterKey (chatID , pubsubTopic )
550+
551+ if chat , ok := f .filters [filterKey ]; ok {
523552 if chat .PubsubTopic != pubsubTopic {
524553 f .logger .Debug ("updating pubsub topic for filter" ,
525554 zap .String ("chatID" , chatID ),
@@ -528,9 +557,8 @@ func (f *FiltersManager) LoadPublic(chatID string, pubsubTopic string) (*Filter,
528557 zap .String ("newTopic" , pubsubTopic ),
529558 )
530559 chat .PubsubTopic = pubsubTopic
531- f .filters [chatID ] = chat
560+ f .filters [filterKey ] = chat
532561 }
533-
534562 return chat , nil
535563 }
536564
@@ -550,7 +578,7 @@ func (f *FiltersManager) LoadPublic(chatID string, pubsubTopic string) (*Filter,
550578 OneToOne : false ,
551579 }
552580
553- f .filters [chatID ] = chat
581+ f .filters [filterKey ] = chat
554582
555583 f .logger .Debug ("registering filter for" ,
556584 zap .String ("chatID" , chatID ),
@@ -681,3 +709,13 @@ func (f *FiltersManager) GetNegotiated(identity *ecdsa.PublicKey) *Filter {
681709
682710 return f .filters [NegotiatedTopic (identity )]
683711}
712+
713+ // toFilterKey creates a unique key for filters map using chatID and pubsubTopic
714+ //
715+ // to allow one chat to have multiple filters in different pubsubTopics so that we can migrate the communities to 128 and 256 shards
716+ func toFilterKey (chatID string , pubsubTopic string ) string {
717+ if pubsubTopic == "" {
718+ return chatID
719+ }
720+ return fmt .Sprintf ("%s::%s" , chatID , pubsubTopic )
721+ }
0 commit comments