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