Skip to content

Commit

Permalink
Add tests for leaf node epoch logic
Browse files Browse the repository at this point in the history
  • Loading branch information
bifurcation authored and germ-mark committed Dec 11, 2024
1 parent b1f0139 commit f8bfccf
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 23 deletions.
78 changes: 56 additions & 22 deletions mls-rs/src/group/proposal_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,8 @@ mod tests {
use crate::group::proposal_ref::test_utils::auth_content_from_proposal;
use crate::group::proposal_ref::ProposalRef;
use crate::group::{
AddProposal, AuthenticatedContent, Content, ExternalInit, GroupContext, Proposal,
AddProposal, AuthenticatedContent, Content, ExternalInit, GroupContext,
LeafNodeEpochExt, Proposal,
ProposalOrRef, ReInitProposal, RemoveProposal, Roster, Sender, UpdateProposal,
};
use crate::key_package::test_utils::test_key_package_with_signer;
Expand Down Expand Up @@ -778,15 +779,40 @@ mod tests {
.unwrap()[0]
}

#[cfg(feature = "replace_proposal")]
#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
async fn update_leaf_node(name: &str, leaf_index: u32) -> LeafNode {
async fn update_member(tree: &mut TreeKemPublic, leaf_index: u32, leaf_node: LeafNode) {
tree.update_leaf(
leaf_index,
leaf_node,
&BasicIdentityProvider,
&test_cipher_suite_provider(TEST_CIPHER_SUITE),
)
.await
.unwrap();
}

#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
async fn update_leaf_node(name: &str, leaf_index: u32, epoch: Option<u64>) -> LeafNode {
let (mut leaf, _, signer) = get_basic_test_node_sig_key(TEST_CIPHER_SUITE, name).await;

let properties = default_properties();

#[cfg(feature = "replace_proposal")]
let mut properties = properties;

#[cfg(feature = "replace_proposal")]
if let Some(epoch) = epoch {
properties
.extensions
.set(LeafNodeEpochExt::new(epoch).into_extension().unwrap());
}

leaf.update(
&test_cipher_suite_provider(TEST_CIPHER_SUITE),
TEST_GROUP,
leaf_index,
Some(default_properties()),
properties,
None,
&signer,
)
Expand Down Expand Up @@ -3089,21 +3115,18 @@ mod tests {
assert_eq!(processed_proposals.1.unused_proposals, vec![replace_info]);
}

// TODO(RLB) Scenario
// * Alice creates the group
// * Bob joins
// * Bob creates a LeafNode
// * Bob commits
// * Alice sends Replace {1, bob_leaf_node}

#[cfg(feature = "replace_proposal")]
#[maybe_async::test(not(mls_build_async), async(mls_build_async, crate::futures_test))]
async fn receiving_replace_for_old_epoch_fails() {
/*
let (alice, mut tree) = new_tree("alice").await;
let _bob = add_member(&mut tree, "bob").await;
add_member(&mut tree, "bob").await;

let replace = Proposal::Replace(make_replace_proposal(1, "carol"));
// Fast-forward Bob to epoch 42
let bob_leaf_new_epoch = update_leaf_node("bob", 1, Some(42));
update_member(&mut tree, 1, bob_leaf_new_epoch);

// Try to replace Bob with a LeafNode from epoch 21
let replace = Proposal::Replace(make_replace_proposal_custom(1, "bob", 21));
let replace_ref = make_proposal_ref(&replace, alice).await;

let res = CommitReceiver::new(
Expand All @@ -3117,17 +3140,20 @@ mod tests {
.await;

assert_matches!(res, Err(MlsError::InvalidSuccessor));
*/
}

#[cfg(feature = "replace_proposal")]
#[maybe_async::test(not(mls_build_async), async(mls_build_async, crate::futures_test))]
async fn sending_replace_for_old_epoch_filters_it_out() {
/*
let (alice, mut tree) = new_tree("alice").await;
let _bob = add_member(&mut tree, "bob").await;
add_member(&mut tree, "bob").await;

let replace = Proposal::Replace(make_replace_proposal(1, "carol"));
// Fast-forward Bob to epoch 42
let bob_leaf_new_epoch = update_leaf_node("bob", 1, Some(42));
update_member(&mut tree, 1, bob_leaf_new_epoch);

// Try to replace Bob with a LeafNode from epoch 21
let replace = Proposal::Replace(make_replace_proposal_custom(1, "bob", 21));
let replace_info = make_proposal_info(&replace, alice).await;

let processed_proposals =
Expand All @@ -3141,7 +3167,6 @@ mod tests {

#[cfg(feature = "state_update")]
assert_eq!(processed_proposals.1.unused_proposals, vec![replace_info]);
*/
}

#[maybe_async::test(not(mls_build_async), async(mls_build_async, crate::futures_test))]
Expand Down Expand Up @@ -3814,7 +3839,7 @@ mod tests {
.await
.unwrap();

let bob_new_leaf = update_leaf_node("bob", 1).await;
let bob_new_leaf = update_leaf_node("bob", 1, None).await;

let pk1_to_pk2 = Proposal::Update(UpdateProposal {
leaf_node: alice_new_leaf.clone(),
Expand Down Expand Up @@ -4560,7 +4585,7 @@ mod tests {
#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
async fn make_update_proposal(name: &str) -> UpdateProposal {
UpdateProposal {
leaf_node: update_leaf_node(name, 1).await,
leaf_node: update_leaf_node(name, 1, None).await,
}
}

Expand All @@ -4569,14 +4594,23 @@ mod tests {
async fn make_replace_proposal(index: u32, name: &str) -> ReplaceProposal {
ReplaceProposal {
to_replace: LeafIndex(index),
leaf_node: update_leaf_node(name, index).await,
leaf_node: update_leaf_node(name, index, None).await,
}
}

#[cfg(feature = "replace_proposal")]
#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
async fn make_replace_proposal_custom(index: u32, name: &str, epoch: u64) -> ReplaceProposal {
ReplaceProposal {
to_replace: LeafIndex(index),
leaf_node: update_leaf_node(name, index, Some(epoch)).await,
}
}

#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
async fn make_update_proposal_custom(name: &str, leaf_index: u32) -> UpdateProposal {
UpdateProposal {
leaf_node: update_leaf_node(name, leaf_index).await,
leaf_node: update_leaf_node(name, leaf_index, None).await,
}
}

Expand Down
6 changes: 5 additions & 1 deletion mls-rs/src/tree_kem/leaf_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ pub(crate) mod test_utils {
identity::test_utils::{get_test_signing_identity, BasicWithCustomProvider},
};

use crate::extension::ApplicationIdExt;
use crate::extension::{ApplicationIdExt, ExtensionType};

use super::*;

Expand Down Expand Up @@ -392,6 +392,10 @@ pub(crate) mod test_utils {
CredentialType::from(BasicWithCustomProvider::CUSTOM_CREDENTIAL_TYPE),
],
cipher_suites: TestCryptoProvider::all_supported_cipher_suites(),

#[cfg(feature = "replace_proposal")]
extensions: vec![ExtensionType::LEAF_NODE_EPOCH],

..Default::default()
}
}
Expand Down

0 comments on commit f8bfccf

Please sign in to comment.