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 blocks;
15pub mod integer_list;
16pub mod metadata;
17pub mod sharded_key;
18pub mod storage_sharded_key;
19
20pub use accounts::*;
21pub use blocks::*;
22pub use integer_list::IntegerList;
23pub use metadata::*;
24pub use reth_db_models::{
25    AccountBeforeTx, ClientVersion, StaticFileBlockWithdrawals, StorageBeforeTx,
26    StoredBlockBodyIndices, StoredBlockWithdrawals,
27};
28pub use sharded_key::ShardedKey;
29
30/// Macro that implements [`Encode`] and [`Decode`] for uint types.
31macro_rules! impl_uints {
32    ($($name:tt),+) => {
33        $(
34            impl Encode for $name {
35                type Encoded = [u8; std::mem::size_of::<$name>()];
36
37                fn encode(self) -> Self::Encoded {
38                    self.to_be_bytes()
39                }
40            }
41
42            impl Decode for $name {
43                fn decode(value: &[u8]) -> Result<Self, $crate::DatabaseError> {
44                    Ok(
45                        $name::from_be_bytes(
46                            value.try_into().map_err(|_| $crate::DatabaseError::Decode)?
47                        )
48                    )
49                }
50            }
51        )+
52    };
53}
54
55impl_uints!(u64, u32, u16, u8);
56
57impl Encode for Vec<u8> {
58    type Encoded = Self;
59
60    fn encode(self) -> Self::Encoded {
61        self
62    }
63}
64
65impl Decode for Vec<u8> {
66    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
67        Ok(value.to_vec())
68    }
69
70    fn decode_owned(value: Vec<u8>) -> Result<Self, DatabaseError> {
71        Ok(value)
72    }
73}
74
75impl Encode for Address {
76    type Encoded = [u8; 20];
77
78    fn encode(self) -> Self::Encoded {
79        self.0 .0
80    }
81}
82
83impl Decode for Address {
84    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
85        Ok(Self::from_slice(value))
86    }
87}
88
89impl Encode for B256 {
90    type Encoded = [u8; 32];
91
92    fn encode(self) -> Self::Encoded {
93        self.0
94    }
95}
96
97impl Decode for B256 {
98    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
99        Ok(Self::new(value.try_into().map_err(|_| DatabaseError::Decode)?))
100    }
101}
102
103impl Encode for String {
104    type Encoded = Vec<u8>;
105
106    fn encode(self) -> Self::Encoded {
107        self.into_bytes()
108    }
109}
110
111impl Decode for String {
112    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
113        Self::decode_owned(value.to_vec())
114    }
115
116    fn decode_owned(value: Vec<u8>) -> Result<Self, DatabaseError> {
117        Self::from_utf8(value).map_err(|_| DatabaseError::Decode)
118    }
119}
120
121impl Encode for StoredNibbles {
122    type Encoded = arrayvec::ArrayVec<u8, 64>;
123
124    fn encode(self) -> Self::Encoded {
125        self.0.iter().collect()
126    }
127}
128
129impl Decode for StoredNibbles {
130    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
131        Ok(Self::from_compact(value, value.len()).0)
132    }
133}
134
135impl Encode for StoredNibblesSubKey {
136    type Encoded = [u8; 65];
137
138    fn encode(self) -> Self::Encoded {
139        self.to_compact_array()
140    }
141}
142
143impl Decode for StoredNibblesSubKey {
144    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
145        Ok(Self::from_compact(value, value.len()).0)
146    }
147}
148
149impl Encode for PackedStoredNibbles {
150    type Encoded = [u8; 33];
151
152    fn encode(self) -> Self::Encoded {
153        self.to_compact_array()
154    }
155}
156
157impl Decode for PackedStoredNibbles {
158    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
159        Ok(Self::from_compact(value, value.len()).0)
160    }
161}
162
163impl Encode for PackedStoredNibblesSubKey {
164    type Encoded = [u8; 33];
165
166    fn encode(self) -> Self::Encoded {
167        self.to_compact_array()
168    }
169}
170
171impl Decode for PackedStoredNibblesSubKey {
172    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
173        Ok(Self::from_compact(value, value.len()).0)
174    }
175}
176
177impl Encode for PruneSegment {
178    type Encoded = [u8; 1];
179
180    fn encode(self) -> Self::Encoded {
181        let mut buf = [0u8];
182        self.to_compact(&mut buf.as_mut());
183        buf
184    }
185}
186
187impl Decode for PruneSegment {
188    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
189        Ok(Self::from_compact(value, value.len()).0)
190    }
191}
192
193impl Encode for ClientVersion {
194    type Encoded = Vec<u8>;
195
196    // Delegate to the Compact implementation
197    fn encode(self) -> Self::Encoded {
198        let mut buf = vec![];
199        self.to_compact(&mut buf);
200        buf
201    }
202}
203
204impl Decode for ClientVersion {
205    fn decode(value: &[u8]) -> Result<Self, DatabaseError> {
206        Ok(Self::from_compact(value, value.len()).0)
207    }
208}
209
210impl_compression_for_compact!(StoredBlockOmmers<H>, CompactU256);
211
212/// Adds wrapper structs for some primitive types so they can use `StructFlags` from Compact, when
213/// used as pure table values.
214macro_rules! add_wrapper_struct {
215    ($(($name:tt, $wrapper:tt)),+) => {
216        $(
217            /// Wrapper struct so it can use `StructFlags` from Compact, when used as pure table values.
218            #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, Compact)]
219            #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
220            #[add_arbitrary_tests(compact)]
221            pub struct $wrapper(pub $name);
222
223            impl From<$name> for $wrapper {
224                fn from(value: $name) -> Self {
225                    $wrapper(value)
226                }
227            }
228
229            impl From<$wrapper> for $name {
230                fn from(value: $wrapper) -> Self {
231                    value.0
232                }
233            }
234
235            impl std::ops::Deref for $wrapper {
236                type Target = $name;
237
238                fn deref(&self) -> &Self::Target {
239                    &self.0
240                }
241            }
242
243        )+
244    };
245}
246
247add_wrapper_struct!((U256, CompactU256));
248add_wrapper_struct!((u64, CompactU64));
249add_wrapper_struct!((ClientVersion, CompactClientVersion));
250
251#[cfg(test)]
252mod tests {
253    // each value in the database has an extra field named flags that encodes metadata about other
254    // fields in the value, e.g. offset and length.
255    //
256    // this check is to ensure we do not inadvertently add too many fields to a struct which would
257    // expand the flags field and break backwards compatibility
258    #[test]
259    fn test_ensure_backwards_compatibility() {
260        use super::*;
261        use reth_codecs::{test_utils::UnusedBits, validate_bitflag_backwards_compat};
262        use reth_primitives_traits::Account;
263        use reth_prune_types::{PruneCheckpoint, PruneMode, PruneSegment};
264        use reth_stages_types::{
265            AccountHashingCheckpoint, CheckpointBlockRange, EntitiesCheckpoint,
266            ExecutionCheckpoint, HeadersCheckpoint, IndexHistoryCheckpoint, StageCheckpoint,
267            StageUnitCheckpoint, StorageHashingCheckpoint,
268        };
269        assert_eq!(Account::bitflag_encoded_bytes(), 2);
270        assert_eq!(AccountHashingCheckpoint::bitflag_encoded_bytes(), 1);
271        assert_eq!(CheckpointBlockRange::bitflag_encoded_bytes(), 1);
272        assert_eq!(CompactClientVersion::bitflag_encoded_bytes(), 0);
273        assert_eq!(CompactU256::bitflag_encoded_bytes(), 1);
274        assert_eq!(CompactU64::bitflag_encoded_bytes(), 1);
275        assert_eq!(EntitiesCheckpoint::bitflag_encoded_bytes(), 1);
276        assert_eq!(ExecutionCheckpoint::bitflag_encoded_bytes(), 0);
277        assert_eq!(HeadersCheckpoint::bitflag_encoded_bytes(), 0);
278        assert_eq!(IndexHistoryCheckpoint::bitflag_encoded_bytes(), 0);
279        assert_eq!(PruneCheckpoint::bitflag_encoded_bytes(), 1);
280        assert_eq!(PruneMode::bitflag_encoded_bytes(), 1);
281        assert_eq!(PruneSegment::bitflag_encoded_bytes(), 1);
282        assert_eq!(StageCheckpoint::bitflag_encoded_bytes(), 1);
283        assert_eq!(StageUnitCheckpoint::bitflag_encoded_bytes(), 1);
284        assert_eq!(StoredBlockBodyIndices::bitflag_encoded_bytes(), 1);
285        assert_eq!(StoredBlockWithdrawals::bitflag_encoded_bytes(), 0);
286        assert_eq!(StorageHashingCheckpoint::bitflag_encoded_bytes(), 1);
287
288        validate_bitflag_backwards_compat!(Account, UnusedBits::NotZero);
289        validate_bitflag_backwards_compat!(AccountHashingCheckpoint, UnusedBits::NotZero);
290        validate_bitflag_backwards_compat!(CheckpointBlockRange, UnusedBits::Zero);
291        validate_bitflag_backwards_compat!(CompactClientVersion, UnusedBits::Zero);
292        validate_bitflag_backwards_compat!(CompactU256, UnusedBits::NotZero);
293        validate_bitflag_backwards_compat!(CompactU64, UnusedBits::NotZero);
294        validate_bitflag_backwards_compat!(EntitiesCheckpoint, UnusedBits::Zero);
295        validate_bitflag_backwards_compat!(ExecutionCheckpoint, UnusedBits::Zero);
296        validate_bitflag_backwards_compat!(HeadersCheckpoint, UnusedBits::Zero);
297        validate_bitflag_backwards_compat!(IndexHistoryCheckpoint, UnusedBits::Zero);
298        validate_bitflag_backwards_compat!(PruneCheckpoint, UnusedBits::NotZero);
299        validate_bitflag_backwards_compat!(PruneMode, UnusedBits::Zero);
300        validate_bitflag_backwards_compat!(PruneSegment, UnusedBits::Zero);
301        validate_bitflag_backwards_compat!(StageCheckpoint, UnusedBits::NotZero);
302        validate_bitflag_backwards_compat!(StageUnitCheckpoint, UnusedBits::Zero);
303        validate_bitflag_backwards_compat!(StoredBlockBodyIndices, UnusedBits::Zero);
304        validate_bitflag_backwards_compat!(StoredBlockWithdrawals, UnusedBits::Zero);
305        validate_bitflag_backwards_compat!(StorageHashingCheckpoint, UnusedBits::NotZero);
306    }
307}