1use crate::{
4 table::{Compress, Decode, Decompress, Encode},
5 DatabaseError,
6};
7use alloy_consensus::Header;
8use alloy_genesis::GenesisAccount;
9use alloy_primitives::{Address, Bytes, Log, B256, U256};
10use reth_codecs::{add_arbitrary_tests, Compact};
11use reth_primitives::{Receipt, StorageEntry, TransactionSigned, TxType};
12use reth_primitives_traits::{Account, Bytecode};
13use reth_prune_types::{PruneCheckpoint, PruneSegment};
14use reth_stages_types::StageCheckpoint;
15use reth_trie_common::{StoredNibbles, StoredNibblesSubKey, *};
16use serde::{Deserialize, Serialize};
17
18pub mod accounts;
19pub mod blocks;
20pub mod integer_list;
21pub mod sharded_key;
22pub mod storage_sharded_key;
23
24pub use accounts::*;
25pub use blocks::*;
26pub use integer_list::IntegerList;
27pub use reth_db_models::{
28 AccountBeforeTx, ClientVersion, StoredBlockBodyIndices, StoredBlockWithdrawals,
29};
30pub use sharded_key::ShardedKey;
31
32macro_rules! impl_uints {
34 ($($name:tt),+) => {
35 $(
36 impl Encode for $name {
37 type Encoded = [u8; std::mem::size_of::<$name>()];
38
39 fn encode(self) -> Self::Encoded {
40 self.to_be_bytes()
41 }
42 }
43
44 impl Decode for $name {
45 fn decode(value: &[u8]) -> Result<Self, $crate::DatabaseError> {
46 Ok(
47 $name::from_be_bytes(
48 value.try_into().map_err(|_| $crate::DatabaseError::Decode)?
49 )
50 )
51 }
52 }
53 )+
54 };
55}
56
57impl_uints!(u64, u32, u16, u8);
58
59impl Encode for Vec<u8> {
60 type Encoded = Self;
61
62 fn encode(self) -> Self::Encoded {
63 self
64 }
65}
66
67impl Decode for Vec<u8> {
68 fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
69 Ok(value.to_vec())
70 }
71
72 fn decode_owned(value: Vec<u8>) -> Result<Self, DatabaseError> {
73 Ok(value)
74 }
75}
76
77impl Encode for Address {
78 type Encoded = [u8; 20];
79
80 fn encode(self) -> Self::Encoded {
81 self.0 .0
82 }
83}
84
85impl Decode for Address {
86 fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
87 Ok(Self::from_slice(value))
88 }
89}
90
91impl Encode for B256 {
92 type Encoded = [u8; 32];
93
94 fn encode(self) -> Self::Encoded {
95 self.0
96 }
97}
98
99impl Decode for B256 {
100 fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
101 Ok(Self::new(value.try_into().map_err(|_| DatabaseError::Decode)?))
102 }
103}
104
105impl Encode for String {
106 type Encoded = Vec<u8>;
107
108 fn encode(self) -> Self::Encoded {
109 self.into_bytes()
110 }
111}
112
113impl Decode for String {
114 fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
115 Self::decode_owned(value.to_vec())
116 }
117
118 fn decode_owned(value: Vec<u8>) -> Result<Self, DatabaseError> {
119 Self::from_utf8(value).map_err(|_| DatabaseError::Decode)
120 }
121}
122
123impl Encode for StoredNibbles {
124 type Encoded = Vec<u8>;
125
126 fn encode(self) -> Self::Encoded {
128 self.0.into()
131 }
132}
133
134impl Decode for StoredNibbles {
135 fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
136 Ok(Self::from_compact(value, value.len()).0)
137 }
138}
139
140impl Encode for StoredNibblesSubKey {
141 type Encoded = Vec<u8>;
142
143 fn encode(self) -> Self::Encoded {
145 let mut buf = Vec::with_capacity(65);
146 self.to_compact(&mut buf);
147 buf
148 }
149}
150
151impl Decode for StoredNibblesSubKey {
152 fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
153 Ok(Self::from_compact(value, value.len()).0)
154 }
155}
156
157impl Encode for PruneSegment {
158 type Encoded = [u8; 1];
159
160 fn encode(self) -> Self::Encoded {
161 let mut buf = [0u8];
162 self.to_compact(&mut buf.as_mut());
163 buf
164 }
165}
166
167impl Decode for PruneSegment {
168 fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
169 Ok(Self::from_compact(value, value.len()).0)
170 }
171}
172
173impl Encode for ClientVersion {
174 type Encoded = Vec<u8>;
175
176 fn encode(self) -> Self::Encoded {
178 let mut buf = vec![];
179 self.to_compact(&mut buf);
180 buf
181 }
182}
183
184impl Decode for ClientVersion {
185 fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
186 Ok(Self::from_compact(value, value.len()).0)
187 }
188}
189
190macro_rules! impl_compression_for_compact {
192 ($($name:ident$(<$($generic:ident),*>)?),+) => {
193 $(
194 impl$(<$($generic: core::fmt::Debug + Send + Sync + Compact),*>)? Compress for $name$(<$($generic),*>)? {
195 type Compressed = Vec<u8>;
196
197 fn compress_to_buf<B: bytes::BufMut + AsMut<[u8]>>(self, buf: &mut B) {
198 let _ = Compact::to_compact(&self, buf);
199 }
200 }
201
202 impl$(<$($generic: core::fmt::Debug + Send + Sync + Compact),*>)? Decompress for $name$(<$($generic),*>)? {
203 fn decompress(value: &[u8]) -> Result<$name$(<$($generic),*>)?, $crate::DatabaseError> {
204 let (obj, _) = Compact::from_compact(value, value.len());
205 Ok(obj)
206 }
207 }
208 )+
209 };
210}
211
212impl_compression_for_compact!(
213 Bytes,
214 Header,
215 Account,
216 Log,
217 Receipt,
218 TxType,
219 StorageEntry,
220 BranchNodeCompact,
221 StoredNibbles,
222 StoredNibblesSubKey,
223 StorageTrieEntry,
224 StoredBlockBodyIndices,
225 StoredBlockOmmers<H>,
226 StoredBlockWithdrawals,
227 Bytecode,
228 AccountBeforeTx,
229 TransactionSigned,
230 CompactU256,
231 StageCheckpoint,
232 PruneCheckpoint,
233 ClientVersion,
234 GenesisAccount
236);
237
238macro_rules! impl_compression_fixed_compact {
239 ($($name:tt),+) => {
240 $(
241 impl Compress for $name {
242 type Compressed = Vec<u8>;
243
244 fn uncompressable_ref(&self) -> Option<&[u8]> {
245 Some(self.as_ref())
246 }
247
248 fn compress_to_buf<B: bytes::BufMut + AsMut<[u8]>>(self, buf: &mut B) {
249 let _ = Compact::to_compact(&self, buf);
250 }
251 }
252
253 impl Decompress for $name {
254 fn decompress(value: &[u8]) -> Result<$name, $crate::DatabaseError> {
255 let (obj, _) = Compact::from_compact(&value, value.len());
256 Ok(obj)
257 }
258 }
259
260 )+
261 };
262}
263
264impl_compression_fixed_compact!(B256, Address);
265
266macro_rules! add_wrapper_struct {
269 ($(($name:tt, $wrapper:tt)),+) => {
270 $(
271 #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, Compact)]
273 #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
274 #[add_arbitrary_tests(compact)]
275 pub struct $wrapper(pub $name);
276
277 impl From<$name> for $wrapper {
278 fn from(value: $name) -> Self {
279 $wrapper(value)
280 }
281 }
282
283 impl From<$wrapper> for $name {
284 fn from(value: $wrapper) -> Self {
285 value.0
286 }
287 }
288
289 impl std::ops::Deref for $wrapper {
290 type Target = $name;
291
292 fn deref(&self) -> &Self::Target {
293 &self.0
294 }
295 }
296
297 )+
298 };
299}
300
301add_wrapper_struct!((U256, CompactU256));
302add_wrapper_struct!((u64, CompactU64));
303add_wrapper_struct!((ClientVersion, CompactClientVersion));
304
305#[cfg(test)]
306mod tests {
307 #[cfg(not(feature = "optimism"))]
313 #[test]
314 fn test_ensure_backwards_compatibility() {
315 use super::*;
316 use reth_codecs::{test_utils::UnusedBits, validate_bitflag_backwards_compat};
317 use reth_primitives::{Account, Receipt};
318 use reth_prune_types::{PruneCheckpoint, PruneMode, PruneSegment};
319 use reth_stages_types::{
320 AccountHashingCheckpoint, CheckpointBlockRange, EntitiesCheckpoint,
321 ExecutionCheckpoint, HeadersCheckpoint, IndexHistoryCheckpoint, StageCheckpoint,
322 StageUnitCheckpoint, StorageHashingCheckpoint,
323 };
324 assert_eq!(Account::bitflag_encoded_bytes(), 2);
325 assert_eq!(AccountHashingCheckpoint::bitflag_encoded_bytes(), 1);
326 assert_eq!(CheckpointBlockRange::bitflag_encoded_bytes(), 1);
327 assert_eq!(CompactClientVersion::bitflag_encoded_bytes(), 0);
328 assert_eq!(CompactU256::bitflag_encoded_bytes(), 1);
329 assert_eq!(CompactU64::bitflag_encoded_bytes(), 1);
330 assert_eq!(EntitiesCheckpoint::bitflag_encoded_bytes(), 1);
331 assert_eq!(ExecutionCheckpoint::bitflag_encoded_bytes(), 0);
332 assert_eq!(HeadersCheckpoint::bitflag_encoded_bytes(), 0);
333 assert_eq!(IndexHistoryCheckpoint::bitflag_encoded_bytes(), 0);
334 assert_eq!(PruneCheckpoint::bitflag_encoded_bytes(), 1);
335 assert_eq!(PruneMode::bitflag_encoded_bytes(), 1);
336 assert_eq!(PruneSegment::bitflag_encoded_bytes(), 1);
337 assert_eq!(Receipt::bitflag_encoded_bytes(), 1);
338 assert_eq!(StageCheckpoint::bitflag_encoded_bytes(), 1);
339 assert_eq!(StageUnitCheckpoint::bitflag_encoded_bytes(), 1);
340 assert_eq!(StoredBlockBodyIndices::bitflag_encoded_bytes(), 1);
341 assert_eq!(StoredBlockWithdrawals::bitflag_encoded_bytes(), 0);
342 assert_eq!(StorageHashingCheckpoint::bitflag_encoded_bytes(), 1);
343
344 validate_bitflag_backwards_compat!(Account, UnusedBits::NotZero);
345 validate_bitflag_backwards_compat!(AccountHashingCheckpoint, UnusedBits::NotZero);
346 validate_bitflag_backwards_compat!(CheckpointBlockRange, UnusedBits::Zero);
347 validate_bitflag_backwards_compat!(CompactClientVersion, UnusedBits::Zero);
348 validate_bitflag_backwards_compat!(CompactU256, UnusedBits::NotZero);
349 validate_bitflag_backwards_compat!(CompactU64, UnusedBits::NotZero);
350 validate_bitflag_backwards_compat!(EntitiesCheckpoint, UnusedBits::Zero);
351 validate_bitflag_backwards_compat!(ExecutionCheckpoint, UnusedBits::Zero);
352 validate_bitflag_backwards_compat!(HeadersCheckpoint, UnusedBits::Zero);
353 validate_bitflag_backwards_compat!(IndexHistoryCheckpoint, UnusedBits::Zero);
354 validate_bitflag_backwards_compat!(PruneCheckpoint, UnusedBits::NotZero);
355 validate_bitflag_backwards_compat!(PruneMode, UnusedBits::Zero);
356 validate_bitflag_backwards_compat!(PruneSegment, UnusedBits::Zero);
357 validate_bitflag_backwards_compat!(Receipt, UnusedBits::Zero);
358 validate_bitflag_backwards_compat!(StageCheckpoint, UnusedBits::NotZero);
359 validate_bitflag_backwards_compat!(StageUnitCheckpoint, UnusedBits::Zero);
360 validate_bitflag_backwards_compat!(StoredBlockBodyIndices, UnusedBits::Zero);
361 validate_bitflag_backwards_compat!(StoredBlockWithdrawals, UnusedBits::Zero);
362 validate_bitflag_backwards_compat!(StorageHashingCheckpoint, UnusedBits::NotZero);
363 }
364}