reth_db_api/models/
storage_sharded_key.rs

1//! Storage sharded key
2use crate::{
3    table::{Decode, Encode},
4    DatabaseError,
5};
6use alloy_primitives::{Address, BlockNumber, B256};
7use derive_more::AsRef;
8use serde::{Deserialize, Serialize};
9
10use super::ShardedKey;
11
12/// Number of indices in one shard.
13pub const NUM_OF_INDICES_IN_SHARD: usize = 2_000;
14
15/// The size of [`StorageShardedKey`] encode bytes.
16/// The fields are: 20-byte address, 32-byte key, and 8-byte block number
17const STORAGE_SHARD_KEY_BYTES_SIZE: usize = 20 + 32 + 8;
18
19/// Sometimes data can be too big to be saved for a single key. This helps out by dividing the data
20/// into different shards. Example:
21///
22/// `Address | StorageKey | 200` -> data is from transition 0 to 200.
23///
24/// `Address | StorageKey | 300` -> data is from transition 201 to 300.
25#[derive(
26    Debug, Default, Clone, Eq, Ord, PartialOrd, PartialEq, AsRef, Serialize, Deserialize, Hash,
27)]
28pub struct StorageShardedKey {
29    /// Storage account address.
30    pub address: Address,
31    /// Storage slot with highest transition id.
32    #[as_ref]
33    pub sharded_key: ShardedKey<B256>,
34}
35
36impl StorageShardedKey {
37    /// Creates a new `StorageShardedKey`.
38    pub const fn new(
39        address: Address,
40        storage_key: B256,
41        highest_block_number: BlockNumber,
42    ) -> Self {
43        Self { address, sharded_key: ShardedKey { key: storage_key, highest_block_number } }
44    }
45
46    /// Creates a new key with the highest block number set to maximum.
47    /// This is useful when we want to search the last value for a given key.
48    pub const fn last(address: Address, storage_key: B256) -> Self {
49        Self {
50            address,
51            sharded_key: ShardedKey { key: storage_key, highest_block_number: u64::MAX },
52        }
53    }
54}
55
56impl Encode for StorageShardedKey {
57    type Encoded = Vec<u8>;
58
59    fn encode(self) -> Self::Encoded {
60        let mut buf: Vec<u8> = Vec::with_capacity(STORAGE_SHARD_KEY_BYTES_SIZE);
61        buf.extend_from_slice(&Encode::encode(self.address));
62        buf.extend_from_slice(&Encode::encode(self.sharded_key.key));
63        buf.extend_from_slice(&self.sharded_key.highest_block_number.to_be_bytes());
64        buf
65    }
66}
67
68impl Decode for StorageShardedKey {
69    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
70        if value.len() != STORAGE_SHARD_KEY_BYTES_SIZE {
71            return Err(DatabaseError::Decode)
72        }
73        let tx_num_index = value.len() - 8;
74
75        let highest_tx_number = u64::from_be_bytes(
76            value[tx_num_index..].try_into().map_err(|_| DatabaseError::Decode)?,
77        );
78        let address = Address::decode(&value[..20])?;
79        let storage_key = B256::decode(&value[20..52])?;
80
81        Ok(Self { address, sharded_key: ShardedKey::new(storage_key, highest_tx_number) })
82    }
83}