reth_db_api/models/
storage_sharded_key.rs1use 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
12pub const NUM_OF_INDICES_IN_SHARD: usize = 2_000;
14
15const STORAGE_SHARD_KEY_BYTES_SIZE: usize = 20 + 32 + 8;
18
19pub type StorageShardedKeyEncoded = [u8; STORAGE_SHARD_KEY_BYTES_SIZE];
26
27#[derive(
34 Debug, Default, Clone, Eq, Ord, PartialOrd, PartialEq, AsRef, Serialize, Deserialize, Hash,
35)]
36pub struct StorageShardedKey {
37 pub address: Address,
39 #[as_ref]
41 pub sharded_key: ShardedKey<B256>,
42}
43
44impl StorageShardedKey {
45 pub const fn new(
47 address: Address,
48 storage_key: B256,
49 highest_block_number: BlockNumber,
50 ) -> Self {
51 Self { address, sharded_key: ShardedKey { key: storage_key, highest_block_number } }
52 }
53
54 pub const fn last(address: Address, storage_key: B256) -> Self {
57 Self {
58 address,
59 sharded_key: ShardedKey { key: storage_key, highest_block_number: u64::MAX },
60 }
61 }
62}
63
64impl Encode for StorageShardedKey {
65 type Encoded = StorageShardedKeyEncoded;
66
67 #[inline]
68 fn encode(self) -> Self::Encoded {
69 let mut buf = [0u8; STORAGE_SHARD_KEY_BYTES_SIZE];
70 buf[..20].copy_from_slice(self.address.as_slice());
71 buf[20..52].copy_from_slice(self.sharded_key.key.as_slice());
72 buf[52..].copy_from_slice(&self.sharded_key.highest_block_number.to_be_bytes());
73 buf
74 }
75}
76
77impl Decode for StorageShardedKey {
78 fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
79 if value.len() != STORAGE_SHARD_KEY_BYTES_SIZE {
80 return Err(DatabaseError::Decode)
81 }
82 let block_num_index = value.len() - 8;
83
84 let highest_block_number = u64::from_be_bytes(
85 value[block_num_index..].try_into().map_err(|_| DatabaseError::Decode)?,
86 );
87 let address = Address::decode(&value[..20])?;
88 let storage_key = B256::decode(&value[20..52])?;
89
90 Ok(Self { address, sharded_key: ShardedKey::new(storage_key, highest_block_number) })
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97 use alloy_primitives::{address, b256};
98
99 #[test]
100 fn storage_sharded_key_encode_decode_roundtrip() {
101 let addr = address!("0102030405060708091011121314151617181920");
102 let storage_key = b256!("0001020304050607080910111213141516171819202122232425262728293031");
103 let block_num = 0x123456789ABCDEFu64;
104 let key = StorageShardedKey::new(addr, storage_key, block_num);
105
106 let encoded = key.encode();
107
108 assert_eq!(encoded.len(), 60);
110 assert_eq!(std::mem::size_of_val(&encoded), 60);
111
112 let decoded = StorageShardedKey::decode(&encoded).unwrap();
114 assert_eq!(decoded.address, address!("0102030405060708091011121314151617181920"));
115 assert_eq!(
116 decoded.sharded_key.key,
117 b256!("0001020304050607080910111213141516171819202122232425262728293031")
118 );
119 assert_eq!(decoded.sharded_key.highest_block_number, 0x123456789ABCDEFu64);
120 }
121
122 #[test]
123 fn storage_sharded_key_last_works() {
124 let addr = address!("0102030405060708091011121314151617181920");
125 let storage_key = b256!("0001020304050607080910111213141516171819202122232425262728293031");
126 let key = StorageShardedKey::last(addr, storage_key);
127 assert_eq!(key.sharded_key.highest_block_number, u64::MAX);
128
129 let encoded = key.encode();
130 let decoded = StorageShardedKey::decode(&encoded).unwrap();
131 assert_eq!(decoded.sharded_key.highest_block_number, u64::MAX);
132 }
133}