Skip to main content

reth_db_api/models/
mod.rs

1//! Implements data structures specific to the database
2
3use crate::{
4    table::{Decode, Encode},
5    DatabaseError,
6};
7use alloy_primitives::{Address, B256, U256};
8use reth_codecs::{add_arbitrary_tests, impl_compression_for_compact, Compact};
9use reth_prune_types::PruneSegment;
10use reth_trie_common::{StoredNibbles, StoredNibblesSubKey, *};
11use serde::{Deserialize, Serialize};
12
13pub mod accounts;
14pub mod bal;
15pub mod blocks;
16pub mod integer_list;
17pub mod metadata;
18pub mod sharded_key;
19pub mod storage_sharded_key;
20
21pub use accounts::*;
22pub use bal::*;
23pub use blocks::*;
24pub use integer_list::IntegerList;
25pub use metadata::*;
26pub use reth_db_models::{
27    AccountBeforeTx, ClientVersion, StaticFileBlockWithdrawals, StorageBeforeTx,
28    StoredBlockBodyIndices, StoredBlockWithdrawals,
29};
30pub use sharded_key::ShardedKey;
31
32/// Macro that implements [`Encode`] and [`Decode`] for uint types.
33macro_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 = arrayvec::ArrayVec<u8, 64>;
125
126    fn encode(self) -> Self::Encoded {
127        self.0.iter().collect()
128    }
129}
130
131impl Decode for StoredNibbles {
132    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
133        Ok(Self::from_compact(value, value.len()).0)
134    }
135}
136
137impl Encode for StoredNibblesSubKey {
138    type Encoded = [u8; 65];
139
140    fn encode(self) -> Self::Encoded {
141        self.to_compact_array()
142    }
143}
144
145impl Decode for StoredNibblesSubKey {
146    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
147        Ok(Self::from_compact(value, value.len()).0)
148    }
149}
150
151impl Encode for PackedStoredNibbles {
152    type Encoded = [u8; 33];
153
154    fn encode(self) -> Self::Encoded {
155        self.to_compact_array()
156    }
157}
158
159impl Decode for PackedStoredNibbles {
160    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
161        Ok(Self::from_compact(value, value.len()).0)
162    }
163}
164
165impl Encode for PackedStoredNibblesSubKey {
166    type Encoded = [u8; 33];
167
168    fn encode(self) -> Self::Encoded {
169        self.to_compact_array()
170    }
171}
172
173impl Decode for PackedStoredNibblesSubKey {
174    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
175        Ok(Self::from_compact(value, value.len()).0)
176    }
177}
178
179impl Encode for PruneSegment {
180    type Encoded = [u8; 1];
181
182    fn encode(self) -> Self::Encoded {
183        let mut buf = [0u8];
184        self.to_compact(&mut buf.as_mut());
185        buf
186    }
187}
188
189impl Decode for PruneSegment {
190    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
191        Ok(Self::from_compact(value, value.len()).0)
192    }
193}
194
195impl Encode for ClientVersion {
196    type Encoded = Vec<u8>;
197
198    // Delegate to the Compact implementation
199    fn encode(self) -> Self::Encoded {
200        let mut buf = vec![];
201        self.to_compact(&mut buf);
202        buf
203    }
204}
205
206impl Decode for ClientVersion {
207    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
208        Ok(Self::from_compact(value, value.len()).0)
209    }
210}
211
212impl_compression_for_compact!(StoredBlockOmmers<H>, CompactU256);
213
214/// Adds wrapper structs for some primitive types so they can use `StructFlags` from Compact, when
215/// used as pure table values.
216macro_rules! add_wrapper_struct {
217    ($(($name:tt, $wrapper:tt)),+) => {
218        $(
219            /// Wrapper struct so it can use `StructFlags` from Compact, when used as pure table values.
220            #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, Compact)]
221            #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
222            #[add_arbitrary_tests(compact)]
223            pub struct $wrapper(pub $name);
224
225            impl From<$name> for $wrapper {
226                fn from(value: $name) -> Self {
227                    $wrapper(value)
228                }
229            }
230
231            impl From<$wrapper> for $name {
232                fn from(value: $wrapper) -> Self {
233                    value.0
234                }
235            }
236
237            impl std::ops::Deref for $wrapper {
238                type Target = $name;
239
240                fn deref(&self) -> &Self::Target {
241                    &self.0
242                }
243            }
244
245        )+
246    };
247}
248
249add_wrapper_struct!((U256, CompactU256));
250add_wrapper_struct!((u64, CompactU64));
251add_wrapper_struct!((ClientVersion, CompactClientVersion));
252
253#[cfg(test)]
254mod tests {
255    // each value in the database has an extra field named flags that encodes metadata about other
256    // fields in the value, e.g. offset and length.
257    //
258    // this check is to ensure we do not inadvertently add too many fields to a struct which would
259    // expand the flags field and break backwards compatibility
260    #[test]
261    fn test_ensure_backwards_compatibility() {
262        use super::*;
263        use reth_codecs::{test_utils::UnusedBits, validate_bitflag_backwards_compat};
264        use reth_primitives_traits::Account;
265        use reth_prune_types::{PruneCheckpoint, PruneMode, PruneSegment};
266        use reth_stages_types::{
267            AccountHashingCheckpoint, CheckpointBlockRange, EntitiesCheckpoint,
268            ExecutionCheckpoint, HeadersCheckpoint, IndexHistoryCheckpoint, StageCheckpoint,
269            StageUnitCheckpoint, StorageHashingCheckpoint,
270        };
271        assert_eq!(Account::bitflag_encoded_bytes(), 2);
272        assert_eq!(AccountHashingCheckpoint::bitflag_encoded_bytes(), 1);
273        assert_eq!(CheckpointBlockRange::bitflag_encoded_bytes(), 1);
274        assert_eq!(CompactClientVersion::bitflag_encoded_bytes(), 0);
275        assert_eq!(CompactU256::bitflag_encoded_bytes(), 1);
276        assert_eq!(CompactU64::bitflag_encoded_bytes(), 1);
277        assert_eq!(EntitiesCheckpoint::bitflag_encoded_bytes(), 1);
278        assert_eq!(ExecutionCheckpoint::bitflag_encoded_bytes(), 0);
279        assert_eq!(HeadersCheckpoint::bitflag_encoded_bytes(), 0);
280        assert_eq!(IndexHistoryCheckpoint::bitflag_encoded_bytes(), 0);
281        assert_eq!(PruneCheckpoint::bitflag_encoded_bytes(), 1);
282        assert_eq!(PruneMode::bitflag_encoded_bytes(), 1);
283        assert_eq!(PruneSegment::bitflag_encoded_bytes(), 1);
284        assert_eq!(StageCheckpoint::bitflag_encoded_bytes(), 1);
285        assert_eq!(StageUnitCheckpoint::bitflag_encoded_bytes(), 1);
286        assert_eq!(StoredBlockBodyIndices::bitflag_encoded_bytes(), 1);
287        assert_eq!(StoredBlockWithdrawals::bitflag_encoded_bytes(), 0);
288        assert_eq!(StorageHashingCheckpoint::bitflag_encoded_bytes(), 1);
289
290        validate_bitflag_backwards_compat!(Account, UnusedBits::NotZero);
291        validate_bitflag_backwards_compat!(AccountHashingCheckpoint, UnusedBits::NotZero);
292        validate_bitflag_backwards_compat!(CheckpointBlockRange, UnusedBits::Zero);
293        validate_bitflag_backwards_compat!(CompactClientVersion, UnusedBits::Zero);
294        validate_bitflag_backwards_compat!(CompactU256, UnusedBits::NotZero);
295        validate_bitflag_backwards_compat!(CompactU64, UnusedBits::NotZero);
296        validate_bitflag_backwards_compat!(EntitiesCheckpoint, UnusedBits::Zero);
297        validate_bitflag_backwards_compat!(ExecutionCheckpoint, UnusedBits::Zero);
298        validate_bitflag_backwards_compat!(HeadersCheckpoint, UnusedBits::Zero);
299        validate_bitflag_backwards_compat!(IndexHistoryCheckpoint, UnusedBits::Zero);
300        validate_bitflag_backwards_compat!(PruneCheckpoint, UnusedBits::NotZero);
301        validate_bitflag_backwards_compat!(PruneMode, UnusedBits::Zero);
302        validate_bitflag_backwards_compat!(PruneSegment, UnusedBits::Zero);
303        validate_bitflag_backwards_compat!(StageCheckpoint, UnusedBits::NotZero);
304        validate_bitflag_backwards_compat!(StageUnitCheckpoint, UnusedBits::Zero);
305        validate_bitflag_backwards_compat!(StoredBlockBodyIndices, UnusedBits::Zero);
306        validate_bitflag_backwards_compat!(StoredBlockWithdrawals, UnusedBits::Zero);
307        validate_bitflag_backwards_compat!(StorageHashingCheckpoint, UnusedBits::NotZero);
308    }
309}