Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Key Update Before Every New GroupIntent #658

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
8e87ba7
queue_key_update
Apr 15, 2024
9df8308
lint
Apr 15, 2024
60e8adc
lint
Apr 15, 2024
cb88c9e
merge main
Apr 15, 2024
3438591
queue key update test
Apr 16, 2024
0e9d812
key-update
Apr 22, 2024
1624a05
Fix paths in update-schema script
richardhuaaa Apr 22, 2024
7d0dade
merge master and add rotated_at_ns item
Apr 30, 2024
e62cdfc
add get_rotated_at_ns
Apr 30, 2024
5f35add
fetch rotated_at_ns
May 1, 2024
928bca4
Merge remote-tracking branch 'origin' into dz/key-update
May 1, 2024
b319f56
add pre_intent_hook
May 6, 2024
ed6e1dd
Revert unneeded fix, and specify the correct directory in the README …
richardhuaaa May 13, 2024
cd28efd
apply pre_intent_hook
May 16, 2024
c160c14
Merge remote-tracking branch 'origin' into dz/key-update
May 16, 2024
e1b5f56
merge master and resolve comments
May 16, 2024
c6ed2c0
fix tests
May 17, 2024
79d714e
test 1
May 30, 2024
4a317b4
merge master
May 31, 2024
ceb8d34
modify test
May 31, 2024
ecc3dc0
merge main
Jun 20, 2024
48ad52a
modify
Jun 20, 2024
059df1c
solve db connection and update
Jun 21, 2024
e8a3308
more key updates and test updates
Jun 24, 2024
a4482c6
add
Jun 24, 2024
dc2ba36
test
Jun 28, 2024
b4d676e
finish key update test
Jul 2, 2024
979dcea
Merge remote-tracking branch 'origin/main' into dz/key-update
richardhuaaa Oct 1, 2024
41a7618
Small fixes
richardhuaaa Oct 1, 2024
3d143eb
Fix group initialization error - no need to rotate keys if you are th…
richardhuaaa Oct 1, 2024
6377d85
Undo unit test changes
richardhuaaa Oct 1, 2024
71478f1
Make it impossible to miss a pre_intent_hook, add missing locations
richardhuaaa Oct 2, 2024
bb75ed4
Reduce duplication of maybe_update_installations
richardhuaaa Oct 2, 2024
8750c10
Progress on key rotation for optimistic message sends
richardhuaaa Oct 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 44 additions & 41 deletions xmtp_mls/src/groups/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,12 @@
validate_initial_group_membership(client, provider.conn_ref(), &mls_group).await?;

let stored_group = provider.conn().insert_or_ignore_group(to_store)?;
let xmtp_group = Self::new(context, stored_group.id, stored_group.created_at_ns);
Ok(xmtp_group)

Ok(Self::new(
client.context.clone(),
stored_group.id,
stored_group.created_at_ns,
))
}

// Decrypt a welcome message using HPKE and then create and save a group from the stored message
Expand Down Expand Up @@ -477,36 +481,41 @@
return Err(GroupError::UserLimitExceeded);
}

let conn = self.context.store.conn()?;
let intent_data: Vec<u8> =
AddMembersIntentData::new(account_addresses.into()).try_into()?;

self.pre_intent_hook(client).await?;

let intent = conn.insert_group_intent(NewGroupIntent::new(
IntentKind::AddMembers,
self.group_id.clone(),
intent_data,
))?;
if inbox_id_map.len() != account_addresses.len() {
let found_addresses: HashSet<&String> = inbox_id_map.keys().collect();
let to_add_hashset = HashSet::from_iter(account_addresses.iter());
self.pre_intent_hook(client).await?;
richardhuaaa marked this conversation as resolved.
Show resolved Hide resolved
let missing_addresses = found_addresses.difference(&to_add_hashset);
return Err(GroupError::AddressNotFound(
missing_addresses.into_iter().cloned().cloned().collect(),
));
}

self.add_members_by_inbox_id(client, inbox_id_map.into_values().collect())
.await
}

// Before calling this function, please verify pre_intent_hook has been called.
pub async fn add_members_by_installation_id<ApiClient>(
pub async fn add_members_by_inbox_id<ApiClient: XmtpApi>(
&self,
client: &Client<ApiClient>,
) -> Result<(), GroupError>
where
ApiClient: XmtpApi,
{
validate_ed25519_keys(&installation_ids)?;
let conn = self.context.store.conn()?;
let intent_data: Vec<u8> = AddMembersIntentData::new(installation_ids.into()).try_into()?;
inbox_ids: Vec<String>,
) -> Result<(), GroupError> {
let conn = client.store().conn()?;
let provider = client.mls_provider(conn);
let intent_data = self
.get_membership_update_intent(client, &provider, inbox_ids, vec![])
.await?;

let intent = conn.insert_group_intent(NewGroupIntent::new(
IntentKind::AddMembers,
// TODO:nm this isn't the best test for whether the request is valid
// If some existing group member has an update, this will return an intent with changes
// when we really should return an error
if intent_data.is_empty() {
return Err(GroupError::NoChanges);
}

let intent = provider.conn().insert_group_intent(NewGroupIntent::new(
IntentKind::UpdateGroupMembership,
self.group_id.clone(),
intent_data.into(),
))?;
Expand All @@ -521,16 +530,7 @@
account_addresses_to_remove: Vec<InboxId>,
) -> Result<(), GroupError> {
let account_addresses = sanitize_evm_addresses(account_addresses_to_remove)?;
let conn = self.context.store.conn()?;
let intent_data: Vec<u8> = RemoveMembersIntentData::new(account_addresses.into()).into();

self.pre_intent_hook(client).await?;

let intent = conn.insert_group_intent(NewGroupIntent::new(
IntentKind::RemoveMembers,
self.group_id.clone(),
intent_data,
))?;
let inbox_id_map = client.api_client.get_inbox_ids(account_addresses).await?;
richardhuaaa marked this conversation as resolved.
Show resolved Hide resolved

self.remove_members_by_inbox_id(client, inbox_id_map.into_values().collect())
.await
Expand Down Expand Up @@ -626,10 +626,15 @@
ApiClient: XmtpApi,
{
let conn = self.context.store.conn()?;
let intent_data: Vec<u8> = RemoveMembersIntentData::new(installation_ids.into()).into();

let intent_action_type = match action_type {
UpdateAdminListType::Add => AdminListActionType::Add,
UpdateAdminListType::Remove => AdminListActionType::Remove,
UpdateAdminListType::AddSuper => AdminListActionType::AddSuper,
UpdateAdminListType::RemoveSuper => AdminListActionType::RemoveSuper,
};
let intent_data: Vec<u8> =
UpdateAdminListIntentData::new(intent_action_type, inbox_id).into();
self.pre_intent_hook(client).await?;

let intent = conn.insert_group_intent(NewGroupIntent::new(
IntentKind::UpdateAdminList,
self.group_id.clone(),
Expand Down Expand Up @@ -936,14 +941,13 @@

#[cfg(test)]
mod tests {
use openmls::prelude::{tls_codec::Serialize, Member, MlsGroup as OpenMlsGroup};
use openmls::prelude::tls_codec::Deserialize;
use openmls::prelude::Member;
use openmls::prelude::MlsMessageIn;
use openmls::prelude::MlsMessageBodyIn;
use openmls::prelude::Proposal;
use openmls::prelude::ProcessedMessageContent;
use crate::groups::GroupMessageVersion;
use crate::groups::OpenMlsGroup;
use prost::Message;
use tracing_test::traced_test;
use xmtp_cryptography::utils::generate_local_wallet;
Expand Down Expand Up @@ -1055,8 +1059,7 @@
.query_group_messages(group.group_id, None)
.await
.expect("read topic");

assert_eq!(messages.len(), 2)
assert_eq!(messages.len(), 2);
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
Expand Down Expand Up @@ -1393,7 +1396,7 @@

// client A makes a group with client B.
let group = client_a.create_group(None).expect("create group");
group.add_members(vec![client_b.account_address()], &client_a).await.unwrap();

Check failure on line 1399 in xmtp_mls/src/groups/mod.rs

View workflow job for this annotation

GitHub Actions / Test

no method named `account_address` found for struct `client::Client` in the current scope

Check failure on line 1399 in xmtp_mls/src/groups/mod.rs

View workflow job for this annotation

GitHub Actions / Test

arguments to this method are incorrect

// client B creates it from welcome.
let client_b_group = receive_group_invite(&client_b).await;
Expand Down Expand Up @@ -1442,7 +1445,7 @@
};
}

#[tokio::test]
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_post_commit() {
let client = ClientBuilder::new_test_client(&generate_local_wallet()).await;
let client_2 = ClientBuilder::new_test_client(&generate_local_wallet()).await;
Expand Down
9 changes: 5 additions & 4 deletions xmtp_mls/src/storage/encrypted_store/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ pub struct StoredGroup {
pub installations_last_checked: i64,
/// Enum, [`Purpose`] signifies the group purpose which extends to who can access it.
pub purpose: Purpose,
/// The wallet address of who added the user to a group.
pub added_by_address: String,

/// The inbox_id of who added the user to a group.
pub added_by_inbox_id: String,
pub rotated_at_ns: i64,
}

Expand All @@ -57,7 +58,7 @@ impl StoredGroup {
membership_state,
installations_last_checked: 0,
purpose: Purpose::Conversation,
added_by_address,
added_by_inbox_id,
rotated_at_ns: 0,
}
}
Expand All @@ -75,7 +76,7 @@ impl StoredGroup {
membership_state,
installations_last_checked: 0,
purpose: Purpose::Sync,
added_by_address: "".into(),
added_by_inbox_id: "".into(),
rotated_at_ns: 0,
}
}
Expand Down
2 changes: 1 addition & 1 deletion xmtp_mls/src/storage/encrypted_store/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ diesel::table! {
membership_state -> Integer,
installations_last_checked -> BigInt,
purpose -> Integer,
added_by_address -> Text,
added_by_inbox_id -> Text,
rotated_at_ns -> BigInt,
}
}
Expand Down
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.