1use alloy_eips::merge::EPOCH_SLOTS;
4
5pub const DEFAULT_PERSISTENCE_THRESHOLD: u64 = 2;
7
8pub const DEFAULT_MEMORY_BLOCK_BUFFER_TARGET: u64 = 0;
10
11pub const MIN_WORKER_COUNT: usize = 32;
13
14fn default_storage_worker_count() -> usize {
16 #[cfg(feature = "std")]
17 {
18 std::thread::available_parallelism().map_or(8, |n| n.get() * 2).min(MIN_WORKER_COUNT)
19 }
20 #[cfg(not(feature = "std"))]
21 {
22 8
23 }
24}
25
26fn default_account_worker_count() -> usize {
31 default_storage_worker_count()
32}
33
34pub const DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE: usize = 60;
36
37pub const DEFAULT_RESERVED_CPU_CORES: usize = 1;
41
42pub const DEFAULT_PREWARM_MAX_CONCURRENCY: usize = 16;
44
45const DEFAULT_BLOCK_BUFFER_LIMIT: u32 = EPOCH_SLOTS as u32 * 2;
46const DEFAULT_MAX_INVALID_HEADER_CACHE_LENGTH: u32 = 256;
47const DEFAULT_MAX_EXECUTE_BLOCK_BATCH_SIZE: usize = 4;
48const DEFAULT_CROSS_BLOCK_CACHE_SIZE: u64 = 4 * 1024 * 1024 * 1024;
49
50pub fn has_enough_parallelism() -> bool {
59 #[cfg(feature = "std")]
60 {
61 std::thread::available_parallelism().is_ok_and(|num| num.get() >= 5)
62 }
63 #[cfg(not(feature = "std"))]
64 false
65}
66
67#[derive(Debug, Clone)]
69pub struct TreeConfig {
70 persistence_threshold: u64,
73 memory_block_buffer_target: u64,
78 block_buffer_limit: u32,
81 max_invalid_header_cache_length: u32,
83 max_execute_block_batch_size: usize,
88 legacy_state_root: bool,
91 always_compare_trie_updates: bool,
94 disable_state_cache: bool,
96 disable_prewarming: bool,
98 disable_parallel_sparse_trie: bool,
100 state_provider_metrics: bool,
102 cross_block_cache_size: u64,
104 has_enough_parallelism: bool,
106 multiproof_chunking_enabled: bool,
108 multiproof_chunk_size: usize,
110 reserved_cpu_cores: usize,
112 precompile_cache_disabled: bool,
114 state_root_fallback: bool,
116 always_process_payload_attributes_on_canonical_head: bool,
130 prewarm_max_concurrency: usize,
132 allow_unwind_canonical_header: bool,
134 storage_worker_count: usize,
136 account_worker_count: usize,
138 enable_proof_v2: bool,
140}
141
142impl Default for TreeConfig {
143 fn default() -> Self {
144 Self {
145 persistence_threshold: DEFAULT_PERSISTENCE_THRESHOLD,
146 memory_block_buffer_target: DEFAULT_MEMORY_BLOCK_BUFFER_TARGET,
147 block_buffer_limit: DEFAULT_BLOCK_BUFFER_LIMIT,
148 max_invalid_header_cache_length: DEFAULT_MAX_INVALID_HEADER_CACHE_LENGTH,
149 max_execute_block_batch_size: DEFAULT_MAX_EXECUTE_BLOCK_BATCH_SIZE,
150 legacy_state_root: false,
151 always_compare_trie_updates: false,
152 disable_state_cache: false,
153 disable_prewarming: false,
154 disable_parallel_sparse_trie: false,
155 state_provider_metrics: false,
156 cross_block_cache_size: DEFAULT_CROSS_BLOCK_CACHE_SIZE,
157 has_enough_parallelism: has_enough_parallelism(),
158 multiproof_chunking_enabled: true,
159 multiproof_chunk_size: DEFAULT_MULTIPROOF_TASK_CHUNK_SIZE,
160 reserved_cpu_cores: DEFAULT_RESERVED_CPU_CORES,
161 precompile_cache_disabled: false,
162 state_root_fallback: false,
163 always_process_payload_attributes_on_canonical_head: false,
164 prewarm_max_concurrency: DEFAULT_PREWARM_MAX_CONCURRENCY,
165 allow_unwind_canonical_header: false,
166 storage_worker_count: default_storage_worker_count(),
167 account_worker_count: default_account_worker_count(),
168 enable_proof_v2: false,
169 }
170 }
171}
172
173impl TreeConfig {
174 #[expect(clippy::too_many_arguments)]
176 pub const fn new(
177 persistence_threshold: u64,
178 memory_block_buffer_target: u64,
179 block_buffer_limit: u32,
180 max_invalid_header_cache_length: u32,
181 max_execute_block_batch_size: usize,
182 legacy_state_root: bool,
183 always_compare_trie_updates: bool,
184 disable_state_cache: bool,
185 disable_prewarming: bool,
186 disable_parallel_sparse_trie: bool,
187 state_provider_metrics: bool,
188 cross_block_cache_size: u64,
189 has_enough_parallelism: bool,
190 multiproof_chunking_enabled: 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 prewarm_max_concurrency: usize,
197 allow_unwind_canonical_header: bool,
198 storage_worker_count: usize,
199 account_worker_count: usize,
200 enable_proof_v2: bool,
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 disable_parallel_sparse_trie,
213 state_provider_metrics,
214 cross_block_cache_size,
215 has_enough_parallelism,
216 multiproof_chunking_enabled,
217 multiproof_chunk_size,
218 reserved_cpu_cores,
219 precompile_cache_disabled,
220 state_root_fallback,
221 always_process_payload_attributes_on_canonical_head,
222 prewarm_max_concurrency,
223 allow_unwind_canonical_header,
224 storage_worker_count,
225 account_worker_count,
226 enable_proof_v2,
227 }
228 }
229
230 pub const fn persistence_threshold(&self) -> u64 {
232 self.persistence_threshold
233 }
234
235 pub const fn memory_block_buffer_target(&self) -> u64 {
237 self.memory_block_buffer_target
238 }
239
240 pub const fn block_buffer_limit(&self) -> u32 {
242 self.block_buffer_limit
243 }
244
245 pub const fn max_invalid_header_cache_length(&self) -> u32 {
247 self.max_invalid_header_cache_length
248 }
249
250 pub const fn max_execute_block_batch_size(&self) -> usize {
252 self.max_execute_block_batch_size
253 }
254
255 pub const fn multiproof_chunking_enabled(&self) -> bool {
257 self.multiproof_chunking_enabled
258 }
259
260 pub const fn multiproof_chunk_size(&self) -> usize {
262 self.multiproof_chunk_size
263 }
264
265 pub const fn reserved_cpu_cores(&self) -> usize {
267 self.reserved_cpu_cores
268 }
269
270 pub const fn legacy_state_root(&self) -> bool {
273 self.legacy_state_root
274 }
275
276 pub const fn state_provider_metrics(&self) -> bool {
278 self.state_provider_metrics
279 }
280
281 pub const fn disable_parallel_sparse_trie(&self) -> bool {
283 self.disable_parallel_sparse_trie
284 }
285
286 pub const fn disable_state_cache(&self) -> bool {
288 self.disable_state_cache
289 }
290
291 pub const fn disable_prewarming(&self) -> bool {
293 self.disable_prewarming
294 }
295
296 pub const fn always_compare_trie_updates(&self) -> bool {
299 self.always_compare_trie_updates
300 }
301
302 pub const fn cross_block_cache_size(&self) -> u64 {
304 self.cross_block_cache_size
305 }
306
307 pub const fn precompile_cache_disabled(&self) -> bool {
309 self.precompile_cache_disabled
310 }
311
312 pub const fn state_root_fallback(&self) -> bool {
314 self.state_root_fallback
315 }
316
317 pub const fn with_always_process_payload_attributes_on_canonical_head(
319 mut self,
320 always_process_payload_attributes_on_canonical_head: bool,
321 ) -> Self {
322 self.always_process_payload_attributes_on_canonical_head =
323 always_process_payload_attributes_on_canonical_head;
324 self
325 }
326
327 pub const fn always_process_payload_attributes_on_canonical_head(&self) -> bool {
330 self.always_process_payload_attributes_on_canonical_head
331 }
332
333 pub const fn unwind_canonical_header(&self) -> bool {
335 self.allow_unwind_canonical_header
336 }
337
338 pub const fn with_persistence_threshold(mut self, persistence_threshold: u64) -> Self {
340 self.persistence_threshold = persistence_threshold;
341 self
342 }
343
344 pub const fn with_memory_block_buffer_target(
346 mut self,
347 memory_block_buffer_target: u64,
348 ) -> Self {
349 self.memory_block_buffer_target = memory_block_buffer_target;
350 self
351 }
352
353 pub const fn with_block_buffer_limit(mut self, block_buffer_limit: u32) -> Self {
355 self.block_buffer_limit = block_buffer_limit;
356 self
357 }
358
359 pub const fn with_max_invalid_header_cache_length(
361 mut self,
362 max_invalid_header_cache_length: u32,
363 ) -> Self {
364 self.max_invalid_header_cache_length = max_invalid_header_cache_length;
365 self
366 }
367
368 pub const fn with_max_execute_block_batch_size(
370 mut self,
371 max_execute_block_batch_size: usize,
372 ) -> Self {
373 self.max_execute_block_batch_size = max_execute_block_batch_size;
374 self
375 }
376
377 pub const fn with_legacy_state_root(mut self, legacy_state_root: bool) -> Self {
379 self.legacy_state_root = legacy_state_root;
380 self
381 }
382
383 pub const fn without_state_cache(mut self, disable_state_cache: bool) -> Self {
385 self.disable_state_cache = disable_state_cache;
386 self
387 }
388
389 pub const fn without_prewarming(mut self, disable_prewarming: bool) -> Self {
391 self.disable_prewarming = disable_prewarming;
392 self
393 }
394
395 pub const fn with_always_compare_trie_updates(
398 mut self,
399 always_compare_trie_updates: bool,
400 ) -> Self {
401 self.always_compare_trie_updates = always_compare_trie_updates;
402 self
403 }
404
405 pub const fn with_cross_block_cache_size(mut self, cross_block_cache_size: u64) -> Self {
407 self.cross_block_cache_size = cross_block_cache_size;
408 self
409 }
410
411 pub const fn with_has_enough_parallelism(mut self, has_enough_parallelism: bool) -> Self {
413 self.has_enough_parallelism = has_enough_parallelism;
414 self
415 }
416
417 pub const fn with_state_provider_metrics(mut self, state_provider_metrics: bool) -> Self {
419 self.state_provider_metrics = state_provider_metrics;
420 self
421 }
422
423 pub const fn with_disable_parallel_sparse_trie(
425 mut self,
426 disable_parallel_sparse_trie: bool,
427 ) -> Self {
428 self.disable_parallel_sparse_trie = disable_parallel_sparse_trie;
429 self
430 }
431
432 pub const fn with_multiproof_chunking_enabled(
434 mut self,
435 multiproof_chunking_enabled: bool,
436 ) -> Self {
437 self.multiproof_chunking_enabled = multiproof_chunking_enabled;
438 self
439 }
440
441 pub const fn with_multiproof_chunk_size(mut self, multiproof_chunk_size: usize) -> Self {
443 self.multiproof_chunk_size = multiproof_chunk_size;
444 self
445 }
446
447 pub const fn with_reserved_cpu_cores(mut self, reserved_cpu_cores: usize) -> Self {
449 self.reserved_cpu_cores = reserved_cpu_cores;
450 self
451 }
452
453 pub const fn without_precompile_cache(mut self, precompile_cache_disabled: bool) -> Self {
455 self.precompile_cache_disabled = precompile_cache_disabled;
456 self
457 }
458
459 pub const fn with_state_root_fallback(mut self, state_root_fallback: bool) -> Self {
461 self.state_root_fallback = state_root_fallback;
462 self
463 }
464
465 pub const fn with_unwind_canonical_header(mut self, unwind_canonical_header: bool) -> Self {
467 self.allow_unwind_canonical_header = unwind_canonical_header;
468 self
469 }
470
471 pub const fn use_state_root_task(&self) -> bool {
473 self.has_enough_parallelism && !self.legacy_state_root
474 }
475
476 pub const fn with_prewarm_max_concurrency(mut self, prewarm_max_concurrency: usize) -> Self {
478 self.prewarm_max_concurrency = prewarm_max_concurrency;
479 self
480 }
481
482 pub const fn prewarm_max_concurrency(&self) -> usize {
484 self.prewarm_max_concurrency
485 }
486
487 pub const fn storage_worker_count(&self) -> usize {
489 self.storage_worker_count
490 }
491
492 pub fn with_storage_worker_count(mut self, storage_worker_count: usize) -> Self {
494 self.storage_worker_count = storage_worker_count.max(MIN_WORKER_COUNT);
495 self
496 }
497
498 pub const fn account_worker_count(&self) -> usize {
500 self.account_worker_count
501 }
502
503 pub fn with_account_worker_count(mut self, account_worker_count: usize) -> Self {
505 self.account_worker_count = account_worker_count.max(MIN_WORKER_COUNT);
506 self
507 }
508
509 pub const fn enable_proof_v2(&self) -> bool {
511 self.enable_proof_v2
512 }
513
514 pub const fn with_enable_proof_v2(mut self, enable_proof_v2: bool) -> Self {
516 self.enable_proof_v2 = enable_proof_v2;
517 self
518 }
519}