Since we created this document we gained a bit more understanding of how topics and filters work in status-go and waku: please check Filters, Topics, Channels, and Chat IDs in status-go and waku.

This is the definition of the ChatFilter type:

type ChatFilter struct {
	chatID       string
	filterID     string
	identity     string
	pubsubTopic  string
	contentTopic ContentTopic
	discovery    bool
	negotiated   bool
	listen       bool
	ephemeral    bool
	priority     uint64
}

For each community, we can have a number of filters. This is how we get them.

func (m *ArchiveManager) GetCommunityChatsFilters(communityID types.HexBytes) (messagingtypes.ChatFilters, error) {
	chatIDs, err := m.persistence.GetCommunityChatIDs(communityID)
	if err != nil {
		return nil, err
	}
 
	filters := messagingtypes.ChatFilters{}
	for _, cid := range chatIDs {
		filter := m.messaging.ChatFilterByChatID(cid)
		if filter != nil {
			filters = append(filters, filter)
		}
	}
	return filters, nil
}

Perhaps simplifying too much, a filter is basically a reference to a waku pubsub channel where the messages can be posted/received: all messages for all chats in that community. This seems to be related to Universal Topic Optimization in Waku (AI).

What is associated with a filter is a contentTopic and the filters are used to make sure we later get all relevant community messages. But here we get a lot of strange inconsistencies. First, if there suppose to be a single universal topic for the community, why do we still have multiple filters:

filters, err := m.archiveManager.GetCommunityChatsFilters(c.ID())
if err != nil {
	m.logger.Error("failed to get community chats filters for community", zap.Error(err))
	continue
}
 
if len(filters) == 0 {
	m.logger.Debug("no filters or chats for this community starting interval", zap.String("id", c.IDString()))
	go m.archiveManager.StartHistoryArchiveTasksInterval(c, messageArchiveInterval)
	continue
}

The why the universal filter is only included later, and never mapped to the corresponding topics?

topics := []messagingtypes.ContentTopic{}
 
for _, filter := range filters {
	topics = append(topics, filter.ContentTopic())
}
 
filter := m.messaging.ChatFilterByChatID(c.UniversalChatID())
if filter != nil {
	filters = append(filters, filter)
}

It is kind of crucial, because the topics are effectively used to get the messages in GetWakuMessagesByFilterTopic (check the body of this function here).