Skip to main content

ic_memory/runtime/
error.rs

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