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, 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 /// Private Key of the Issuer
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct IssuerPrivKey { pub struct IssuerPrivKey {
@ -510,6 +516,25 @@ impl BridgeAuth {
res 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 /// Attempt to remove a bridge that is failing tests and replace it with a bridge from
/// available_bridge or from a spare bucket /// available_bridge or from a spare bucket
pub fn bridge_replace( pub fn bridge_replace(
@ -573,28 +598,10 @@ impl BridgeAuth {
else { else {
return ReplaceSuccess::NotReplaced; return ReplaceSuccess::NotReplaced;
}; };
self.bridge_table.spares.remove(&spare); let Ok(_) = self.dissolve_spare_bucket(spare) else {
// Get the actual bridges from the spare bucket return ReplaceSuccess::NotReplaced;
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,
}; };
// Remove the spare bucket uid from the keys map let replacement = &self.bridge_table.unallocated_bridges.pop().unwrap();
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;
}
}
for (bucketnum, offset) in positions.iter() { for (bucketnum, offset) in positions.iter() {
let mut bridgelines = match self.bridge_table.buckets.get(bucketnum) { let mut bridgelines = match self.bridge_table.buckets.get(bucketnum) {
Some(bridgelines) => *bridgelines, Some(bridgelines) => *bridgelines,