reth_db_api/models/
accounts.rs
1use std::ops::{Range, RangeInclusive};
4
5use crate::{
6 impl_fixed_arbitrary,
7 table::{Decode, Encode},
8 DatabaseError,
9};
10use alloy_primitives::{Address, BlockNumber, StorageKey};
11use serde::{Deserialize, Serialize};
12
13#[derive(
17 Debug, Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd, Hash,
18)]
19pub struct BlockNumberAddress(pub (BlockNumber, Address));
20
21impl BlockNumberAddress {
22 pub fn range(range: RangeInclusive<BlockNumber>) -> Range<Self> {
26 (*range.start(), Address::ZERO).into()..(*range.end() + 1, Address::ZERO).into()
27 }
28
29 pub const fn block_number(&self) -> BlockNumber {
31 self.0 .0
32 }
33
34 pub const fn address(&self) -> Address {
36 self.0 .1
37 }
38
39 pub const fn take(self) -> (BlockNumber, Address) {
41 (self.0 .0, self.0 .1)
42 }
43}
44
45impl From<(BlockNumber, Address)> for BlockNumberAddress {
46 fn from(tpl: (u64, Address)) -> Self {
47 Self(tpl)
48 }
49}
50
51impl Encode for BlockNumberAddress {
52 type Encoded = [u8; 28];
53
54 fn encode(self) -> Self::Encoded {
55 let block_number = self.0 .0;
56 let address = self.0 .1;
57
58 let mut buf = [0u8; 28];
59
60 buf[..8].copy_from_slice(&block_number.to_be_bytes());
61 buf[8..].copy_from_slice(address.as_slice());
62 buf
63 }
64}
65
66impl Decode for BlockNumberAddress {
67 fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
68 let num = u64::from_be_bytes(value[..8].try_into().map_err(|_| DatabaseError::Decode)?);
69 let hash = Address::from_slice(&value[8..]);
70 Ok(Self((num, hash)))
71 }
72}
73
74#[derive(
78 Debug, Default, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd, Hash,
79)]
80pub struct AddressStorageKey(pub (Address, StorageKey));
81
82impl Encode for AddressStorageKey {
83 type Encoded = [u8; 52];
84
85 fn encode(self) -> Self::Encoded {
86 let address = self.0 .0;
87 let storage_key = self.0 .1;
88
89 let mut buf = [0u8; 52];
90
91 buf[..20].copy_from_slice(address.as_slice());
92 buf[20..].copy_from_slice(storage_key.as_slice());
93 buf
94 }
95}
96
97impl Decode for AddressStorageKey {
98 fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
99 let address = Address::from_slice(&value[..20]);
100 let storage_key = StorageKey::from_slice(&value[20..]);
101 Ok(Self((address, storage_key)))
102 }
103}
104
105impl_fixed_arbitrary!((BlockNumberAddress, 28), (AddressStorageKey, 52));
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110 use rand::{rng, Rng};
111 use std::str::FromStr;
112
113 #[test]
114 fn test_block_number_address() {
115 let num = 1u64;
116 let hash = Address::from_str("ba5e000000000000000000000000000000000000").unwrap();
117 let key = BlockNumberAddress((num, hash));
118
119 let mut bytes = [0u8; 28];
120 bytes[..8].copy_from_slice(&num.to_be_bytes());
121 bytes[8..].copy_from_slice(hash.as_slice());
122
123 let encoded = Encode::encode(key);
124 assert_eq!(encoded, bytes);
125
126 let decoded: BlockNumberAddress = Decode::decode(&encoded).unwrap();
127 assert_eq!(decoded, key);
128 }
129
130 #[test]
131 fn test_block_number_address_rand() {
132 let mut bytes = [0u8; 28];
133 rng().fill(bytes.as_mut_slice());
134 let key = BlockNumberAddress::arbitrary(&mut Unstructured::new(&bytes)).unwrap();
135 assert_eq!(bytes, Encode::encode(key));
136 }
137
138 #[test]
139 fn test_address_storage_key() {
140 let storage_key = StorageKey::random();
141 let address = Address::from_str("ba5e000000000000000000000000000000000000").unwrap();
142 let key = AddressStorageKey((address, storage_key));
143
144 let mut bytes = [0u8; 52];
145 bytes[..20].copy_from_slice(address.as_slice());
146 bytes[20..].copy_from_slice(storage_key.as_slice());
147
148 let encoded = Encode::encode(key);
149 assert_eq!(encoded, bytes);
150
151 let decoded: AddressStorageKey = Decode::decode(&encoded).unwrap();
152 assert_eq!(decoded, key);
153 }
154
155 #[test]
156 fn test_address_storage_key_rand() {
157 let mut bytes = [0u8; 52];
158 rng().fill(bytes.as_mut_slice());
159 let key = AddressStorageKey::arbitrary(&mut Unstructured::new(&bytes)).unwrap();
160 assert_eq!(bytes, Encode::encode(key));
161 }
162}