Skip to main content

ic_memory/runtime/
error.rs

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