use super::{AllocationLedger, LedgerIntegrityError};
impl AllocationLedger {
pub(crate) const fn validate_bounds(&self) -> Result<(), LedgerIntegrityError> {
if self.records.len() > crate::constants::MAX_ALLOCATIONS {
return Err(LedgerIntegrityError::LimitExceeded {
resource: "allocation records",
limit: crate::constants::MAX_ALLOCATIONS,
});
}
Ok(())
}
pub fn validate_integrity(&self) -> Result<(), LedgerIntegrityError> {
self.validate_bounds()?;
let duplicate_keys = crate::key::duplicate_key_positions(
self.records()
.iter()
.enumerate()
.map(|(index, record)| (record.stable_key(), index))
.collect(),
);
let mut slots = [false; crate::constants::MAX_ALLOCATIONS];
for (index, record) in self.records().iter().enumerate() {
if duplicate_keys[index] {
return Err(LedgerIntegrityError::DuplicateStableKey {
stable_key: record.stable_key.clone(),
});
}
if slots[usize::from(record.slot.id())] {
return Err(LedgerIntegrityError::DuplicateSlot {
slot: record.slot.clone(),
});
}
slots[usize::from(record.slot.id())] = true;
}
if self.current_generation == 0 && !self.records.is_empty() {
return Err(LedgerIntegrityError::NonemptyGenesis);
}
Ok(())
}
}