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