Skip to main content

miden_protocol/account/storage/slot/
storage_slot.rs

1use crate::Word;
2use crate::account::storage::slot::StorageSlotId;
3use crate::account::{StorageMap, StorageSlotContent, StorageSlotName, StorageSlotType};
4
5/// An individual storage slot in [`AccountStorage`](crate::account::AccountStorage).
6///
7/// This consists of a [`StorageSlotName`] that uniquely identifies the slot and its
8/// [`StorageSlotContent`].
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct StorageSlot {
11    /// The name of the storage slot.
12    name: StorageSlotName,
13    /// The content of the storage slot.
14    content: StorageSlotContent,
15}
16
17impl StorageSlot {
18    // CONSTANTS
19    // --------------------------------------------------------------------------------------------
20
21    /// The number of field elements that represent a [`StorageSlot`] in kernel memory.
22    pub const NUM_ELEMENTS: usize = 8;
23
24    // CONSTRUCTORS
25    // --------------------------------------------------------------------------------------------
26
27    /// Creates a new [`StorageSlot`] with the given [`StorageSlotName`] and
28    /// [`StorageSlotContent`].
29    pub fn new(name: StorageSlotName, content: StorageSlotContent) -> Self {
30        Self { name, content }
31    }
32
33    /// Creates a new [`StorageSlot`] with the given [`StorageSlotName`] and the `value`
34    /// wrapped into a [`StorageSlotContent::Value`].
35    pub fn with_value(name: StorageSlotName, value: Word) -> Self {
36        Self::new(name, StorageSlotContent::Value(value))
37    }
38
39    /// Creates a new [`StorageSlot`] with the given [`StorageSlotName`] and
40    /// [`StorageSlotContent::empty_value`].
41    pub fn with_empty_value(name: StorageSlotName) -> Self {
42        Self::new(name, StorageSlotContent::empty_value())
43    }
44
45    /// Creates a new [`StorageSlot`] with the given [`StorageSlotName`] and the `map` wrapped
46    /// into a [`StorageSlotContent::Map`]
47    pub fn with_map(name: StorageSlotName, map: StorageMap) -> Self {
48        Self::new(name, StorageSlotContent::Map(map))
49    }
50
51    /// Creates a new [`StorageSlot`] with the given [`StorageSlotName`] and
52    /// [`StorageSlotContent::empty_map`].
53    pub fn with_empty_map(name: StorageSlotName) -> Self {
54        Self::new(name, StorageSlotContent::empty_map())
55    }
56
57    // ACCESSORS
58    // --------------------------------------------------------------------------------------------
59
60    /// Returns the [`StorageSlotName`] by which the [`StorageSlot`] is identified.
61    pub fn name(&self) -> &StorageSlotName {
62        &self.name
63    }
64
65    /// Returns the [`StorageSlotId`] by which the [`StorageSlot`] is identified.
66    pub fn id(&self) -> StorageSlotId {
67        self.name.id()
68    }
69
70    /// Returns this storage slot value as a [Word]
71    ///
72    /// Returns:
73    /// - For [`StorageSlotContent::Value`] the value.
74    /// - For [`StorageSlotContent::Map`] the root of the [StorageMap].
75    pub fn value(&self) -> Word {
76        self.content().value()
77    }
78
79    /// Returns a reference to the [`StorageSlotContent`] contained in this [`StorageSlot`].
80    pub fn content(&self) -> &StorageSlotContent {
81        &self.content
82    }
83
84    /// Returns the [`StorageSlotType`] of this [`StorageSlot`].
85    pub fn slot_type(&self) -> StorageSlotType {
86        self.content.slot_type()
87    }
88
89    // MUTATORS
90    // --------------------------------------------------------------------------------------------
91
92    /// Returns a mutable reference to the [`StorageSlotContent`] contained in this
93    /// [`StorageSlot`].
94    pub fn content_mut(&mut self) -> &mut StorageSlotContent {
95        &mut self.content
96    }
97
98    /// Consumes self and returns the underlying parts.
99    pub fn into_parts(self) -> (StorageSlotName, StorageSlotContent) {
100        (self.name, self.content)
101    }
102}
103
104impl Ord for StorageSlot {
105    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
106        self.name().cmp(&other.name)
107    }
108}
109
110impl PartialOrd for StorageSlot {
111    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
112        Some(self.cmp(other))
113    }
114}
115
116// SERIALIZATION
117// ================================================================================================
118
119impl crate::utils::serde::Serializable for StorageSlot {
120    fn write_into<W: crate::utils::serde::ByteWriter>(&self, target: &mut W) {
121        target.write(&self.name);
122        target.write(&self.content);
123    }
124
125    fn get_size_hint(&self) -> usize {
126        self.name.get_size_hint() + self.content().get_size_hint()
127    }
128}
129
130impl crate::utils::serde::Deserializable for StorageSlot {
131    fn read_from<R: miden_core::utils::ByteReader>(
132        source: &mut R,
133    ) -> Result<Self, crate::utils::serde::DeserializationError> {
134        let name: StorageSlotName = source.read()?;
135        let content: StorageSlotContent = source.read()?;
136
137        Ok(Self::new(name, content))
138    }
139}