1use std::net::SocketAddr;
5use std::path::PathBuf;
6use std::time::Duration;
7
8use consensus_config::{ObserverParameters, Parameters as ConsensusParameters};
9use fastcrypto::encoding::{Encoding, Hex};
10use fastcrypto::traits::KeyPair;
11use sui_config::node::{
12 AuthorityKeyPairWithPath, AuthorityOverloadConfig, AuthorityStorePruningConfig,
13 CheckpointExecutorConfig, DBCheckpointConfig, DEFAULT_GRPC_CONCURRENCY_LIMIT,
14 ExecutionCacheConfig, ExecutionTimeObserverConfig, ExpensiveSafetyCheckConfig,
15 FundsWithdrawSchedulerType, Genesis, KeyPairWithPath, StateSnapshotConfig,
16 default_enable_index_processing, default_end_of_epoch_broadcast_channel_capacity,
17};
18use sui_config::node::{RunWithRange, TransactionDriverConfig, default_zklogin_oauth_providers};
19use sui_config::p2p::{P2pConfig, SeedPeer, StateSyncConfig};
20use sui_config::verifier_signing_config::VerifierSigningConfig;
21use sui_config::{
22 AUTHORITIES_DB_NAME, CONSENSUS_DB_NAME, ConsensusConfig, FULL_NODE_DB_PATH, NodeConfig,
23 local_ip_utils,
24};
25use sui_protocol_config::Chain;
26use sui_types::crypto::{AuthorityKeyPair, AuthorityPublicKeyBytes, NetworkKeyPair, SuiKeyPair};
27use sui_types::multiaddr::Multiaddr;
28use sui_types::node_role::FullNodeSyncMode;
29use sui_types::supported_protocol_versions::SupportedProtocolVersions;
30use sui_types::traffic_control::{PolicyConfig, RemoteFirewallConfig};
31
32use crate::genesis_config::{ValidatorGenesisConfig, ValidatorGenesisConfigBuilder};
33use crate::network_config::NetworkConfig;
34
35#[derive(Clone, Default)]
38pub struct ValidatorConfigBuilder {
39 config_directory: Option<PathBuf>,
40 supported_protocol_versions: Option<SupportedProtocolVersions>,
41 force_unpruned_checkpoints: bool,
42 jwk_fetch_interval: Option<Duration>,
43 authority_overload_config: Option<AuthorityOverloadConfig>,
44 execution_cache_config: Option<ExecutionCacheConfig>,
45 data_ingestion_dir: Option<PathBuf>,
46 policy_config: Option<PolicyConfig>,
47 firewall_config: Option<RemoteFirewallConfig>,
48 global_state_hash_v2: bool,
49 funds_withdraw_scheduler_type: FundsWithdrawSchedulerType,
50 execution_time_observer_config: Option<ExecutionTimeObserverConfig>,
51 chain_override: Option<Chain>,
52 state_sync_config: Option<StateSyncConfig>,
53 observer_config: Option<ObserverParameters>,
54}
55
56impl ValidatorConfigBuilder {
57 pub fn new() -> Self {
58 Self {
59 global_state_hash_v2: true,
60 ..Default::default()
61 }
62 }
63
64 pub fn with_chain_override(mut self, chain: Chain) -> Self {
65 assert!(self.chain_override.is_none(), "Chain override already set");
66 self.chain_override = Some(chain);
67 self
68 }
69
70 pub fn with_config_directory(mut self, config_directory: PathBuf) -> Self {
71 assert!(self.config_directory.is_none());
72 self.config_directory = Some(config_directory);
73 self
74 }
75
76 pub fn with_supported_protocol_versions(
77 mut self,
78 supported_protocol_versions: SupportedProtocolVersions,
79 ) -> Self {
80 assert!(self.supported_protocol_versions.is_none());
81 self.supported_protocol_versions = Some(supported_protocol_versions);
82 self
83 }
84
85 pub fn with_unpruned_checkpoints(mut self) -> Self {
86 self.force_unpruned_checkpoints = true;
87 self
88 }
89
90 pub fn with_jwk_fetch_interval(mut self, i: Duration) -> Self {
91 self.jwk_fetch_interval = Some(i);
92 self
93 }
94
95 pub fn with_authority_overload_config(mut self, config: AuthorityOverloadConfig) -> Self {
96 self.authority_overload_config = Some(config);
97 self
98 }
99
100 pub fn with_execution_cache_config(mut self, config: ExecutionCacheConfig) -> Self {
101 self.execution_cache_config = Some(config);
102 self
103 }
104
105 pub fn with_data_ingestion_dir(mut self, path: PathBuf) -> Self {
106 self.data_ingestion_dir = Some(path);
107 self
108 }
109
110 pub fn with_policy_config(mut self, config: Option<PolicyConfig>) -> Self {
111 self.policy_config = config;
112 self
113 }
114
115 pub fn with_firewall_config(mut self, config: Option<RemoteFirewallConfig>) -> Self {
116 self.firewall_config = config;
117 self
118 }
119
120 pub fn with_global_state_hash_v2_enabled(mut self, enabled: bool) -> Self {
121 self.global_state_hash_v2 = enabled;
122 self
123 }
124
125 pub fn with_funds_withdraw_scheduler_type(
126 mut self,
127 scheduler_type: FundsWithdrawSchedulerType,
128 ) -> Self {
129 self.funds_withdraw_scheduler_type = scheduler_type;
130 self
131 }
132
133 pub fn with_execution_time_observer_config(
134 mut self,
135 config: ExecutionTimeObserverConfig,
136 ) -> Self {
137 self.execution_time_observer_config = Some(config);
138 self
139 }
140
141 pub fn with_state_sync_config(mut self, config: StateSyncConfig) -> Self {
142 self.state_sync_config = Some(config);
143 self
144 }
145
146 pub fn with_observer_config(mut self, config: ObserverParameters) -> Self {
147 self.observer_config = Some(config);
148 self
149 }
150
151 pub fn build(
152 self,
153 validator: ValidatorGenesisConfig,
154 genesis: sui_config::genesis::Genesis,
155 ) -> NodeConfig {
156 let key_path = get_key_path(&validator.key_pair);
157 let config_directory = self
158 .config_directory
159 .unwrap_or_else(|| mysten_common::tempdir().unwrap().keep());
160 let db_path = config_directory
161 .join(AUTHORITIES_DB_NAME)
162 .join(key_path.clone());
163
164 let network_address = validator.network_address;
165 let consensus_db_path = config_directory.join(CONSENSUS_DB_NAME).join(key_path);
166 let localhost = local_ip_utils::localhost_for_testing();
167 let parameters = self
168 .observer_config
169 .map(|observer_config| ConsensusParameters {
170 observer: ObserverParameters {
171 server_port: observer_config
172 .server_port
173 .or_else(|| Some(local_ip_utils::get_available_port(&localhost))),
174 allowlist: observer_config.allowlist,
175 peers: observer_config.peers,
176 },
177 ..Default::default()
178 });
179 let consensus_config = ConsensusConfig {
180 db_path: consensus_db_path,
181 db_retention_epochs: None,
182 db_pruner_period_secs: None,
183 max_pending_transactions: None,
184 parameters,
185 listen_address: None,
186 external_address: None,
187 };
188
189 let p2p_config = P2pConfig {
190 listen_address: validator.p2p_listen_address.unwrap_or_else(|| {
191 validator
192 .p2p_address
193 .udp_multiaddr_to_listen_address()
194 .unwrap()
195 }),
196 external_address: Some(validator.p2p_address),
197 state_sync: Some(if let Some(mut config) = self.state_sync_config {
200 if config.checkpoint_content_timeout_ms.is_none() {
201 config.checkpoint_content_timeout_ms = Some(10_000);
202 }
203 config
204 } else {
205 StateSyncConfig {
206 checkpoint_content_timeout_ms: Some(10_000),
207 ..Default::default()
208 }
209 }),
210 ..Default::default()
211 };
212
213 let mut pruning_config = AuthorityStorePruningConfig::default();
214 if self.force_unpruned_checkpoints {
215 pruning_config.set_num_epochs_to_retain_for_checkpoints(None);
216 }
217 let pruning_config = pruning_config;
218 let checkpoint_executor_config = CheckpointExecutorConfig {
219 data_ingestion_dir: self.data_ingestion_dir,
220 ..Default::default()
221 };
222
223 NodeConfig {
224 protocol_key_pair: AuthorityKeyPairWithPath::new(validator.key_pair),
225 network_key_pair: KeyPairWithPath::new(SuiKeyPair::Ed25519(validator.network_key_pair)),
226 account_key_pair: KeyPairWithPath::new(validator.account_key_pair),
227 worker_key_pair: KeyPairWithPath::new(SuiKeyPair::Ed25519(validator.worker_key_pair)),
228 db_path,
229 network_address,
230 metrics_address: validator.metrics_address,
231 admin_interface_port: local_ip_utils::get_available_port(&localhost),
232 json_rpc_address: local_ip_utils::new_tcp_address_for_testing(&localhost)
233 .to_socket_addr()
234 .unwrap(),
235 consensus_config: Some(consensus_config),
236 fullnode_sync_mode: None,
237 remove_deprecated_tables: false,
238 enable_index_processing: default_enable_index_processing(),
239 sync_post_process_one_tx: false,
240 genesis: sui_config::node::Genesis::new(genesis),
241 grpc_load_shed: None,
242 grpc_concurrency_limit: Some(DEFAULT_GRPC_CONCURRENCY_LIMIT),
243 p2p_config,
244 authority_store_pruning_config: pruning_config,
245 end_of_epoch_broadcast_channel_capacity:
246 default_end_of_epoch_broadcast_channel_capacity(),
247 checkpoint_executor_config,
248 metrics: None,
249 supported_protocol_versions: self.supported_protocol_versions,
250 db_checkpoint_config: Default::default(),
251 expensive_safety_check_config: ExpensiveSafetyCheckConfig::default(),
253 name_service_package_address: None,
254 name_service_registry_id: None,
255 name_service_reverse_registry_id: None,
256 transaction_deny_config: Default::default(),
257 dev_inspect_disabled: false,
258 certificate_deny_config: Default::default(),
259 state_debug_dump_config: Default::default(),
260 state_archive_read_config: vec![],
261 state_snapshot_write_config: StateSnapshotConfig::default(),
262 indexer_max_subscriptions: Default::default(),
263 transaction_kv_store_read_config: Default::default(),
264 transaction_kv_store_write_config: None,
265 rpc: Some(sui_rpc_api::Config {
266 ..Default::default()
267 }),
268 jwk_fetch_interval_seconds: self
269 .jwk_fetch_interval
270 .map(|i| i.as_secs())
271 .unwrap_or(3600),
272 zklogin_oauth_providers: default_zklogin_oauth_providers(),
273 authority_overload_config: self.authority_overload_config.unwrap_or_default(),
274 execution_cache: self.execution_cache_config.unwrap_or_default(),
275 run_with_range: None,
276 jsonrpc_server_type: None,
277 policy_config: self.policy_config,
278 firewall_config: self.firewall_config,
279 state_accumulator_v2: self.global_state_hash_v2,
280 funds_withdraw_scheduler_type: self.funds_withdraw_scheduler_type,
281 enable_soft_bundle: true,
282 verifier_signing_config: VerifierSigningConfig::default(),
283 enable_db_write_stall: None,
284 enable_db_sync_to_disk: None,
285 execution_time_observer_config: self.execution_time_observer_config,
286 chain_override_for_testing: self.chain_override,
287 validator_client_monitor_config: None,
288 fork_recovery: None,
289 transaction_driver_config: Some(TransactionDriverConfig::default()),
290 congestion_log: None,
291 }
292 }
293
294 pub fn build_new_validator<R: rand::RngCore + rand::CryptoRng>(
295 self,
296 rng: &mut R,
297 network_config: &NetworkConfig,
298 ) -> NodeConfig {
299 let validator_config = ValidatorGenesisConfigBuilder::new().build(rng);
300 self.build(validator_config, network_config.genesis.clone())
301 }
302}
303
304#[derive(Clone, Debug, Default)]
305pub struct FullnodeConfigBuilder {
306 config_directory: Option<PathBuf>,
307 rpc_port: Option<u16>,
309 rpc_addr: Option<SocketAddr>,
310 supported_protocol_versions: Option<SupportedProtocolVersions>,
311 db_checkpoint_config: Option<DBCheckpointConfig>,
312 expensive_safety_check_config: Option<ExpensiveSafetyCheckConfig>,
313 db_path: Option<PathBuf>,
314 network_address: Option<Multiaddr>,
315 json_rpc_address: Option<SocketAddr>,
316 metrics_address: Option<SocketAddr>,
317 admin_interface_port: Option<u16>,
318 genesis: Option<Genesis>,
319 p2p_external_address: Option<Multiaddr>,
320 p2p_listen_address: Option<SocketAddr>,
321 network_key_pair: Option<KeyPairWithPath>,
322 run_with_range: Option<RunWithRange>,
323 policy_config: Option<PolicyConfig>,
324 fw_config: Option<RemoteFirewallConfig>,
325 data_ingestion_dir: Option<PathBuf>,
326 disable_pruning: bool,
327 sync_post_process_one_tx: bool,
328 chain_override: Option<Chain>,
329 transaction_driver_config: Option<TransactionDriverConfig>,
330 rpc_config: Option<sui_config::RpcConfig>,
331 state_sync_config: Option<StateSyncConfig>,
332 observer_config: Option<ObserverParameters>,
333}
334
335impl FullnodeConfigBuilder {
336 pub fn new() -> Self {
337 Self::default()
338 }
339
340 pub fn with_chain_override(mut self, chain: Chain) -> Self {
341 assert!(self.chain_override.is_none(), "Chain override already set");
342 self.chain_override = Some(chain);
343 self
344 }
345
346 pub fn with_config_directory(mut self, config_directory: PathBuf) -> Self {
347 self.config_directory = Some(config_directory);
348 self
349 }
350
351 pub fn with_rpc_port(mut self, port: u16) -> Self {
352 assert!(self.rpc_addr.is_none() && self.rpc_port.is_none());
353 self.rpc_port = Some(port);
354 self
355 }
356
357 pub fn with_rpc_addr(mut self, addr: SocketAddr) -> Self {
358 assert!(self.rpc_addr.is_none() && self.rpc_port.is_none());
359 self.rpc_addr = Some(addr);
360 self
361 }
362
363 pub fn with_rpc_config(mut self, rpc_config: sui_config::RpcConfig) -> Self {
364 self.rpc_config = Some(rpc_config);
365 self
366 }
367
368 pub fn with_supported_protocol_versions(mut self, versions: SupportedProtocolVersions) -> Self {
369 self.supported_protocol_versions = Some(versions);
370 self
371 }
372
373 pub fn with_db_checkpoint_config(mut self, db_checkpoint_config: DBCheckpointConfig) -> Self {
374 self.db_checkpoint_config = Some(db_checkpoint_config);
375 self
376 }
377
378 pub fn with_disable_pruning(mut self, disable_pruning: bool) -> Self {
379 self.disable_pruning = disable_pruning;
380 self
381 }
382
383 pub fn with_expensive_safety_check_config(
384 mut self,
385 expensive_safety_check_config: ExpensiveSafetyCheckConfig,
386 ) -> Self {
387 self.expensive_safety_check_config = Some(expensive_safety_check_config);
388 self
389 }
390
391 pub fn with_sync_post_process_one_tx(mut self, sync: bool) -> Self {
392 self.sync_post_process_one_tx = sync;
393 self
394 }
395
396 pub fn with_db_path(mut self, db_path: PathBuf) -> Self {
397 self.db_path = Some(db_path);
398 self
399 }
400
401 pub fn with_network_address(mut self, network_address: Multiaddr) -> Self {
402 self.network_address = Some(network_address);
403 self
404 }
405
406 pub fn with_json_rpc_address(mut self, json_rpc_address: SocketAddr) -> Self {
407 self.json_rpc_address = Some(json_rpc_address);
408 self
409 }
410
411 pub fn with_metrics_address(mut self, metrics_address: SocketAddr) -> Self {
412 self.metrics_address = Some(metrics_address);
413 self
414 }
415
416 pub fn with_admin_interface_port(mut self, admin_interface_port: u16) -> Self {
417 self.admin_interface_port = Some(admin_interface_port);
418 self
419 }
420
421 pub fn with_genesis(mut self, genesis: Genesis) -> Self {
422 self.genesis = Some(genesis);
423 self
424 }
425
426 pub fn with_p2p_external_address(mut self, p2p_external_address: Multiaddr) -> Self {
427 self.p2p_external_address = Some(p2p_external_address);
428 self
429 }
430
431 pub fn with_p2p_listen_address(mut self, p2p_listen_address: SocketAddr) -> Self {
432 self.p2p_listen_address = Some(p2p_listen_address);
433 self
434 }
435
436 pub fn with_network_key_pair(mut self, network_key_pair: Option<NetworkKeyPair>) -> Self {
437 if let Some(network_key_pair) = network_key_pair {
438 self.network_key_pair =
439 Some(KeyPairWithPath::new(SuiKeyPair::Ed25519(network_key_pair)));
440 }
441 self
442 }
443
444 pub fn with_run_with_range(mut self, run_with_range: Option<RunWithRange>) -> Self {
445 if let Some(run_with_range) = run_with_range {
446 self.run_with_range = Some(run_with_range);
447 }
448 self
449 }
450
451 pub fn with_policy_config(mut self, config: Option<PolicyConfig>) -> Self {
452 self.policy_config = config;
453 self
454 }
455
456 pub fn with_fw_config(mut self, config: Option<RemoteFirewallConfig>) -> Self {
457 self.fw_config = config;
458 self
459 }
460
461 pub fn with_data_ingestion_dir(mut self, path: Option<PathBuf>) -> Self {
462 self.data_ingestion_dir = path;
463 self
464 }
465
466 pub fn with_transaction_driver_config(
467 mut self,
468 config: Option<TransactionDriverConfig>,
469 ) -> Self {
470 self.transaction_driver_config = config;
471 self
472 }
473
474 pub fn with_state_sync_config(mut self, config: StateSyncConfig) -> Self {
475 self.state_sync_config = Some(config);
476 self
477 }
478
479 pub fn with_observer_config(mut self, config: ObserverParameters) -> Self {
480 self.observer_config = Some(config);
481 self
482 }
483
484 pub fn build<R: rand::RngCore + rand::CryptoRng>(
485 self,
486 rng: &mut R,
487 network_config: &NetworkConfig,
488 ) -> NodeConfig {
489 let validator_config = ValidatorGenesisConfigBuilder::new().build(rng);
492 let ip = validator_config
493 .network_address
494 .to_socket_addr()
495 .unwrap()
496 .ip()
497 .to_string();
498
499 let key_path = get_key_path(&validator_config.key_pair);
500 let config_directory = self
501 .config_directory
502 .unwrap_or_else(|| mysten_common::tempdir().unwrap().keep());
503
504 let consensus_db_path = config_directory.join(CONSENSUS_DB_NAME).join(&key_path);
505
506 let fullnode_sync_mode = self
507 .observer_config
508 .as_ref()
509 .filter(|c| !c.peers.is_empty())
510 .map(|_| FullNodeSyncMode::ConsensusObserver);
511
512 let consensus_config = self.observer_config.map(|observer_config| ConsensusConfig {
514 db_path: consensus_db_path,
515 db_retention_epochs: None,
516 db_pruner_period_secs: None,
517 max_pending_transactions: None,
518 parameters: Some(ConsensusParameters {
519 observer: ObserverParameters {
520 server_port: observer_config
521 .server_port
522 .or_else(|| Some(local_ip_utils::get_available_port(&ip))),
523 allowlist: observer_config.allowlist,
524 peers: observer_config.peers,
525 },
526 ..Default::default()
527 }),
528 listen_address: None,
529 external_address: None,
530 });
531
532 let p2p_config = {
533 let seed_peers = network_config
534 .validator_configs
535 .iter()
536 .map(|config| SeedPeer {
537 peer_id: Some(anemo::PeerId(
538 config.network_key_pair().public().0.to_bytes(),
539 )),
540 address: config.p2p_config.external_address.clone().unwrap(),
541 })
542 .collect();
543
544 P2pConfig {
545 listen_address: self.p2p_listen_address.unwrap_or_else(|| {
546 validator_config.p2p_listen_address.unwrap_or_else(|| {
547 validator_config
548 .p2p_address
549 .udp_multiaddr_to_listen_address()
550 .unwrap()
551 })
552 }),
553 external_address: self
554 .p2p_external_address
555 .or(Some(validator_config.p2p_address.clone())),
556 seed_peers,
557 state_sync: Some(if let Some(mut config) = self.state_sync_config {
560 if config.checkpoint_content_timeout_ms.is_none() {
561 config.checkpoint_content_timeout_ms = Some(10_000);
562 }
563 config
564 } else {
565 StateSyncConfig {
566 checkpoint_content_timeout_ms: Some(10_000),
567 ..Default::default()
568 }
569 }),
570 ..Default::default()
571 }
572 };
573
574 let localhost = local_ip_utils::localhost_for_testing();
575 let json_rpc_address = self.rpc_addr.unwrap_or_else(|| {
576 let rpc_port = self
577 .rpc_port
578 .unwrap_or_else(|| local_ip_utils::get_available_port(&ip));
579 format!("{}:{}", ip, rpc_port).parse().unwrap()
580 });
581
582 let checkpoint_executor_config = CheckpointExecutorConfig {
583 data_ingestion_dir: self.data_ingestion_dir,
584 ..Default::default()
585 };
586
587 let mut pruning_config = AuthorityStorePruningConfig::default();
588 if self.disable_pruning {
589 pruning_config.set_num_epochs_to_retain_for_checkpoints(None);
590 pruning_config.set_num_epochs_to_retain(u64::MAX);
591 };
592
593 NodeConfig {
594 protocol_key_pair: AuthorityKeyPairWithPath::new(validator_config.key_pair),
595 account_key_pair: KeyPairWithPath::new(validator_config.account_key_pair),
596 worker_key_pair: KeyPairWithPath::new(SuiKeyPair::Ed25519(
597 validator_config.worker_key_pair,
598 )),
599 network_key_pair: self.network_key_pair.unwrap_or(KeyPairWithPath::new(
600 SuiKeyPair::Ed25519(validator_config.network_key_pair),
601 )),
602 db_path: self
603 .db_path
604 .unwrap_or(config_directory.join(FULL_NODE_DB_PATH).join(key_path)),
605 network_address: self
606 .network_address
607 .unwrap_or(validator_config.network_address),
608 metrics_address: self
609 .metrics_address
610 .unwrap_or(local_ip_utils::new_local_tcp_socket_for_testing()),
611 admin_interface_port: self
612 .admin_interface_port
613 .unwrap_or(local_ip_utils::get_available_port(&localhost)),
614 json_rpc_address: self.json_rpc_address.unwrap_or(json_rpc_address),
615 fullnode_sync_mode,
616 consensus_config,
617 remove_deprecated_tables: false,
618 enable_index_processing: default_enable_index_processing(),
619 sync_post_process_one_tx: self.sync_post_process_one_tx,
620 genesis: self.genesis.unwrap_or(sui_config::node::Genesis::new(
621 network_config.genesis.clone(),
622 )),
623 grpc_load_shed: None,
624 grpc_concurrency_limit: None,
625 p2p_config,
626 authority_store_pruning_config: pruning_config,
627 end_of_epoch_broadcast_channel_capacity:
628 default_end_of_epoch_broadcast_channel_capacity(),
629 checkpoint_executor_config,
630 metrics: None,
631 supported_protocol_versions: self.supported_protocol_versions,
632 db_checkpoint_config: self.db_checkpoint_config.unwrap_or_default(),
633 expensive_safety_check_config: self
634 .expensive_safety_check_config
635 .unwrap_or_else(ExpensiveSafetyCheckConfig::new_enable_all),
636 name_service_package_address: None,
637 name_service_registry_id: None,
638 name_service_reverse_registry_id: None,
639 transaction_deny_config: Default::default(),
640 dev_inspect_disabled: false,
641 certificate_deny_config: Default::default(),
642 state_debug_dump_config: Default::default(),
643 state_archive_read_config: vec![],
644 state_snapshot_write_config: StateSnapshotConfig::default(),
645 indexer_max_subscriptions: Default::default(),
646 transaction_kv_store_read_config: Default::default(),
647 transaction_kv_store_write_config: Default::default(),
648 rpc: self.rpc_config.or_else(|| {
649 Some(sui_rpc_api::Config {
650 enable_indexing: Some(true),
651 ..Default::default()
652 })
653 }),
654 jwk_fetch_interval_seconds: 3600,
656 zklogin_oauth_providers: default_zklogin_oauth_providers(),
657 authority_overload_config: Default::default(),
658 run_with_range: self.run_with_range,
659 jsonrpc_server_type: None,
660 policy_config: self.policy_config,
661 firewall_config: self.fw_config,
662 execution_cache: ExecutionCacheConfig::default(),
663 state_accumulator_v2: true,
664 funds_withdraw_scheduler_type: FundsWithdrawSchedulerType::default(),
665 enable_soft_bundle: true,
666 verifier_signing_config: VerifierSigningConfig::default(),
667 enable_db_write_stall: None,
668 enable_db_sync_to_disk: None,
669 execution_time_observer_config: None,
670 chain_override_for_testing: self.chain_override,
671 validator_client_monitor_config: None,
672 fork_recovery: None,
673 transaction_driver_config: self
674 .transaction_driver_config
675 .or(Some(TransactionDriverConfig::default())),
676 congestion_log: None,
677 }
678 }
679}
680
681fn get_key_path(key_pair: &AuthorityKeyPair) -> String {
683 let public_key: AuthorityPublicKeyBytes = key_pair.public().into();
684 let mut key_path = Hex::encode(public_key);
685 key_path.truncate(12);
687 key_path
688}