Skip to main content

ic_memory/
session.rs

1use crate::{
2    declaration::AllocationDeclaration, key::StableKey, slot::AllocationSlotDescriptor,
3    substrate::StorageSubstrate,
4};
5use serde::{Deserialize, Serialize};
6
7///
8/// ValidatedAllocations
9///
10/// Allocation declarations accepted by policy and historical ledger validation.
11///
12/// This value is produced by [`crate::validate_allocations`] and is the bridge
13/// between declaration validation and opening storage. It is not a durable
14/// ledger record; staging commits it into the next generation before an
15/// integration should expose memory handles.
16///
17
18#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
19pub struct ValidatedAllocations {
20    /// Committed generation that validated these allocations.
21    generation: u64,
22    /// Validated declarations.
23    declarations: Vec<AllocationDeclaration>,
24    /// Optional binary/runtime identity for generation diagnostics.
25    runtime_fingerprint: Option<String>,
26}
27
28impl ValidatedAllocations {
29    pub(crate) const fn new(
30        generation: u64,
31        declarations: Vec<AllocationDeclaration>,
32        runtime_fingerprint: Option<String>,
33    ) -> Self {
34        Self {
35            generation,
36            declarations,
37            runtime_fingerprint,
38        }
39    }
40
41    pub(crate) const fn with_generation(mut self, generation: u64) -> Self {
42        self.generation = generation;
43        self
44    }
45
46    /// Return the committed generation that validated these allocations.
47    #[must_use]
48    pub const fn generation(&self) -> u64 {
49        self.generation
50    }
51
52    /// Borrow the validated declarations.
53    #[must_use]
54    pub fn declarations(&self) -> &[AllocationDeclaration] {
55        &self.declarations
56    }
57
58    /// Borrow the optional runtime fingerprint.
59    #[must_use]
60    pub fn runtime_fingerprint(&self) -> Option<&str> {
61        self.runtime_fingerprint.as_deref()
62    }
63
64    /// Find a validated slot by stable key.
65    #[must_use]
66    pub fn slot_for(&self, key: &StableKey) -> Option<&AllocationSlotDescriptor> {
67        self.declarations
68            .iter()
69            .find(|declaration| &declaration.stable_key == key)
70            .map(|declaration| &declaration.slot)
71    }
72}
73
74///
75/// AllocationSession
76///
77/// Validated capability required before opening allocation slots.
78///
79/// Integrations should construct sessions only after recovering the ledger,
80/// validating declarations, and committing the next generation. Opening storage
81/// through this type keeps handle creation tied to the validated stable-key
82/// snapshot.
83pub struct AllocationSession<S: StorageSubstrate> {
84    substrate: S,
85    validated: ValidatedAllocations,
86}
87
88impl<S: StorageSubstrate> AllocationSession<S> {
89    /// Construct a session from a substrate and validated allocation set.
90    #[must_use]
91    pub const fn new(substrate: S, validated: ValidatedAllocations) -> Self {
92        Self {
93            substrate,
94            validated,
95        }
96    }
97
98    /// Borrow the validated allocation set.
99    #[must_use]
100    pub const fn validated(&self) -> &ValidatedAllocations {
101        &self.validated
102    }
103
104    /// Open an allocation by stable key.
105    pub fn open(
106        &self,
107        key: &StableKey,
108    ) -> Result<S::MemoryHandle, AllocationSessionError<S::Error>> {
109        let slot = self
110            .validated
111            .slot_for(key)
112            .ok_or_else(|| AllocationSessionError::UnknownStableKey(key.clone()))?;
113        self.substrate
114            .open_slot(slot)
115            .map_err(AllocationSessionError::Substrate)
116    }
117}
118
119///
120/// AllocationSessionError
121///
122/// Failure to open through a validated allocation session.
123#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
124pub enum AllocationSessionError<E> {
125    /// Stable key was not part of the validated allocation snapshot.
126    #[error("stable key '{0}' was not validated for this allocation session")]
127    UnknownStableKey(StableKey),
128    /// Storage substrate failed to open the validated slot.
129    #[error("storage substrate failed to open allocation slot")]
130    Substrate(E),
131}