Skip to main content

ic_memory/slot/
descriptor.rs

1use crate::validation::Validate;
2use serde::{Deserialize, Serialize};
3
4///
5/// AllocationSlot
6///
7/// Durable physical allocation identity interpreted by a storage substrate.
8///
9/// Stable keys are logical identities; allocation slots are the physical
10/// locations those keys are bound to in the ledger.
11#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
12pub enum AllocationSlot {
13    /// `ic-stable-structures::MemoryManager` virtual memory ID.
14    MemoryManagerId(u8),
15    /// Named substrate partition.
16    NamedPartition(String),
17    /// Forward-compatible custom slot descriptor.
18    Custom {
19        /// Substrate-defined slot kind.
20        kind: String,
21        /// Slot descriptor version.
22        version: u32,
23        /// Canonical substrate-defined value.
24        value: Vec<u8>,
25    },
26}
27
28///
29/// AllocationSlotDescriptor
30///
31/// Encoded allocation slot persisted in the ledger.
32///
33/// Constructors for built-in substrates validate their invariants before a
34/// descriptor can be used publicly. For `MemoryManager` slots, use
35/// [`AllocationSlotDescriptor::memory_manager`] so ID 255 is rejected.
36#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
37pub struct AllocationSlotDescriptor {
38    /// Durable allocation slot.
39    pub(crate) slot: AllocationSlot,
40    /// Substrate identifier that interprets the slot.
41    pub(crate) substrate: String,
42    /// Descriptor encoding version.
43    pub(crate) descriptor_version: u32,
44}
45
46impl AllocationSlotDescriptor {
47    /// Return the durable allocation slot value.
48    #[must_use]
49    pub const fn slot(&self) -> &AllocationSlot {
50        &self.slot
51    }
52
53    /// Return the substrate identifier that interprets this slot.
54    #[must_use]
55    pub fn substrate(&self) -> &str {
56        &self.substrate
57    }
58
59    /// Return the descriptor encoding version.
60    #[must_use]
61    pub const fn descriptor_version(&self) -> u32 {
62        self.descriptor_version
63    }
64}
65
66impl Validate for AllocationSlotDescriptor {
67    type Error = AllocationSlotDescriptorError;
68
69    fn validate(&self) -> Result<(), Self::Error> {
70        if matches!(self.slot, AllocationSlot::MemoryManagerId(_))
71            || self.substrate == super::memory_manager::MEMORY_MANAGER_SUBSTRATE
72        {
73            self.memory_manager_id()
74                .map_err(AllocationSlotDescriptorError::MemoryManager)?;
75        }
76
77        Ok(())
78    }
79}
80
81///
82/// AllocationSlotDescriptorError
83///
84/// Allocation slot descriptor validation failure.
85#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
86pub enum AllocationSlotDescriptorError {
87    /// `MemoryManager` descriptor invariants failed.
88    #[error(transparent)]
89    MemoryManager(super::memory_manager::MemoryManagerSlotError),
90}