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