ic_memory/ledger/
integrity.rs1use super::{AllocationLedger, LedgerIntegrityError};
2
3impl AllocationLedger {
4 pub(crate) const fn validate_bounds(&self) -> Result<(), LedgerIntegrityError> {
5 if self.records.len() > crate::constants::MAX_ALLOCATIONS {
6 return Err(LedgerIntegrityError::LimitExceeded {
7 resource: "allocation records",
8 limit: crate::constants::MAX_ALLOCATIONS,
9 });
10 }
11 Ok(())
12 }
13
14 pub fn validate_integrity(&self) -> Result<(), LedgerIntegrityError> {
17 self.validate_bounds()?;
18 let duplicate_keys = crate::key::duplicate_key_positions(
19 self.records()
20 .iter()
21 .enumerate()
22 .map(|(index, record)| (record.stable_key(), index))
23 .collect(),
24 );
25 let mut slots = [false; crate::constants::MAX_ALLOCATIONS];
26 for (index, record) in self.records().iter().enumerate() {
27 if duplicate_keys[index] {
28 return Err(LedgerIntegrityError::DuplicateStableKey {
29 stable_key: record.stable_key.clone(),
30 });
31 }
32 if slots[usize::from(record.slot.id())] {
33 return Err(LedgerIntegrityError::DuplicateSlot {
34 slot: record.slot.clone(),
35 });
36 }
37 slots[usize::from(record.slot.id())] = true;
38 }
39 if self.current_generation == 0 && !self.records.is_empty() {
40 return Err(LedgerIntegrityError::NonemptyGenesis);
41 }
42 Ok(())
43 }
44}