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