The proposer needs to create an intent, and make sure that the proposal makes it onto the group successfully, before deleting the group on their end. Logic to add for the proposer:
- Add another membership state like
LEFT
here: https://github.com/xmtp/libxmtp/blob/main/xmtp_mls/src/storage/encrypted_store/group.rs#L192 - Create a
IntentKind::LeaveGroup
intent type here. - Cmd+F for
IntentKind::RemoveMembers
, and follow the same lifecycle:- Just like
remove_members()
, add a method calledleave_group()
that constructs theLeaveGroup
intent and then syncs. - In
get_publish_intent_data()
, add another match arm forLeaveGroup
. There is noIntentData
to fetch - you know that you are removing all installations with your own wallet address. Use the same logic to gather the list of leaf nodes to remove, then build a list of proposals (not a commit) to remove them. Return this fromget_publish_intent_data
and it will be sent on the group.- When saving the payload hash on the intent, we can just hash the first proposal, so that it's easier to match against later.
- In
process_own_message()
, add another case forIntentKind::LeaveGroup
. Extract thePrivateMessageIn
from themessage: ProtocolMessage
param, then decrypt it viaopenmls_group.process_message()
. If the decryption fails, callconn.set_group_intent_to_publish()
to reset the intent. If the decryption is successful, our proposal has been successfully synced, and we can go ahead and update the group membership state toLEFT
. (conn.set_group_intent_committed()
will automatically be called at the end of the function)- We can update the group here because we don't care if the proposal is committed or not. We've done our end by making sure the proposal is correctly published, it's up to the rest of the group to commit it.
- Just like
- We need to somehow expose that the group is 'left' to the bindings. Perhaps we can add an optional filter to whatever method lists groups if it doesn't already exist, and make sure the membership state is accessible to the bindings.
Once the committer receives the proposal, they can 'lazy commit' it the next time they interact with the group. Logic to add for the committer:
Added by Rich: MLS allows you to publish proposals and commits. In some systems, the proposals are sent separately, and then a later commit is published by someone else that commits all of the previous proposals. In our current implementation, all proposals are immediately committed by the proposer, so we don't use separate proposal messages, just commits that include the proposals.
The problem with removing yourself is that MLS prohibits commiting a Remove proposal that removes the committer. I think the reason is that generating commits requires deriving secrets to use for the next epoch of the group, and therefore anyone being removed from the group should not have access to those secrets.
It seems there are two ways to solve this problem:
Add support for separating out proposals and commits. So to remove yourself, you publish a proposal, and then somebody else commits it. This requires a bunch of changes to how we do proposals/commits today. We will need to chat about how to design this.
You remove yourself from the group, but don't update the group encryption state (in essence, you've effectively 'muted' the group without changing the group membership). I don't like this so much, because you still need a way to notify your other devices you've done this, otherwise you're only muting for your current device.