Skip to main content

reth_primitives_traits/
lib.rs

1//! Commonly used types and traits in Reth.
2//!
3//! ## Overview
4//!
5//! This crate defines various traits and types that form the foundation of the reth stack.
6//! The top-level trait is [`Block`] which represents a block in the blockchain. A [`Block`] is
7//! composed of a [`Header`] and a [`BlockBody`]. A [`BlockBody`] contains the transactions in the
8//! block and additional data that is part of the block. In ethereum, this includes uncle headers
9//! and withdrawals. For optimism, uncle headers and withdrawals are always empty lists.
10//!
11//! The most common types you'll use are:
12//! - [`Block`] - A basic block with header and body
13//! - [`SealedBlock`] - A block with its hash cached
14//! - [`SealedHeader`] - A header with its hash cached
15//! - [`RecoveredBlock`] - A sealed block with sender addresses recovered
16//!
17//! ## Feature Flags
18//!
19//! - `arbitrary`: Adds `proptest` and `arbitrary` support for primitive types.
20//! - `op`: Implements the traits for various [op-alloy](https://github.com/alloy-rs/op-alloy)
21//!   types.
22//! - `reth-codec`: Enables db codec support for reth types including zstd compression for certain
23//!   types.
24//! - `rpc-compat`: Adds RPC compatibility functions for the types in this crate, e.g. rpc type
25//!   conversions.
26//! - `serde`: Adds serde support for all types.
27//! - `secp256k1`: Adds secp256k1 support for transaction signing/recovery. (By default the no-std
28//!   friendly `k256` is used)
29//! - `rayon`: Uses `rayon` for parallel transaction sender recovery in [`BlockBody`] by default.
30//! - `serde-bincode-compat` provides helpers for dealing with the `bincode` crate.
31//!
32//! ### Sealing (Hashing)
33//!
34//! The block hash is derived from the [`Header`] and is used to uniquely identify the block. This
35//! operation is referred to as sealing in the context of this crate. Sealing is an expensive
36//! operation. This crate provides various wrapper types that cache the hash of the block to avoid
37//! recomputing it: [`SealedHeader`] and [`SealedBlock`]. All sealed types can be downgraded to
38//! their unsealed counterparts.
39//!
40//! ### Recovery
41//!
42//! The raw consensus transactions that make up a block don't include the sender's address. This
43//! information is recovered from the transaction signature. This operation is referred to as
44//! recovery in the context of this crate and is an expensive operation. The [`RecoveredBlock`]
45//! represents a [`SealedBlock`] with the sender addresses recovered. A [`SealedBlock`] can be
46//! upgraded to a [`RecoveredBlock`] by recovering the sender addresses:
47//! [`SealedBlock::try_recover`]. A [`RecoveredBlock`] can be downgraded to a [`SealedBlock`] by
48//! removing the sender addresses: [`RecoveredBlock::into_sealed_block`].
49//!
50//! #### Naming
51//!
52//! The types in this crate support multiple recovery functions, e.g.
53//! [`SealedBlock::try_recover`] and [`SealedBlock::try_recover_unchecked`]. The `_unchecked` suffix indicates that this function recovers the signer _without ensuring that the signature has a low `s` value_, in other words this rule introduced in [EIP-2](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md) is ignored.
54//! Hence this function is necessary when dealing with pre EIP-2 transactions on the ethereum
55//! mainnet. Newer transactions must always be recovered with the regular `recover` functions, see
56//! also [`recover_signer`](crypto::secp256k1::recover_signer).
57//!
58//! ## Error Handling
59//!
60//! Most operations that can fail return `Result` types:
61//! - [`RecoveryError`](transaction::signed::RecoveryError) - Transaction signature recovery failed
62//! - [`BlockRecoveryError`](block::error::BlockRecoveryError) - Block-level recovery failed
63//! - [`GotExpected`] / [`GotExpectedBoxed`] - Generic error for mismatched values
64//!
65//! Recovery errors typically indicate invalid signatures or corrupted data. The block recovery
66//! error preserves the original block for further inspection.
67//!
68//! ### Example
69//!
70//! ```rust
71//! # use reth_primitives_traits::{SealedBlock, RecoveredBlock};
72//! # use reth_primitives_traits::block::error::BlockRecoveryError;
73//! # fn example<B: reth_primitives_traits::Block>(sealed_block: SealedBlock<B>) -> Result<(), BlockRecoveryError<SealedBlock<B>>>
74//! # where B::Body: reth_primitives_traits::BlockBody<Transaction: reth_primitives_traits::SignedTransaction> {
75//! // Attempt to recover senders from a sealed block
76//! match sealed_block.try_recover() {
77//!     Ok(recovered) => {
78//!         // Successfully recovered all senders
79//!         println!("Recovered {} senders", recovered.senders().len());
80//!         Ok(())
81//!     }
82//!     Err(err) => {
83//!         // Recovery failed - the block is returned in the error
84//!         println!("Failed to recover senders for block");
85//!         // You can still access the original block
86//!         let block = err.into_inner();
87//!         let hash = block.hash();
88//!         Err(BlockRecoveryError::new(block))
89//!     }
90//! }
91//! # }
92//! ```
93//!
94//! ## Performance Considerations
95//!
96//! - **Hashing**: Block hashing is expensive. Use [`SealedBlock`] to cache hashes.
97//! - **Recovery**: Sender recovery is CPU-intensive. Use [`RecoveredBlock`] to cache results.
98//! - **Parallel Recovery**: Enable the `rayon` feature for parallel transaction recovery.
99//!
100//! ## Bincode serde compatibility
101//!
102//! The [bincode-crate](https://github.com/bincode-org/bincode) is often used by additional tools when sending data over the network.
103//! `bincode` crate doesn't work well with optionally serializable serde fields, but some of the consensus types require optional serialization for RPC compatibility. Read more: <https://github.com/bincode-org/bincode/issues/326>
104//!
105//! As a workaround this crate introduces the `SerdeBincodeCompat` trait (available with the
106//! `serde-bincode-compat` feature) used to provide a bincode compatible serde representation.
107
108#![doc(
109    html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png",
110    html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256",
111    issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/"
112)]
113#![cfg_attr(not(test), warn(unused_crate_dependencies))]
114#![cfg_attr(docsrs, feature(doc_cfg))]
115#![cfg_attr(not(feature = "std"), no_std)]
116
117#[macro_use]
118extern crate alloc;
119
120/// Re-export of [`quanta::Instant`] for high-resolution timing with minimal overhead.
121#[cfg(feature = "std")]
122pub use quanta::Instant as FastInstant;
123
124/// Common constants.
125pub mod constants;
126pub use constants::gas_units::{format_gas, format_gas_throughput};
127
128/// Minimal account
129pub mod account;
130pub use account::{Account, Bytecode};
131
132pub mod receipt;
133pub use receipt::{FullReceipt, Receipt};
134
135pub mod transaction;
136pub use alloy_consensus::{
137    transaction::{Recovered, TransactionMeta},
138    ReceiptWithBloom,
139};
140
141pub use transaction::{
142    execute::FillTxEnv,
143    signed::{FullSignedTx, SignedTransaction},
144    FullTransaction, SignerRecoverable, Transaction,
145};
146
147pub mod block;
148pub use block::{
149    body::{BlockBody, FullBlockBody},
150    header::{AlloyBlockHeader, BlockHeader, FullBlockHeader},
151    recovered::IndexedTx,
152    Block, FullBlock, RecoveredBlock, SealedBlock,
153};
154
155#[cfg(test)]
156mod withdrawal;
157pub use alloy_eips::eip2718::WithEncoded;
158
159pub mod crypto;
160
161mod error;
162pub use error::{GotExpected, GotExpectedBoxed};
163
164#[cfg(test)]
165mod log;
166pub use alloy_primitives::{logs_bloom, Log, LogData};
167
168pub mod proofs;
169
170mod storage;
171pub use storage::{StorageEntry, ValueWithSubKey};
172
173pub mod sync;
174
175mod extended;
176pub use extended::Extended;
177/// Common header types
178pub mod header;
179pub use header::{Header, SealedHeader, SealedHeaderFor};
180
181/// Bincode-compatible serde implementations for common abstracted types in Reth.
182///
183/// `bincode` crate doesn't work with optionally serializable serde fields, but some of the
184/// Reth types require optional serialization for RPC compatibility. This module makes so that
185/// all fields are serialized.
186///
187/// Read more: <https://github.com/bincode-org/bincode/issues/326>
188#[cfg(feature = "serde-bincode-compat")]
189pub mod serde_bincode_compat;
190
191/// Heuristic size trait
192pub mod size;
193pub use size::InMemorySize;
194
195/// Rayon utilities
196#[cfg(feature = "rayon")]
197pub mod rayon;
198#[cfg(feature = "rayon")]
199pub use rayon::ParallelBridgeBuffered;
200
201/// Node traits
202pub mod node;
203pub use node::{BlockTy, BodyTy, HeaderTy, NodePrimitives, ReceiptTy, TxTy};
204
205/// Helper trait that requires de-/serialize implementation since `serde` feature is enabled.
206#[cfg(feature = "serde")]
207pub trait MaybeSerde: serde::Serialize + for<'de> serde::Deserialize<'de> {}
208/// Noop. Helper trait that would require de-/serialize implementation if `serde` feature were
209/// enabled.
210#[cfg(not(feature = "serde"))]
211pub trait MaybeSerde {}
212
213#[cfg(feature = "serde")]
214impl<T> MaybeSerde for T where T: serde::Serialize + for<'de> serde::Deserialize<'de> {}
215#[cfg(not(feature = "serde"))]
216impl<T> MaybeSerde for T {}
217
218/// Helper trait that requires database encoding implementation since `reth-codec` feature is
219/// enabled.
220#[cfg(feature = "reth-codec")]
221pub trait MaybeCompact: reth_codecs::Compact {}
222/// Noop. Helper trait that would require database encoding implementation if `reth-codec` feature
223/// were enabled.
224#[cfg(not(feature = "reth-codec"))]
225pub trait MaybeCompact {}
226
227#[cfg(feature = "reth-codec")]
228impl<T> MaybeCompact for T where T: reth_codecs::Compact {}
229#[cfg(not(feature = "reth-codec"))]
230impl<T> MaybeCompact for T {}
231
232/// Helper trait that requires serde bincode compatibility implementation.
233#[cfg(feature = "serde-bincode-compat")]
234pub trait MaybeSerdeBincodeCompat: crate::serde_bincode_compat::SerdeBincodeCompat {}
235/// Noop. Helper trait that would require serde bincode compatibility implementation if
236/// `serde-bincode-compat` feature were enabled.
237#[cfg(not(feature = "serde-bincode-compat"))]
238pub trait MaybeSerdeBincodeCompat {}
239
240#[cfg(feature = "serde-bincode-compat")]
241impl<T> MaybeSerdeBincodeCompat for T where T: crate::serde_bincode_compat::SerdeBincodeCompat {}
242#[cfg(not(feature = "serde-bincode-compat"))]
243impl<T> MaybeSerdeBincodeCompat for T {}
244
245/// Utilities for testing.
246#[cfg(any(test, feature = "arbitrary", feature = "test-utils"))]
247pub mod test_utils {
248    pub use crate::header::test_utils::{generate_valid_header, valid_header_strategy};
249    #[cfg(any(test, feature = "test-utils"))]
250    pub use crate::{block::TestBlock, header::test_utils::TestHeader};
251}
252
253/// Re-exports of `dashmap` types with [`alloy_primitives::map::DefaultHashBuilder`] as the hasher.
254#[cfg(feature = "dashmap")]
255pub mod dashmap {
256    pub use ::dashmap::{mapref, DashSet, Entry};
257    /// Re-export of `DashMap` with [`alloy_primitives::map::DefaultHashBuilder`] as the hasher.
258    pub type DashMap<K, V, S = alloy_primitives::map::DefaultHashBuilder> =
259        ::dashmap::DashMap<K, V, S>;
260}