add dynamic test

This commit is contained in:
otsmr 2026-04-21 21:53:14 +02:00
parent 5d8133a92f
commit 954eedd40e
4 changed files with 104 additions and 11 deletions

View file

@ -104,10 +104,14 @@ impl<Store: UserDiscoveryStore, Utils: UserDiscoveryUtils> UserDiscovery<Store,
let signature = self.utils.sign_data(&signed_data.encode_to_vec()).await?;
debug_assert_eq!(threshold, config.threshold);
let verification_shares = self
.setup_announcements(&config, signed_data, signature)
.await?;
debug_assert_eq!(verification_shares.len(), threshold as usize - 1);
config.public_id = public_id;
config.announcement_version += 1;
config.verification_shares = verification_shares;

View file

@ -40,6 +40,7 @@ impl UserDiscoveryStore for InMemoryStore {
}
async fn set_shares(&self, shares: Vec<Vec<u8>>) -> Result<()> {
self.storage().used_shares.clear();
self.storage().unused_shares = shares;
Ok(())
}

View file

@ -52,7 +52,10 @@ impl<S: UserDiscoveryStore + Clone + Default> TestNetwork<S> {
fn expect_announced_user(&mut self, user: &str, contact: &str, friends_of_contact: &[&str]) {
let user_id = self.ids_by_name[user];
let contact_id = self.ids_by_name[contact];
let f_ids: Vec<usize> = friends_of_contact.iter().map(|f| self.ids_by_name[*f]).collect();
let f_ids: Vec<usize> = friends_of_contact
.iter()
.map(|f| self.ids_by_name[*f])
.collect();
self.announced_users_expected[user_id].push((contact_id, f_ids));
}
}
@ -108,6 +111,91 @@ async fn get_with_five_users<S: UserDiscoveryStore + Default + Clone>() -> TestN
network
}
#[tokio::test]
async fn test_user_discovery_dynamic_threshold_in_memory_store() {
let _ = pretty_env_logger::try_init();
let mut network = TestNetwork::<InMemoryStore>::new();
// Start ALICE with a more strict threshold of 3.
// David only has 2 paths to Alice (via Bob and Charlie). Since 2 < 3, David cannot discover Alice.
network.add_user("ALICE", 3).await;
network.add_user("BOB", 2).await;
network.add_user("CHARLIE", 2).await;
network.add_user("DAVID", 2).await;
network.add_user("FRANK", 2).await;
// Same topology as the initial 5 users
network.set_friends("ALICE", &["BOB", "CHARLIE"]);
network.set_friends("BOB", &["ALICE", "CHARLIE", "DAVID"]);
network.set_friends("CHARLIE", &["ALICE", "BOB", "DAVID", "FRANK"]);
network.set_friends("DAVID", &["BOB", "CHARLIE"]);
network.set_friends("FRANK", &["CHARLIE"]);
let david_idx = network.ids_by_name["DAVID"];
let alice_idx = network.ids_by_name["ALICE"];
let charlie_idx = network.ids_by_name["CHARLIE"];
// Phase 1: Exchange with ALICE threshold = 3
step0_exchange_random::<InMemoryStore>(&network).await;
step1_verify_no_new_messages::<InMemoryStore>(&network).await;
let version = network.uds[david_idx]
.get_contact_version(charlie_idx as UserID)
.await
.unwrap()
.unwrap();
assert_eq!(version, get_version_bytes(1, 4));
// DAVID should NOT know ALICE yet because ALICE's threshold is 3, but David only has 2 shares.
let david_knows = network.uds[david_idx]
.get_all_announced_users()
.await
.unwrap();
let knows_alice = david_knows
.iter()
.any(|(u, _)| u.user_id == alice_idx as UserID);
assert!(!knows_alice, "David should not know Alice yet because Alice's threshold is 3 and David only receives 2 shares");
// Phase 2: Update ALICE's threshold to 2
network.uds[alice_idx]
.initialize_or_update(2, alice_idx as UserID, vec![alice_idx as u8; 32])
.await
.unwrap();
let version = network.uds[alice_idx].get_current_version().await.unwrap();
assert_eq!(version, get_version_bytes(2, 2));
// ALICE's new announcement with threshold 2 should propagate further.
step0_exchange_random::<InMemoryStore>(&network).await;
step1_verify_no_new_messages::<InMemoryStore>(&network).await;
let version = network.uds[david_idx]
.get_contact_version(charlie_idx as UserID)
.await
.unwrap()
.unwrap();
assert_eq!(version, get_version_bytes(1, 5));
let version = network.uds[alice_idx].get_current_version().await.unwrap();
assert_eq!(version, get_version_bytes(2, 2));
// Now DAVID SHOULD know ALICE
let david_knows = network.uds[david_idx]
.get_all_announced_users()
.await
.unwrap();
let knows_alice_now = david_knows
.iter()
.any(|(u, _)| u.user_id == alice_idx as UserID);
assert!(
knows_alice_now,
"David should know Alice now because her threshold was updated to 2"
);
}
#[tokio::test]
async fn test_user_discovery_in_memory_store() {
let _ = pretty_env_logger::try_init();

View file

@ -14,7 +14,7 @@ pub struct OtherPromotion {
pub public_key_verified_timestamp: Option<i64>,
}
#[derive(Clone, Hash, PartialEq, Eq)]
#[derive(Clone, Hash, PartialEq, Eq, Debug)]
pub struct AnnouncedUser {
pub user_id: UserID,
pub public_key: Vec<u8>,