reth_db_api/models/
sharded_key.rs1use crate::{
3 table::{Decode, Encode},
4 DatabaseError,
5};
6use alloy_primitives::{Address, BlockNumber};
7use serde::{Deserialize, Serialize};
8use std::hash::Hash;
9
10pub const NUM_OF_INDICES_IN_SHARD: usize = 2_000;
12
13const BLOCK_NUMBER_SIZE: usize = std::mem::size_of::<BlockNumber>();
15
16#[derive(Debug, Default, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
23pub struct ShardedKey<T> {
24 pub key: T,
26 pub highest_block_number: BlockNumber,
28}
29
30impl<T> AsRef<Self> for ShardedKey<T> {
31 fn as_ref(&self) -> &Self {
32 self
33 }
34}
35
36impl<T> ShardedKey<T> {
37 pub const fn new(key: T, highest_block_number: BlockNumber) -> Self {
39 Self { key, highest_block_number }
40 }
41
42 pub const fn last(key: T) -> Self {
45 Self { key, highest_block_number: u64::MAX }
46 }
47}
48
49pub type ShardedKeyAddressEncoded = [u8; 20 + BLOCK_NUMBER_SIZE];
55
56impl Encode for ShardedKey<Address> {
57 type Encoded = ShardedKeyAddressEncoded;
58
59 #[inline]
60 fn encode(self) -> Self::Encoded {
61 let mut buf = [0u8; 20 + BLOCK_NUMBER_SIZE];
62 buf[..20].copy_from_slice(self.key.as_slice());
63 buf[20..].copy_from_slice(&self.highest_block_number.to_be_bytes());
64 buf
65 }
66}
67
68impl Decode for ShardedKey<Address> {
69 fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
70 if value.len() != 20 + BLOCK_NUMBER_SIZE {
71 return Err(DatabaseError::Decode);
72 }
73 let key = Address::from_slice(&value[..20]);
74 let highest_block_number =
75 u64::from_be_bytes(value[20..].try_into().map_err(|_| DatabaseError::Decode)?);
76 Ok(Self::new(key, highest_block_number))
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83 use alloy_primitives::address;
84
85 #[test]
86 fn sharded_key_address_encode_decode_roundtrip() {
87 let addr = address!("0102030405060708091011121314151617181920");
88 let block_num = 0x123456789ABCDEF0u64;
89 let key = ShardedKey::new(addr, block_num);
90
91 let encoded = key.encode();
92
93 assert_eq!(encoded.len(), 28);
95 assert_eq!(std::mem::size_of_val(&encoded), 28);
96
97 let decoded = ShardedKey::<Address>::decode(&encoded).unwrap();
99 assert_eq!(decoded.key, address!("0102030405060708091011121314151617181920"));
100 assert_eq!(decoded.highest_block_number, 0x123456789ABCDEF0u64);
101 }
102
103 #[test]
104 fn sharded_key_last_works() {
105 let addr = address!("0102030405060708091011121314151617181920");
106 let key = ShardedKey::<Address>::last(addr);
107 assert_eq!(key.highest_block_number, u64::MAX);
108
109 let encoded = key.encode();
110 let decoded = ShardedKey::<Address>::decode(&encoded).unwrap();
111 assert_eq!(decoded.highest_block_number, u64::MAX);
112 }
113}