Skip to main content

ic_memory/runtime/
error.rs

1use crate::{
2    LedgerCommitError, PolicyIdentity, PolicyIdentityError, StableCellLedgerError,
3    registry::StaticMemoryDeclarationError,
4    slot::{MemoryManagerRangeAuthorityError, MemoryManagerSlotError},
5};
6
7///
8/// RuntimeConstructionError
9///
10/// Failure to construct a memory runtime without overwriting unrecognized
11/// backing memory.
12///
13
14#[non_exhaustive]
15#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
16pub enum RuntimeConstructionError {
17    /// Zero pages cannot form a bucket.
18    #[error("bucket size must be nonzero")]
19    InvalidBucketSize,
20    /// Explicit policy differs from the actual durable setting.
21    #[error("persisted bucket size {persisted} pages differs from requested {requested}")]
22    BucketSizeMismatch { persisted: u16, requested: u16 },
23    /// Persisted manager metadata failed bounded validation.
24    #[error(transparent)]
25    Layout(#[from] super::MemoryManagerLayoutError),
26    /// Nonempty backing memory does not contain a `MemoryManager` header.
27    #[error(
28        "nonempty backing memory is not an ic-stable-structures MemoryManager \
29         (expected magic 'MGR', found bytes {observed_magic:?})"
30    )]
31    ForeignMemory {
32        /// First three bytes found in the nonempty backing memory.
33        observed_magic: [u8; 3],
34    },
35    /// Backing memory contains an unsupported `MemoryManager` layout version.
36    #[error(
37        "unsupported ic-stable-structures MemoryManager layout version {observed}; \
38         expected {supported}"
39    )]
40    UnsupportedMemoryManagerVersion {
41        /// Version byte found after the `MemoryManager` magic.
42        observed: u8,
43        /// Version supported by the pinned `ic-stable-structures` dependency.
44        supported: u8,
45    },
46}
47
48///
49/// RuntimeStateError
50///
51/// Failure to enter or maintain one memory runtime's in-memory lifecycle.
52///
53
54#[non_exhaustive]
55#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
56pub enum RuntimeStateError {
57    /// This thread's default runtime could not safely claim its backing memory.
58    #[error(transparent)]
59    Construction(#[from] RuntimeConstructionError),
60    /// A default-runtime operation re-entered while that TLS runtime was borrowed.
61    #[error("ic-memory default runtime is already borrowed by an active operation")]
62    ReentrantAccess,
63    /// The thread-local default runtime is being destroyed and cannot be entered.
64    #[error("ic-memory default runtime is unavailable during thread-local destruction")]
65    Unavailable,
66    /// Internal runtime lifecycle state was inconsistent.
67    #[error("ic-memory runtime lifecycle is internally inconsistent")]
68    InconsistentLifecycle,
69}
70
71///
72/// RuntimeBootstrapError
73///
74/// Failure to bootstrap one `MemoryRuntime`.
75///
76
77#[non_exhaustive]
78#[derive(Debug, thiserror::Error)]
79pub enum RuntimeBootstrapError<P> {
80    /// A known-only historical selection failed before commitment.
81    #[error(transparent)]
82    Admission(#[from] super::BootstrapAdmissionError),
83    /// Consumer identity or key-set admission rejected this attempt.
84    #[error("bootstrap admission policy rejected recovered allocation metadata")]
85    AdmissionPolicy(P),
86    #[error(transparent)]
87    Resolution(#[from] MemoryResolutionError),
88    /// The policy did not provide a valid bounded semantic identity.
89    #[error(transparent)]
90    PolicyIdentity(#[from] PolicyIdentityError),
91    /// A bootstrapped runtime was called with a different declaration snapshot.
92    #[error("runtime bootstrap declaration snapshot differs from the established binding")]
93    DeclarationSnapshotMismatch,
94    /// A bootstrapped runtime was called with a different policy identity.
95    #[error("runtime bootstrap policy identity changed from {established:?} to {requested:?}")]
96    PolicyIdentityMismatch {
97        /// Policy identity established by successful bootstrap.
98        established: PolicyIdentity,
99        /// Policy identity supplied by the repeated call.
100        requested: PolicyIdentity,
101    },
102    /// Linked-program declaration snapshot sealing failed.
103    #[error(transparent)]
104    Registry(#[from] StaticMemoryDeclarationError),
105    /// Runtime ledger genesis construction failed.
106    #[error(transparent)]
107    LedgerIntegrity(#[from] crate::LedgerIntegrityError),
108    /// Protected ledger recovery or commit failed.
109    #[error(transparent)]
110    LedgerCommit(#[from] crate::LedgerCommitError),
111    /// Stable-cell ledger storage is corrupt before protected recovery can run.
112    #[error(transparent)]
113    StableCellLedger(#[from] StableCellLedgerError),
114    /// Stable-cell ledger storage cannot fit the next protected ledger record.
115    #[error("stable-cell ledger record size {value_size} cannot be written to stable memory")]
116    StableCellLedgerWriteTooLarge {
117        /// Encoded stable-cell ledger record size in bytes.
118        value_size: usize,
119    },
120    /// Declaration validation failed.
121    #[error(transparent)]
122    Validation(#[from] crate::AllocationValidationError<RuntimePolicyError<P>>),
123    /// Validated declarations could not be staged.
124    #[error(transparent)]
125    Staging(#[from] crate::AllocationStageError),
126    /// Runtime lifecycle or default TLS access failed.
127    #[error(transparent)]
128    State(#[from] RuntimeStateError),
129}
130
131///
132/// RuntimeOpenError
133///
134/// Failure to open an allocation through one memory runtime.
135///
136
137#[non_exhaustive]
138#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
139pub enum RuntimeOpenError {
140    /// This runtime has not published committed allocations.
141    #[error("ic-memory runtime has not completed bootstrap validation")]
142    NotBootstrapped,
143    /// Runtime lifecycle or default TLS access failed.
144    #[error(transparent)]
145    State(#[from] RuntimeStateError),
146    /// Stable-key grammar failure.
147    #[error(transparent)]
148    StableKey(#[from] crate::StableKeyError),
149    /// The stable key was not present in this runtime's committed declaration set.
150    #[error("stable key '{0}' was not committed by ic-memory runtime bootstrap")]
151    StableKeyNotCommitted(String),
152    /// Runtime governance stable keys are internal and cannot be opened publicly.
153    #[error("stable key '{stable_key}' is reserved for ic-memory runtime governance")]
154    ReservedStableKey {
155        /// Reserved stable key.
156        stable_key: String,
157    },
158    /// The committed slot is not a usable `MemoryManager` ID.
159    #[error(transparent)]
160    MemoryManagerSlot(#[from] MemoryManagerSlotError),
161    /// The requested memory ID does not match the committed stable-key binding.
162    #[error(
163        "stable key '{stable_key}' is committed for MemoryManager ID {committed_id}, not requested ID {requested_id}"
164    )]
165    MemoryIdMismatch {
166        /// Stable key being opened.
167        stable_key: String,
168        /// Committed MemoryManager ID.
169        committed_id: u8,
170        /// Requested MemoryManager ID.
171        requested_id: u8,
172    },
173}
174
175///
176/// RuntimeDiagnosticError
177///
178/// Failure to build diagnostics for one memory runtime.
179///
180
181#[non_exhaustive]
182#[derive(Debug, thiserror::Error)]
183pub enum RuntimeDiagnosticError {
184    /// Persisted manager metadata is invalid or unsupported.
185    #[error(transparent)]
186    Construction(#[from] RuntimeConstructionError),
187    /// Current binding metadata exceeds the fixed usable ID domain.
188    #[error("allocation bindings exceed the bounded manager domain")]
189    AllocationBound,
190    /// This runtime has not opened and validated its ledger cell.
191    #[error("ic-memory runtime has not completed bootstrap validation")]
192    NotBootstrapped,
193    /// Linked-program declaration snapshot sealing failed.
194    #[error(transparent)]
195    Registry(#[from] StaticMemoryDeclarationError),
196    /// Runtime lifecycle or default TLS access failed.
197    #[error(transparent)]
198    State(#[from] RuntimeStateError),
199    /// The recovered allocation ledger failed protected commit validation.
200    #[error(transparent)]
201    LedgerCommit(#[from] LedgerCommitError),
202    /// Stable-cell ledger storage is corrupt before protected recovery can run.
203    #[error(transparent)]
204    StableCellLedger(#[from] StableCellLedgerError),
205    /// A committed allocation slot was not a usable `MemoryManager` ID.
206    #[error(transparent)]
207    MemoryManagerSlot(#[from] MemoryManagerSlotError),
208}
209
210///
211/// RuntimePolicyError
212///
213/// Failure in generic runtime range policy or caller-supplied policy.
214///
215
216#[non_exhaustive]
217#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
218pub enum RuntimePolicyError<P> {
219    /// Runtime range authority rejected the declaration.
220    #[error(transparent)]
221    Range(#[from] MemoryManagerRangeAuthorityError),
222    /// Runtime metadata is internally inconsistent.
223    #[error("runtime declaration metadata is missing for stable key '{0}'")]
224    MissingDeclarationMetadata(String),
225    /// `ic_memory.*` stable keys are reserved to the `ic-memory` authority.
226    #[error("stable key '{stable_key}' is reserved to authority '{expected_authority}'")]
227    ReservedStableKeyAuthority {
228        /// Stable key being declared.
229        stable_key: String,
230        /// Required declaring authority.
231        expected_authority: &'static str,
232    },
233    /// Caller-supplied policy rejected the declaration.
234    #[error(transparent)]
235    Custom(P),
236}
237
238///
239/// MemoryResolutionError
240///
241/// Logical placement failed before publishing allocation authority.
242///
243
244#[non_exhaustive]
245#[derive(Debug, thiserror::Error)]
246pub enum MemoryResolutionError {
247    #[error("no eligible free slot for {stable_key} under authority {authority}")]
248    Exhausted {
249        stable_key: crate::StableKey,
250        authority: String,
251    },
252    #[error(transparent)]
253    Range(#[from] crate::MemoryManagerRangeAuthorityError),
254    #[error(transparent)]
255    Registry(#[from] StaticMemoryDeclarationError),
256    #[error(transparent)]
257    Declaration(#[from] crate::DeclarationSnapshotError),
258}