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