The CommunityDescription
’s message size has been an issue in the past (reached a size over 1MB, the current max message size limit for Status shards) and has been identified as not scalable: Scaling Status Communities : Potential Problems · Issue #177 · vacp2p/research · GitHub
In Optimizing the `CommunityDescription` dissemination - HackMD, @rymnc proposed to extract the membership list from the message and push it to IPFS.
When considering RLN and de-MLS, there may be new options to handle a community’s membership list.
Note: forking the conversation from Scaling Status Communities : Potential Problems · Issue #177 · vacp2p/research · GitHub as the design below assumes usage of RLN or de-MLS for Communities, which has not yet been planned.
RLN for Communities
In the case of community dedicated shards, where one and only one community routes their messages on one or several shards.
The current DoS protection model is opt-in message signing. Where the community owner broadcast a pre-shared private key to all community members.
Community members sign their messages on the routing layer with this key.
Waku relay nodes routing for this community’s shard, validate the signature against the matching private key at gossipsub level.
While this strategy can help ensure that no other community or application pushes traffic to the protected community, it has a number of caveats:
- No bandwidth capping or usage guarantees
- No model to handle kick/ban of members
- Difficult handling of breach (eg key is leaked). Breach risk is high, as all members have access to the same key.
Using RLN would remediate those drawbacks. The community owner could deploy an RLN smart contract specfiically for their community. Community member would need a membership inserted in the contract. Membership insertion could be done:
- via stealth commitment where the community owner inserts the membership on the contract
- via token gating, where the community owner drop a token to accept a member in the community, said token can then be used as an authorization to insert a membership in the smart contract
In this case, the RLN Merkle tree now acts as a membership list. As only members of the community are in the tree and can publish to the community’s shard.
Which means the membership list could be potentially removed from CommunityDescription
. Where instead, members would broadcast their own details to the network in lieu of the community owner sending the full list.
The list could then be constructed from member’s messages. This would also introduce some efficiency where offline members do not pollute the membership list. After all, if they are inactive and haven’t open the app for a while, why a user would want to see them in the list (product assumption)?
The missing feature would be to express the members’ roles
. In this case, the community owner could still include some community members in the CommunityDescription
message, only if their roles is not none
.
deMLS for Communities
Currently, community traffic is encrypted using symmetric encryption. The community owner provides a symmetric key to new members. Members of the community use this key to encrypt and decrypt all messages. This comes with a number of caveats:
- no forward secrecy
- authentication is out of band
- No model to handle kick/ban of members
- Difficult handling of breach (eg key is leaked). Breach risk is high, as all members have access to the same key.
Using deMLS would solve this drawback.
deMLS proposes to use onchain smart contract to manage groups and their members (reference missing).
The community owner would need to deploy a smart contract to manage group encryption for their community. Similar to RLN, the community owner could add/remove members to the group, or drop tokens to allow members to add their own information.
Similar to RLN, it would mean that only members of the deMLS group matching the community would be able to send messages in the encrypted group. A similar approach than before, where the members list is constructed from messages emitted by active members, could be adopted.
Conclusion
The previous proposal of using IPFS to store a Community’s membership list is still relevant. However, it does mean integrating new technology in the Status app (IPFS) and solving problems of pinning, retrieval etc.
Looking at medium and long term protocols applicable to Status Communities (RLN, deMLS), new opportunity arises to solve the problem of unbounded size of the community description message.
Annex
The protobuf for CommunityDescription
message CommunityDescription {
// The Lamport timestamp of the message
uint64 clock = 1;
// A mapping of members in the community to their roles
map<string,CommunityMember> members = 2;
// The permissions of the Community
CommunityPermissions permissions = 3;
// The metadata of the Community
ChatIdentity identity = 5;
// A mapping of chats to their details
map<string,CommunityChat> chats = 6;
// A list of banned members
repeated string ban_list = 7;
// A mapping of categories to their details
map<string,CommunityCategory> categories = 8;
// The admin settings of the Community
CommunityAdminSettings admin_settings = 10;
// If the community is encrypted
bool encrypted = 13;
// The list of tags
repeated string tags = 14;
}
message CommunityMember {
enum Roles {
reserved 2, 3;
reserved "ROLE_MANAGE_USERS", "ROLE_MODERATE_CONTENT";
ROLE_NONE = 0;
ROLE_OWNER = 1;
ROLE_ADMIN = 4;
ROLE_TOKEN_MASTER = 5;
}
enum ChannelRole {
// We make POSTER the first role to be the default one.
// This is for backwards compatibility. Older protobufs won't have this field and will default to 0.
CHANNEL_ROLE_POSTER = 0;
CHANNEL_ROLE_VIEWER = 1;
}
repeated Roles roles = 1;
repeated RevealedAccount revealed_accounts = 2 [deprecated = true];
uint64 last_update_clock = 3;
ChannelRole channel_role = 4;
}