diff --git a/Cargo.lock b/Cargo.lock index 81afcebc75ae..9929ef06af38 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -726,7 +726,7 @@ checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", - "semver 1.0.17", + "semver", "serde", "serde_json", "thiserror", @@ -1351,6 +1351,16 @@ dependencies = [ "darling_macro 0.14.3", ] +[[package]] +name = "darling" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" +dependencies = [ + "darling_core 0.20.1", + "darling_macro 0.20.1", +] + [[package]] name = "darling_core" version = "0.10.2" @@ -1379,6 +1389,20 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "darling_core" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2 1.0.60", + "quote 1.0.28", + "strsim 0.10.0", + "syn 2.0.18", +] + [[package]] name = "darling_macro" version = "0.10.2" @@ -1401,6 +1425,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "darling_macro" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" +dependencies = [ + "darling_core 0.20.1", + "quote 1.0.28", + "syn 2.0.18", +] + [[package]] name = "dashmap" version = "5.4.0" @@ -2094,7 +2129,7 @@ checksum = "84ebb401ba97c6f5af278c2c9936c4546cad75dec464b439ae6df249906f4caa" dependencies = [ "ethers-core", "reqwest", - "semver 1.0.17", + "semver", "serde", "serde_json", "thiserror", @@ -4217,16 +4252,6 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" -[[package]] -name = "pest" -version = "2.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cbd939b234e95d72bc393d51788aec68aeeb5d51e748ca08ff3aad58cb722f7" -dependencies = [ - "thiserror", - "ucd-trie", -] - [[package]] name = "pharos" version = "0.5.3" @@ -5046,6 +5071,7 @@ dependencies = [ "parking_lot 0.12.1", "reth-db", "reth-interfaces", + "reth-metrics", "reth-primitives", "reth-provider", "tokio", @@ -6061,7 +6087,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.17", + "semver", ] [[package]] @@ -6332,15 +6358,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.17" @@ -6350,15 +6367,6 @@ dependencies = [ "serde", ] -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "send_wrapper" version = "0.4.0" @@ -6975,9 +6983,9 @@ checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8" [[package]] name = "test-fuzz" -version = "3.0.5" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd4a3a7f00909d5a1d1f83b86b65d91e4c94f80b0c2d0ae37e2ef44da7b7a0a0" +checksum = "a7bb2f404d5d20140588fb209481f5841920a7e29c36124f3d1ac1041eb1842c" dependencies = [ "serde", "test-fuzz-internal", @@ -6987,9 +6995,9 @@ dependencies = [ [[package]] name = "test-fuzz-internal" -version = "3.0.5" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9186daca5c58cb307d09731e0ba06b13fd6c036c90672b9bfc31cecf76cf689" +checksum = "385624eb0031d550fe1bf99c08af79b838605fc4fcec2c4d55e229a2c342fdd0" dependencies = [ "cargo_metadata", "proc-macro2 1.0.60", @@ -7000,27 +7008,27 @@ dependencies = [ [[package]] name = "test-fuzz-macro" -version = "3.0.5" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d187b450bfb5b7939f82f9747dc1ebb15a7a9c4a93cd304a41aece7149608b" +checksum = "69247423e2d89bd51160e42200f6f45f921a23e5b44a0e5b57b888a378334037" dependencies = [ - "darling 0.14.3", + "darling 0.20.1", "if_chain", + "itertools", "lazy_static", "proc-macro2 1.0.60", "quote 1.0.28", "subprocess", - "syn 1.0.109", + "syn 2.0.18", "test-fuzz-internal", "toolchain_find", - "unzip-n", ] [[package]] name = "test-fuzz-runtime" -version = "3.0.5" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a0d69068569b9b7311095823fe0e49eedfd05ad4277eb64fc334cf1a5bc5116" +checksum = "f5054a92d02b1a95a0120155d20aef49b5c5673ba8a65d6f4ce667c2a6f3146c" dependencies = [ "bincode", "hex", @@ -7283,14 +7291,14 @@ dependencies = [ [[package]] name = "toolchain_find" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e85654a10e7a07a47c6f19d93818f3f343e22927f2fa280c84f7c8042743413" +checksum = "ebc8c9a7f0a2966e1acdaf0461023d0b01471eeead645370cf4c3f5cff153f2a" dependencies = [ "home", - "lazy_static", + "once_cell", "regex", - "semver 0.11.0", + "semver", "walkdir", ] @@ -7636,12 +7644,6 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "ucd-trie" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" - [[package]] name = "uint" version = "0.9.5" @@ -7730,17 +7732,6 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" -[[package]] -name = "unzip-n" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7e85a0596447f0f2ac090e16bc4c516c6fe91771fb0c0ccf7fa3dae896b9c" -dependencies = [ - "proc-macro2 1.0.60", - "quote 1.0.28", - "syn 1.0.109", -] - [[package]] name = "url" version = "2.3.1" diff --git a/Cargo.toml b/Cargo.toml index 52113588c4dd..09bf2988a245 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,7 +100,8 @@ ethers-signers = { version = "2.0.7", default-features = false } ethers-middleware = { version = "2.0.7", default-features = false } ## misc -tracing = "^0.1.0" +bytes = "1.4" +tracing = "0.1.0" thiserror = "1.0.37" serde_json = "1.0.94" serde = { version = "1.0", default-features = false } diff --git a/bin/reth/src/lib.rs b/bin/reth/src/lib.rs index eaffb131c3ab..a3ba783bfdf2 100644 --- a/bin/reth/src/lib.rs +++ b/bin/reth/src/lib.rs @@ -6,6 +6,14 @@ ))] //! Rust Ethereum (reth) binary executable. +//! +//! ## Feature Flags +//! +//! - `jemalloc`: Uses [jemallocator](https://github.com/tikv/jemallocator) as the global allocator. +//! This is **not recommended on Windows**. See [here](https://rust-lang.github.io/rfcs/1974-global-allocators.html#jemalloc) +//! for more info. +//! - `only-info-logs`: Disables all logs below `info` level. This can speed up the node, since +//! fewer calls to the logging component is made. pub mod args; pub mod chain; diff --git a/crates/blockchain-tree/Cargo.toml b/crates/blockchain-tree/Cargo.toml index f955fde9ef3a..0a4bf9559037 100644 --- a/crates/blockchain-tree/Cargo.toml +++ b/crates/blockchain-tree/Cargo.toml @@ -18,6 +18,7 @@ normal = [ reth-primitives = { workspace = true } reth-interfaces = { workspace = true } reth-db = { path = "../storage/db" } +reth-metrics = { workspace = true, features = ["common"] } reth-provider = { workspace = true } # common diff --git a/crates/blockchain-tree/src/block_buffer.rs b/crates/blockchain-tree/src/block_buffer.rs index 86d6ef2552ad..9ef9870d960d 100644 --- a/crates/blockchain-tree/src/block_buffer.rs +++ b/crates/blockchain-tree/src/block_buffer.rs @@ -4,6 +4,8 @@ use std::{ collections::{btree_map::Entry, hash_map, BTreeMap, HashMap, HashSet}, num::NonZeroUsize, }; + +use crate::metrics::BlockBufferMetrics; /// Type that contains blocks by number and hash. pub type BufferedBlocks = BTreeMap>; @@ -35,6 +37,8 @@ pub struct BlockBuffer { /// /// Used as counter of amount of blocks inside buffer. pub(crate) lru: LruCache, + /// Various metrics for the block buffer. + pub(crate) metrics: BlockBufferMetrics, } impl BlockBuffer { @@ -45,6 +49,7 @@ impl BlockBuffer { parent_to_child: Default::default(), hash_to_num: Default::default(), lru: LruCache::new(NonZeroUsize::new(limit).unwrap()), + metrics: Default::default(), } } @@ -65,6 +70,7 @@ impl BlockBuffer { self.remove_from_parent(evicted_block.parent_hash, &evicted_num_hash); } } + self.metrics.blocks.set(self.len() as f64); } /// Removes the given block from the buffer and also all the children of the block. @@ -81,6 +87,7 @@ impl BlockBuffer { } taken.extend(self.remove_children(vec![parent]).into_iter()); + self.metrics.blocks.set(self.len() as f64); taken } @@ -105,6 +112,7 @@ impl BlockBuffer { } self.remove_children(remove_parent_children); + self.metrics.blocks.set(self.len() as f64); } /// Return reference to buffered blocks diff --git a/crates/blockchain-tree/src/blockchain_tree.rs b/crates/blockchain-tree/src/blockchain_tree.rs index 7b013bf9bd29..efc7e82ce6d4 100644 --- a/crates/blockchain-tree/src/blockchain_tree.rs +++ b/crates/blockchain-tree/src/blockchain_tree.rs @@ -2,6 +2,7 @@ use crate::{ canonical_chain::CanonicalChain, chain::{BlockChainId, BlockKind}, + metrics::TreeMetrics, AppendableChain, BlockBuffer, BlockIndices, BlockchainTreeConfig, PostStateData, TreeExternals, }; use reth_db::{cursor::DbCursorRO, database::Database, tables, transaction::DbTx}; @@ -87,6 +88,8 @@ pub struct BlockchainTree { config: BlockchainTreeConfig, /// Broadcast channel for canon state changes notifications. canon_state_notification_sender: CanonStateNotificationSender, + /// Metrics for the blockchain tree. + metrics: TreeMetrics, } /// A container that wraps chains and block indices to allow searching for block hashes across all @@ -137,6 +140,7 @@ impl BlockchainTree ), config, canon_state_notification_sender, + metrics: Default::default(), }) } @@ -1058,6 +1062,12 @@ impl BlockchainTree Ok(Some(Chain::new(blocks_and_execution))) } } + + /// Update blockchain tree metrics + pub(crate) fn update_tree_metrics(&self) { + self.metrics.sidechains.set(self.chains.len() as f64); + self.metrics.canonical_chain_height.set(self.canonical_chain().tip().number as f64); + } } #[cfg(test)] diff --git a/crates/blockchain-tree/src/lib.rs b/crates/blockchain-tree/src/lib.rs index cc7dcb058f20..87bdcaeb2279 100644 --- a/crates/blockchain-tree/src/lib.rs +++ b/crates/blockchain-tree/src/lib.rs @@ -4,7 +4,17 @@ no_crate_inject, attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) ))] -//! Implementation of the [BlockchainTree] +//! Implementation of a tree-like structure for blockchains. +//! +//! The [BlockchainTree] can validate, execute, and revert blocks in multiple competing sidechains. +//! This structure is used for Reth's sync mode at the tip instead of the pipeline, and is the +//! primary executor and validator of payloads sent from the consensus layer. +//! +//! Blocks and their resulting state transitions are kept in-memory until they are persisted. +//! +//! ## Feature Flags +//! +//! - `test-utils`: Export utilities for testing /// Execution result types. pub use reth_provider::post_state; @@ -34,4 +44,7 @@ pub use post_state_data::{PostStateData, PostStateDataRef}; pub mod block_buffer; mod canonical_chain; +/// Common blockchain tree metrics. +pub mod metrics; + pub use block_buffer::BlockBuffer; diff --git a/crates/blockchain-tree/src/metrics.rs b/crates/blockchain-tree/src/metrics.rs new file mode 100644 index 000000000000..38610c5a69bd --- /dev/null +++ b/crates/blockchain-tree/src/metrics.rs @@ -0,0 +1,22 @@ +use reth_metrics::{ + metrics::{self, Gauge}, + Metrics, +}; + +/// Metrics for the entire blockchain tree +#[derive(Metrics)] +#[metrics(scope = "blockchain_tree")] +pub struct TreeMetrics { + /// Total number of sidechains (not including the canonical chain) + pub sidechains: Gauge, + /// The highest block number in the canonical chain + pub canonical_chain_height: Gauge, +} + +/// Metrics for the blockchain tree block buffer +#[derive(Metrics)] +#[metrics(scope = "blockchain_tree.block_buffer")] +pub struct BlockBufferMetrics { + /// Total blocks in the block buffer + pub blocks: Gauge, +} diff --git a/crates/blockchain-tree/src/shareable.rs b/crates/blockchain-tree/src/shareable.rs index 75ced6dc90f3..bd3eb3247797 100644 --- a/crates/blockchain-tree/src/shareable.rs +++ b/crates/blockchain-tree/src/shareable.rs @@ -41,7 +41,10 @@ impl BlockchainTreeEngine for ShareableBlockchainTree { fn buffer_block(&self, block: SealedBlockWithSenders) -> Result<(), InsertBlockError> { - self.tree.write().buffer_block(block) + let mut tree = self.tree.write(); + let res = tree.buffer_block(block); + tree.update_tree_metrics(); + res } fn insert_block( @@ -49,27 +52,41 @@ impl BlockchainTreeEngine block: SealedBlockWithSenders, ) -> Result { trace!(target: "blockchain_tree", hash=?block.hash, number=block.number, parent_hash=?block.parent_hash, "Inserting block"); - self.tree.write().insert_block(block) + let mut tree = self.tree.write(); + let res = tree.insert_block(block); + tree.update_tree_metrics(); + res } fn finalize_block(&self, finalized_block: BlockNumber) { trace!(target: "blockchain_tree", ?finalized_block, "Finalizing block"); - self.tree.write().finalize_block(finalized_block) + let mut tree = self.tree.write(); + tree.finalize_block(finalized_block); + tree.update_tree_metrics(); } fn restore_canonical_hashes(&self, last_finalized_block: BlockNumber) -> Result<(), Error> { trace!(target: "blockchain_tree", ?last_finalized_block, "Restoring canonical hashes for last finalized block"); - self.tree.write().restore_canonical_hashes(last_finalized_block) + let mut tree = self.tree.write(); + let res = tree.restore_canonical_hashes(last_finalized_block); + tree.update_tree_metrics(); + res } fn make_canonical(&self, block_hash: &BlockHash) -> Result { trace!(target: "blockchain_tree", ?block_hash, "Making block canonical"); - self.tree.write().make_canonical(block_hash) + let mut tree = self.tree.write(); + let res = tree.make_canonical(block_hash); + tree.update_tree_metrics(); + res } fn unwind(&self, unwind_to: BlockNumber) -> Result<(), Error> { trace!(target: "blockchain_tree", ?unwind_to, "Unwinding to block number"); - self.tree.write().unwind(unwind_to) + let mut tree = self.tree.write(); + let res = tree.unwind(unwind_to); + tree.update_tree_metrics(); + res } } diff --git a/crates/interfaces/Cargo.toml b/crates/interfaces/Cargo.toml index 87681561e344..d358cdef0074 100644 --- a/crates/interfaces/Cargo.toml +++ b/crates/interfaces/Cargo.toml @@ -52,5 +52,4 @@ secp256k1 = { workspace = true, features = [ ] } [features] -bench = [] test-utils = ["tokio-stream/sync", "secp256k1", "rand/std_rng"] diff --git a/crates/interfaces/src/lib.rs b/crates/interfaces/src/lib.rs index 41b0fdee47ff..7c92bc21b8bd 100644 --- a/crates/interfaces/src/lib.rs +++ b/crates/interfaces/src/lib.rs @@ -5,7 +5,11 @@ attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) ))] -//! Reth interface bindings +//! A collection of shared traits and error types used in Reth. +//! +//! ## Feature Flags +//! +//! - `test-utils`: Export utilities for testing /// Consensus traits. pub mod consensus; diff --git a/crates/metrics/src/lib.rs b/crates/metrics/src/lib.rs index 65360ada32a3..ff0aaa4b0e01 100644 --- a/crates/metrics/src/lib.rs +++ b/crates/metrics/src/lib.rs @@ -6,6 +6,11 @@ ))] //! Collection of metrics utilities. +//! +//! ## Feature Flags +//! +//! - `common`: Common metrics utilities, such as wrappers around tokio senders and receivers. Pulls +//! in `tokio`. /// Metrics derive macro. pub use reth_metrics_derive::Metrics; diff --git a/crates/net/discv4/src/lib.rs b/crates/net/discv4/src/lib.rs index 49df08c1a005..712b77a00553 100644 --- a/crates/net/discv4/src/lib.rs +++ b/crates/net/discv4/src/lib.rs @@ -17,6 +17,11 @@ //! state and drives the UDP socket. The (optional) [`Discv4`] serves as the frontend to interact //! with the service via a channel. Whenever the underlying table changes service produces a //! [`DiscoveryUpdate`] that listeners will receive. +//! +//! ## Feature Flags +//! +//! - `serde` (default): Enable serde support +//! - `test-utils`: Export utilities for testing use crate::{ error::{DecodePacketError, Discv4Error}, proto::{FindNode, Message, Neighbours, Packet, Ping, Pong}, diff --git a/crates/net/dns/src/lib.rs b/crates/net/dns/src/lib.rs index d32dd00691e4..0edcf3df0751 100644 --- a/crates/net/dns/src/lib.rs +++ b/crates/net/dns/src/lib.rs @@ -6,7 +6,11 @@ ))] //! Implementation of [EIP-1459](https://eips.ethereum.org/EIPS/eip-1459) Node Discovery via DNS. - +//! +//! ## Feature Flags +//! +//! - `serde` (default): Enable serde support +//! - `test-utils`: Export utilities for testing pub use crate::resolver::{DnsResolver, MapResolver, Resolver}; use crate::{ query::{QueryOutcome, QueryPool, ResolveEntryResult, ResolveRootResult}, diff --git a/crates/net/downloaders/src/lib.rs b/crates/net/downloaders/src/lib.rs index c192c9231c6e..5a59412a2ce4 100644 --- a/crates/net/downloaders/src/lib.rs +++ b/crates/net/downloaders/src/lib.rs @@ -7,6 +7,10 @@ #![allow(clippy::result_large_err)] //! Implements the downloader algorithms. +//! +//! ## Feature Flags +//! +//! - `test-utils`: Export utilities for testing /// The collection of algorithms for downloading block bodies. pub mod bodies; diff --git a/crates/net/eth-wire/Cargo.toml b/crates/net/eth-wire/Cargo.toml index c39a527a0819..de43afd7130b 100644 --- a/crates/net/eth-wire/Cargo.toml +++ b/crates/net/eth-wire/Cargo.toml @@ -9,7 +9,7 @@ homepage.workspace = true repository.workspace = true [dependencies] -bytes = "1.4" +bytes.workspace = true thiserror = { workspace = true } serde = { workspace = true, optional = true } @@ -49,7 +49,7 @@ reth-primitives = { workspace = true, features = ["arbitrary"] } reth-tracing = { path = "../../tracing" } ethers-core = { workspace = true, default-features = false } -test-fuzz = "3.0.4" +test-fuzz = "4" tokio-util = { workspace = true, features = ["io", "codec"] } hex-literal = "0.3" hex = "0.4" diff --git a/crates/net/eth-wire/src/lib.rs b/crates/net/eth-wire/src/lib.rs index 44715489b62c..24197e22c81e 100644 --- a/crates/net/eth-wire/src/lib.rs +++ b/crates/net/eth-wire/src/lib.rs @@ -5,6 +5,11 @@ attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) ))] //! Implementation of the `eth` wire protocol. +//! +//! ## Feature Flags +//! +//! - `serde` (default): Enable serde support +//! - `arbitrary`: Adds `proptest` and `arbitrary` support for wire types. pub mod builder; pub mod capability; diff --git a/crates/net/nat/src/lib.rs b/crates/net/nat/src/lib.rs index 6d6bd0536a0a..fadd2d01f614 100644 --- a/crates/net/nat/src/lib.rs +++ b/crates/net/nat/src/lib.rs @@ -6,6 +6,10 @@ ))] //! Helpers for resolving the external IP. +//! +//! ## Feature Flags +//! +//! - `serde` (default): Enable serde support use igd::aio::search_gateway; use pin_project_lite::pin_project; diff --git a/crates/net/network-api/src/lib.rs b/crates/net/network-api/src/lib.rs index 644613c5235e..62af27bc22e6 100644 --- a/crates/net/network-api/src/lib.rs +++ b/crates/net/network-api/src/lib.rs @@ -8,7 +8,10 @@ //! Reth network interface definitions. //! //! Provides abstractions for the reth-network crate. - +//! +//! ## Feature Flags +//! +//! - `serde` (default): Enable serde support use async_trait::async_trait; use reth_eth_wire::DisconnectReason; use reth_primitives::{NodeRecord, PeerId}; diff --git a/crates/net/network/src/lib.rs b/crates/net/network/src/lib.rs index f6e424eb9b09..acf5f408459d 100644 --- a/crates/net/network/src/lib.rs +++ b/crates/net/network/src/lib.rs @@ -107,9 +107,9 @@ //! } //! ``` //! -//! # Features +//! # Feature Flags //! -//! - `serde`: Enable serde support for configuration types (enabled by default). +//! - `serde` (default): Enable serde support for configuration types. //! - `test-utils`: Various utilities helpful for writing tests //! - `geth-tests`: Runs tests that require Geth to be installed locally. diff --git a/crates/payload/builder/src/lib.rs b/crates/payload/builder/src/lib.rs index 2c91a2abf256..49a12ef2ccf5 100644 --- a/crates/payload/builder/src/lib.rs +++ b/crates/payload/builder/src/lib.rs @@ -16,6 +16,10 @@ //! - [PayloadJobGenerator]: a type that knows how to create new jobs for creating payloads based //! on [PayloadAttributes](reth_rpc_types::engine::PayloadAttributes). //! - [PayloadJob]: a type that can yields (better) payloads over time. +//! +//! ## Feature Flags +//! +//! - `test-utils`: Export utilities for testing pub mod database; pub mod error; diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 4661f92bc693..a34e21094d04 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -43,7 +43,7 @@ tokio = { workspace = true, default-features = false, features = ["sync"] } tokio-stream = { workspace = true } # misc -bytes = "1.4" +bytes.workspace = true serde = { workspace = true } serde_json = { workspace = true } serde_with = "2.1.0" @@ -73,7 +73,7 @@ strum = { version = "0.24", features = ["derive"] } [dev-dependencies] serde_json = { workspace = true } hex-literal = "0.3" -test-fuzz = "3.0.4" +test-fuzz = "4" rand = { workspace = true } revm-primitives = { workspace = true, features = ["arbitrary"] } arbitrary = { version = "1.1.7", features = ["derive"] } diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 3084617989c8..4fee46ffb4bb 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -8,7 +8,11 @@ //! Commonly used types in reth. //! //! This crate contains Ethereum primitive types and helper functions. - +//! +//! ## Feature Flags +//! +//! - `arbitrary`: Adds `proptest` and `arbitrary` support for primitive types. +//! - `test-utils`: Export utilities for testing pub mod abi; mod account; pub mod basefee; diff --git a/crates/revm/revm-inspectors/src/lib.rs b/crates/revm/revm-inspectors/src/lib.rs index 04cffd048c81..ff8ba39ffa2f 100644 --- a/crates/revm/revm-inspectors/src/lib.rs +++ b/crates/revm/revm-inspectors/src/lib.rs @@ -5,7 +5,12 @@ attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) ))] -//! revm [Inspector](revm::Inspector) implementations +//! revm [Inspector](revm::Inspector) implementations, such as call tracers +//! +//! ## Feature Flags +//! +//! - `js-tracer` (default): Enables a JavaScript tracer implementation. This pulls in extra +//! dependencies (such as `boa`, `tokio` and `serde_json`). /// An inspector implementation for an EIP2930 Accesslist pub mod access_list; diff --git a/crates/rlp/Cargo.toml b/crates/rlp/Cargo.toml index c7977b49492c..234e9a52c983 100644 --- a/crates/rlp/Cargo.toml +++ b/crates/rlp/Cargo.toml @@ -11,7 +11,7 @@ repository.workspace = true [dependencies] arrayvec = { version = "0.7", default-features = false } auto_impl = "1" -bytes = { version = "1", default-features = false } +bytes.workspace = true ethnum = { version = "1", default-features = false, optional = true } smol_str = { version = "0.1", default-features = false, optional = true } ethereum-types = { version = "0.14", features = ["codec"], optional = true } diff --git a/crates/rlp/src/lib.rs b/crates/rlp/src/lib.rs index c4671f55bfff..1e60ea5dd4b2 100644 --- a/crates/rlp/src/lib.rs +++ b/crates/rlp/src/lib.rs @@ -6,6 +6,15 @@ ))] #![cfg_attr(not(feature = "std"), no_std)] +//! A fast RLP implementation. +//! +//! ## Feature Flags +//! +//! This crate works on `#[no_std]` targets if `std` is not enabled. +//! +//! - `derive`: Enables derive macros. +//! - `std`: Uses the Rust standard library. + #[cfg(feature = "alloc")] extern crate alloc; diff --git a/crates/rpc/ipc/Cargo.toml b/crates/rpc/ipc/Cargo.toml index 7f118f83c2e3..417dfd8239d0 100644 --- a/crates/rpc/ipc/Cargo.toml +++ b/crates/rpc/ipc/Cargo.toml @@ -26,12 +26,9 @@ tower = "0.4" jsonrpsee = { version = "0.18", features = ["server", "client"] } serde_json = { workspace = true } tracing = { workspace = true } -bytes = "1.4" +bytes = { workspace = true } thiserror = { workspace = true } [dev-dependencies] tracing-test = "0.2" tokio-stream = { workspace = true, features = ["sync"] } - -[features] -client = ["jsonrpsee/client", "jsonrpsee/async-client"] diff --git a/crates/rpc/ipc/src/lib.rs b/crates/rpc/ipc/src/lib.rs index f8ed954c16e9..13517148a5ea 100644 --- a/crates/rpc/ipc/src/lib.rs +++ b/crates/rpc/ipc/src/lib.rs @@ -5,7 +5,11 @@ attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) ))] -//! Reth IPC implementation +//! Reth IPC transport implementation +//! +//! ## Feature Flags +//! +//! - `client`: Enables JSON-RPC client support. #[cfg(unix)] pub mod client; diff --git a/crates/rpc/rpc-api/src/lib.rs b/crates/rpc/rpc-api/src/lib.rs index cecbe0f90752..54b8ddb4c12a 100644 --- a/crates/rpc/rpc-api/src/lib.rs +++ b/crates/rpc/rpc-api/src/lib.rs @@ -8,6 +8,10 @@ //! Reth RPC interface definitions //! //! Provides all RPC interfaces. +//! +//! ## Feature Flags +//! +//! - `client`: Enables JSON-RPC client support. mod admin; mod debug; diff --git a/crates/rpc/rpc-builder/src/auth.rs b/crates/rpc/rpc-builder/src/auth.rs index eb83578ee609..edf398117e85 100644 --- a/crates/rpc/rpc-builder/src/auth.rs +++ b/crates/rpc/rpc-builder/src/auth.rs @@ -208,8 +208,13 @@ impl AuthServerConfigBuilder { secret: self.secret, server_config: self.server_config.unwrap_or_else(|| { ServerBuilder::new() - // allows for 300mb responses (for large eth_getLogs deposit logs) - .max_response_body_size(300 * 1024 * 1024) + // This needs to large enough to handle large eth_getLogs responses and maximum + // payload bodies limit for `engine_getPayloadBodiesByRangeV` + // ~750MB per response should be enough + .max_response_body_size(750 * 1024 * 1024) + // bump the default request size slightly, there aren't any methods exposed with + // dynamic request params that can exceed this + .max_request_body_size(25 * 1024 * 1024) .set_id_provider(EthSubscriptionIdProvider::default()) }), } diff --git a/crates/rpc/rpc/Cargo.toml b/crates/rpc/rpc/Cargo.toml index a698109232f6..30b94277f700 100644 --- a/crates/rpc/rpc/Cargo.toml +++ b/crates/rpc/rpc/Cargo.toml @@ -47,7 +47,7 @@ tokio-stream = { workspace = true, features = ["sync"] } tokio-util = "0.7" pin-project = { workspace = true } -bytes = "1.4" +bytes.workspace = true secp256k1 = { workspace = true, features = ["global-context", "rand-std", "recovery"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } diff --git a/crates/rpc/rpc/src/eth/api/call.rs b/crates/rpc/rpc/src/eth/api/call.rs index 63d8d1d3d6ec..f7039b3ea9ca 100644 --- a/crates/rpc/rpc/src/eth/api/call.rs +++ b/crates/rpc/rpc/src/eth/api/call.rs @@ -4,8 +4,8 @@ use crate::{ eth::{ error::{ensure_success, EthApiError, EthResult, RevertError, RpcInvalidTransactionError}, revm_utils::{ - build_call_evm_env, cap_tx_gas_limit_with_caller_allowance, get_precompiles, inspect, - transact, EvmOverrides, + build_call_evm_env, caller_gas_allowance, cap_tx_gas_limit_with_caller_allowance, + get_precompiles, inspect, transact, EvmOverrides, }, EthTransactions, }, @@ -122,19 +122,8 @@ where } // check funds of the sender - let gas_price = env.tx.gas_price; - if gas_price > U256::ZERO { - let mut available_funds = - db.basic(env.tx.caller)?.map(|acc| acc.balance).unwrap_or_default(); - if env.tx.value > available_funds { - return Err(RpcInvalidTransactionError::InsufficientFunds.into()) - } - // subtract transferred value from available funds - // SAFETY: value < available_funds, checked above - available_funds -= env.tx.value; - // amount of gas the sender can afford with the `gas_price` - // SAFETY: gas_price not zero - let allowance = available_funds.checked_div(gas_price).unwrap_or_default(); + if env.tx.gas_price > U256::ZERO { + let allowance = caller_gas_allowance(&mut db, &env.tx)?; if highest_gas_limit > allowance { // cap the highest gas limit by max gas caller can afford with given gas price diff --git a/crates/rpc/rpc/src/eth/revm_utils.rs b/crates/rpc/rpc/src/eth/revm_utils.rs index 2313e19fd643..54e996870af4 100644 --- a/crates/rpc/rpc/src/eth/revm_utils.rs +++ b/crates/rpc/rpc/src/eth/revm_utils.rs @@ -2,7 +2,8 @@ use crate::eth::error::{EthApiError, EthResult, RpcInvalidTransactionError}; use reth_primitives::{ - AccessList, Address, TransactionSigned, TransactionSignedEcRecovered, TxHash, H256, U256, + constants::ETHEREUM_BLOCK_GAS_LIMIT, AccessList, Address, TransactionSigned, + TransactionSignedEcRecovered, TxHash, H256, U256, }; use reth_revm::env::{fill_tx_env, fill_tx_env_with_recovered}; use reth_rpc_types::{ @@ -236,10 +237,21 @@ where apply_block_overrides(*block_overrides, &mut env.block); } - if request_gas.is_none() && env.tx.gas_price > U256::ZERO { - trace!(target: "rpc::eth::call", ?env, "Applying gas limit cap"); - // no gas limit was provided in the request, so we need to cap the request's gas limit - cap_tx_gas_limit_with_caller_allowance(db, &mut env.tx)?; + if request_gas.is_none() { + // No gas limit was provided in the request, so we need to cap the transaction gas limit + if env.tx.gas_price > U256::ZERO { + // If gas price is specified, cap transaction gas limit with caller allowance + trace!(target: "rpc::eth::call", ?env, "Applying gas limit cap with caller allowance"); + cap_tx_gas_limit_with_caller_allowance(db, &mut env.tx)?; + } else { + // If no gas price is specified, use maximum allowed gas limit. The reason for this is + // that both Erigon and Geth use pre-configured gas cap even if it's possible + // to derive the gas limit from the block: + // https://github.com/ledgerwatch/erigon/blob/eae2d9a79cb70dbe30b3a6b79c436872e4605458/cmd/rpcdaemon/commands/trace_adhoc.go#L956 + // https://github.com/ledgerwatch/erigon/blob/eae2d9a79cb70dbe30b3a6b79c436872e4605458/eth/ethconfig/config.go#L94 + trace!(target: "rpc::eth::call", ?env, "Applying gas limit cap as the maximum gas limit"); + env.tx.gas_limit = ETHEREUM_BLOCK_GAS_LIMIT; + } } Ok(env) @@ -305,31 +317,45 @@ pub(crate) fn create_txn_env(block_env: &BlockEnv, request: CallRequest) -> EthR } /// Caps the configured [TxEnv] `gas_limit` with the allowance of the caller. -/// -/// Returns an error if the caller has insufficient funds -pub(crate) fn cap_tx_gas_limit_with_caller_allowance( - mut db: DB, - env: &mut TxEnv, -) -> EthResult<()> +pub(crate) fn cap_tx_gas_limit_with_caller_allowance(db: DB, env: &mut TxEnv) -> EthResult<()> where DB: Database, EthApiError: From<::Error>, { - let mut allowance = db.basic(env.caller)?.map(|acc| acc.balance).unwrap_or_default(); - - // subtract transferred value - allowance = allowance - .checked_sub(env.value) - .ok_or_else(|| RpcInvalidTransactionError::InsufficientFunds)?; - - // cap the gas limit - if let Ok(gas_limit) = allowance.checked_div(env.gas_price).unwrap_or_default().try_into() { + if let Ok(gas_limit) = caller_gas_allowance(db, env)?.try_into() { env.gas_limit = gas_limit; } Ok(()) } +/// Calculates the caller gas allowance. +/// +/// `allowance = (account.balance - tx.value) / tx.gas_price` +/// +/// Returns an error if the caller has insufficient funds. +/// Caution: This assumes non-zero `env.gas_price`. Otherwise, zero allowance will be returned. +pub(crate) fn caller_gas_allowance(mut db: DB, env: &TxEnv) -> EthResult +where + DB: Database, + EthApiError: From<::Error>, +{ + Ok(db + // Get the caller account. + .basic(env.caller)? + // Get the caller balance. + .map(|acc| acc.balance) + .unwrap_or_default() + // Subtract transferred value from the caller balance. + .checked_sub(env.value) + // Return error if the caller has insufficient funds. + .ok_or_else(|| RpcInvalidTransactionError::InsufficientFunds)? + // Calculate the amount of gas the caller can afford with the specified gas price. + .checked_div(env.gas_price) + // This will be 0 if gas price is 0. It is fine, because we check it before. + .unwrap_or_default()) +} + /// Helper type for representing the fees of a [CallRequest] pub(crate) struct CallFees { /// EIP-1559 priority fee diff --git a/crates/staged-sync/src/lib.rs b/crates/staged-sync/src/lib.rs index b32db26cbbc3..e864aa337c31 100644 --- a/crates/staged-sync/src/lib.rs +++ b/crates/staged-sync/src/lib.rs @@ -7,7 +7,7 @@ //! Puts together all the Reth stages in a unified abstraction. //! -//! # Features +//! ## Feature Flags //! //! - `test-utils`: Various utilities helpful for writing tests //! - `geth-tests`: Runs tests that require Geth to be installed locally. diff --git a/crates/stages/src/lib.rs b/crates/stages/src/lib.rs index 14b31668e40d..0a8ba2f10f0a 100644 --- a/crates/stages/src/lib.rs +++ b/crates/stages/src/lib.rs @@ -53,6 +53,10 @@ //! ) //! .build(db, MAINNET.clone()); //! ``` +//! +//! ## Feature Flags +//! +//! - `test-utils`: Export utilities for testing mod error; mod pipeline; mod stage; diff --git a/crates/storage/codecs/Cargo.toml b/crates/storage/codecs/Cargo.toml index 5b3a9497bcfa..3b6719ae0ad8 100644 --- a/crates/storage/codecs/Cargo.toml +++ b/crates/storage/codecs/Cargo.toml @@ -16,7 +16,7 @@ no_codec = ["codecs-derive/no_codec"] arbitrary = ["revm-primitives/arbitrary", "dep:arbitrary", "dep:proptest", "dep:proptest-derive"] [dependencies] -bytes = "1.4" +bytes.workspace = true codecs-derive = { path = "./derive", default-features = false } revm-primitives = { workspace = true, features = ["serde"] } @@ -30,7 +30,7 @@ revm-primitives = { workspace = true, features = ["serde", "arbitrary"] } serde = "1.0" modular-bitfield = "0.11.2" -test-fuzz = "3.0.4" +test-fuzz = "4" arbitrary = { version = "1.1.7", features = ["derive"] } proptest = { version = "1.0" } diff --git a/crates/storage/db/Cargo.toml b/crates/storage/db/Cargo.toml index 57370c3fc1f9..818c22738b74 100644 --- a/crates/storage/db/Cargo.toml +++ b/crates/storage/db/Cargo.toml @@ -32,7 +32,7 @@ secp256k1 = { workspace = true, default-features = false, features = [ modular-bitfield = "0.11.2" # misc -bytes = "1.4" +bytes.workspace = true page_size = "0.4.2" thiserror = { workspace = true } tempfile = { version = "3.3.0", optional = true } @@ -47,10 +47,10 @@ proptest-derive = { version = "0.3", optional = true } # reth libs with arbitrary reth-primitives = { workspace = true, features = ["arbitrary"] } reth-codecs = { path = "../codecs", features = ["arbitrary"] } -reth-interfaces = { workspace = true, features = ["bench"] } +reth-interfaces = { workspace = true } tempfile = "3.3.0" -test-fuzz = "3.0.4" +test-fuzz = "4" pprof = { version = "0.11", features = ["flamegraph", "frame-pointer", "criterion"] } criterion = "0.4.0" diff --git a/crates/storage/provider/Cargo.toml b/crates/storage/provider/Cargo.toml index d270c0c2d0f1..22fcaba5e781 100644 --- a/crates/storage/provider/Cargo.toml +++ b/crates/storage/provider/Cargo.toml @@ -42,5 +42,4 @@ reth-trie = { path = "../../trie", features = ["test-utils"] } parking_lot = "0.12" [features] -bench = [] test-utils = ["reth-rlp"] diff --git a/crates/storage/provider/src/lib.rs b/crates/storage/provider/src/lib.rs index 51b74379525d..5a988cf88cfa 100644 --- a/crates/storage/provider/src/lib.rs +++ b/crates/storage/provider/src/lib.rs @@ -7,6 +7,10 @@ //! This crate contains a collection of traits and trait implementations for common database //! operations. +//! +//! ## Feature Flags +//! +//! - `test-utils`: Export utilities for testing /// Various provider traits. mod traits; diff --git a/crates/transaction-pool/src/lib.rs b/crates/transaction-pool/src/lib.rs index fa1c73b93f93..d0054c9cc407 100644 --- a/crates/transaction-pool/src/lib.rs +++ b/crates/transaction-pool/src/lib.rs @@ -79,7 +79,11 @@ //! The transaction pool will be used by separate consumers (RPC, P2P), to make sharing easier, the //! [`Pool`](crate::Pool) type is just an `Arc` wrapper around `PoolInner`. This is the usable type //! that provides the `TransactionPool` interface. - +//! +//! ## Feature Flags +//! +//! - `serde` (default): Enable serde support +//! - `test-utils`: Export utilities for testing use crate::pool::PoolInner; use aquamarine as _; use reth_primitives::{Address, TxHash, U256}; diff --git a/crates/trie/src/lib.rs b/crates/trie/src/lib.rs index ea45b5fcadc9..d52d4acc06c3 100644 --- a/crates/trie/src/lib.rs +++ b/crates/trie/src/lib.rs @@ -8,6 +8,10 @@ //! The implementation of Merkle Patricia Trie, a cryptographically //! authenticated radix trie that is used to store key-value bindings. //! +//! +//! ## Feature Flags +//! +//! - `test-utils`: Export utilities for testing /// The Ethereum account as represented in the trie. pub mod account;