Added open inv cleanup test

This commit is contained in:
onyinyang 2023-07-13 17:36:40 -04:00
parent a62b537aa6
commit 9c2b7703a8
No known key found for this signature in database
GPG Key ID: 156A6435430C2036
6 changed files with 130 additions and 32 deletions

View File

@ -65,7 +65,8 @@ impl LoxServerContext {
pub fn add_spare_bucket(&self, bucket: [BridgeLine; 3]) {
let mut ba_obj = self.ba.lock().unwrap();
ba_obj.add_spare_bucket(bucket);
let mut db_obj = self.db.lock().unwrap();
ba_obj.add_spare_bucket(bucket, &mut db_obj);
}
pub fn replace_with_new(&self, bridgeline: BridgeLine) -> lox_library::ReplaceSuccess {

View File

@ -235,7 +235,7 @@ mod tests {
// Add hot_spare more hot spare buckets
for _ in 0..5 {
let bucket = [random(), random(), random()];
lox_auth.add_spare_bucket(bucket);
lox_auth.add_spare_bucket(bucket, &mut bridgedb);
}
// Create the encrypted bridge table
lox_auth.enc_bridge_table();

View File

@ -290,7 +290,7 @@ impl BridgeTable {
// }
/// Append a new bucket to the bridge table, returning its index
pub fn new_bucket(&mut self, bucket: &[BridgeLine; MAX_BRIDGES_PER_BUCKET], index: u32) -> u32 {
pub fn new_bucket(&mut self, bucket: &[BridgeLine; MAX_BRIDGES_PER_BUCKET], index: u32) {
// Pick a random key to encrypt this bucket
let mut rng = rand::thread_rng();
let mut key: [u8; 16] = [0; 16];
@ -311,7 +311,6 @@ impl BridgeTable {
}
}
}
self.counter
}
/// Create the vector of encrypted buckets from the keys and buckets

View File

@ -300,24 +300,28 @@ impl BridgeAuth {
bridges: [BridgeLine; MAX_BRIDGES_PER_BUCKET],
bdb: &mut BridgeDb,
) {
let index = self.find_next_available_key();
let bnum = self.bridge_table.new_bucket(&bridges, index);
let bindex = self.find_next_available_key(bdb);
self.bridge_table.new_bucket(&bridges, bindex);
let mut single = [BridgeLine::default(); MAX_BRIDGES_PER_BUCKET];
for b in bridges.iter() {
let index = self.find_next_available_key();
let sindex = self.find_next_available_key(bdb);
single[0] = *b;
let snum = self.bridge_table.new_bucket(&single, index);
self.bridge_table.open_inv_keys.push((snum, self.today()));
bdb.insert_openinv(snum);
self.trustup_migration_table.table.insert(snum, bnum);
self.bridge_table.new_bucket(&single, sindex);
self.bridge_table.open_inv_keys.push((sindex, self.today()));
bdb.insert_openinv(sindex);
self.trustup_migration_table.table.insert(sindex, bindex);
}
}
/// Insert a hot spare bucket of bridges
pub fn add_spare_bucket(&mut self, bucket: [BridgeLine; MAX_BRIDGES_PER_BUCKET]) {
let index = self.find_next_available_key();
let bnum = self.bridge_table.new_bucket(&bucket, index);
self.bridge_table.spares.insert(bnum);
pub fn add_spare_bucket(
&mut self,
bucket: [BridgeLine; MAX_BRIDGES_PER_BUCKET],
bdb: &mut BridgeDb,
) {
let index = self.find_next_available_key(bdb);
self.bridge_table.new_bucket(&bucket, index);
self.bridge_table.spares.insert(index);
}
pub fn sync_table(&mut self) {
@ -607,8 +611,8 @@ impl BridgeAuth {
// does not overwrite existing bridges could become an issue. We keep a list
// of recycleable lookup keys from buckets that have been removed and prioritize
// this list before increasing the counter
fn find_next_available_key(&mut self) -> u32 {
self.clean_up_expired_buckets(); //This function probably should be moved to lib.rs to handle trustup and migration tables too
fn find_next_available_key(&mut self, bdb: &mut BridgeDb) -> u32 {
self.clean_up_expired_buckets(bdb);
if self.bridge_table.recycleable_keys.is_empty() {
let mut test_index = 1;
let mut test_counter = self.bridge_table.counter.wrapping_add(test_index);
@ -630,7 +634,7 @@ impl BridgeAuth {
// that we no longer want to allow migration to, or else, open-entry buckets that
// have been unblocked long enough to become trusted and who's users' credentials
// would have expired (after 511 days)
pub fn clean_up_expired_buckets(&mut self) {
pub fn clean_up_expired_buckets(&mut self, bdb: &mut BridgeDb) {
// Consider including migration tables and check age of from buckets
// If an open-invitation bucket is more than 511 days old, it should be recycled
// If a blocked bridge is more than 511 (the maximum validity of a credential in days) days old, it should also be recycled
@ -638,7 +642,7 @@ impl BridgeAuth {
// First check if there are any blocked indexes that are old enough to be replaced
self.clean_up_blocked();
// Next do the same for open_invitations buckets
// self.clean_up_open_entry();
self.clean_up_open_entry(bdb);
}
fn clean_up_blocked(&mut self) {
@ -687,7 +691,7 @@ impl BridgeAuth {
}
}
fn clean_up_open_entry(&mut self) {
fn clean_up_open_entry(&mut self, bdb: &mut BridgeDb) {
// First check if there are any open invitation indexes that are old enough to be replaced
if !self.bridge_table.open_inv_keys.is_empty()
&& self
@ -704,6 +708,12 @@ impl BridgeAuth {
.partition(|&x| x.1 + 511 < self.today());
for item in expired {
let new_item = item.0;
bdb.remove_openinv(&new_item);
// Remove any trust upgrade migrations from this
// bucket
self.trustup_migration_table
.table
.retain(|&k, _| k != new_item);
self.bridge_table.buckets.remove(&new_item);
self.bridge_table.keys.remove(&new_item);
//and add them to the recyclable keys

View File

@ -154,11 +154,10 @@ impl BridgeAuth {
// Check the signature on the open_invite. We manually match
// here because we're changing the Err type from SignatureError
// to ProofError
let (invite_id, bucket_id_u32) = match BridgeDb::verify(req.invite, self.bridgedb_pub) {
let (invite_id, bucket_id) = match BridgeDb::verify(req.invite, self.bridgedb_pub) {
Ok(res) => res,
Err(_) => return Err(ProofError::VerificationFailure),
};
let bucket_id: usize = bucket_id_u32 as usize;
// Only proceed if the invite_id is fresh
if self.openinv_filter.filter(&invite_id) == SeenType::Seen {
@ -166,7 +165,7 @@ impl BridgeAuth {
}
// And also check that the bucket id is valid
if bucket_id >= self.bridge_table.num_buckets() {
if !self.bridge_table.buckets.contains_key(&bucket_id) {
return Err(ProofError::VerificationFailure);
}
@ -196,9 +195,9 @@ impl BridgeAuth {
// Create the bucket attribute (Scalar), which is a combination
// of the bucket id (u32) and the bucket's decryption key ([u8; 16])
let bucket_key = self.bridge_table.keys.get(&bucket_id_u32).unwrap();
let bucket: Scalar = bridge_table::to_scalar(bucket_id_u32, bucket_key);
let bridge_lines = self.bridge_table.buckets.get(&bucket_id_u32).unwrap();
let bucket_key = self.bridge_table.keys.get(&bucket_id).unwrap();
let bucket: Scalar = bridge_table::to_scalar(bucket_id, bucket_key);
let bridge_lines = self.bridge_table.buckets.get(&bucket_id).unwrap();
let bridge_line = bridge_lines[0];
// Create the level_since attribute (Scalar), which is today's

View File

@ -50,7 +50,7 @@ impl TestHarness {
BridgeLine::random(),
BridgeLine::random(),
];
ba.add_spare_bucket(bucket);
ba.add_spare_bucket(bucket, &mut bdb);
}
// Create the encrypted bridge table
ba.enc_bridge_table();
@ -651,13 +651,16 @@ fn test_clean_up_blocked() {
BridgeLine::random(),
BridgeLine::random(),
];
// Add new bridges to trigger bucket cleanup
// Add new bridges to trigger bucket cleanup, but also open invitation cleanup so 150 buckets - blocked
th.ba.add_openinv_bridges(bucket, &mut th.bdb);
}
// 150 is the number of open invitation buckets that will be cleared, + the number of blocked bridges
// 40 is the number of keys that will have had to be used after creating 10 new open invitation buckets
println!(
"Size of recyclable keys: {:?}",
th.ba.bridge_table.recycleable_keys.len()
"Size of recyclable keys: {:?}. Which should be the same as 150+blocked-40 = {:?}",
th.ba.bridge_table.recycleable_keys.len(),
150 + blocked - 40
);
println!("Counter: {:?}", th.ba.bridge_table.counter);
println!("\n**AFTER NEW BUCKETS ADDED**\n");
@ -666,7 +669,7 @@ fn test_clean_up_blocked() {
"After adding new buckets, blocked keys should be empty"
);
assert!(
th.ba.bridge_table.recycleable_keys.is_empty(),
th.ba.bridge_table.recycleable_keys.len() == 150 + blocked - 40,
"After adding new buckets, recycleable keys should be empty"
);
// Because of open-entry buckets added and open-entry cleanup, the counter increases to 278
@ -674,7 +677,93 @@ fn test_clean_up_blocked() {
}
#[test]
fn test_clean_up_open_entry() {}
fn test_clean_up_open_entry() {
let mut th = TestHarness::new_buckets(50, 50);
let mut credentials: Vec<cred::Lox> = Vec::new();
let mut level_1_credentials: Vec<cred::Lox> = Vec::new();
// Users
for _ in 0..100 {
let cred = th.open_invite().1 .0;
credentials.push(cred);
}
assert!(
th.ba.trustup_migration_table.table.len() == 150,
"There should be 50*3 eligible trust up migrations"
);
th.advance_days(30);
for cred in credentials {
let (_, migcred) = th.trust_promotion(&cred);
let (_, cred1) = th.level0_migration(&cred, &migcred);
level_1_credentials.push(cred1);
}
th.advance_days(512);
assert!(
th.ba.bridge_table.open_inv_keys.len() == 150,
"Open Inv keys does not equal 50*3 = 150"
);
assert!(th.ba.bridge_table.recycleable_keys.is_empty(), "");
th.ba.clean_up_open_entry(&mut th.bdb);
assert!(
th.ba.bridge_table.open_inv_keys.is_empty(),
"Open entry keys should be 0"
);
assert!(
th.ba.trustup_migration_table.table.len() == 0,
"There should be no remaining eligible trust up migrations"
);
assert!(
th.ba.bridge_table.recycleable_keys.len() == 150,
"Recycleable keys is 150"
);
// Each open invitation bucket creates 4 buckets -> 50*4 = 200 + 50 hotspare buckets = 250 total
assert!(
th.ba.bridge_table.counter == 250,
"Total number of buckets should be 250"
);
for cred in level_1_credentials {
let (_, _cred2) = th.level_up(&cred);
}
println!("Succeeded upgrading all creds to level 2");
// Open Invite will fail since there are no open invitation buckets
// Lets add more
for _ in 0..10 {
let bucket = [
BridgeLine::random(),
BridgeLine::random(),
BridgeLine::random(),
];
// Add new bridges to trigger bucket cleanup
th.ba.add_openinv_bridges(bucket, &mut th.bdb);
}
println!(
"The number of trustup migrations after adding 10 new buckets is: {:?}",
th.ba.trustup_migration_table.table.len()
);
assert!(
th.ba.trustup_migration_table.table.len() == 30,
"There should be 10*3 eligible trust up migrations"
);
// Let's also make sure that open invitation works again
let cred = th.open_invite().1 .0;
println!("Yep, worked!");
th.advance_days(30);
assert!(
th.ba.bridge_table.recycleable_keys.len() == 110,
"Size of recycleable keys should be 150 - (10*4) = 110"
);
assert!(
th.ba.bridge_table.counter == 250,
"Counter should be unchanged"
);
assert!(
th.ba.bridge_table.open_inv_keys.len() == 30,
"Open inv keys should be 10*3 = 30"
);
}
#[test]
fn find_next_available_key() {}