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