Skip to main content

reth_node_core/args/
engine.rs

1//! clap [Args](clap::Args) for engine purposes
2
3use clap::{builder::Resettable, Args};
4use reth_engine_primitives::{
5    TreeConfig, DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE, DEFAULT_SPARSE_TRIE_MAX_STORAGE_TRIES,
6    DEFAULT_SPARSE_TRIE_PRUNE_DEPTH,
7};
8use std::{sync::OnceLock, time::Duration};
9
10use crate::node_config::{
11    DEFAULT_CROSS_BLOCK_CACHE_SIZE_MB, DEFAULT_MEMORY_BLOCK_BUFFER_TARGET,
12    DEFAULT_PERSISTENCE_THRESHOLD, DEFAULT_RESERVED_CPU_CORES,
13};
14
15/// Global static engine defaults
16static ENGINE_DEFAULTS: OnceLock<DefaultEngineValues> = OnceLock::new();
17
18/// Default values for engine that can be customized
19///
20/// Global defaults can be set via [`DefaultEngineValues::try_init`].
21#[derive(Debug, Clone)]
22pub struct DefaultEngineValues {
23    persistence_threshold: u64,
24    memory_block_buffer_target: u64,
25    legacy_state_root_task_enabled: bool,
26    state_cache_disabled: bool,
27    prewarming_disabled: bool,
28    state_provider_metrics: bool,
29    cross_block_cache_size: usize,
30    state_root_task_compare_updates: bool,
31    accept_execution_requests_hash: bool,
32    multiproof_chunking_enabled: bool,
33    multiproof_chunk_size: usize,
34    reserved_cpu_cores: usize,
35    precompile_cache_disabled: bool,
36    state_root_fallback: bool,
37    always_process_payload_attributes_on_canonical_head: bool,
38    allow_unwind_canonical_header: bool,
39    storage_worker_count: Option<usize>,
40    account_worker_count: Option<usize>,
41    disable_proof_v2: bool,
42    cache_metrics_disabled: bool,
43    disable_trie_cache: bool,
44    sparse_trie_prune_depth: usize,
45    sparse_trie_max_storage_tries: usize,
46    disable_sparse_trie_cache_pruning: bool,
47    state_root_task_timeout: Option<String>,
48}
49
50impl DefaultEngineValues {
51    /// Initialize the global engine defaults with this configuration
52    pub fn try_init(self) -> Result<(), Self> {
53        ENGINE_DEFAULTS.set(self)
54    }
55
56    /// Get a reference to the global engine defaults
57    pub fn get_global() -> &'static Self {
58        ENGINE_DEFAULTS.get_or_init(Self::default)
59    }
60
61    /// Set the default persistence threshold
62    pub const fn with_persistence_threshold(mut self, v: u64) -> Self {
63        self.persistence_threshold = v;
64        self
65    }
66
67    /// Set the default memory block buffer target
68    pub const fn with_memory_block_buffer_target(mut self, v: u64) -> Self {
69        self.memory_block_buffer_target = v;
70        self
71    }
72
73    /// Set whether to enable legacy state root task by default
74    pub const fn with_legacy_state_root_task_enabled(mut self, v: bool) -> Self {
75        self.legacy_state_root_task_enabled = v;
76        self
77    }
78
79    /// Set whether to disable state cache by default
80    pub const fn with_state_cache_disabled(mut self, v: bool) -> Self {
81        self.state_cache_disabled = v;
82        self
83    }
84
85    /// Set whether to disable prewarming by default
86    pub const fn with_prewarming_disabled(mut self, v: bool) -> Self {
87        self.prewarming_disabled = v;
88        self
89    }
90
91    /// Set whether to enable state provider metrics by default
92    pub const fn with_state_provider_metrics(mut self, v: bool) -> Self {
93        self.state_provider_metrics = v;
94        self
95    }
96
97    /// Set the default cross-block cache size in MB
98    pub const fn with_cross_block_cache_size(mut self, v: usize) -> Self {
99        self.cross_block_cache_size = v;
100        self
101    }
102
103    /// Set whether to compare state root task updates by default
104    pub const fn with_state_root_task_compare_updates(mut self, v: bool) -> Self {
105        self.state_root_task_compare_updates = v;
106        self
107    }
108
109    /// Set whether to accept execution requests hash by default
110    pub const fn with_accept_execution_requests_hash(mut self, v: bool) -> Self {
111        self.accept_execution_requests_hash = v;
112        self
113    }
114
115    /// Set whether to enable multiproof chunking by default
116    pub const fn with_multiproof_chunking_enabled(mut self, v: bool) -> Self {
117        self.multiproof_chunking_enabled = v;
118        self
119    }
120
121    /// Set the default multiproof chunk size
122    pub const fn with_multiproof_chunk_size(mut self, v: usize) -> Self {
123        self.multiproof_chunk_size = v;
124        self
125    }
126
127    /// Set the default number of reserved CPU cores
128    pub const fn with_reserved_cpu_cores(mut self, v: usize) -> Self {
129        self.reserved_cpu_cores = v;
130        self
131    }
132
133    /// Set whether to disable precompile cache by default
134    pub const fn with_precompile_cache_disabled(mut self, v: bool) -> Self {
135        self.precompile_cache_disabled = v;
136        self
137    }
138
139    /// Set whether to enable state root fallback by default
140    pub const fn with_state_root_fallback(mut self, v: bool) -> Self {
141        self.state_root_fallback = v;
142        self
143    }
144
145    /// Set whether to always process payload attributes on canonical head by default
146    pub const fn with_always_process_payload_attributes_on_canonical_head(
147        mut self,
148        v: bool,
149    ) -> Self {
150        self.always_process_payload_attributes_on_canonical_head = v;
151        self
152    }
153
154    /// Set whether to allow unwinding canonical header by default
155    pub const fn with_allow_unwind_canonical_header(mut self, v: bool) -> Self {
156        self.allow_unwind_canonical_header = v;
157        self
158    }
159
160    /// Set the default storage worker count
161    pub const fn with_storage_worker_count(mut self, v: Option<usize>) -> Self {
162        self.storage_worker_count = v;
163        self
164    }
165
166    /// Set the default account worker count
167    pub const fn with_account_worker_count(mut self, v: Option<usize>) -> Self {
168        self.account_worker_count = v;
169        self
170    }
171
172    /// Set whether to disable proof V2 by default
173    pub const fn with_disable_proof_v2(mut self, v: bool) -> Self {
174        self.disable_proof_v2 = v;
175        self
176    }
177
178    /// Set whether to disable cache metrics by default
179    pub const fn with_cache_metrics_disabled(mut self, v: bool) -> Self {
180        self.cache_metrics_disabled = v;
181        self
182    }
183
184    /// Set whether to disable sparse trie cache by default
185    pub const fn with_disable_trie_cache(mut self, v: bool) -> Self {
186        self.disable_trie_cache = v;
187        self
188    }
189
190    /// Set the sparse trie prune depth by default
191    pub const fn with_sparse_trie_prune_depth(mut self, v: usize) -> Self {
192        self.sparse_trie_prune_depth = v;
193        self
194    }
195
196    /// Set the maximum number of storage tries to retain after sparse trie pruning by default
197    pub const fn with_sparse_trie_max_storage_tries(mut self, v: usize) -> Self {
198        self.sparse_trie_max_storage_tries = v;
199        self
200    }
201
202    /// Set whether to disable sparse trie cache pruning by default
203    pub const fn with_disable_sparse_trie_cache_pruning(mut self, v: bool) -> Self {
204        self.disable_sparse_trie_cache_pruning = v;
205        self
206    }
207
208    /// Set the default state root task timeout
209    pub fn with_state_root_task_timeout(mut self, v: Option<String>) -> Self {
210        self.state_root_task_timeout = v;
211        self
212    }
213}
214
215impl Default for DefaultEngineValues {
216    fn default() -> Self {
217        Self {
218            persistence_threshold: DEFAULT_PERSISTENCE_THRESHOLD,
219            memory_block_buffer_target: DEFAULT_MEMORY_BLOCK_BUFFER_TARGET,
220            legacy_state_root_task_enabled: false,
221            state_cache_disabled: false,
222            prewarming_disabled: false,
223            state_provider_metrics: false,
224            cross_block_cache_size: DEFAULT_CROSS_BLOCK_CACHE_SIZE_MB,
225            state_root_task_compare_updates: false,
226            accept_execution_requests_hash: false,
227            multiproof_chunking_enabled: true,
228            multiproof_chunk_size: DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE,
229            reserved_cpu_cores: DEFAULT_RESERVED_CPU_CORES,
230            precompile_cache_disabled: false,
231            state_root_fallback: false,
232            always_process_payload_attributes_on_canonical_head: false,
233            allow_unwind_canonical_header: false,
234            storage_worker_count: None,
235            account_worker_count: None,
236            disable_proof_v2: false,
237            cache_metrics_disabled: false,
238            disable_trie_cache: false,
239            sparse_trie_prune_depth: DEFAULT_SPARSE_TRIE_PRUNE_DEPTH,
240            sparse_trie_max_storage_tries: DEFAULT_SPARSE_TRIE_MAX_STORAGE_TRIES,
241            disable_sparse_trie_cache_pruning: false,
242            state_root_task_timeout: Some("1s".to_string()),
243        }
244    }
245}
246
247/// Parameters for configuring the engine driver.
248#[derive(Debug, Clone, Args, PartialEq, Eq)]
249#[command(next_help_heading = "Engine")]
250pub struct EngineArgs {
251    /// Configure persistence threshold for the engine. This determines how many canonical blocks
252    /// must be in-memory, ahead of the last persisted block, before flushing canonical blocks to
253    /// disk again.
254    ///
255    /// To persist blocks as fast as the node receives them, set this value to zero. This will
256    /// cause more frequent DB writes.
257    #[arg(long = "engine.persistence-threshold", default_value_t = DefaultEngineValues::get_global().persistence_threshold)]
258    pub persistence_threshold: u64,
259
260    /// Configure the target number of blocks to keep in memory.
261    #[arg(long = "engine.memory-block-buffer-target", default_value_t = DefaultEngineValues::get_global().memory_block_buffer_target)]
262    pub memory_block_buffer_target: u64,
263
264    /// Enable legacy state root
265    #[arg(long = "engine.legacy-state-root", default_value_t = DefaultEngineValues::get_global().legacy_state_root_task_enabled)]
266    pub legacy_state_root_task_enabled: bool,
267
268    /// CAUTION: This CLI flag has no effect anymore, use --engine.disable-caching-and-prewarming
269    /// if you want to disable caching and prewarming
270    #[arg(long = "engine.caching-and-prewarming", default_value = "true", hide = true)]
271    #[deprecated]
272    pub caching_and_prewarming_enabled: bool,
273
274    /// Disable state cache
275    #[arg(long = "engine.disable-state-cache", default_value_t = DefaultEngineValues::get_global().state_cache_disabled)]
276    pub state_cache_disabled: bool,
277
278    /// Disable parallel prewarming
279    #[arg(long = "engine.disable-prewarming", alias = "engine.disable-caching-and-prewarming", default_value_t = DefaultEngineValues::get_global().prewarming_disabled)]
280    pub prewarming_disabled: bool,
281
282    /// CAUTION: This CLI flag has no effect anymore. The parallel sparse trie is always enabled.
283    #[deprecated]
284    #[arg(long = "engine.parallel-sparse-trie", default_value = "true", hide = true)]
285    pub parallel_sparse_trie_enabled: bool,
286
287    /// CAUTION: This CLI flag has no effect anymore. The parallel sparse trie is always enabled.
288    #[deprecated]
289    #[arg(long = "engine.disable-parallel-sparse-trie", default_value = "false", hide = true)]
290    pub parallel_sparse_trie_disabled: bool,
291
292    /// Enable state provider latency metrics. This allows the engine to collect and report stats
293    /// about how long state provider calls took during execution, but this does introduce slight
294    /// overhead to state provider calls.
295    #[arg(long = "engine.state-provider-metrics", default_value_t = DefaultEngineValues::get_global().state_provider_metrics)]
296    pub state_provider_metrics: bool,
297
298    /// Configure the size of cross-block cache in megabytes
299    #[arg(long = "engine.cross-block-cache-size", default_value_t = DefaultEngineValues::get_global().cross_block_cache_size)]
300    pub cross_block_cache_size: usize,
301
302    /// Enable comparing trie updates from the state root task to the trie updates from the regular
303    /// state root calculation.
304    #[arg(long = "engine.state-root-task-compare-updates", default_value_t = DefaultEngineValues::get_global().state_root_task_compare_updates)]
305    pub state_root_task_compare_updates: bool,
306
307    /// Enables accepting requests hash instead of an array of requests in `engine_newPayloadV4`.
308    #[arg(long = "engine.accept-execution-requests-hash", default_value_t = DefaultEngineValues::get_global().accept_execution_requests_hash)]
309    pub accept_execution_requests_hash: bool,
310
311    /// Whether multiproof task should chunk proof targets.
312    #[arg(long = "engine.multiproof-chunking", default_value_t = DefaultEngineValues::get_global().multiproof_chunking_enabled)]
313    pub multiproof_chunking_enabled: bool,
314
315    /// Multiproof task chunk size for proof targets.
316    #[arg(long = "engine.multiproof-chunk-size", default_value_t = DefaultEngineValues::get_global().multiproof_chunk_size)]
317    pub multiproof_chunk_size: usize,
318
319    /// Configure the number of reserved CPU cores for non-reth processes
320    #[arg(long = "engine.reserved-cpu-cores", default_value_t = DefaultEngineValues::get_global().reserved_cpu_cores)]
321    pub reserved_cpu_cores: usize,
322
323    /// CAUTION: This CLI flag has no effect anymore, use --engine.disable-precompile-cache
324    /// if you want to disable precompile cache
325    #[arg(long = "engine.precompile-cache", default_value = "true", hide = true)]
326    #[deprecated]
327    pub precompile_cache_enabled: bool,
328
329    /// Disable precompile cache
330    #[arg(long = "engine.disable-precompile-cache", default_value_t = DefaultEngineValues::get_global().precompile_cache_disabled)]
331    pub precompile_cache_disabled: bool,
332
333    /// Enable state root fallback, useful for testing
334    #[arg(long = "engine.state-root-fallback", default_value_t = DefaultEngineValues::get_global().state_root_fallback)]
335    pub state_root_fallback: bool,
336
337    /// Always process payload attributes and begin a payload build process even if
338    /// `forkchoiceState.headBlockHash` is already the canonical head or an ancestor. See
339    /// `TreeConfig::always_process_payload_attributes_on_canonical_head` for more details.
340    ///
341    /// Note: This is a no-op on OP Stack.
342    #[arg(
343        long = "engine.always-process-payload-attributes-on-canonical-head",
344        default_value_t = DefaultEngineValues::get_global().always_process_payload_attributes_on_canonical_head
345    )]
346    pub always_process_payload_attributes_on_canonical_head: bool,
347
348    /// Allow unwinding canonical header to ancestor during forkchoice updates.
349    /// See `TreeConfig::unwind_canonical_header` for more details.
350    #[arg(long = "engine.allow-unwind-canonical-header", default_value_t = DefaultEngineValues::get_global().allow_unwind_canonical_header)]
351    pub allow_unwind_canonical_header: bool,
352
353    /// Configure the number of storage proof workers in the Tokio blocking pool.
354    /// If not specified, defaults to 2x available parallelism.
355    #[arg(long = "engine.storage-worker-count", default_value = Resettable::from(DefaultEngineValues::get_global().storage_worker_count.map(|v| v.to_string().into())))]
356    pub storage_worker_count: Option<usize>,
357
358    /// Configure the number of account proof workers in the Tokio blocking pool.
359    /// If not specified, defaults to the same count as storage workers.
360    #[arg(long = "engine.account-worker-count", default_value = Resettable::from(DefaultEngineValues::get_global().account_worker_count.map(|v| v.to_string().into())))]
361    pub account_worker_count: Option<usize>,
362
363    /// Disable V2 storage proofs for state root calculations
364    #[arg(long = "engine.disable-proof-v2", default_value_t = DefaultEngineValues::get_global().disable_proof_v2)]
365    pub disable_proof_v2: bool,
366
367    /// Disable cache metrics recording, which can take up to 50ms with large cached state.
368    #[arg(long = "engine.disable-cache-metrics", default_value_t = DefaultEngineValues::get_global().cache_metrics_disabled)]
369    pub cache_metrics_disabled: bool,
370
371    /// Disable sparse trie cache.
372    #[arg(long = "engine.disable-trie-cache", default_value_t = DefaultEngineValues::get_global().disable_trie_cache, conflicts_with = "disable_proof_v2")]
373    pub disable_trie_cache: bool,
374
375    /// Sparse trie prune depth.
376    #[arg(long = "engine.sparse-trie-prune-depth", default_value_t = DefaultEngineValues::get_global().sparse_trie_prune_depth)]
377    pub sparse_trie_prune_depth: usize,
378
379    /// Maximum number of storage tries to retain after sparse trie pruning.
380    #[arg(long = "engine.sparse-trie-max-storage-tries", default_value_t = DefaultEngineValues::get_global().sparse_trie_max_storage_tries)]
381    pub sparse_trie_max_storage_tries: usize,
382
383    /// Fully disable sparse trie cache pruning. When set, the cached sparse trie is preserved
384    /// without any node pruning or storage trie eviction between blocks. Useful for benchmarking
385    /// the effects of retaining the full trie cache.
386    #[arg(long = "engine.disable-sparse-trie-cache-pruning", default_value_t = DefaultEngineValues::get_global().disable_sparse_trie_cache_pruning)]
387    pub disable_sparse_trie_cache_pruning: bool,
388
389    /// Configure the timeout for the state root task before spawning a sequential fallback.
390    /// If the state root task takes longer than this, a sequential computation starts in
391    /// parallel and whichever finishes first is used.
392    ///
393    /// --engine.state-root-task-timeout 1s
394    /// --engine.state-root-task-timeout 400ms
395    ///
396    /// Set to 0s to disable.
397    #[arg(
398        long = "engine.state-root-task-timeout",
399        value_parser = humantime::parse_duration,
400        default_value = DefaultEngineValues::get_global().state_root_task_timeout.as_deref().unwrap_or("1s"),
401    )]
402    pub state_root_task_timeout: Option<Duration>,
403}
404
405#[allow(deprecated)]
406impl Default for EngineArgs {
407    fn default() -> Self {
408        let DefaultEngineValues {
409            persistence_threshold,
410            memory_block_buffer_target,
411            legacy_state_root_task_enabled,
412            state_cache_disabled,
413            prewarming_disabled,
414            state_provider_metrics,
415            cross_block_cache_size,
416            state_root_task_compare_updates,
417            accept_execution_requests_hash,
418            multiproof_chunking_enabled,
419            multiproof_chunk_size,
420            reserved_cpu_cores,
421            precompile_cache_disabled,
422            state_root_fallback,
423            always_process_payload_attributes_on_canonical_head,
424            allow_unwind_canonical_header,
425            storage_worker_count,
426            account_worker_count,
427            disable_proof_v2,
428            cache_metrics_disabled,
429            disable_trie_cache,
430            sparse_trie_prune_depth,
431            sparse_trie_max_storage_tries,
432            disable_sparse_trie_cache_pruning,
433            state_root_task_timeout,
434        } = DefaultEngineValues::get_global().clone();
435        Self {
436            persistence_threshold,
437            memory_block_buffer_target,
438            legacy_state_root_task_enabled,
439            state_root_task_compare_updates,
440            caching_and_prewarming_enabled: true,
441            state_cache_disabled,
442            prewarming_disabled,
443            parallel_sparse_trie_enabled: true,
444            parallel_sparse_trie_disabled: false,
445            state_provider_metrics,
446            cross_block_cache_size,
447            accept_execution_requests_hash,
448            multiproof_chunking_enabled,
449            multiproof_chunk_size,
450            reserved_cpu_cores,
451            precompile_cache_enabled: true,
452            precompile_cache_disabled,
453            state_root_fallback,
454            always_process_payload_attributes_on_canonical_head,
455            allow_unwind_canonical_header,
456            storage_worker_count,
457            account_worker_count,
458            disable_proof_v2,
459            cache_metrics_disabled,
460            disable_trie_cache,
461            sparse_trie_prune_depth,
462            sparse_trie_max_storage_tries,
463            disable_sparse_trie_cache_pruning,
464            state_root_task_timeout: state_root_task_timeout
465                .as_deref()
466                .map(|s| humantime::parse_duration(s).expect("valid default duration")),
467        }
468    }
469}
470
471impl EngineArgs {
472    /// Creates a [`TreeConfig`] from the engine arguments.
473    pub fn tree_config(&self) -> TreeConfig {
474        TreeConfig::default()
475            .with_persistence_threshold(self.persistence_threshold)
476            .with_memory_block_buffer_target(self.memory_block_buffer_target)
477            .with_legacy_state_root(self.legacy_state_root_task_enabled)
478            .without_state_cache(self.state_cache_disabled)
479            .without_prewarming(self.prewarming_disabled)
480            .with_state_provider_metrics(self.state_provider_metrics)
481            .with_always_compare_trie_updates(self.state_root_task_compare_updates)
482            .with_cross_block_cache_size(self.cross_block_cache_size * 1024 * 1024)
483            .with_multiproof_chunking_enabled(self.multiproof_chunking_enabled)
484            .with_multiproof_chunk_size(self.multiproof_chunk_size)
485            .with_reserved_cpu_cores(self.reserved_cpu_cores)
486            .without_precompile_cache(self.precompile_cache_disabled)
487            .with_state_root_fallback(self.state_root_fallback)
488            .with_always_process_payload_attributes_on_canonical_head(
489                self.always_process_payload_attributes_on_canonical_head,
490            )
491            .with_unwind_canonical_header(self.allow_unwind_canonical_header)
492            .with_storage_worker_count_opt(self.storage_worker_count)
493            .with_account_worker_count_opt(self.account_worker_count)
494            .with_disable_proof_v2(self.disable_proof_v2)
495            .without_cache_metrics(self.cache_metrics_disabled)
496            .with_disable_trie_cache(self.disable_trie_cache)
497            .with_sparse_trie_prune_depth(self.sparse_trie_prune_depth)
498            .with_sparse_trie_max_storage_tries(self.sparse_trie_max_storage_tries)
499            .with_disable_sparse_trie_cache_pruning(self.disable_sparse_trie_cache_pruning)
500            .with_state_root_task_timeout(self.state_root_task_timeout.filter(|d| !d.is_zero()))
501    }
502}
503
504#[cfg(test)]
505mod tests {
506    use super::*;
507    use clap::Parser;
508
509    /// A helper type to parse Args more easily
510    #[derive(Parser)]
511    struct CommandParser<T: Args> {
512        #[command(flatten)]
513        args: T,
514    }
515
516    #[test]
517    fn test_parse_engine_args() {
518        let default_args = EngineArgs::default();
519        let args = CommandParser::<EngineArgs>::parse_from(["reth"]).args;
520        assert_eq!(args, default_args);
521    }
522
523    #[test]
524    #[allow(deprecated)]
525    fn engine_args() {
526        let args = EngineArgs {
527            persistence_threshold: 100,
528            memory_block_buffer_target: 50,
529            legacy_state_root_task_enabled: true,
530            caching_and_prewarming_enabled: true,
531            state_cache_disabled: true,
532            prewarming_disabled: true,
533            parallel_sparse_trie_enabled: true,
534            parallel_sparse_trie_disabled: false,
535            state_provider_metrics: true,
536            cross_block_cache_size: 256,
537            state_root_task_compare_updates: true,
538            accept_execution_requests_hash: true,
539            multiproof_chunking_enabled: true,
540            multiproof_chunk_size: 512,
541            reserved_cpu_cores: 4,
542            precompile_cache_enabled: true,
543            precompile_cache_disabled: true,
544            state_root_fallback: true,
545            always_process_payload_attributes_on_canonical_head: true,
546            allow_unwind_canonical_header: true,
547            storage_worker_count: Some(16),
548            account_worker_count: Some(8),
549            disable_proof_v2: false,
550            cache_metrics_disabled: true,
551            disable_trie_cache: true,
552            sparse_trie_prune_depth: 10,
553            sparse_trie_max_storage_tries: 100,
554            disable_sparse_trie_cache_pruning: true,
555            state_root_task_timeout: Some(Duration::from_secs(2)),
556        };
557
558        let parsed_args = CommandParser::<EngineArgs>::parse_from([
559            "reth",
560            "--engine.persistence-threshold",
561            "100",
562            "--engine.memory-block-buffer-target",
563            "50",
564            "--engine.legacy-state-root",
565            "--engine.disable-state-cache",
566            "--engine.disable-prewarming",
567            "--engine.state-provider-metrics",
568            "--engine.cross-block-cache-size",
569            "256",
570            "--engine.state-root-task-compare-updates",
571            "--engine.accept-execution-requests-hash",
572            "--engine.multiproof-chunking",
573            "--engine.multiproof-chunk-size",
574            "512",
575            "--engine.reserved-cpu-cores",
576            "4",
577            "--engine.disable-precompile-cache",
578            "--engine.state-root-fallback",
579            "--engine.always-process-payload-attributes-on-canonical-head",
580            "--engine.allow-unwind-canonical-header",
581            "--engine.storage-worker-count",
582            "16",
583            "--engine.account-worker-count",
584            "8",
585            "--engine.disable-cache-metrics",
586            "--engine.disable-trie-cache",
587            "--engine.sparse-trie-prune-depth",
588            "10",
589            "--engine.sparse-trie-max-storage-tries",
590            "100",
591            "--engine.disable-sparse-trie-cache-pruning",
592            "--engine.state-root-task-timeout",
593            "2s",
594        ])
595        .args;
596
597        assert_eq!(parsed_args, args);
598    }
599}