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
12pub const DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE: usize = 5;
14
15pub const SMALL_BLOCK_GAS_THRESHOLD: u64 = 20_000_000;
17
18pub const DEFAULT_RESERVED_CPU_CORES: usize = 1;
22
23pub const DEFAULT_SPARSE_TRIE_PRUNE_DEPTH: usize = 4;
28
29pub const DEFAULT_SPARSE_TRIE_MAX_HOT_SLOTS: usize = 1500;
33
34pub const DEFAULT_SPARSE_TRIE_MAX_HOT_ACCOUNTS: usize = 1000;
38
39pub const DEFAULT_STATE_ROOT_TASK_TIMEOUT: Duration = Duration::from_secs(1);
41
42const DEFAULT_BLOCK_BUFFER_LIMIT: u32 = EPOCH_SLOTS as u32 * 2;
43const DEFAULT_MAX_INVALID_HEADER_CACHE_LENGTH: u32 = 256;
44const DEFAULT_MAX_EXECUTE_BLOCK_BATCH_SIZE: usize = 4;
45const DEFAULT_CROSS_BLOCK_CACHE_SIZE: usize = default_cross_block_cache_size();
46
47const fn default_cross_block_cache_size() -> usize {
48 if cfg!(test) {
49 1024 * 1024 } else if cfg!(target_pointer_width = "32") {
51 usize::MAX } else {
53 4 * 1024 * 1024 * 1024 }
55}
56
57pub fn has_enough_parallelism() -> bool {
66 #[cfg(feature = "std")]
67 {
68 std::thread::available_parallelism().is_ok_and(|num| num.get() >= 5)
69 }
70 #[cfg(not(feature = "std"))]
71 false
72}
73
74#[derive(Debug, Clone)]
76pub struct TreeConfig {
77 persistence_threshold: u64,
80 memory_block_buffer_target: u64,
85 block_buffer_limit: u32,
88 max_invalid_header_cache_length: u32,
90 max_execute_block_batch_size: usize,
95 legacy_state_root: bool,
98 always_compare_trie_updates: bool,
101 disable_state_cache: bool,
103 disable_prewarming: bool,
105 state_provider_metrics: bool,
107 cross_block_cache_size: usize,
109 has_enough_parallelism: bool,
111 multiproof_chunk_size: usize,
113 reserved_cpu_cores: usize,
115 precompile_cache_disabled: bool,
117 state_root_fallback: bool,
119 always_process_payload_attributes_on_canonical_head: bool,
133 allow_unwind_canonical_header: bool,
135 disable_cache_metrics: bool,
137 sparse_trie_prune_depth: usize,
139 sparse_trie_max_hot_slots: usize,
141 sparse_trie_max_hot_accounts: usize,
143 slow_block_threshold: Option<Duration>,
147 disable_sparse_trie_cache_pruning: bool,
149 state_root_task_timeout: Option<Duration>,
154 #[cfg(feature = "trie-debug")]
158 proof_jitter: Option<Duration>,
159}
160
161impl Default for TreeConfig {
162 fn default() -> Self {
163 Self {
164 persistence_threshold: DEFAULT_PERSISTENCE_THRESHOLD,
165 memory_block_buffer_target: DEFAULT_MEMORY_BLOCK_BUFFER_TARGET,
166 block_buffer_limit: DEFAULT_BLOCK_BUFFER_LIMIT,
167 max_invalid_header_cache_length: DEFAULT_MAX_INVALID_HEADER_CACHE_LENGTH,
168 max_execute_block_batch_size: DEFAULT_MAX_EXECUTE_BLOCK_BATCH_SIZE,
169 legacy_state_root: false,
170 always_compare_trie_updates: false,
171 disable_state_cache: false,
172 disable_prewarming: false,
173 state_provider_metrics: false,
174 cross_block_cache_size: DEFAULT_CROSS_BLOCK_CACHE_SIZE,
175 has_enough_parallelism: has_enough_parallelism(),
176 multiproof_chunk_size: DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE,
177 reserved_cpu_cores: DEFAULT_RESERVED_CPU_CORES,
178 precompile_cache_disabled: false,
179 state_root_fallback: false,
180 always_process_payload_attributes_on_canonical_head: false,
181 allow_unwind_canonical_header: false,
182 disable_cache_metrics: false,
183 sparse_trie_prune_depth: DEFAULT_SPARSE_TRIE_PRUNE_DEPTH,
184 sparse_trie_max_hot_slots: DEFAULT_SPARSE_TRIE_MAX_HOT_SLOTS,
185 sparse_trie_max_hot_accounts: DEFAULT_SPARSE_TRIE_MAX_HOT_ACCOUNTS,
186 slow_block_threshold: None,
187 disable_sparse_trie_cache_pruning: false,
188 state_root_task_timeout: Some(DEFAULT_STATE_ROOT_TASK_TIMEOUT),
189 #[cfg(feature = "trie-debug")]
190 proof_jitter: None,
191 }
192 }
193}
194
195impl TreeConfig {
196 #[expect(clippy::too_many_arguments)]
198 pub const fn new(
199 persistence_threshold: u64,
200 memory_block_buffer_target: u64,
201 block_buffer_limit: u32,
202 max_invalid_header_cache_length: u32,
203 max_execute_block_batch_size: usize,
204 legacy_state_root: bool,
205 always_compare_trie_updates: bool,
206 disable_state_cache: bool,
207 disable_prewarming: bool,
208 state_provider_metrics: bool,
209 cross_block_cache_size: usize,
210 has_enough_parallelism: bool,
211 multiproof_chunk_size: usize,
212 reserved_cpu_cores: usize,
213 precompile_cache_disabled: bool,
214 state_root_fallback: bool,
215 always_process_payload_attributes_on_canonical_head: bool,
216 allow_unwind_canonical_header: bool,
217 disable_cache_metrics: bool,
218 sparse_trie_prune_depth: usize,
219 sparse_trie_max_hot_slots: usize,
220 sparse_trie_max_hot_accounts: usize,
221 slow_block_threshold: Option<Duration>,
222 state_root_task_timeout: Option<Duration>,
223 ) -> Self {
224 Self {
225 persistence_threshold,
226 memory_block_buffer_target,
227 block_buffer_limit,
228 max_invalid_header_cache_length,
229 max_execute_block_batch_size,
230 legacy_state_root,
231 always_compare_trie_updates,
232 disable_state_cache,
233 disable_prewarming,
234 state_provider_metrics,
235 cross_block_cache_size,
236 has_enough_parallelism,
237 multiproof_chunk_size,
238 reserved_cpu_cores,
239 precompile_cache_disabled,
240 state_root_fallback,
241 always_process_payload_attributes_on_canonical_head,
242 allow_unwind_canonical_header,
243 disable_cache_metrics,
244 sparse_trie_prune_depth,
245 sparse_trie_max_hot_slots,
246 sparse_trie_max_hot_accounts,
247 slow_block_threshold,
248 disable_sparse_trie_cache_pruning: false,
249 state_root_task_timeout,
250 #[cfg(feature = "trie-debug")]
251 proof_jitter: None,
252 }
253 }
254
255 pub const fn persistence_threshold(&self) -> u64 {
257 self.persistence_threshold
258 }
259
260 pub const fn memory_block_buffer_target(&self) -> u64 {
262 self.memory_block_buffer_target
263 }
264
265 pub const fn block_buffer_limit(&self) -> u32 {
267 self.block_buffer_limit
268 }
269
270 pub const fn max_invalid_header_cache_length(&self) -> u32 {
272 self.max_invalid_header_cache_length
273 }
274
275 pub const fn max_execute_block_batch_size(&self) -> usize {
277 self.max_execute_block_batch_size
278 }
279
280 pub const fn multiproof_chunk_size(&self) -> usize {
282 self.multiproof_chunk_size
283 }
284
285 pub const fn effective_multiproof_chunk_size(&self) -> usize {
287 self.multiproof_chunk_size
288 }
289
290 pub const fn reserved_cpu_cores(&self) -> usize {
292 self.reserved_cpu_cores
293 }
294
295 pub const fn legacy_state_root(&self) -> bool {
298 self.legacy_state_root
299 }
300
301 pub const fn state_provider_metrics(&self) -> bool {
303 self.state_provider_metrics
304 }
305
306 pub const fn disable_state_cache(&self) -> bool {
308 self.disable_state_cache
309 }
310
311 pub const fn disable_prewarming(&self) -> bool {
313 self.disable_prewarming
314 }
315
316 pub const fn always_compare_trie_updates(&self) -> bool {
319 self.always_compare_trie_updates
320 }
321
322 pub const fn cross_block_cache_size(&self) -> usize {
324 self.cross_block_cache_size
325 }
326
327 pub const fn precompile_cache_disabled(&self) -> bool {
329 self.precompile_cache_disabled
330 }
331
332 pub const fn state_root_fallback(&self) -> bool {
334 self.state_root_fallback
335 }
336
337 pub const fn with_always_process_payload_attributes_on_canonical_head(
339 mut self,
340 always_process_payload_attributes_on_canonical_head: bool,
341 ) -> Self {
342 self.always_process_payload_attributes_on_canonical_head =
343 always_process_payload_attributes_on_canonical_head;
344 self
345 }
346
347 pub const fn always_process_payload_attributes_on_canonical_head(&self) -> bool {
350 self.always_process_payload_attributes_on_canonical_head
351 }
352
353 pub const fn unwind_canonical_header(&self) -> bool {
355 self.allow_unwind_canonical_header
356 }
357
358 pub const fn with_persistence_threshold(mut self, persistence_threshold: u64) -> Self {
360 self.persistence_threshold = persistence_threshold;
361 self
362 }
363
364 pub const fn with_memory_block_buffer_target(
366 mut self,
367 memory_block_buffer_target: u64,
368 ) -> Self {
369 self.memory_block_buffer_target = memory_block_buffer_target;
370 self
371 }
372
373 pub const fn with_block_buffer_limit(mut self, block_buffer_limit: u32) -> Self {
375 self.block_buffer_limit = block_buffer_limit;
376 self
377 }
378
379 pub const fn with_max_invalid_header_cache_length(
381 mut self,
382 max_invalid_header_cache_length: u32,
383 ) -> Self {
384 self.max_invalid_header_cache_length = max_invalid_header_cache_length;
385 self
386 }
387
388 pub const fn with_max_execute_block_batch_size(
390 mut self,
391 max_execute_block_batch_size: usize,
392 ) -> Self {
393 self.max_execute_block_batch_size = max_execute_block_batch_size;
394 self
395 }
396
397 pub const fn with_legacy_state_root(mut self, legacy_state_root: bool) -> Self {
399 self.legacy_state_root = legacy_state_root;
400 self
401 }
402
403 pub const fn without_state_cache(mut self, disable_state_cache: bool) -> Self {
405 self.disable_state_cache = disable_state_cache;
406 self
407 }
408
409 pub const fn without_prewarming(mut self, disable_prewarming: bool) -> Self {
411 self.disable_prewarming = disable_prewarming;
412 self
413 }
414
415 pub const fn with_always_compare_trie_updates(
418 mut self,
419 always_compare_trie_updates: bool,
420 ) -> Self {
421 self.always_compare_trie_updates = always_compare_trie_updates;
422 self
423 }
424
425 pub const fn with_cross_block_cache_size(mut self, cross_block_cache_size: usize) -> Self {
427 self.cross_block_cache_size = cross_block_cache_size;
428 self
429 }
430
431 pub const fn with_has_enough_parallelism(mut self, has_enough_parallelism: bool) -> Self {
433 self.has_enough_parallelism = has_enough_parallelism;
434 self
435 }
436
437 pub const fn with_state_provider_metrics(mut self, state_provider_metrics: bool) -> Self {
439 self.state_provider_metrics = state_provider_metrics;
440 self
441 }
442
443 pub const fn with_multiproof_chunk_size(mut self, multiproof_chunk_size: usize) -> Self {
445 self.multiproof_chunk_size = multiproof_chunk_size;
446 self
447 }
448
449 pub const fn with_reserved_cpu_cores(mut self, reserved_cpu_cores: usize) -> Self {
451 self.reserved_cpu_cores = reserved_cpu_cores;
452 self
453 }
454
455 pub const fn without_precompile_cache(mut self, precompile_cache_disabled: bool) -> Self {
457 self.precompile_cache_disabled = precompile_cache_disabled;
458 self
459 }
460
461 pub const fn with_state_root_fallback(mut self, state_root_fallback: bool) -> Self {
463 self.state_root_fallback = state_root_fallback;
464 self
465 }
466
467 pub const fn with_unwind_canonical_header(mut self, unwind_canonical_header: bool) -> Self {
469 self.allow_unwind_canonical_header = unwind_canonical_header;
470 self
471 }
472
473 pub const fn use_state_root_task(&self) -> bool {
475 self.has_enough_parallelism && !self.legacy_state_root
476 }
477
478 pub const fn disable_cache_metrics(&self) -> bool {
480 self.disable_cache_metrics
481 }
482
483 pub const fn without_cache_metrics(mut self, disable_cache_metrics: bool) -> Self {
485 self.disable_cache_metrics = disable_cache_metrics;
486 self
487 }
488
489 pub const fn sparse_trie_prune_depth(&self) -> usize {
491 self.sparse_trie_prune_depth
492 }
493
494 pub const fn with_sparse_trie_prune_depth(mut self, depth: usize) -> Self {
496 self.sparse_trie_prune_depth = depth;
497 self
498 }
499
500 pub const fn sparse_trie_max_hot_slots(&self) -> usize {
502 self.sparse_trie_max_hot_slots
503 }
504
505 pub const fn with_sparse_trie_max_hot_slots(mut self, max_hot_slots: usize) -> Self {
507 self.sparse_trie_max_hot_slots = max_hot_slots;
508 self
509 }
510
511 pub const fn sparse_trie_max_hot_accounts(&self) -> usize {
513 self.sparse_trie_max_hot_accounts
514 }
515
516 pub const fn with_sparse_trie_max_hot_accounts(mut self, max_hot_accounts: usize) -> Self {
518 self.sparse_trie_max_hot_accounts = max_hot_accounts;
519 self
520 }
521
522 pub const fn slow_block_threshold(&self) -> Option<Duration> {
528 self.slow_block_threshold
529 }
530
531 pub const fn with_slow_block_threshold(
533 mut self,
534 slow_block_threshold: Option<Duration>,
535 ) -> Self {
536 self.slow_block_threshold = slow_block_threshold;
537 self
538 }
539
540 pub const fn disable_sparse_trie_cache_pruning(&self) -> bool {
542 self.disable_sparse_trie_cache_pruning
543 }
544
545 pub const fn with_disable_sparse_trie_cache_pruning(mut self, value: bool) -> Self {
547 self.disable_sparse_trie_cache_pruning = value;
548 self
549 }
550
551 pub const fn state_root_task_timeout(&self) -> Option<Duration> {
553 self.state_root_task_timeout
554 }
555
556 pub const fn with_state_root_task_timeout(mut self, timeout: Option<Duration>) -> Self {
558 self.state_root_task_timeout = timeout;
559 self
560 }
561
562 #[cfg(feature = "trie-debug")]
564 pub const fn proof_jitter(&self) -> Option<Duration> {
565 self.proof_jitter
566 }
567
568 #[cfg(feature = "trie-debug")]
570 pub const fn with_proof_jitter(mut self, proof_jitter: Option<Duration>) -> Self {
571 self.proof_jitter = proof_jitter;
572 self
573 }
574}