reth_db_models/
storage.rs

1use alloy_primitives::{Address, B256, U256};
2use reth_primitives_traits::ValueWithSubKey;
3
4/// Storage entry as it is saved in the static files.
5///
6/// [`B256`] is the subkey.
7#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
8#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(compact))]
11pub struct StorageBeforeTx {
12    /// Address for the storage entry. Acts as `DupSort::SubKey` in static files.
13    pub address: Address,
14    /// Storage key.
15    pub key: B256,
16    /// Value on storage key.
17    pub value: U256,
18}
19
20impl ValueWithSubKey for StorageBeforeTx {
21    type SubKey = B256;
22
23    fn get_subkey(&self) -> Self::SubKey {
24        self.key
25    }
26}
27
28// NOTE: Removing reth_codec and manually encode subkey
29// and compress second part of the value. If we have compression
30// over whole value (Even SubKey) that would mess up fetching of values with seek_by_key_subkey
31#[cfg(any(test, feature = "reth-codec"))]
32impl reth_codecs::Compact for StorageBeforeTx {
33    fn to_compact<B>(&self, buf: &mut B) -> usize
34    where
35        B: bytes::BufMut + AsMut<[u8]>,
36    {
37        buf.put_slice(self.address.as_slice());
38        buf.put_slice(&self.key[..]);
39        self.value.to_compact(buf) + 52
40    }
41
42    fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) {
43        let address = Address::from_slice(&buf[..20]);
44        let key = B256::from_slice(&buf[20..52]);
45        let (value, out) = U256::from_compact(&buf[52..], len - 52);
46        (Self { address, key, value }, out)
47    }
48}