reth_primitives_traits/
storage.rs

1use alloy_primitives::{B256, U256};
2use revm_state::FlaggedStorage;
3
4/// Account storage entry.
5///
6/// `key` is the subkey when used as a value in the `StorageChangeSets` table.
7#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
10#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(compact))]
11pub struct StorageEntry {
12    /// Storage key.
13    pub key: B256,
14    /// Value on storage key.
15    pub value: FlaggedStorage,
16}
17
18impl StorageEntry {
19    /// Create a new `StorageEntry` with given key and value.
20    pub const fn new(key: B256, value: U256, is_private: bool) -> Self {
21        Self { key, value: FlaggedStorage { value, is_private } }
22    }
23
24    /// Convert the storage entry to a flagged storage entry.
25    pub const fn to_flagged_storage(self) -> FlaggedStorage {
26        self.value
27    }
28}
29
30impl From<(B256, U256, bool)> for StorageEntry {
31    fn from((key, value, is_private): (B256, U256, bool)) -> Self {
32        Self::new(key, value, is_private)
33    }
34}
35
36impl From<(B256, (U256, bool))> for StorageEntry {
37    fn from((key, (value, is_private)): (B256, (U256, bool))) -> Self {
38        Self::new(key, value, is_private)
39    }
40}
41
42impl From<(B256, FlaggedStorage)> for StorageEntry {
43    fn from((key, value): (B256, FlaggedStorage)) -> Self {
44        Self { key, value }
45    }
46}
47
48impl From<StorageEntry> for FlaggedStorage {
49    fn from(entry: StorageEntry) -> Self {
50        entry.value
51    }
52}
53
54// NOTE: Removing reth_codec and manually encode subkey
55// and compress second part of the value. If we have compression
56// over whole value (Even SubKey) that would mess up fetching of values with seek_by_key_subkey
57#[cfg(any(test, feature = "reth-codec"))]
58impl reth_codecs::Compact for StorageEntry {
59    fn to_compact<B>(&self, buf: &mut B) -> usize
60    where
61        B: bytes::BufMut + AsMut<[u8]>,
62    {
63        // for now put full bytes and later compress it.
64        buf.put_slice(&self.key[..]);
65        buf.put_u8(self.value.is_private as u8);
66        self.value.value.to_compact(buf) + 32 + 1
67    }
68
69    fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) {
70        let key = B256::from_slice(&buf[..32]);
71        let is_private = buf[32] != 0;
72        let (value, out) = U256::from_compact(&buf[33..], len - 33);
73        (Self { key, value: FlaggedStorage { value, is_private } }, out)
74    }
75}