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