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    /// The policy did not provide a valid bounded semantic identity.
81    #[error(transparent)]
82    PolicyIdentity(#[from] PolicyIdentityError),
83    /// A bootstrapped runtime was called with a different declaration snapshot.
84    #[error("runtime bootstrap declaration snapshot differs from the established binding")]
85    DeclarationSnapshotMismatch,
86    /// A bootstrapped runtime was called with a different policy identity.
87    #[error("runtime bootstrap policy identity changed from {established:?} to {requested:?}")]
88    PolicyIdentityMismatch {
89        /// Policy identity established by successful bootstrap.
90        established: PolicyIdentity,
91        /// Policy identity supplied by the repeated call.
92        requested: PolicyIdentity,
93    },
94    /// Linked-program declaration snapshot sealing failed.
95    #[error(transparent)]
96    Registry(#[from] StaticMemoryDeclarationError),
97    /// Runtime ledger genesis construction failed.
98    #[error(transparent)]
99    LedgerIntegrity(#[from] crate::LedgerIntegrityError),
100    /// Protected ledger recovery or commit failed.
101    #[error(transparent)]
102    LedgerCommit(#[from] crate::LedgerCommitError),
103    /// Stable-cell ledger storage is corrupt before protected recovery can run.
104    #[error(transparent)]
105    StableCellLedger(#[from] StableCellLedgerError),
106    /// Stable-cell ledger storage cannot fit the next protected ledger record.
107    #[error("stable-cell ledger record size {value_size} cannot be written to stable memory")]
108    StableCellLedgerWriteTooLarge {
109        /// Encoded stable-cell ledger record size in bytes.
110        value_size: usize,
111    },
112    /// Declaration validation failed.
113    #[error(transparent)]
114    Validation(#[from] crate::AllocationValidationError<RuntimePolicyError<P>>),
115    /// Validated declarations could not be staged.
116    #[error(transparent)]
117    Staging(#[from] crate::AllocationStageError),
118    /// Runtime lifecycle or default TLS access failed.
119    #[error(transparent)]
120    State(#[from] RuntimeStateError),
121}
122
123///
124/// RuntimeOpenError
125///
126/// Failure to open an allocation through one memory runtime.
127///
128
129#[non_exhaustive]
130#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
131pub enum RuntimeOpenError {
132    /// This runtime has not published committed allocations.
133    #[error("ic-memory runtime has not completed bootstrap validation")]
134    NotBootstrapped,
135    /// Runtime lifecycle or default TLS access failed.
136    #[error(transparent)]
137    State(#[from] RuntimeStateError),
138    /// Stable-key grammar failure.
139    #[error(transparent)]
140    StableKey(#[from] crate::StableKeyError),
141    /// The stable key was not present in this runtime's committed declaration set.
142    #[error("stable key '{0}' was not committed by ic-memory runtime bootstrap")]
143    StableKeyNotCommitted(String),
144    /// Runtime governance stable keys are internal and cannot be opened publicly.
145    #[error("stable key '{stable_key}' is reserved for ic-memory runtime governance")]
146    ReservedStableKey {
147        /// Reserved stable key.
148        stable_key: String,
149    },
150    /// The committed slot is not a usable `MemoryManager` ID.
151    #[error(transparent)]
152    MemoryManagerSlot(#[from] MemoryManagerSlotError),
153    /// The requested memory ID does not match the committed stable-key binding.
154    #[error(
155        "stable key '{stable_key}' is committed for MemoryManager ID {committed_id}, not requested ID {requested_id}"
156    )]
157    MemoryIdMismatch {
158        /// Stable key being opened.
159        stable_key: String,
160        /// Committed MemoryManager ID.
161        committed_id: u8,
162        /// Requested MemoryManager ID.
163        requested_id: u8,
164    },
165}
166
167///
168/// RuntimeDiagnosticError
169///
170/// Failure to build diagnostics for one memory runtime.
171///
172
173#[non_exhaustive]
174#[derive(Debug, thiserror::Error)]
175pub enum RuntimeDiagnosticError {
176    /// Persisted manager metadata is invalid or unsupported.
177    #[error(transparent)]
178    Construction(#[from] RuntimeConstructionError),
179    /// Current binding metadata exceeds the fixed usable ID domain.
180    #[error("allocation bindings exceed the bounded manager domain")]
181    AllocationBound,
182    /// This runtime has not opened and validated its ledger cell.
183    #[error("ic-memory runtime has not completed bootstrap validation")]
184    NotBootstrapped,
185    /// Linked-program declaration snapshot sealing failed.
186    #[error(transparent)]
187    Registry(#[from] StaticMemoryDeclarationError),
188    /// Runtime lifecycle or default TLS access failed.
189    #[error(transparent)]
190    State(#[from] RuntimeStateError),
191    /// The recovered allocation ledger failed protected commit validation.
192    #[error(transparent)]
193    LedgerCommit(#[from] LedgerCommitError),
194    /// Stable-cell ledger storage is corrupt before protected recovery can run.
195    #[error(transparent)]
196    StableCellLedger(#[from] StableCellLedgerError),
197    /// A committed allocation slot was not a usable `MemoryManager` ID.
198    #[error(transparent)]
199    MemoryManagerSlot(#[from] MemoryManagerSlotError),
200}
201
202///
203/// RuntimePolicyError
204///
205/// Failure in generic runtime range policy or caller-supplied policy.
206///
207
208#[non_exhaustive]
209#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
210pub enum RuntimePolicyError<P> {
211    /// Runtime range authority rejected the declaration.
212    #[error(transparent)]
213    Range(#[from] MemoryManagerRangeAuthorityError),
214    /// Runtime metadata is internally inconsistent.
215    #[error("runtime declaration metadata is missing for stable key '{0}'")]
216    MissingDeclarationMetadata(String),
217    /// `ic_memory.*` stable keys are reserved to the `ic-memory` authority.
218    #[error("stable key '{stable_key}' is reserved to authority '{expected_authority}'")]
219    ReservedStableKeyAuthority {
220        /// Stable key being declared.
221        stable_key: String,
222        /// Required declaring authority.
223        expected_authority: &'static str,
224    },
225    /// Caller-supplied policy rejected the declaration.
226    #[error(transparent)]
227    Custom(P),
228}