Skip to main content

reth_rpc_eth_types/builder/
config.rs

1//! Configuration for `eth` namespace APIs.
2
3use std::time::Duration;
4
5use crate::{
6    EthStateCacheConfig, FeeHistoryCacheConfig, ForwardConfig, GasPriceOracleConfig,
7    RPC_DEFAULT_GAS_CAP,
8};
9use reqwest::Url;
10use reth_rpc_server_types::constants::{
11    default_max_tracing_requests, DEFAULT_ETH_PROOF_WINDOW, DEFAULT_MAX_BLOCKING_IO_REQUEST,
12    DEFAULT_MAX_BLOCKS_PER_FILTER, DEFAULT_MAX_LOGS_PER_RESPONSE, DEFAULT_MAX_SIMULATE_BLOCKS,
13    DEFAULT_MAX_TRACE_FILTER_BLOCKS, DEFAULT_PROOF_PERMITS,
14    RPC_DEFAULT_SEND_RAW_TX_SYNC_TIMEOUT_SECS,
15};
16use serde::{Deserialize, Serialize};
17
18/// Default value for stale filter ttl
19pub const DEFAULT_STALE_FILTER_TTL: Duration = Duration::from_secs(5 * 60);
20
21/// Config for the locally built pending block
22#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Default)]
23#[serde(rename_all = "lowercase")]
24pub enum PendingBlockKind {
25    /// Return a pending block with header only, no transactions included
26    Empty,
27    /// Return null/no pending block
28    None,
29    /// Return a pending block with all transactions from the mempool (default behavior)
30    #[default]
31    Full,
32}
33
34impl std::str::FromStr for PendingBlockKind {
35    type Err = String;
36
37    fn from_str(s: &str) -> Result<Self, Self::Err> {
38        match s.to_lowercase().as_str() {
39            "empty" => Ok(Self::Empty),
40            "none" => Ok(Self::None),
41            "full" => Ok(Self::Full),
42            _ => Err(format!(
43                "Invalid pending block kind: {s}. Valid options are: empty, none, full"
44            )),
45        }
46    }
47}
48
49impl PendingBlockKind {
50    /// Returns true if the pending block kind is `None`
51    pub const fn is_none(&self) -> bool {
52        matches!(self, Self::None)
53    }
54
55    /// Returns true if the pending block kind is `Empty`
56    pub const fn is_empty(&self) -> bool {
57        matches!(self, Self::Empty)
58    }
59}
60
61/// Additional config values for the eth namespace.
62#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
63pub struct EthConfig {
64    /// Settings for the caching layer
65    pub cache: EthStateCacheConfig,
66    /// Settings for the gas price oracle
67    pub gas_oracle: GasPriceOracleConfig,
68    /// The maximum number of blocks into the past for generating state proofs.
69    pub eth_proof_window: u64,
70    /// The maximum number of tracing calls that can be executed in concurrently.
71    pub max_tracing_requests: usize,
72    /// The maximum number of blocking IO calls that can be executed in concurrently.
73    ///
74    /// Requests such as `eth_call`, `eth_estimateGas` and alike require evm execution, which is
75    /// considered blocking since it's usually more heavy on the IO side but also CPU constrained.
76    /// It is expected that these are spawned as short lived blocking tokio tasks. This config
77    /// determines how many can be spawned concurrently, to avoid a build up in the tokio's
78    /// blocking pool queue since there's only a limited number of threads available. This setting
79    /// restricts how many tasks are spawned concurrently.
80    pub max_blocking_io_requests: usize,
81    /// Maximum number of blocks for `trace_filter` requests.
82    pub max_trace_filter_blocks: u64,
83    /// Maximum number of blocks that could be scanned per filter request in `eth_getLogs` calls.
84    pub max_blocks_per_filter: u64,
85    /// Maximum number of logs that can be returned in a single response in `eth_getLogs` calls.
86    pub max_logs_per_response: usize,
87    /// Gas limit for `eth_call`, `eth_estimateGas`, and call tracing RPC methods.
88    ///
89    /// Defaults to [`RPC_DEFAULT_GAS_CAP`]
90    pub rpc_gas_cap: u64,
91    /// Max number of blocks for `eth_simulateV1`.
92    pub rpc_max_simulate_blocks: u64,
93    /// Whether to compute state roots for `eth_simulateV1` responses.
94    pub compute_state_root_for_eth_simulate: bool,
95    ///
96    /// Sets TTL for stale filters
97    pub stale_filter_ttl: Duration,
98    /// Settings for the fee history cache
99    pub fee_history_cache: FeeHistoryCacheConfig,
100    /// The maximum number of getproof calls that can be executed concurrently.
101    pub proof_permits: usize,
102    /// Maximum batch size for transaction pool insertions.
103    pub max_batch_size: usize,
104    /// Controls how pending blocks are built when requested via RPC methods
105    pub pending_block_kind: PendingBlockKind,
106    /// The raw transaction forwarder.
107    pub raw_tx_forwarder: ForwardConfig,
108    /// Timeout duration for `send_raw_transaction_sync` RPC method.
109    pub send_raw_transaction_sync_timeout: Duration,
110    /// Maximum memory the EVM can allocate per RPC request.
111    pub rpc_evm_memory_limit: u64,
112    /// Whether to force upcasting EIP-4844 blob sidecars to EIP-7594 format when Osaka is active.
113    ///
114    /// This is disabled by default, allowing blob transactions with EIP-4844 sidecars to be
115    /// submitted without automatic conversion.
116    pub force_blob_sidecar_upcasting: bool,
117}
118
119impl EthConfig {
120    /// Returns the filter config for the `eth_filter` handler.
121    pub fn filter_config(&self) -> EthFilterConfig {
122        EthFilterConfig::default()
123            .max_blocks_per_filter(self.max_blocks_per_filter)
124            .max_logs_per_response(self.max_logs_per_response)
125            .stale_filter_ttl(self.stale_filter_ttl)
126    }
127}
128
129impl Default for EthConfig {
130    fn default() -> Self {
131        Self {
132            cache: EthStateCacheConfig::default(),
133            gas_oracle: GasPriceOracleConfig::default(),
134            eth_proof_window: DEFAULT_ETH_PROOF_WINDOW,
135            max_tracing_requests: default_max_tracing_requests(),
136            max_blocking_io_requests: DEFAULT_MAX_BLOCKING_IO_REQUEST,
137            max_trace_filter_blocks: DEFAULT_MAX_TRACE_FILTER_BLOCKS,
138            max_blocks_per_filter: DEFAULT_MAX_BLOCKS_PER_FILTER,
139            max_logs_per_response: DEFAULT_MAX_LOGS_PER_RESPONSE,
140            rpc_gas_cap: RPC_DEFAULT_GAS_CAP.into(),
141            rpc_max_simulate_blocks: DEFAULT_MAX_SIMULATE_BLOCKS,
142            compute_state_root_for_eth_simulate: false,
143            stale_filter_ttl: DEFAULT_STALE_FILTER_TTL,
144            fee_history_cache: FeeHistoryCacheConfig::default(),
145            proof_permits: DEFAULT_PROOF_PERMITS,
146            max_batch_size: 1,
147            pending_block_kind: PendingBlockKind::Full,
148            raw_tx_forwarder: ForwardConfig::default(),
149            send_raw_transaction_sync_timeout: RPC_DEFAULT_SEND_RAW_TX_SYNC_TIMEOUT_SECS,
150            rpc_evm_memory_limit: (1 << 32) - 1,
151            force_blob_sidecar_upcasting: false,
152        }
153    }
154}
155
156impl EthConfig {
157    /// Configures the caching layer settings
158    pub const fn state_cache(mut self, cache: EthStateCacheConfig) -> Self {
159        self.cache = cache;
160        self
161    }
162
163    /// Configures the gas price oracle settings
164    pub const fn gpo_config(mut self, gas_oracle_config: GasPriceOracleConfig) -> Self {
165        self.gas_oracle = gas_oracle_config;
166        self
167    }
168
169    /// Configures the maximum number of tracing requests
170    pub const fn max_tracing_requests(mut self, max_requests: usize) -> Self {
171        self.max_tracing_requests = max_requests;
172        self
173    }
174
175    /// Configures the maximum number of blocking IO requests
176    pub const fn max_blocking_io_requests(mut self, max_requests: usize) -> Self {
177        self.max_blocking_io_requests = max_requests;
178        self
179    }
180
181    /// Configures the maximum block length to scan per `eth_getLogs` request
182    pub const fn max_blocks_per_filter(mut self, max_blocks: u64) -> Self {
183        self.max_blocks_per_filter = max_blocks;
184        self
185    }
186
187    /// Configures the maximum number of blocks for `trace_filter` requests
188    pub const fn max_trace_filter_blocks(mut self, max_blocks: u64) -> Self {
189        self.max_trace_filter_blocks = max_blocks;
190        self
191    }
192
193    /// Configures the maximum number of logs per response
194    pub const fn max_logs_per_response(mut self, max_logs: usize) -> Self {
195        self.max_logs_per_response = max_logs;
196        self
197    }
198
199    /// Configures the maximum gas limit for `eth_call`, `eth_estimateGas`, and call tracing RPC
200    /// methods.
201    pub const fn rpc_gas_cap(mut self, rpc_gas_cap: u64) -> Self {
202        self.rpc_gas_cap = rpc_gas_cap;
203        self
204    }
205
206    /// Configures the maximum gas limit for `eth_call` and call tracing RPC methods
207    pub const fn rpc_max_simulate_blocks(mut self, max_blocks: u64) -> Self {
208        self.rpc_max_simulate_blocks = max_blocks;
209        self
210    }
211
212    /// Configures whether to compute state roots for `eth_simulateV1` responses.
213    pub const fn compute_state_root_for_eth_simulate(mut self, enabled: bool) -> Self {
214        self.compute_state_root_for_eth_simulate = enabled;
215        self
216    }
217
218    /// Configures the maximum proof window for historical proof generation.
219    pub const fn eth_proof_window(mut self, window: u64) -> Self {
220        self.eth_proof_window = window;
221        self
222    }
223
224    /// Configures the number of getproof requests
225    pub const fn proof_permits(mut self, permits: usize) -> Self {
226        self.proof_permits = permits;
227        self
228    }
229
230    /// Configures the maximum batch size for transaction pool insertions
231    pub const fn max_batch_size(mut self, max_batch_size: usize) -> Self {
232        self.max_batch_size = max_batch_size;
233        self
234    }
235
236    /// Configures the pending block config
237    pub const fn pending_block_kind(mut self, pending_block_kind: PendingBlockKind) -> Self {
238        self.pending_block_kind = pending_block_kind;
239        self
240    }
241
242    /// Configures the raw transaction forwarder.
243    pub fn raw_tx_forwarder(mut self, tx_forwarder: Option<Url>) -> Self {
244        if let Some(tx_forwarder) = tx_forwarder {
245            self.raw_tx_forwarder.tx_forwarder = Some(tx_forwarder);
246        }
247        self
248    }
249
250    /// Configures the timeout duration for `send_raw_transaction_sync` RPC method.
251    pub const fn send_raw_transaction_sync_timeout(mut self, timeout: Duration) -> Self {
252        self.send_raw_transaction_sync_timeout = timeout;
253        self
254    }
255
256    /// Configures the maximum memory the EVM can allocate per RPC request.
257    pub const fn rpc_evm_memory_limit(mut self, memory_limit: u64) -> Self {
258        self.rpc_evm_memory_limit = memory_limit;
259        self
260    }
261
262    /// Configures whether to force upcasting EIP-4844 blob sidecars to EIP-7594 format.
263    pub const fn force_blob_sidecar_upcasting(mut self, force: bool) -> Self {
264        self.force_blob_sidecar_upcasting = force;
265        self
266    }
267}
268
269/// Config for the filter
270#[derive(Debug, Clone, PartialEq, Eq)]
271pub struct EthFilterConfig {
272    /// Maximum number of blocks that a filter can scan for logs.
273    ///
274    /// If `None` then no limit is enforced.
275    pub max_blocks_per_filter: Option<u64>,
276    /// Maximum number of logs that can be returned in a single response in `eth_getLogs` calls.
277    ///
278    /// If `None` then no limit is enforced.
279    pub max_logs_per_response: Option<usize>,
280    /// How long a filter remains valid after the last poll.
281    ///
282    /// A filter is considered stale if it has not been polled for longer than this duration and
283    /// will be removed.
284    pub stale_filter_ttl: Duration,
285}
286
287impl EthFilterConfig {
288    /// Sets the maximum number of blocks that a filter can scan for logs.
289    pub const fn max_blocks_per_filter(mut self, num: u64) -> Self {
290        self.max_blocks_per_filter = Some(num);
291        self
292    }
293
294    /// Sets the maximum number of logs that can be returned in a single response in `eth_getLogs`
295    /// calls.
296    pub const fn max_logs_per_response(mut self, num: usize) -> Self {
297        self.max_logs_per_response = Some(num);
298        self
299    }
300
301    /// Sets how long a filter remains valid after the last poll before it will be removed.
302    pub const fn stale_filter_ttl(mut self, duration: Duration) -> Self {
303        self.stale_filter_ttl = duration;
304        self
305    }
306}
307
308impl Default for EthFilterConfig {
309    fn default() -> Self {
310        Self {
311            max_blocks_per_filter: None,
312            max_logs_per_response: None,
313            // 5min
314            stale_filter_ttl: DEFAULT_STALE_FILTER_TTL,
315        }
316    }
317}