Factor out a dissolve_spare_bucket fn

This function takes a spare bucket, specified by the given key, and
repurposes the bridges as unallocated.
This commit is contained in:
Cecylia Bocovich 2024-03-09 18:26:19 -05:00
parent 41402209f5
commit 2c396f63fa
No known key found for this signature in database
GPG Key ID: 009DE379FD9B7B90
1 changed files with 28 additions and 21 deletions

View File

@ -94,6 +94,12 @@ pub enum OpenInvitationError {
NoBridgesAvailable,
}
#[derive(Error, Debug)]
pub enum BridgeTableError {
#[error("The bucket corresponding to key {0} was not in the bridge table")]
MissingBucket(u32),
}
/// Private Key of the Issuer
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct IssuerPrivKey {
@ -510,6 +516,25 @@ impl BridgeAuth {
res
}
// Repurpose a bucket of spares into unallocated bridges
pub fn dissolve_spare_bucket(&mut self, key: u32) -> Result<(), BridgeTableError> {
self.bridge_table.spares.remove(&key);
// Get the actual bridges from the spare bucket
let spare_bucket = self
.bridge_table
.buckets
.remove(&key)
.ok_or(BridgeTableError::MissingBucket(key))?;
for bridge in spare_bucket.iter() {
self.bridge_table.unallocated_bridges.push(*bridge);
// Mark bucket as unreachable while it is unallocated
self.bridge_table.reachable.remove(bridge);
}
self.bridge_table.keys.remove(&key);
self.bridge_table.recycleable_keys.push(key);
Ok(())
}
/// Attempt to remove a bridge that is failing tests and replace it with a bridge from
/// available_bridge or from a spare bucket
pub fn bridge_replace(
@ -573,28 +598,10 @@ impl BridgeAuth {
else {
return ReplaceSuccess::NotReplaced;
};
self.bridge_table.spares.remove(&spare);
// Get the actual bridges from the spare bucket
let spare_bucket = match self.bridge_table.buckets.remove(&spare) {
Some(spare_bucket) => spare_bucket,
// This should not happen if the rest of the functions are correct, we can assume unwrap will succeed
None => return ReplaceSuccess::NotReplaced,
let Ok(_) = self.dissolve_spare_bucket(spare) else {
return ReplaceSuccess::NotReplaced;
};
// Remove the spare bucket uid from the keys map
self.bridge_table.keys.remove(&spare);
self.bridge_table.recycleable_keys.push(spare);
let mut replacement: &BridgeLine = &BridgeLine::default();
// Make the first spare the replacement bridge, add the others to the set of
// unallocated_bridges
for spare_bridge in spare_bucket.iter() {
if replacement.port > 0 {
self.bridge_table.unallocated_bridges.push(*spare_bridge);
// Mark bucket as unreachable while it is unallocated
self.bridge_table.reachable.remove(spare_bridge);
} else {
replacement = spare_bridge;
}
}
let replacement = &self.bridge_table.unallocated_bridges.pop().unwrap();
for (bucketnum, offset) in positions.iter() {
let mut bridgelines = match self.bridge_table.buckets.get(bucketnum) {
Some(bridgelines) => *bridgelines,