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_STORAGE_TRIES: usize = 100;
33
34pub const DEFAULT_STATE_ROOT_TASK_TIMEOUT: Duration = Duration::from_secs(1);
36
37const DEFAULT_BLOCK_BUFFER_LIMIT: u32 = EPOCH_SLOTS as u32 * 2;
38const DEFAULT_MAX_INVALID_HEADER_CACHE_LENGTH: u32 = 256;
39const DEFAULT_MAX_EXECUTE_BLOCK_BATCH_SIZE: usize = 4;
40const DEFAULT_CROSS_BLOCK_CACHE_SIZE: usize = default_cross_block_cache_size();
41
42const fn default_cross_block_cache_size() -> usize {
43 if cfg!(test) {
44 1024 * 1024 } else if cfg!(target_pointer_width = "32") {
46 usize::MAX } else {
48 4 * 1024 * 1024 * 1024 }
50}
51
52pub fn has_enough_parallelism() -> bool {
61 #[cfg(feature = "std")]
62 {
63 std::thread::available_parallelism().is_ok_and(|num| num.get() >= 5)
64 }
65 #[cfg(not(feature = "std"))]
66 false
67}
68
69#[derive(Debug, Clone)]
71pub struct TreeConfig {
72 persistence_threshold: u64,
75 memory_block_buffer_target: u64,
80 block_buffer_limit: u32,
83 max_invalid_header_cache_length: u32,
85 max_execute_block_batch_size: usize,
90 legacy_state_root: bool,
93 always_compare_trie_updates: bool,
96 disable_state_cache: bool,
98 disable_prewarming: bool,
100 state_provider_metrics: bool,
102 cross_block_cache_size: usize,
104 has_enough_parallelism: bool,
106 multiproof_chunk_size: usize,
108 reserved_cpu_cores: usize,
110 precompile_cache_disabled: bool,
112 state_root_fallback: bool,
114 always_process_payload_attributes_on_canonical_head: bool,
128 allow_unwind_canonical_header: bool,
130 disable_cache_metrics: bool,
132 sparse_trie_prune_depth: usize,
134 sparse_trie_max_storage_tries: usize,
136 disable_sparse_trie_cache_pruning: bool,
138 state_root_task_timeout: Option<Duration>,
143}
144
145impl Default for TreeConfig {
146 fn default() -> Self {
147 Self {
148 persistence_threshold: DEFAULT_PERSISTENCE_THRESHOLD,
149 memory_block_buffer_target: DEFAULT_MEMORY_BLOCK_BUFFER_TARGET,
150 block_buffer_limit: DEFAULT_BLOCK_BUFFER_LIMIT,
151 max_invalid_header_cache_length: DEFAULT_MAX_INVALID_HEADER_CACHE_LENGTH,
152 max_execute_block_batch_size: DEFAULT_MAX_EXECUTE_BLOCK_BATCH_SIZE,
153 legacy_state_root: false,
154 always_compare_trie_updates: false,
155 disable_state_cache: false,
156 disable_prewarming: false,
157 state_provider_metrics: false,
158 cross_block_cache_size: DEFAULT_CROSS_BLOCK_CACHE_SIZE,
159 has_enough_parallelism: has_enough_parallelism(),
160 multiproof_chunk_size: DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE,
161 reserved_cpu_cores: DEFAULT_RESERVED_CPU_CORES,
162 precompile_cache_disabled: false,
163 state_root_fallback: false,
164 always_process_payload_attributes_on_canonical_head: false,
165 allow_unwind_canonical_header: false,
166 disable_cache_metrics: false,
167 sparse_trie_prune_depth: DEFAULT_SPARSE_TRIE_PRUNE_DEPTH,
168 sparse_trie_max_storage_tries: DEFAULT_SPARSE_TRIE_MAX_STORAGE_TRIES,
169 disable_sparse_trie_cache_pruning: false,
170 state_root_task_timeout: Some(DEFAULT_STATE_ROOT_TASK_TIMEOUT),
171 }
172 }
173}
174
175impl TreeConfig {
176 #[expect(clippy::too_many_arguments)]
178 pub const fn new(
179 persistence_threshold: u64,
180 memory_block_buffer_target: u64,
181 block_buffer_limit: u32,
182 max_invalid_header_cache_length: u32,
183 max_execute_block_batch_size: usize,
184 legacy_state_root: bool,
185 always_compare_trie_updates: bool,
186 disable_state_cache: bool,
187 disable_prewarming: bool,
188 state_provider_metrics: bool,
189 cross_block_cache_size: usize,
190 has_enough_parallelism: bool,
191 multiproof_chunk_size: usize,
192 reserved_cpu_cores: usize,
193 precompile_cache_disabled: bool,
194 state_root_fallback: bool,
195 always_process_payload_attributes_on_canonical_head: bool,
196 allow_unwind_canonical_header: bool,
197 disable_cache_metrics: bool,
198 sparse_trie_prune_depth: usize,
199 sparse_trie_max_storage_tries: usize,
200 state_root_task_timeout: Option<Duration>,
201 ) -> Self {
202 Self {
203 persistence_threshold,
204 memory_block_buffer_target,
205 block_buffer_limit,
206 max_invalid_header_cache_length,
207 max_execute_block_batch_size,
208 legacy_state_root,
209 always_compare_trie_updates,
210 disable_state_cache,
211 disable_prewarming,
212 state_provider_metrics,
213 cross_block_cache_size,
214 has_enough_parallelism,
215 multiproof_chunk_size,
216 reserved_cpu_cores,
217 precompile_cache_disabled,
218 state_root_fallback,
219 always_process_payload_attributes_on_canonical_head,
220 allow_unwind_canonical_header,
221 disable_cache_metrics,
222 sparse_trie_prune_depth,
223 sparse_trie_max_storage_tries,
224 disable_sparse_trie_cache_pruning: false,
225 state_root_task_timeout,
226 }
227 }
228
229 pub const fn persistence_threshold(&self) -> u64 {
231 self.persistence_threshold
232 }
233
234 pub const fn memory_block_buffer_target(&self) -> u64 {
236 self.memory_block_buffer_target
237 }
238
239 pub const fn block_buffer_limit(&self) -> u32 {
241 self.block_buffer_limit
242 }
243
244 pub const fn max_invalid_header_cache_length(&self) -> u32 {
246 self.max_invalid_header_cache_length
247 }
248
249 pub const fn max_execute_block_batch_size(&self) -> usize {
251 self.max_execute_block_batch_size
252 }
253
254 pub const fn multiproof_chunk_size(&self) -> usize {
256 self.multiproof_chunk_size
257 }
258
259 pub const fn effective_multiproof_chunk_size(&self) -> usize {
261 self.multiproof_chunk_size
262 }
263
264 pub const fn reserved_cpu_cores(&self) -> usize {
266 self.reserved_cpu_cores
267 }
268
269 pub const fn legacy_state_root(&self) -> bool {
272 self.legacy_state_root
273 }
274
275 pub const fn state_provider_metrics(&self) -> bool {
277 self.state_provider_metrics
278 }
279
280 pub const fn disable_state_cache(&self) -> bool {
282 self.disable_state_cache
283 }
284
285 pub const fn disable_prewarming(&self) -> bool {
287 self.disable_prewarming
288 }
289
290 pub const fn always_compare_trie_updates(&self) -> bool {
293 self.always_compare_trie_updates
294 }
295
296 pub const fn cross_block_cache_size(&self) -> usize {
298 self.cross_block_cache_size
299 }
300
301 pub const fn precompile_cache_disabled(&self) -> bool {
303 self.precompile_cache_disabled
304 }
305
306 pub const fn state_root_fallback(&self) -> bool {
308 self.state_root_fallback
309 }
310
311 pub const fn with_always_process_payload_attributes_on_canonical_head(
313 mut self,
314 always_process_payload_attributes_on_canonical_head: bool,
315 ) -> Self {
316 self.always_process_payload_attributes_on_canonical_head =
317 always_process_payload_attributes_on_canonical_head;
318 self
319 }
320
321 pub const fn always_process_payload_attributes_on_canonical_head(&self) -> bool {
324 self.always_process_payload_attributes_on_canonical_head
325 }
326
327 pub const fn unwind_canonical_header(&self) -> bool {
329 self.allow_unwind_canonical_header
330 }
331
332 pub const fn with_persistence_threshold(mut self, persistence_threshold: u64) -> Self {
334 self.persistence_threshold = persistence_threshold;
335 self
336 }
337
338 pub const fn with_memory_block_buffer_target(
340 mut self,
341 memory_block_buffer_target: u64,
342 ) -> Self {
343 self.memory_block_buffer_target = memory_block_buffer_target;
344 self
345 }
346
347 pub const fn with_block_buffer_limit(mut self, block_buffer_limit: u32) -> Self {
349 self.block_buffer_limit = block_buffer_limit;
350 self
351 }
352
353 pub const fn with_max_invalid_header_cache_length(
355 mut self,
356 max_invalid_header_cache_length: u32,
357 ) -> Self {
358 self.max_invalid_header_cache_length = max_invalid_header_cache_length;
359 self
360 }
361
362 pub const fn with_max_execute_block_batch_size(
364 mut self,
365 max_execute_block_batch_size: usize,
366 ) -> Self {
367 self.max_execute_block_batch_size = max_execute_block_batch_size;
368 self
369 }
370
371 pub const fn with_legacy_state_root(mut self, legacy_state_root: bool) -> Self {
373 self.legacy_state_root = legacy_state_root;
374 self
375 }
376
377 pub const fn without_state_cache(mut self, disable_state_cache: bool) -> Self {
379 self.disable_state_cache = disable_state_cache;
380 self
381 }
382
383 pub const fn without_prewarming(mut self, disable_prewarming: bool) -> Self {
385 self.disable_prewarming = disable_prewarming;
386 self
387 }
388
389 pub const fn with_always_compare_trie_updates(
392 mut self,
393 always_compare_trie_updates: bool,
394 ) -> Self {
395 self.always_compare_trie_updates = always_compare_trie_updates;
396 self
397 }
398
399 pub const fn with_cross_block_cache_size(mut self, cross_block_cache_size: usize) -> Self {
401 self.cross_block_cache_size = cross_block_cache_size;
402 self
403 }
404
405 pub const fn with_has_enough_parallelism(mut self, has_enough_parallelism: bool) -> Self {
407 self.has_enough_parallelism = has_enough_parallelism;
408 self
409 }
410
411 pub const fn with_state_provider_metrics(mut self, state_provider_metrics: bool) -> Self {
413 self.state_provider_metrics = state_provider_metrics;
414 self
415 }
416
417 pub const fn with_multiproof_chunk_size(mut self, multiproof_chunk_size: usize) -> Self {
419 self.multiproof_chunk_size = multiproof_chunk_size;
420 self
421 }
422
423 pub const fn with_reserved_cpu_cores(mut self, reserved_cpu_cores: usize) -> Self {
425 self.reserved_cpu_cores = reserved_cpu_cores;
426 self
427 }
428
429 pub const fn without_precompile_cache(mut self, precompile_cache_disabled: bool) -> Self {
431 self.precompile_cache_disabled = precompile_cache_disabled;
432 self
433 }
434
435 pub const fn with_state_root_fallback(mut self, state_root_fallback: bool) -> Self {
437 self.state_root_fallback = state_root_fallback;
438 self
439 }
440
441 pub const fn with_unwind_canonical_header(mut self, unwind_canonical_header: bool) -> Self {
443 self.allow_unwind_canonical_header = unwind_canonical_header;
444 self
445 }
446
447 pub const fn use_state_root_task(&self) -> bool {
449 self.has_enough_parallelism && !self.legacy_state_root
450 }
451
452 pub const fn disable_cache_metrics(&self) -> bool {
454 self.disable_cache_metrics
455 }
456
457 pub const fn without_cache_metrics(mut self, disable_cache_metrics: bool) -> Self {
459 self.disable_cache_metrics = disable_cache_metrics;
460 self
461 }
462
463 pub const fn sparse_trie_prune_depth(&self) -> usize {
465 self.sparse_trie_prune_depth
466 }
467
468 pub const fn with_sparse_trie_prune_depth(mut self, depth: usize) -> Self {
470 self.sparse_trie_prune_depth = depth;
471 self
472 }
473
474 pub const fn sparse_trie_max_storage_tries(&self) -> usize {
476 self.sparse_trie_max_storage_tries
477 }
478
479 pub const fn with_sparse_trie_max_storage_tries(mut self, max_tries: usize) -> Self {
481 self.sparse_trie_max_storage_tries = max_tries;
482 self
483 }
484
485 pub const fn disable_sparse_trie_cache_pruning(&self) -> bool {
487 self.disable_sparse_trie_cache_pruning
488 }
489
490 pub const fn with_disable_sparse_trie_cache_pruning(mut self, value: bool) -> Self {
492 self.disable_sparse_trie_cache_pruning = value;
493 self
494 }
495
496 pub const fn state_root_task_timeout(&self) -> Option<Duration> {
498 self.state_root_task_timeout
499 }
500
501 pub const fn with_state_root_task_timeout(mut self, timeout: Option<Duration>) -> Self {
503 self.state_root_task_timeout = timeout;
504 self
505 }
506}