reth_node_core/args/
engine.rs

1//! clap [Args](clap::Args) for engine purposes
2
3use clap::Args;
4use reth_engine_primitives::{TreeConfig, DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE};
5
6use crate::node_config::{
7    DEFAULT_CROSS_BLOCK_CACHE_SIZE_MB, DEFAULT_MAX_PROOF_TASK_CONCURRENCY,
8    DEFAULT_MEMORY_BLOCK_BUFFER_TARGET, DEFAULT_PERSISTENCE_THRESHOLD, DEFAULT_RESERVED_CPU_CORES,
9};
10
11/// Parameters for configuring the engine driver.
12#[derive(Debug, Clone, Args, PartialEq, Eq)]
13#[command(next_help_heading = "Engine")]
14pub struct EngineArgs {
15    /// Configure persistence threshold for engine experimental.
16    #[arg(long = "engine.persistence-threshold", default_value_t = DEFAULT_PERSISTENCE_THRESHOLD)]
17    pub persistence_threshold: u64,
18
19    /// Configure the target number of blocks to keep in memory.
20    #[arg(long = "engine.memory-block-buffer-target", default_value_t = DEFAULT_MEMORY_BLOCK_BUFFER_TARGET)]
21    pub memory_block_buffer_target: u64,
22
23    /// Enable legacy state root
24    #[arg(long = "engine.legacy-state-root", default_value = "false")]
25    pub legacy_state_root_task_enabled: bool,
26
27    /// CAUTION: This CLI flag has no effect anymore, use --engine.disable-caching-and-prewarming
28    /// if you want to disable caching and prewarming
29    #[arg(long = "engine.caching-and-prewarming", default_value = "true", hide = true)]
30    #[deprecated]
31    pub caching_and_prewarming_enabled: bool,
32
33    /// Disable cross-block caching and parallel prewarming
34    #[arg(long = "engine.disable-caching-and-prewarming")]
35    pub caching_and_prewarming_disabled: bool,
36
37    /// CAUTION: This CLI flag has no effect anymore, use --engine.disable-parallel-sparse-trie
38    /// if you want to disable usage of the `ParallelSparseTrie`.
39    #[deprecated]
40    #[arg(long = "engine.parallel-sparse-trie", default_value = "true", hide = true)]
41    pub parallel_sparse_trie_enabled: bool,
42
43    /// Disable the parallel sparse trie in the engine.
44    #[arg(long = "engine.disable-parallel-sparse-trie", default_value = "false")]
45    pub parallel_sparse_trie_disabled: bool,
46
47    /// Enable state provider latency metrics. This allows the engine to collect and report stats
48    /// about how long state provider calls took during execution, but this does introduce slight
49    /// overhead to state provider calls.
50    #[arg(long = "engine.state-provider-metrics", default_value = "false")]
51    pub state_provider_metrics: bool,
52
53    /// Configure the size of cross-block cache in megabytes
54    #[arg(long = "engine.cross-block-cache-size", default_value_t = DEFAULT_CROSS_BLOCK_CACHE_SIZE_MB)]
55    pub cross_block_cache_size: u64,
56
57    /// Enable comparing trie updates from the state root task to the trie updates from the regular
58    /// state root calculation.
59    #[arg(long = "engine.state-root-task-compare-updates")]
60    pub state_root_task_compare_updates: bool,
61
62    /// Enables accepting requests hash instead of an array of requests in `engine_newPayloadV4`.
63    #[arg(long = "engine.accept-execution-requests-hash")]
64    pub accept_execution_requests_hash: bool,
65
66    /// Configure the maximum number of concurrent proof tasks
67    #[arg(long = "engine.max-proof-task-concurrency", default_value_t = DEFAULT_MAX_PROOF_TASK_CONCURRENCY)]
68    pub max_proof_task_concurrency: u64,
69
70    /// Whether multiproof task should chunk proof targets.
71    #[arg(long = "engine.multiproof-chunking", default_value = "true")]
72    pub multiproof_chunking_enabled: bool,
73
74    /// Multiproof task chunk size for proof targets.
75    #[arg(long = "engine.multiproof-chunk-size", default_value_t = DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE)]
76    pub multiproof_chunk_size: usize,
77
78    /// Configure the number of reserved CPU cores for non-reth processes
79    #[arg(long = "engine.reserved-cpu-cores", default_value_t = DEFAULT_RESERVED_CPU_CORES)]
80    pub reserved_cpu_cores: usize,
81
82    /// CAUTION: This CLI flag has no effect anymore, use --engine.disable-precompile-cache
83    /// if you want to disable precompile cache
84    #[arg(long = "engine.precompile-cache", default_value = "true", hide = true)]
85    #[deprecated]
86    pub precompile_cache_enabled: bool,
87
88    /// Disable precompile cache
89    #[arg(long = "engine.disable-precompile-cache", default_value = "false")]
90    pub precompile_cache_disabled: bool,
91
92    /// Enable state root fallback, useful for testing
93    #[arg(long = "engine.state-root-fallback", default_value = "false")]
94    pub state_root_fallback: bool,
95
96    /// Always process payload attributes and begin a payload build process even if
97    /// `forkchoiceState.headBlockHash` is already the canonical head or an ancestor. See
98    /// `TreeConfig::always_process_payload_attributes_on_canonical_head` for more details.
99    ///
100    /// Note: This is a no-op on OP Stack.
101    #[arg(
102        long = "engine.always-process-payload-attributes-on-canonical-head",
103        default_value = "false"
104    )]
105    pub always_process_payload_attributes_on_canonical_head: bool,
106
107    /// Allow unwinding canonical header to ancestor during forkchoice updates.
108    /// See `TreeConfig::unwind_canonical_header` for more details.
109    #[arg(long = "engine.allow-unwind-canonical-header", default_value = "false")]
110    pub allow_unwind_canonical_header: bool,
111
112    /// Configure the number of storage proof workers in the Tokio blocking pool.
113    /// If not specified, defaults to 2x available parallelism, clamped between 2 and 64.
114    #[arg(long = "engine.storage-worker-count")]
115    pub storage_worker_count: Option<usize>,
116}
117
118#[allow(deprecated)]
119impl Default for EngineArgs {
120    fn default() -> Self {
121        Self {
122            persistence_threshold: DEFAULT_PERSISTENCE_THRESHOLD,
123            memory_block_buffer_target: DEFAULT_MEMORY_BLOCK_BUFFER_TARGET,
124            legacy_state_root_task_enabled: false,
125            state_root_task_compare_updates: false,
126            caching_and_prewarming_enabled: true,
127            caching_and_prewarming_disabled: false,
128            parallel_sparse_trie_enabled: true,
129            parallel_sparse_trie_disabled: false,
130            state_provider_metrics: false,
131            cross_block_cache_size: DEFAULT_CROSS_BLOCK_CACHE_SIZE_MB,
132            accept_execution_requests_hash: false,
133            max_proof_task_concurrency: DEFAULT_MAX_PROOF_TASK_CONCURRENCY,
134            multiproof_chunking_enabled: true,
135            multiproof_chunk_size: DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE,
136            reserved_cpu_cores: DEFAULT_RESERVED_CPU_CORES,
137            precompile_cache_enabled: true,
138            precompile_cache_disabled: false,
139            state_root_fallback: false,
140            always_process_payload_attributes_on_canonical_head: false,
141            allow_unwind_canonical_header: false,
142            storage_worker_count: None,
143        }
144    }
145}
146
147impl EngineArgs {
148    /// Creates a [`TreeConfig`] from the engine arguments.
149    pub fn tree_config(&self) -> TreeConfig {
150        let mut config = TreeConfig::default()
151            .with_persistence_threshold(self.persistence_threshold)
152            .with_memory_block_buffer_target(self.memory_block_buffer_target)
153            .with_legacy_state_root(self.legacy_state_root_task_enabled)
154            .without_caching_and_prewarming(self.caching_and_prewarming_disabled)
155            .with_disable_parallel_sparse_trie(self.parallel_sparse_trie_disabled)
156            .with_state_provider_metrics(self.state_provider_metrics)
157            .with_always_compare_trie_updates(self.state_root_task_compare_updates)
158            .with_cross_block_cache_size(self.cross_block_cache_size * 1024 * 1024)
159            .with_max_proof_task_concurrency(self.max_proof_task_concurrency)
160            .with_multiproof_chunking_enabled(self.multiproof_chunking_enabled)
161            .with_multiproof_chunk_size(self.multiproof_chunk_size)
162            .with_reserved_cpu_cores(self.reserved_cpu_cores)
163            .without_precompile_cache(self.precompile_cache_disabled)
164            .with_state_root_fallback(self.state_root_fallback)
165            .with_always_process_payload_attributes_on_canonical_head(
166                self.always_process_payload_attributes_on_canonical_head,
167            )
168            .with_unwind_canonical_header(self.allow_unwind_canonical_header);
169
170        if let Some(count) = self.storage_worker_count {
171            config = config.with_storage_worker_count(count);
172        }
173
174        config
175    }
176}
177
178#[cfg(test)]
179mod tests {
180    use super::*;
181    use clap::Parser;
182
183    /// A helper type to parse Args more easily
184    #[derive(Parser)]
185    struct CommandParser<T: Args> {
186        #[command(flatten)]
187        args: T,
188    }
189
190    #[test]
191    fn test_parse_engine_args() {
192        let default_args = EngineArgs::default();
193        let args = CommandParser::<EngineArgs>::parse_from(["reth"]).args;
194        assert_eq!(args, default_args);
195    }
196}