ic_memory/ledger/
record.rs1use super::{AllocationRetirementError, LedgerIntegrityError};
2use crate::{
3 declaration::AllocationDeclaration, key::StableKey, schema::SchemaMetadata,
4 slot::MemoryManagerSlot,
5};
6use serde::{Deserialize, Serialize};
7
8#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
20#[serde(deny_unknown_fields)]
21pub struct AllocationLedger {
22 pub(crate) current_generation: u64,
23 #[serde(deserialize_with = "crate::cbor::deserialize_records")]
24 pub(crate) records: Vec<AllocationRecord>,
25}
26
27#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
36#[serde(deny_unknown_fields)]
37pub struct AllocationRecord {
38 pub(crate) stable_key: StableKey,
39 pub(crate) slot: MemoryManagerSlot,
40 pub(crate) state: AllocationState,
41 pub(crate) schema: SchemaMetadata,
42}
43
44#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
52#[serde(deny_unknown_fields)]
53pub enum AllocationState {
54 Reserved,
56 Active,
58 Retired,
60}
61
62#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
70#[serde(deny_unknown_fields)]
71pub struct AllocationRetirement {
72 pub(crate) stable_key: StableKey,
73 pub(crate) slot: MemoryManagerSlot,
74}
75
76impl AllocationRetirement {
77 pub fn new(
79 stable_key: impl AsRef<str>,
80 slot: MemoryManagerSlot,
81 ) -> Result<Self, AllocationRetirementError> {
82 let stable_key = StableKey::parse(stable_key).map_err(AllocationRetirementError::Key)?;
83 Ok(Self { stable_key, slot })
84 }
85
86 #[must_use]
88 pub const fn stable_key(&self) -> &StableKey {
89 &self.stable_key
90 }
91
92 #[must_use]
94 pub const fn slot(&self) -> &MemoryManagerSlot {
95 &self.slot
96 }
97}
98
99#[derive(Clone, Debug, Eq, PartialEq)]
108pub struct RecoveredLedger {
109 ledger: AllocationLedger,
110}
111
112impl RecoveredLedger {
113 pub(crate) const fn from_trusted_ledger(ledger: AllocationLedger) -> Self {
114 Self { ledger }
115 }
116
117 #[must_use]
119 pub const fn ledger(&self) -> &AllocationLedger {
120 &self.ledger
121 }
122
123 #[must_use]
125 pub const fn physical_generation(&self) -> u64 {
126 self.ledger.current_generation
127 }
128
129 #[must_use]
131 pub const fn current_generation(&self) -> u64 {
132 self.ledger.current_generation
133 }
134
135 pub(crate) fn into_ledger(self) -> AllocationLedger {
136 self.ledger
137 }
138}
139
140impl AllocationRecord {
141 fn from_declaration(declaration: &AllocationDeclaration, state: AllocationState) -> Self {
142 Self {
143 stable_key: declaration.stable_key.clone(),
144 slot: declaration.slot.clone(),
145 state,
146 schema: declaration.schema.clone(),
147 }
148 }
149
150 pub(crate) fn active(declaration: &AllocationDeclaration) -> Self {
151 Self::from_declaration(declaration, AllocationState::Active)
152 }
153
154 pub(crate) fn reserved(declaration: &AllocationDeclaration) -> Self {
155 Self::from_declaration(declaration, AllocationState::Reserved)
156 }
157
158 #[must_use]
160 pub const fn stable_key(&self) -> &StableKey {
161 &self.stable_key
162 }
163
164 #[must_use]
166 pub const fn slot(&self) -> &MemoryManagerSlot {
167 &self.slot
168 }
169
170 #[must_use]
172 pub const fn state(&self) -> AllocationState {
173 self.state
174 }
175
176 #[must_use]
178 pub const fn schema(&self) -> &SchemaMetadata {
179 &self.schema
180 }
181}
182
183impl AllocationLedger {
184 pub(crate) const fn empty_genesis() -> Self {
185 Self {
186 current_generation: 0,
187 records: Vec::new(),
188 }
189 }
190
191 pub fn new(
194 current_generation: u64,
195 records: Vec<AllocationRecord>,
196 ) -> Result<Self, LedgerIntegrityError> {
197 let ledger = Self {
198 current_generation,
199 records,
200 };
201 ledger.validate_integrity()?;
202 Ok(ledger)
203 }
204
205 #[must_use]
207 pub const fn current_generation(&self) -> u64 {
208 self.current_generation
209 }
210
211 #[must_use]
213 pub fn records(&self) -> &[AllocationRecord] {
214 &self.records
215 }
216}