sov_state/
lib.rs

1//! Storage and state management interfaces for Sovereign SDK modules.
2
3#![deny(missing_docs)]
4
5pub mod codec;
6
7#[cfg(feature = "native")]
8mod prover_storage;
9
10mod internal_cache;
11
12/// Trait and type definitions related to the [`Storage`] trait.
13pub mod storage;
14mod utils;
15mod witness;
16mod zk_storage;
17
18pub use internal_cache::{OrderedReadsAndWrites, StorageInternalCache};
19#[cfg(feature = "native")]
20pub use prover_storage::ProverStorage;
21pub use storage::Storage;
22pub use zk_storage::ZkStorage;
23
24pub mod config;
25
26use std::fmt::Display;
27use std::str;
28
29pub use sov_first_read_last_write_cache::cache::CacheLog;
30use sov_rollup_interface::digest::Digest;
31pub use utils::AlignedVec;
32
33pub use crate::witness::{ArrayWitness, Witness};
34
35/// A prefix prepended to each key before insertion and retrieval from the storage.
36///
37/// When interacting with state containers, you will usually use the same working set instance to
38/// access them, as required by the module API. This also means that you might get key collisions,
39/// so it becomes necessary to prepend a prefix to each key.
40#[derive(
41    borsh::BorshDeserialize,
42    borsh::BorshSerialize,
43    Debug,
44    PartialEq,
45    Eq,
46    Clone,
47    serde::Serialize,
48    serde::Deserialize,
49)]
50#[cfg_attr(
51    feature = "arbitrary",
52    derive(arbitrary::Arbitrary, proptest_derive::Arbitrary)
53)]
54pub struct Prefix {
55    prefix: AlignedVec,
56}
57
58impl Display for Prefix {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        let buf = self.prefix.as_ref();
61        match str::from_utf8(buf) {
62            Ok(s) => {
63                write!(f, "{:?}", s)
64            }
65            Err(_) => {
66                write!(f, "0x{}", hex::encode(buf))
67            }
68        }
69    }
70}
71
72impl Prefix {
73    /// Creates a new prefix from a byte vector.
74    pub fn new(prefix: Vec<u8>) -> Self {
75        Self {
76            prefix: AlignedVec::new(prefix),
77        }
78    }
79
80    /// Returns a reference to the [`AlignedVec`] containing the prefix.
81    pub fn as_aligned_vec(&self) -> &AlignedVec {
82        &self.prefix
83    }
84
85    /// Returns the length in bytes of the prefix.
86    pub fn len(&self) -> usize {
87        self.prefix.len()
88    }
89
90    /// Returns `true` if the prefix is empty, `false` otherwise.
91    #[must_use]
92    pub fn is_empty(&self) -> bool {
93        self.prefix.is_empty()
94    }
95
96    /// Returns a new prefix allocated on the fly, by extending the current
97    /// prefix with the given bytes.
98    pub fn extended(&self, bytes: &[u8]) -> Self {
99        let mut prefix = self.clone();
100        prefix.extend(bytes.iter().copied());
101        prefix
102    }
103}
104
105impl Extend<u8> for Prefix {
106    fn extend<T: IntoIterator<Item = u8>>(&mut self, iter: T) {
107        self.prefix
108            .extend(&AlignedVec::new(iter.into_iter().collect()))
109    }
110}
111
112/// A trait specifying the hash function and format of the witness used in
113/// merkle proofs for storage access
114pub trait MerkleProofSpec {
115    /// The structure that accumulates the witness data
116    type Witness: Witness + Send + Sync;
117    /// The hash function used to compute the merkle root
118    type Hasher: Digest<OutputSize = sha2::digest::typenum::U32>;
119}
120
121use sha2::Sha256;
122
123/// The default [`MerkleProofSpec`] implementation.
124///
125/// This type is typically found as a type parameter for [`ProverStorage`].
126#[derive(Clone)]
127pub struct DefaultStorageSpec;
128
129impl MerkleProofSpec for DefaultStorageSpec {
130    type Witness = ArrayWitness;
131
132    type Hasher = Sha256;
133}