Skip to main content

ic_memory/runtime/
error.rs

1use crate::{
2    LedgerCommitError, 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    /// Nonempty backing memory does not contain a `MemoryManager` header.
18    #[error(
19        "nonempty backing memory is not an ic-stable-structures MemoryManager \
20         (expected magic 'MGR', found bytes {observed_magic:?})"
21    )]
22    ForeignMemory {
23        /// First three bytes found in the nonempty backing memory.
24        observed_magic: [u8; 3],
25    },
26    /// Backing memory contains an unsupported `MemoryManager` layout version.
27    #[error(
28        "unsupported ic-stable-structures MemoryManager layout version {observed}; \
29         expected {supported}"
30    )]
31    UnsupportedMemoryManagerVersion {
32        /// Version byte found after the `MemoryManager` magic.
33        observed: u8,
34        /// Version supported by the pinned `ic-stable-structures` dependency.
35        supported: u8,
36    },
37}
38
39///
40/// RuntimeStateError
41///
42/// Failure to enter or maintain one memory runtime's in-memory lifecycle.
43///
44
45#[non_exhaustive]
46#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
47pub enum RuntimeStateError {
48    /// This thread's default runtime could not safely claim its backing memory.
49    #[error(transparent)]
50    Construction(#[from] RuntimeConstructionError),
51    /// A default-runtime operation re-entered while that TLS runtime was borrowed.
52    #[error("ic-memory default runtime is already borrowed by an active operation")]
53    ReentrantAccess,
54    /// The thread-local default runtime is being destroyed and cannot be entered.
55    #[error("ic-memory default runtime is unavailable during thread-local destruction")]
56    Unavailable,
57    /// Internal runtime lifecycle state was inconsistent.
58    #[error("ic-memory runtime lifecycle is internally inconsistent")]
59    InconsistentLifecycle,
60}
61
62///
63/// RuntimeBootstrapError
64///
65/// Failure to bootstrap one `MemoryRuntime`.
66///
67
68#[non_exhaustive]
69#[derive(Debug, thiserror::Error)]
70pub enum RuntimeBootstrapError<P> {
71    /// The policy did not provide a usable semantic bootstrap identity.
72    #[error("runtime bootstrap policy identity must not be empty")]
73    EmptyPolicyIdentity,
74    /// A bootstrapped runtime was called with a different declaration snapshot.
75    #[error("runtime bootstrap declaration snapshot differs from the established binding")]
76    DeclarationSnapshotMismatch,
77    /// A bootstrapped runtime was called with a different policy identity.
78    #[error("runtime bootstrap policy identity changed from '{established}' to '{requested}'")]
79    PolicyIdentityMismatch {
80        /// Policy identity established by successful bootstrap.
81        established: &'static str,
82        /// Policy identity supplied by the repeated call.
83        requested: &'static str,
84    },
85    /// Linked-program declaration snapshot sealing failed.
86    #[error(transparent)]
87    Registry(#[from] StaticMemoryDeclarationError),
88    /// Runtime ledger genesis construction failed.
89    #[error(transparent)]
90    LedgerIntegrity(#[from] crate::LedgerIntegrityError),
91    /// Protected ledger recovery or commit failed.
92    #[error(transparent)]
93    LedgerCommit(#[from] crate::LedgerCommitError),
94    /// Stable-cell ledger storage is corrupt before protected recovery can run.
95    #[error(transparent)]
96    StableCellLedger(#[from] StableCellLedgerError),
97    /// Stable-cell ledger storage cannot fit the next protected ledger record.
98    #[error("stable-cell ledger record size {value_size} cannot be written to stable memory")]
99    StableCellLedgerWriteTooLarge {
100        /// Encoded stable-cell ledger record size in bytes.
101        value_size: usize,
102    },
103    /// Declaration validation failed.
104    #[error(transparent)]
105    Validation(#[from] crate::AllocationValidationError<RuntimePolicyError<P>>),
106    /// Validated declarations could not be staged.
107    #[error(transparent)]
108    Staging(#[from] crate::AllocationStageError),
109    /// Runtime lifecycle or default TLS access failed.
110    #[error(transparent)]
111    State(#[from] RuntimeStateError),
112}
113
114///
115/// RuntimeOpenError
116///
117/// Failure to open an allocation through one memory runtime.
118///
119
120#[non_exhaustive]
121#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
122pub enum RuntimeOpenError {
123    /// This runtime has not published committed allocations.
124    #[error("ic-memory runtime has not completed bootstrap validation")]
125    NotBootstrapped,
126    /// Runtime lifecycle or default TLS access failed.
127    #[error(transparent)]
128    State(#[from] RuntimeStateError),
129    /// Stable-key grammar failure.
130    #[error(transparent)]
131    StableKey(#[from] crate::StableKeyError),
132    /// The stable key was not present in this runtime's committed declaration set.
133    #[error("stable key '{0}' was not committed by ic-memory runtime bootstrap")]
134    StableKeyNotCommitted(String),
135    /// Runtime governance stable keys are internal and cannot be opened publicly.
136    #[error("stable key '{stable_key}' is reserved for ic-memory runtime governance")]
137    ReservedStableKey {
138        /// Reserved stable key.
139        stable_key: String,
140    },
141    /// The committed slot is not a usable `MemoryManager` ID.
142    #[error(transparent)]
143    MemoryManagerSlot(#[from] MemoryManagerSlotError),
144    /// The requested memory ID does not match the committed stable-key binding.
145    #[error(
146        "stable key '{stable_key}' is committed for MemoryManager ID {committed_id}, not requested ID {requested_id}"
147    )]
148    MemoryIdMismatch {
149        /// Stable key being opened.
150        stable_key: String,
151        /// Committed MemoryManager ID.
152        committed_id: u8,
153        /// Requested MemoryManager ID.
154        requested_id: u8,
155    },
156}
157
158///
159/// RuntimeDiagnosticError
160///
161/// Failure to build diagnostics for one memory runtime.
162///
163
164#[non_exhaustive]
165#[derive(Debug, thiserror::Error)]
166pub enum RuntimeDiagnosticError {
167    /// This runtime has not opened and validated its ledger cell.
168    #[error("ic-memory runtime has not completed bootstrap validation")]
169    NotBootstrapped,
170    /// Linked-program declaration snapshot sealing failed.
171    #[error(transparent)]
172    Registry(#[from] StaticMemoryDeclarationError),
173    /// Runtime lifecycle or default TLS access failed.
174    #[error(transparent)]
175    State(#[from] RuntimeStateError),
176    /// The recovered allocation ledger failed protected commit validation.
177    #[error(transparent)]
178    LedgerCommit(#[from] LedgerCommitError),
179    /// Stable-cell ledger storage is corrupt before protected recovery can run.
180    #[error(transparent)]
181    StableCellLedger(#[from] StableCellLedgerError),
182    /// A committed allocation slot was not a usable `MemoryManager` ID.
183    #[error(transparent)]
184    MemoryManagerSlot(#[from] MemoryManagerSlotError),
185}
186
187///
188/// RuntimePolicyError
189///
190/// Failure in generic runtime range policy or caller-supplied policy.
191///
192
193#[non_exhaustive]
194#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
195pub enum RuntimePolicyError<P> {
196    /// Runtime range authority rejected the declaration.
197    #[error(transparent)]
198    Range(#[from] MemoryManagerRangeAuthorityError),
199    /// Runtime metadata is internally inconsistent.
200    #[error("runtime declaration metadata is missing for stable key '{0}'")]
201    MissingDeclarationMetadata(String),
202    /// `ic_memory.*` stable keys are reserved to the `ic-memory` authority.
203    #[error("stable key '{stable_key}' is reserved to authority '{expected_authority}'")]
204    ReservedStableKeyAuthority {
205        /// Stable key being declared.
206        stable_key: String,
207        /// Required declaring authority.
208        expected_authority: &'static str,
209    },
210    /// Caller-supplied policy rejected the declaration.
211    #[error(transparent)]
212    Custom(P),
213}