1use alloy_eips::merge::EPOCH_SLOTS;
4use core::time::Duration;
5
6pub const DEFAULT_PERSISTENCE_THRESHOLD: u64 = 2;
8
9pub const DEFAULT_MEMORY_BLOCK_BUFFER_TARGET: u64 = 0;
11
12fn default_storage_worker_count() -> usize {
14 #[cfg(feature = "std")]
15 {
16 std::thread::available_parallelism().map_or(8, |n| n.get() * 2)
17 }
18 #[cfg(not(feature = "std"))]
19 {
20 8
21 }
22}
23
24fn default_account_worker_count() -> usize {
29 default_storage_worker_count()
30}
31
32pub const DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE: usize = 60;
34
35pub const DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE_V2: usize = DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE * 4;
39
40pub const DEFAULT_RESERVED_CPU_CORES: usize = 1;
44
45fn default_prewarm_max_concurrency() -> usize {
47 #[cfg(feature = "std")]
48 {
49 std::thread::available_parallelism().map_or(16, |n| n.get())
50 }
51 #[cfg(not(feature = "std"))]
52 {
53 16
54 }
55}
56
57pub const DEFAULT_SPARSE_TRIE_PRUNE_DEPTH: usize = 4;
62
63pub const DEFAULT_SPARSE_TRIE_MAX_STORAGE_TRIES: usize = 100;
67
68pub const DEFAULT_STATE_ROOT_TASK_TIMEOUT: Duration = Duration::from_secs(1);
70
71const DEFAULT_BLOCK_BUFFER_LIMIT: u32 = EPOCH_SLOTS as u32 * 2;
72const DEFAULT_MAX_INVALID_HEADER_CACHE_LENGTH: u32 = 256;
73const DEFAULT_MAX_EXECUTE_BLOCK_BATCH_SIZE: usize = 4;
74const DEFAULT_CROSS_BLOCK_CACHE_SIZE: usize = default_cross_block_cache_size();
75
76const fn default_cross_block_cache_size() -> usize {
77 if cfg!(test) {
78 1024 * 1024 } else if cfg!(target_pointer_width = "32") {
80 usize::MAX } else {
82 4 * 1024 * 1024 * 1024 }
84}
85
86pub fn has_enough_parallelism() -> bool {
95 #[cfg(feature = "std")]
96 {
97 std::thread::available_parallelism().is_ok_and(|num| num.get() >= 5)
98 }
99 #[cfg(not(feature = "std"))]
100 false
101}
102
103#[derive(Debug, Clone)]
105pub struct TreeConfig {
106 persistence_threshold: u64,
109 memory_block_buffer_target: u64,
114 block_buffer_limit: u32,
117 max_invalid_header_cache_length: u32,
119 max_execute_block_batch_size: usize,
124 legacy_state_root: bool,
127 always_compare_trie_updates: bool,
130 disable_state_cache: bool,
132 disable_prewarming: bool,
134 state_provider_metrics: bool,
136 cross_block_cache_size: usize,
138 has_enough_parallelism: bool,
140 multiproof_chunking_enabled: bool,
142 multiproof_chunk_size: usize,
144 reserved_cpu_cores: usize,
146 precompile_cache_disabled: bool,
148 state_root_fallback: bool,
150 always_process_payload_attributes_on_canonical_head: bool,
164 prewarm_max_concurrency: usize,
166 allow_unwind_canonical_header: bool,
168 storage_worker_count: usize,
170 account_worker_count: usize,
172 disable_proof_v2: bool,
174 disable_cache_metrics: bool,
176 disable_trie_cache: bool,
178 sparse_trie_prune_depth: usize,
180 sparse_trie_max_storage_tries: usize,
182 disable_sparse_trie_cache_pruning: bool,
184 state_root_task_timeout: Option<Duration>,
189}
190
191impl Default for TreeConfig {
192 fn default() -> Self {
193 Self {
194 persistence_threshold: DEFAULT_PERSISTENCE_THRESHOLD,
195 memory_block_buffer_target: DEFAULT_MEMORY_BLOCK_BUFFER_TARGET,
196 block_buffer_limit: DEFAULT_BLOCK_BUFFER_LIMIT,
197 max_invalid_header_cache_length: DEFAULT_MAX_INVALID_HEADER_CACHE_LENGTH,
198 max_execute_block_batch_size: DEFAULT_MAX_EXECUTE_BLOCK_BATCH_SIZE,
199 legacy_state_root: false,
200 always_compare_trie_updates: false,
201 disable_state_cache: false,
202 disable_prewarming: false,
203 state_provider_metrics: false,
204 cross_block_cache_size: DEFAULT_CROSS_BLOCK_CACHE_SIZE,
205 has_enough_parallelism: has_enough_parallelism(),
206 multiproof_chunking_enabled: true,
207 multiproof_chunk_size: DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE,
208 reserved_cpu_cores: DEFAULT_RESERVED_CPU_CORES,
209 precompile_cache_disabled: false,
210 state_root_fallback: false,
211 always_process_payload_attributes_on_canonical_head: false,
212 prewarm_max_concurrency: default_prewarm_max_concurrency(),
213 allow_unwind_canonical_header: false,
214 storage_worker_count: default_storage_worker_count(),
215 account_worker_count: default_account_worker_count(),
216 disable_proof_v2: false,
217 disable_cache_metrics: false,
218 disable_trie_cache: false,
219 sparse_trie_prune_depth: DEFAULT_SPARSE_TRIE_PRUNE_DEPTH,
220 sparse_trie_max_storage_tries: DEFAULT_SPARSE_TRIE_MAX_STORAGE_TRIES,
221 disable_sparse_trie_cache_pruning: false,
222 state_root_task_timeout: Some(DEFAULT_STATE_ROOT_TASK_TIMEOUT),
223 }
224 }
225}
226
227impl TreeConfig {
228 #[expect(clippy::too_many_arguments)]
230 pub const fn new(
231 persistence_threshold: u64,
232 memory_block_buffer_target: u64,
233 block_buffer_limit: u32,
234 max_invalid_header_cache_length: u32,
235 max_execute_block_batch_size: usize,
236 legacy_state_root: bool,
237 always_compare_trie_updates: bool,
238 disable_state_cache: bool,
239 disable_prewarming: bool,
240 state_provider_metrics: bool,
241 cross_block_cache_size: usize,
242 has_enough_parallelism: bool,
243 multiproof_chunking_enabled: bool,
244 multiproof_chunk_size: usize,
245 reserved_cpu_cores: usize,
246 precompile_cache_disabled: bool,
247 state_root_fallback: bool,
248 always_process_payload_attributes_on_canonical_head: bool,
249 prewarm_max_concurrency: usize,
250 allow_unwind_canonical_header: bool,
251 storage_worker_count: usize,
252 account_worker_count: usize,
253 disable_proof_v2: bool,
254 disable_cache_metrics: bool,
255 sparse_trie_prune_depth: usize,
256 sparse_trie_max_storage_tries: usize,
257 state_root_task_timeout: Option<Duration>,
258 ) -> Self {
259 Self {
260 persistence_threshold,
261 memory_block_buffer_target,
262 block_buffer_limit,
263 max_invalid_header_cache_length,
264 max_execute_block_batch_size,
265 legacy_state_root,
266 always_compare_trie_updates,
267 disable_state_cache,
268 disable_prewarming,
269 state_provider_metrics,
270 cross_block_cache_size,
271 has_enough_parallelism,
272 multiproof_chunking_enabled,
273 multiproof_chunk_size,
274 reserved_cpu_cores,
275 precompile_cache_disabled,
276 state_root_fallback,
277 always_process_payload_attributes_on_canonical_head,
278 prewarm_max_concurrency,
279 allow_unwind_canonical_header,
280 storage_worker_count,
281 account_worker_count,
282 disable_proof_v2,
283 disable_cache_metrics,
284 disable_trie_cache: false,
285 sparse_trie_prune_depth,
286 sparse_trie_max_storage_tries,
287 disable_sparse_trie_cache_pruning: false,
288 state_root_task_timeout,
289 }
290 }
291
292 pub const fn persistence_threshold(&self) -> u64 {
294 self.persistence_threshold
295 }
296
297 pub const fn memory_block_buffer_target(&self) -> u64 {
299 self.memory_block_buffer_target
300 }
301
302 pub const fn block_buffer_limit(&self) -> u32 {
304 self.block_buffer_limit
305 }
306
307 pub const fn max_invalid_header_cache_length(&self) -> u32 {
309 self.max_invalid_header_cache_length
310 }
311
312 pub const fn max_execute_block_batch_size(&self) -> usize {
314 self.max_execute_block_batch_size
315 }
316
317 pub const fn multiproof_chunking_enabled(&self) -> bool {
319 self.multiproof_chunking_enabled
320 }
321
322 pub const fn multiproof_chunk_size(&self) -> usize {
324 self.multiproof_chunk_size
325 }
326
327 pub const fn effective_multiproof_chunk_size(&self) -> usize {
330 if !self.disable_proof_v2 &&
331 self.multiproof_chunk_size == DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE
332 {
333 DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE_V2
334 } else {
335 self.multiproof_chunk_size
336 }
337 }
338
339 pub const fn reserved_cpu_cores(&self) -> usize {
341 self.reserved_cpu_cores
342 }
343
344 pub const fn legacy_state_root(&self) -> bool {
347 self.legacy_state_root
348 }
349
350 pub const fn state_provider_metrics(&self) -> bool {
352 self.state_provider_metrics
353 }
354
355 pub const fn disable_state_cache(&self) -> bool {
357 self.disable_state_cache
358 }
359
360 pub const fn disable_prewarming(&self) -> bool {
362 self.disable_prewarming
363 }
364
365 pub const fn always_compare_trie_updates(&self) -> bool {
368 self.always_compare_trie_updates
369 }
370
371 pub const fn cross_block_cache_size(&self) -> usize {
373 self.cross_block_cache_size
374 }
375
376 pub const fn precompile_cache_disabled(&self) -> bool {
378 self.precompile_cache_disabled
379 }
380
381 pub const fn state_root_fallback(&self) -> bool {
383 self.state_root_fallback
384 }
385
386 pub const fn with_always_process_payload_attributes_on_canonical_head(
388 mut self,
389 always_process_payload_attributes_on_canonical_head: bool,
390 ) -> Self {
391 self.always_process_payload_attributes_on_canonical_head =
392 always_process_payload_attributes_on_canonical_head;
393 self
394 }
395
396 pub const fn always_process_payload_attributes_on_canonical_head(&self) -> bool {
399 self.always_process_payload_attributes_on_canonical_head
400 }
401
402 pub const fn unwind_canonical_header(&self) -> bool {
404 self.allow_unwind_canonical_header
405 }
406
407 pub const fn with_persistence_threshold(mut self, persistence_threshold: u64) -> Self {
409 self.persistence_threshold = persistence_threshold;
410 self
411 }
412
413 pub const fn with_memory_block_buffer_target(
415 mut self,
416 memory_block_buffer_target: u64,
417 ) -> Self {
418 self.memory_block_buffer_target = memory_block_buffer_target;
419 self
420 }
421
422 pub const fn with_block_buffer_limit(mut self, block_buffer_limit: u32) -> Self {
424 self.block_buffer_limit = block_buffer_limit;
425 self
426 }
427
428 pub const fn with_max_invalid_header_cache_length(
430 mut self,
431 max_invalid_header_cache_length: u32,
432 ) -> Self {
433 self.max_invalid_header_cache_length = max_invalid_header_cache_length;
434 self
435 }
436
437 pub const fn with_max_execute_block_batch_size(
439 mut self,
440 max_execute_block_batch_size: usize,
441 ) -> Self {
442 self.max_execute_block_batch_size = max_execute_block_batch_size;
443 self
444 }
445
446 pub const fn with_legacy_state_root(mut self, legacy_state_root: bool) -> Self {
448 self.legacy_state_root = legacy_state_root;
449 self
450 }
451
452 pub const fn without_state_cache(mut self, disable_state_cache: bool) -> Self {
454 self.disable_state_cache = disable_state_cache;
455 self
456 }
457
458 pub const fn without_prewarming(mut self, disable_prewarming: bool) -> Self {
460 self.disable_prewarming = disable_prewarming;
461 self
462 }
463
464 pub const fn with_always_compare_trie_updates(
467 mut self,
468 always_compare_trie_updates: bool,
469 ) -> Self {
470 self.always_compare_trie_updates = always_compare_trie_updates;
471 self
472 }
473
474 pub const fn with_cross_block_cache_size(mut self, cross_block_cache_size: usize) -> Self {
476 self.cross_block_cache_size = cross_block_cache_size;
477 self
478 }
479
480 pub const fn with_has_enough_parallelism(mut self, has_enough_parallelism: bool) -> Self {
482 self.has_enough_parallelism = has_enough_parallelism;
483 self
484 }
485
486 pub const fn with_state_provider_metrics(mut self, state_provider_metrics: bool) -> Self {
488 self.state_provider_metrics = state_provider_metrics;
489 self
490 }
491
492 pub const fn with_multiproof_chunking_enabled(
494 mut self,
495 multiproof_chunking_enabled: bool,
496 ) -> Self {
497 self.multiproof_chunking_enabled = multiproof_chunking_enabled;
498 self
499 }
500
501 pub const fn with_multiproof_chunk_size(mut self, multiproof_chunk_size: usize) -> Self {
503 self.multiproof_chunk_size = multiproof_chunk_size;
504 self
505 }
506
507 pub const fn with_reserved_cpu_cores(mut self, reserved_cpu_cores: usize) -> Self {
509 self.reserved_cpu_cores = reserved_cpu_cores;
510 self
511 }
512
513 pub const fn without_precompile_cache(mut self, precompile_cache_disabled: bool) -> Self {
515 self.precompile_cache_disabled = precompile_cache_disabled;
516 self
517 }
518
519 pub const fn with_state_root_fallback(mut self, state_root_fallback: bool) -> Self {
521 self.state_root_fallback = state_root_fallback;
522 self
523 }
524
525 pub const fn with_unwind_canonical_header(mut self, unwind_canonical_header: bool) -> Self {
527 self.allow_unwind_canonical_header = unwind_canonical_header;
528 self
529 }
530
531 pub const fn use_state_root_task(&self) -> bool {
533 self.has_enough_parallelism && !self.legacy_state_root
534 }
535
536 pub const fn with_prewarm_max_concurrency(mut self, prewarm_max_concurrency: usize) -> Self {
538 self.prewarm_max_concurrency = prewarm_max_concurrency;
539 self
540 }
541
542 pub const fn prewarm_max_concurrency(&self) -> usize {
544 self.prewarm_max_concurrency
545 }
546
547 pub const fn storage_worker_count(&self) -> usize {
549 self.storage_worker_count
550 }
551
552 pub const fn with_storage_worker_count_opt(
556 mut self,
557 storage_worker_count: Option<usize>,
558 ) -> Self {
559 if let Some(count) = storage_worker_count {
560 self.storage_worker_count = count;
561 }
562 self
563 }
564
565 pub const fn account_worker_count(&self) -> usize {
567 self.account_worker_count
568 }
569
570 pub const fn with_account_worker_count_opt(
574 mut self,
575 account_worker_count: Option<usize>,
576 ) -> Self {
577 if let Some(count) = account_worker_count {
578 self.account_worker_count = count;
579 }
580 self
581 }
582
583 pub const fn disable_proof_v2(&self) -> bool {
585 self.disable_proof_v2
586 }
587
588 pub const fn with_disable_proof_v2(mut self, disable_proof_v2: bool) -> Self {
590 self.disable_proof_v2 = disable_proof_v2;
591 self
592 }
593
594 pub const fn disable_cache_metrics(&self) -> bool {
596 self.disable_cache_metrics
597 }
598
599 pub const fn without_cache_metrics(mut self, disable_cache_metrics: bool) -> Self {
601 self.disable_cache_metrics = disable_cache_metrics;
602 self
603 }
604
605 pub const fn disable_trie_cache(&self) -> bool {
607 self.disable_trie_cache
608 }
609
610 pub const fn with_disable_trie_cache(mut self, value: bool) -> Self {
612 self.disable_trie_cache = value;
613 self
614 }
615
616 pub const fn sparse_trie_prune_depth(&self) -> usize {
618 self.sparse_trie_prune_depth
619 }
620
621 pub const fn with_sparse_trie_prune_depth(mut self, depth: usize) -> Self {
623 self.sparse_trie_prune_depth = depth;
624 self
625 }
626
627 pub const fn sparse_trie_max_storage_tries(&self) -> usize {
629 self.sparse_trie_max_storage_tries
630 }
631
632 pub const fn with_sparse_trie_max_storage_tries(mut self, max_tries: usize) -> Self {
634 self.sparse_trie_max_storage_tries = max_tries;
635 self
636 }
637
638 pub const fn disable_sparse_trie_cache_pruning(&self) -> bool {
640 self.disable_sparse_trie_cache_pruning
641 }
642
643 pub const fn with_disable_sparse_trie_cache_pruning(mut self, value: bool) -> Self {
645 self.disable_sparse_trie_cache_pruning = value;
646 self
647 }
648
649 pub const fn state_root_task_timeout(&self) -> Option<Duration> {
651 self.state_root_task_timeout
652 }
653
654 pub const fn with_state_root_task_timeout(mut self, timeout: Option<Duration>) -> Self {
656 self.state_root_task_timeout = timeout;
657 self
658 }
659}