1use std::{collections::BTreeMap, convert::TryInto, path::PathBuf, sync::Arc};
6
7use cfx_rpc_builder::RpcModuleSelection;
8use lazy_static::*;
9use log::{error, warn};
10use parking_lot::RwLock;
11use rand::Rng;
12
13use cfx_addr::{cfx_addr_decode, Network};
14use cfx_executor::{machine::Machine, spec::CommonParams};
15use cfx_internal_common::{
16 ChainIdParams, ChainIdParamsInner, ChainIdParamsOneChainInner,
17};
18use cfx_parameters::{
19 block::DEFAULT_TARGET_BLOCK_GAS_LIMIT, tx_pool::TXPOOL_DEFAULT_NONCE_BITS,
20};
21use cfx_rpc_cfx_types::{
22 address::USE_SIMPLE_RPC_ADDRESS, apis::ApiSet, RpcImplConfiguration,
23};
24use cfx_storage::{
25 defaults::DEFAULT_DEBUG_SNAPSHOT_CHECKER_THREADS, storage_dir,
26 ConsensusParam, ProvideExtraSnapshotSyncConfig, StorageConfiguration,
27};
28use cfx_types::{
29 parse_hex_string, Address, AllChainID, Space, SpaceMap, H256, U256,
30};
31use cfxcore::{
32 block_data_manager::{DataManagerConfiguration, DbType},
33 block_parameters::*,
34 cache_config::{
35 DEFAULT_INVALID_BLOCK_HASH_CACHE_SIZE_IN_COUNT,
36 DEFAULT_LEDGER_CACHE_SIZE,
37 DEFAULT_TARGET_DIFFICULTIES_CACHE_SIZE_IN_COUNT,
38 },
39 consensus::{
40 consensus_inner::consensus_executor::ConsensusExecutionConfiguration,
41 pivot_hint::PivotHintConfig, ConsensusConfig, ConsensusInnerConfig,
42 },
43 consensus_internal_parameters::*,
44 consensus_parameters::*,
45 light_protocol::LightNodeConfiguration,
46 sync::{ProtocolConfiguration, StateSyncConfiguration, SyncGraphConfig},
47 sync_parameters::*,
48 transaction_pool::TxPoolConfig,
49 NodeType,
50};
51use diem_types::term_state::{
52 pos_state_config::PosStateConfig, IN_QUEUE_LOCKED_VIEWS,
53 OUT_QUEUE_LOCKED_VIEWS, ROUND_PER_TERM, TERM_ELECTED_SIZE, TERM_MAX_SIZE,
54};
55use jsonrpsee::server::ServerConfigBuilder;
56use metrics::MetricsConfiguration;
57use network::DiscoveryConfiguration;
58use primitives::block_header::CIP112_TRANSITION_HEIGHT;
59use txgen::TransactionGeneratorConfig;
60
61use crate::{HttpConfiguration, WsConfiguration};
62
63lazy_static! {
64 pub static ref CHAIN_ID: RwLock<Option<ChainIdParams>> = Default::default();
65}
66const BLOCK_DB_DIR_NAME: &str = "blockchain_db";
67const NET_CONFIG_DB_DIR_NAME: &str = "net_config";
68
69build_config! {
87 {
88 (mode, (Option<String>), None)
113 (debug_invalid_state_root, (bool), false)
115 (debug_invalid_state_root_epoch, (Option<String>), None)
116 (debug_dump_dir_invalid_state_root, (String), "./storage_db/debug_dump_invalid_state_root/".to_string())
117 (dev_block_interval_ms, (Option<u64>), None)
120 (dev_pack_tx_immediately, (Option<bool>), None)
121 (enable_state_expose, (bool), false)
122 (generate_tx, (bool), false)
123 (generate_tx_period_us, (Option<u64>), Some(100_000))
124 (log_conf, (Option<String>), None)
125 (log_file, (Option<String>), None)
126 (max_block_size_in_bytes, (usize), MAX_BLOCK_SIZE_IN_BYTES)
127 (evm_transaction_block_ratio,(u64),EVM_TRANSACTION_BLOCK_RATIO)
128 (evm_transaction_gas_ratio,(u64),EVM_TRANSACTION_GAS_RATIO)
129 (metrics_enabled, (bool), false)
130 (metrics_influxdb_host, (Option<String>), None)
131 (metrics_influxdb_db, (String), "conflux".into())
132 (metrics_influxdb_username, (Option<String>), None)
133 (metrics_influxdb_password, (Option<String>), None)
134 (metrics_influxdb_node, (Option<String>), None)
135 (metrics_output_file, (Option<String>), None)
136 (metrics_report_interval_ms, (u64), 3_000)
137 (metrics_prometheus_listen_addr, (Option<String>), None)
138 (profiling_listen_addr, (Option<String>), None)
139 (rocksdb_disable_wal, (bool), false)
140 (txgen_account_count, (usize), 10)
141
142 (adaptive_weight_beta, (u64), ADAPTIVE_WEIGHT_DEFAULT_BETA)
144 (anticone_penalty_ratio, (u64), ANTICONE_PENALTY_RATIO)
145 (chain_id, (Option<u32>), None)
146 (evm_chain_id, (Option<u32>), None)
147 (execute_genesis, (bool), true)
148 (default_transition_time, (Option<u64>), None)
149 (dev_snapshot_epoch_count, (u32), SNAPSHOT_EPOCHS_CAPACITY)
152 (era_epoch_count, (u64), ERA_DEFAULT_EPOCH_COUNT)
153 (heavy_block_difficulty_ratio, (u64), HEAVY_BLOCK_DEFAULT_DIFFICULTY_RATIO)
154 (genesis_accounts, (Option<String>), None)
155 (genesis_evm_secrets, (Option<String>), None)
156 (genesis_secrets, (Option<String>), None)
157 (pivot_hint_path, (Option<String>), None)
158 (pivot_hint_checksum, (Option<String>), None)
159 (initial_difficulty, (Option<u64>), None)
160 (referee_bound, (usize), REFEREE_DEFAULT_BOUND)
161 (timer_chain_beta, (u64), TIMER_CHAIN_DEFAULT_BETA)
162 (timer_chain_block_difficulty_ratio, (u64), TIMER_CHAIN_BLOCK_DEFAULT_DIFFICULTY_RATIO)
163 (transaction_epoch_bound, (u64), TRANSACTION_DEFAULT_EPOCH_BOUND)
165
166
167 (tanzanite_transition_height, (u64), TANZANITE_HEIGHT)
170 (hydra_transition_number, (Option<u64>), None)
172 (hydra_transition_height, (Option<u64>), None)
173 (cip43_init_end_number, (Option<u64>), None)
174 (cip78_patch_transition_number,(Option<u64>),None)
175 (cip90_transition_height,(Option<u64>),None)
176 (cip90_transition_number,(Option<u64>),None)
177 (dao_vote_transition_number, (Option<u64>), None)
179 (dao_vote_transition_height, (Option<u64>), None)
180 (cip105_transition_number, (Option<u64>), None)
181 (params_dao_vote_period, (u64), DAO_PARAMETER_VOTE_PERIOD)
182 (sigma_fix_transition_number, (Option<u64>), None)
184 (cip107_transition_number, (Option<u64>), None)
186 (cip112_transition_height, (Option<u64>), None)
187 (cip118_transition_number, (Option<u64>), None)
188 (cip119_transition_number, (Option<u64>), None)
189 (base_fee_burn_transition_number, (Option<u64>), None)
191 (base_fee_burn_transition_height, (Option<u64>), None)
192 (cip1559_transition_height, (Option<u64>), None)
193 (cip130_transition_height, (Option<u64>), None)
194 (cancun_opcodes_transition_number, (Option<u64>), None)
195 (min_native_base_price, (Option<u64>), None)
196 (min_eth_base_price, (Option<u64>), None)
197 (c2_fix_transition_height, (Option<u64>), None)
199 (eoa_code_transition_height, (Option<u64>), None)
201 (cip151_transition_height, (Option<u64>), None)
202 (cip645_transition_height, (Option<u64>), None)
203 (cip145_fix_transition_height, (Option<u64>), None)
204 (align_evm_transition_height, (u64), u64::MAX)
206
207 (osaka_opcode_transition_height, (Option<u64>), None)
209 (cip166_transition_height, (Option<u64>), None)
210 (cip167_transition_height, (Option<u64>), None)
211 (cip172_transition_height, (Option<u64>), None)
212 (cip174_transition_height, (Option<u64>), None)
213 (cip175_transition_height, (Option<u64>), None)
214 (cip176_transition_height, (Option<u64>), None)
215
216 (mining_author, (Option<String>), None)
218 (mining_type, (Option<String>), None)
219 (stratum_listen_address, (String), "127.0.0.1".into())
220 (stratum_port, (u16), 32525)
221 (stratum_secret, (Option<String>), None)
222 (use_octopus_in_test_mode, (bool), false)
223 (pow_problem_window_size, (usize), 1)
224
225 (jsonrpc_local_http_port, (Option<u16>), None)
227 (jsonrpc_local_ws_port, (Option<u16>), None)
228 (jsonrpc_ws_port, (Option<u16>), None)
229 (jsonrpc_http_port, (Option<u16>), None)
230 (jsonrpc_http_threads, (Option<usize>), None)
231 (jsonrpc_cors, (Option<String>), None)
232 (jsonrpc_http_keep_alive, (bool), false)
233 (jsonrpc_ws_max_payload_bytes, (usize), 30 * 1024 * 1024)
234 (jsonrpc_http_eth_port, (Option<u16>), None)
235 (jsonrpc_ws_eth_port, (Option<u16>), None)
236 (jsonrpc_max_request_body_size, (u32), 10 * 1024 * 1024)
237 (jsonrpc_max_response_body_size, (u32), 10 * 1024 * 1024)
238 (jsonrpc_max_connections, (u32), 100)
239 (jsonrpc_max_subscriptions_per_connection, (u32), 1024)
240 (jsonrpc_message_buffer_capacity, (u32), 1024)
241 (network_id, (Option<u64>), None)
246 (rpc_enable_metrics, (bool), false)
247 (tcp_port, (u16), 32323)
248 (public_tcp_port, (Option<u16>), None)
249 (public_address, (Option<String>), None)
250 (udp_port, (Option<u16>), Some(32323))
251 (max_estimation_gas_limit, (Option<u64>), None)
252 (rpc_address_simple_mode, (bool), false)
253
254 (blocks_request_timeout_ms, (u64), 20_000)
256 (check_request_period_ms, (u64), 1_000)
257 (chunk_size_byte, (u64), DEFAULT_CHUNK_SIZE)
258 (demote_peer_for_timeout, (bool), false)
259 (dev_allow_phase_change_without_peer, (bool), false)
260 (egress_queue_capacity, (usize), 256)
261 (egress_min_throttle, (usize), 10)
262 (egress_max_throttle, (usize), 64)
263 (expire_block_gc_period_s, (u64), 900)
264 (headers_request_timeout_ms, (u64), 10_000)
265 (heartbeat_period_interval_ms, (u64), 30_000)
266 (heartbeat_timeout_ms, (u64), 180_000)
267 (inflight_pending_tx_index_maintain_timeout_ms, (u64), 30_000)
268 (max_allowed_timeout_in_observing_period, (u64), 10)
269 (max_chunk_number_in_manifest, (usize), 500)
270 (max_downloading_chunks, (usize), 8)
271 (max_downloading_chunk_attempts, (usize), 5)
272 (max_downloading_manifest_attempts, (usize), 5)
273 (max_handshakes, (usize), 64)
274 (max_incoming_peers, (usize), 64)
275 (max_inflight_request_count, (u64), 64)
276 (max_outgoing_peers, (usize), 8)
277 (max_outgoing_peers_archive, (Option<usize>), None)
278 (max_peers_tx_propagation, (usize), 128)
279 (max_unprocessed_block_size_mb, (usize), (128))
280 (min_peers_tx_propagation, (usize), 8)
281 (min_phase_change_normal_peer_count, (usize), 3)
282 (received_tx_index_maintain_timeout_ms, (u64), 300_000)
283 (request_block_with_public, (bool), false)
284 (send_tx_period_ms, (u64), 1300)
285 (snapshot_candidate_request_timeout_ms, (u64), 10_000)
286 (snapshot_chunk_request_timeout_ms, (u64), 30_000)
287 (snapshot_manifest_request_timeout_ms, (u64), 30_000)
288 (sync_expire_block_timeout_s, (u64), 7200)
289 (throttling_conf, (Option<String>), None)
290 (timeout_observing_period_s, (u64), 600)
291 (transaction_request_timeout_ms, (u64), 30_000)
292 (tx_maintained_for_peer_timeout_ms, (u64), 600_000)
293
294 (bootnodes, (Option<String>), None)
296 (discovery_discover_node_count, (u32), 16)
297 (discovery_expire_time_s, (u64), 20)
298 (discovery_fast_refresh_timeout_ms, (u64), 10_000)
299 (discovery_find_node_timeout_ms, (u64), 2_000)
300 (discovery_housekeeping_timeout_ms, (u64), 1_000)
301 (discovery_max_nodes_ping, (usize), 32)
302 (discovery_ping_timeout_ms, (u64), 2_000)
303 (discovery_round_timeout_ms, (u64), 500)
304 (discovery_throttling_interval_ms, (u64), 1_000)
305 (discovery_throttling_limit_ping, (usize), 20)
306 (discovery_throttling_limit_find_nodes, (usize), 10)
307 (enable_discovery, (bool), true)
308 (netconf_dir, (Option<String>), None)
309 (net_key, (Option<String>), None)
310 (node_table_timeout_s, (u64), 300)
311 (node_table_promotion_timeout_s, (u64), 3 * 24 * 3600)
312 (session_ip_limits, (String), "1,8,4,2".into())
313 (subnet_quota, (usize), 128)
314
315 (tx_cache_index_maintain_timeout_ms, (u64), 300_000)
317 (tx_pool_size, (usize), 50_000)
318 (tx_pool_min_native_tx_gas_price, (Option<u64>), None)
319 (tx_pool_min_eth_tx_gas_price, (Option<u64>), None)
320 (tx_pool_nonce_bits, (usize), TXPOOL_DEFAULT_NONCE_BITS)
321 (tx_pool_allow_gas_over_half_block, (bool), false)
322 (max_packing_batch_gas_limit, (u64), 3_000_000)
323 (max_packing_batch_size, (usize), 50)
324 (packing_pool_degree, (u8), 4)
325
326
327 (additional_maintained_snapshot_count, (u32), 1)
329 (additional_maintained_block_body_epoch_count, (Option<usize>), None)
331 (additional_maintained_execution_result_epoch_count, (Option<usize>), None)
332 (additional_maintained_reward_epoch_count, (Option<usize>), None)
333 (additional_maintained_trace_epoch_count, (Option<usize>), None)
334 (additional_maintained_transaction_index_epoch_count, (Option<usize>), None)
335 (block_cache_gc_period_ms, (u64), 5_000)
336 (block_db_dir, (Option<String>), None)
337 (block_db_type, (String), "rocksdb".to_string())
338 (checkpoint_gc_time_in_era_count, (f64), 0.5)
339 (conflux_data_dir, (String), "./blockchain_data".to_string())
341 (enable_single_mpt_storage, (bool), false)
342 (ledger_cache_size, (usize), DEFAULT_LEDGER_CACHE_SIZE)
343 (invalid_block_hash_cache_size_in_count, (usize), DEFAULT_INVALID_BLOCK_HASH_CACHE_SIZE_IN_COUNT)
344 (rocksdb_cache_size, (Option<usize>), Some(128))
345 (rocksdb_compaction_profile, (Option<String>), None)
346 (storage_delta_mpts_cache_recent_lfu_factor, (f64), cfx_storage::defaults::DEFAULT_DELTA_MPTS_CACHE_RECENT_LFU_FACTOR)
347 (storage_delta_mpts_cache_size, (u32), cfx_storage::defaults::DEFAULT_DELTA_MPTS_CACHE_SIZE)
348 (storage_delta_mpts_cache_start_size, (u32), cfx_storage::defaults::DEFAULT_DELTA_MPTS_CACHE_START_SIZE)
349 (storage_delta_mpts_node_map_vec_size, (u32), cfx_storage::defaults::MAX_CACHED_TRIE_NODES_R_LFU_COUNTER)
350 (storage_delta_mpts_slab_idle_size, (u32), cfx_storage::defaults::DEFAULT_DELTA_MPTS_SLAB_IDLE_SIZE)
351 (storage_single_mpt_cache_size, (u32), cfx_storage::defaults::DEFAULT_DELTA_MPTS_CACHE_SIZE * 2)
352 (storage_single_mpt_cache_start_size, (u32), cfx_storage::defaults::DEFAULT_DELTA_MPTS_CACHE_START_SIZE * 2)
353 (storage_single_mpt_slab_idle_size, (u32), cfx_storage::defaults::DEFAULT_DELTA_MPTS_SLAB_IDLE_SIZE * 2)
354 (storage_max_open_snapshots, (u16), cfx_storage::defaults::DEFAULT_MAX_OPEN_SNAPSHOTS)
355 (storage_max_open_mpt_count, (u32), cfx_storage::defaults::DEFAULT_MAX_OPEN_MPT)
356 (strict_tx_index_gc, (bool), true)
357 (sync_state_starting_epoch, (Option<u64>), None)
358 (sync_state_epoch_gap, (Option<u64>), None)
359 (target_difficulties_cache_size_in_count, (usize), DEFAULT_TARGET_DIFFICULTIES_CACHE_SIZE_IN_COUNT)
360
361 (account_provider_refresh_time_ms, (u64), 1000)
363 (check_phase_change_period_ms, (u64), 1000)
364 (enable_optimistic_execution, (bool), true)
365 (future_block_buffer_capacity, (usize), 32768)
366 (get_logs_filter_max_limit, (Option<usize>), None)
367 (get_logs_filter_max_epoch_range, (Option<u64>), None)
368 (get_logs_filter_max_block_number_range, (Option<u64>), None)
369 (get_logs_epoch_batch_size, (usize), 32)
370 (max_trans_count_received_in_catch_up, (u64), 60_000)
371 (persist_tx_index, (bool), false)
372 (persist_block_number_index, (bool), true)
373 (print_memory_usage_period_s, (Option<u64>), None)
374 (target_block_gas_limit, (u64), DEFAULT_TARGET_BLOCK_GAS_LIMIT)
375 (executive_trace, (bool), false)
376 (check_status_genesis, (bool), true)
377 (packing_gas_limit_block_count, (u64), 10)
378 (poll_lifetime_in_seconds, (Option<u32>), None)
379
380 (is_consortium, (bool), false)
382 (pos_config_path, (Option<String>), Some("./pos_config/pos_config.yaml".to_string()))
383 (pos_genesis_pivot_decision, (Option<H256>), None)
384 (vrf_proposal_threshold, (U256), U256::from_str("1111111111111100000000000000000000000000000000000000000000000000").unwrap())
385 (pos_pivot_decision_defer_epoch_count, (u64), 50)
387 (cip113_pivot_decision_defer_epoch_count, (u64), 20)
388 (cip113_transition_height, (u64), u64::MAX)
389 (pos_reference_enable_height, (u64), u64::MAX)
390 (pos_initial_nodes_path, (String), "./pos_config/initial_nodes.json".to_string())
391 (pos_private_key_path, (String), "./pos_config/pos_key".to_string())
392 (pos_round_per_term, (u64), ROUND_PER_TERM)
393 (pos_term_max_size, (usize), TERM_MAX_SIZE)
394 (pos_term_elected_size, (usize), TERM_ELECTED_SIZE)
395 (pos_in_queue_locked_views, (u64), IN_QUEUE_LOCKED_VIEWS)
396 (pos_out_queue_locked_views, (u64), OUT_QUEUE_LOCKED_VIEWS)
397 (pos_cip99_transition_view, (u64), u64::MAX)
398 (pos_cip99_in_queue_locked_views, (u64), IN_QUEUE_LOCKED_VIEWS)
399 (pos_cip99_out_queue_locked_views, (u64), OUT_QUEUE_LOCKED_VIEWS)
400 (nonce_limit_transition_view, (u64), u64::MAX)
401 (pos_cip136_transition_view, (u64), u64::MAX)
402 (pos_cip136_in_queue_locked_views, (u64), IN_QUEUE_LOCKED_VIEWS)
403 (pos_cip136_out_queue_locked_views, (u64), OUT_QUEUE_LOCKED_VIEWS)
404 (pos_cip136_round_per_term, (u64), ROUND_PER_TERM)
405 (pos_cip156_transition_view, (u64), u64::MAX)
406 (pos_cip156_dispute_locked_views, (u64), 6 * 30 * 24 * 60 * 2)
408 (pos_cip173_transition_view, (u64), u64::MAX)
409 (dev_pos_private_key_encryption_password, (Option<String>), None)
410 (pos_started_as_voter, (bool), true)
411
412 (ln_epoch_request_batch_size, (Option<usize>), None)
414 (ln_epoch_request_timeout_sec, (Option<u64>), None)
415 (ln_header_request_batch_size, (Option<usize>), None)
416 (ln_header_request_timeout_sec, (Option<u64>), None)
417 (ln_max_headers_in_flight, (Option<usize>), None)
418 (ln_max_parallel_epochs_to_request, (Option<usize>), None)
419 (ln_num_epochs_to_request, (Option<usize>), None)
420 (ln_num_waiting_headers_threshold, (Option<usize>), None)
421 (keep_snapshot_before_stable_checkpoint, (bool), true)
422 (force_recompute_height_during_construct_pivot, (Option<u64>), None)
423
424 (use_isolated_db_for_mpt_table, (bool), false)
427 (use_isolated_db_for_mpt_table_height, (Option<u64>), None)
431 (recovery_latest_mpt_snapshot, (bool), false)
433 (keep_era_genesis_snapshot, (bool), true)
434
435 (backup_mpt_snapshot, (bool), true)
437 }
438 {
439 (
441 log_level, (LevelFilter), LevelFilter::Info, |l| {
442 LevelFilter::from_str(l)
443 .map_err(|_| format!("Invalid log level: {}", l))
444 }
445 )
446
447 (chain_id_params, (Option<ChainIdParamsOneChainInner>), None,
451 ChainIdParamsOneChainInner::parse_config_str)
452
453 (provide_more_snapshot_for_sync,
455 (Vec<ProvideExtraSnapshotSyncConfig>),
456 vec![ProvideExtraSnapshotSyncConfig::StableCheckpoint],
457 ProvideExtraSnapshotSyncConfig::parse_config_list)
458 (node_type, (Option<NodeType>), None, NodeType::from_str)
459 (public_rpc_apis, (ApiSet), ApiSet::Safe, ApiSet::from_str)
460 (public_evm_rpc_apis, (RpcModuleSelection), RpcModuleSelection::Evm, RpcModuleSelection::from_str)
461 (single_mpt_space, (Option<Space>), None, Space::from_str)
462 }
463}
464
465#[derive(Debug, Clone, Default)]
466pub struct Configuration {
467 pub raw_conf: RawConfiguration,
468}
469
470impl Configuration {
471 pub fn parse(matches: &clap::ArgMatches) -> Result<Configuration, String> {
472 let mut raw_conf = RawConfiguration::parse(matches)?;
473
474 if matches.get_flag("archive") {
475 raw_conf.node_type = Some(NodeType::Archive);
476 } else if matches.get_flag("full") {
477 raw_conf.node_type = Some(NodeType::Full);
478 } else if matches.get_flag("light") {
479 raw_conf.node_type = Some(NodeType::Light);
480 }
481
482 CIP112_TRANSITION_HEIGHT
483 .set(raw_conf.cip112_transition_height.unwrap_or(u64::MAX))
484 .expect("called once");
485
486 USE_SIMPLE_RPC_ADDRESS
487 .set(raw_conf.rpc_address_simple_mode)
488 .expect("called once");
489
490 Ok(Configuration { raw_conf })
491 }
492
493 pub fn from_file(config_path: &str) -> Result<Configuration, String> {
494 Ok(Configuration {
495 raw_conf: RawConfiguration::from_file(config_path)?,
496 })
497 }
498
499 fn network_id(&self) -> u64 {
500 match self.raw_conf.network_id {
501 Some(x) => x,
502 None => {
505 self.chain_id_params()
506 .read()
507 .get_chain_id(0)
508 .in_native_space() as u64
509 }
510 }
511 }
512
513 pub fn net_config(&self) -> Result<NetworkConfiguration, String> {
514 let mut network_config = NetworkConfiguration::new_with_port(
515 self.network_id(),
516 self.raw_conf.tcp_port,
517 self.discovery_protocol(),
518 );
519
520 network_config.is_consortium = self.raw_conf.is_consortium;
521 network_config.discovery_enabled = self.raw_conf.enable_discovery;
522 network_config.boot_nodes = to_bootnodes(&self.raw_conf.bootnodes)
523 .map_err(|e| format!("failed to parse bootnodes: {}", e))?;
524 network_config.config_path = Some(match &self.raw_conf.netconf_dir {
525 Some(dir) => dir.clone(),
526 None => Path::new(&self.raw_conf.conflux_data_dir)
527 .join(NET_CONFIG_DB_DIR_NAME)
528 .into_os_string()
529 .into_string()
530 .unwrap(),
531 });
532 network_config.use_secret =
533 self.raw_conf.net_key.as_ref().map(|sec_str| {
534 parse_hex_string(sec_str)
535 .expect("net_key is not a valid secret string")
536 });
537 if let Some(addr) = self.raw_conf.public_address.clone() {
538 let addr_ip = if let Some(idx) = addr.find(":") {
539 warn!("Public address configuration should not contain port! (val = {}). Content after ':' is ignored.", &addr);
540 addr[0..idx].to_string()
541 } else {
542 addr
543 };
544 let addr_with_port = match self.raw_conf.public_tcp_port {
545 Some(port) => addr_ip + ":" + &port.to_string(),
546 None => addr_ip + ":" + &self.raw_conf.tcp_port.to_string(),
547 };
548 network_config.public_address =
549 match addr_with_port.to_socket_addrs().map(|mut i| i.next()) {
550 Ok(sock_addr) => sock_addr,
551 Err(_e) => {
552 warn!("public_address in config is invalid");
553 None
554 }
555 };
556 }
557 network_config.node_table_timeout =
558 Duration::from_secs(self.raw_conf.node_table_timeout_s);
559 network_config.connection_lifetime_for_promotion =
560 Duration::from_secs(self.raw_conf.node_table_promotion_timeout_s);
561 network_config.test_mode = self.is_test_mode();
562 network_config.subnet_quota = self.raw_conf.subnet_quota;
563 network_config.session_ip_limit_config =
564 self.raw_conf.session_ip_limits.clone().try_into().map_err(
565 |e| format!("failed to parse session ip limit config: {}", e),
566 )?;
567 network_config.fast_discovery_refresh_timeout = Duration::from_millis(
568 self.raw_conf.discovery_fast_refresh_timeout_ms,
569 );
570 network_config.discovery_round_timeout =
571 Duration::from_millis(self.raw_conf.discovery_round_timeout_ms);
572 network_config.housekeeping_timeout = Duration::from_millis(
573 self.raw_conf.discovery_housekeeping_timeout_ms,
574 );
575 network_config.max_handshakes = self.raw_conf.max_handshakes;
576 network_config.max_incoming_peers = self.raw_conf.max_incoming_peers;
577 network_config.max_outgoing_peers = self.raw_conf.max_outgoing_peers;
578 network_config.max_outgoing_peers_archive =
579 self.raw_conf.max_outgoing_peers_archive.unwrap_or(0);
580 Ok(network_config)
581 }
582
583 pub fn cache_config(&self) -> CacheConfig {
584 CacheConfig {
585 ledger: self.raw_conf.ledger_cache_size,
586 invalid_block_hashes_cache_size_in_count: self
587 .raw_conf
588 .invalid_block_hash_cache_size_in_count,
589 target_difficulties_cache_size_in_count: self
590 .raw_conf
591 .target_difficulties_cache_size_in_count,
592 }
593 }
594
595 pub fn db_config(&self) -> (PathBuf, DatabaseConfig) {
596 let db_dir: PathBuf = match &self.raw_conf.block_db_dir {
597 Some(dir) => dir.into(),
598 None => Path::new(&self.raw_conf.conflux_data_dir)
599 .join(BLOCK_DB_DIR_NAME),
600 };
601 if let Err(e) = fs::create_dir_all(&db_dir) {
602 panic!("Error creating database directory: {:?}", e);
603 }
604
605 let compact_profile =
606 match self.raw_conf.rocksdb_compaction_profile.as_ref() {
607 Some(p) => db::DatabaseCompactionProfile::from_str(p).unwrap(),
608 None => db::DatabaseCompactionProfile::default(),
609 };
610 let db_config = db::db_config(
611 &db_dir,
612 self.raw_conf.rocksdb_cache_size,
613 compact_profile,
614 NUM_COLUMNS,
615 self.raw_conf.rocksdb_disable_wal,
616 );
617 (db_dir, db_config)
618 }
619
620 pub fn chain_id_params(&self) -> ChainIdParams {
621 if CHAIN_ID.read().is_none() {
622 let mut to_init = CHAIN_ID.write();
623 if to_init.is_none() {
624 if let Some(_chain_id_params) = &self.raw_conf.chain_id_params {
625 unreachable!("Upgradable ChainId is not ready.")
626 } else {
630 let chain_id = self
631 .raw_conf
632 .chain_id
633 .unwrap_or_else(|| rand::rng().random());
634 let evm_chain_id =
635 self.raw_conf.evm_chain_id.unwrap_or(chain_id);
636 *to_init = Some(ChainIdParamsInner::new_simple(
637 AllChainID::new(chain_id, evm_chain_id),
638 ));
639 }
640 }
641 }
642 CHAIN_ID.read().as_ref().unwrap().clone()
643 }
644
645 pub fn consensus_config(&self) -> ConsensusConfig {
646 let enable_optimistic_execution = if DEFERRED_STATE_EPOCH_COUNT <= 1 {
647 false
648 } else {
649 self.raw_conf.enable_optimistic_execution
650 };
651 let pivot_hint_conf = match (
652 &self.raw_conf.pivot_hint_path,
653 &self.raw_conf.pivot_hint_checksum,
654 ) {
655 (Some(path), Some(checksum)) => {
656 let checksum = H256::from_str(checksum)
657 .expect("Cannot parse `pivot_hint_checksum` as hex string");
658 Some(PivotHintConfig::new(path, checksum))
659 }
660 (None, None) => None,
661 _ => {
662 panic!("`pivot_hint_path` and `pivot_hint_checksum` must be both set or both unset");
663 }
664 };
665 let mut conf = ConsensusConfig {
666 chain_id: self.chain_id_params(),
667 inner_conf: ConsensusInnerConfig {
668 adaptive_weight_beta: self.raw_conf.adaptive_weight_beta,
669 heavy_block_difficulty_ratio: self
670 .raw_conf
671 .heavy_block_difficulty_ratio,
672 timer_chain_block_difficulty_ratio: self
673 .raw_conf
674 .timer_chain_block_difficulty_ratio,
675 timer_chain_beta: self.raw_conf.timer_chain_beta,
676 era_epoch_count: self.raw_conf.era_epoch_count,
677 enable_optimistic_execution,
678 enable_state_expose: self.raw_conf.enable_state_expose,
679 pos_pivot_decision_defer_epoch_count: self.raw_conf.pos_pivot_decision_defer_epoch_count,
680 cip113_pivot_decision_defer_epoch_count: self.raw_conf.cip113_pivot_decision_defer_epoch_count,
681 cip113_transition_height: self.raw_conf.cip113_transition_height,
682 debug_dump_dir_invalid_state_root: if self
683 .raw_conf
684 .debug_invalid_state_root
685 {
686 Some(
687 self.raw_conf.debug_dump_dir_invalid_state_root.clone(),
688 )
689 } else {
690 None
691 },
692
693 debug_invalid_state_root_epoch: self
694 .raw_conf
695 .debug_invalid_state_root_epoch.as_ref().map(|epoch_hex| H256::from_str(epoch_hex).expect("debug_invalid_state_root_epoch byte length is incorrect.")),
696 force_recompute_height_during_construct_pivot: self.raw_conf.force_recompute_height_during_construct_pivot,
697 recovery_latest_mpt_snapshot: self.raw_conf.recovery_latest_mpt_snapshot,
698 use_isolated_db_for_mpt_table: self.raw_conf.use_isolated_db_for_mpt_table,
699 },
700 bench_mode: false,
701 transaction_epoch_bound: self.raw_conf.transaction_epoch_bound,
702 referee_bound: self.raw_conf.referee_bound,
703 get_logs_epoch_batch_size: self.raw_conf.get_logs_epoch_batch_size,
704 get_logs_filter_max_epoch_range: self.raw_conf.get_logs_filter_max_epoch_range,
705 get_logs_filter_max_block_number_range: self.raw_conf.get_logs_filter_max_block_number_range,
706 get_logs_filter_max_limit: self.raw_conf.get_logs_filter_max_limit,
707 sync_state_starting_epoch: self.raw_conf.sync_state_starting_epoch,
708 sync_state_epoch_gap: self.raw_conf.sync_state_epoch_gap,
709 pivot_hint_conf,
710 };
711 match self.raw_conf.node_type {
712 Some(NodeType::Archive) => {
713 if conf.sync_state_starting_epoch.is_none() {
714 conf.sync_state_starting_epoch = Some(0);
715 }
716 }
717 _ => {
718 if conf.sync_state_epoch_gap.is_none() {
719 conf.sync_state_epoch_gap =
720 Some(CATCH_UP_EPOCH_LAG_THRESHOLD);
721 }
722 }
723 }
724 conf
725 }
726
727 pub fn pow_config(&self) -> ProofOfWorkConfig {
728 let stratum_secret =
729 self.raw_conf.stratum_secret.as_ref().map(|hex_str| {
730 parse_hex_string(hex_str)
731 .expect("Stratum secret should be 64-digit hex string")
732 });
733
734 ProofOfWorkConfig::new(
735 self.is_test_or_dev_mode(),
736 self.raw_conf.use_octopus_in_test_mode,
737 self.raw_conf.mining_type.as_ref().map_or_else(
738 || {
739 if self.raw_conf.mining_author.is_some() {
741 "stratum"
742 } else {
743 "disable"
744 }
745 },
746 |s| s.as_str(),
747 ),
748 self.raw_conf.initial_difficulty,
749 self.raw_conf.stratum_listen_address.clone(),
750 self.raw_conf.stratum_port,
751 stratum_secret,
752 self.raw_conf.pow_problem_window_size,
753 self.common_params().transition_heights.cip86,
754 )
755 }
756
757 pub fn verification_config(
758 &self, machine: Arc<Machine>,
759 ) -> VerificationConfig {
760 VerificationConfig::new(
761 self.is_test_mode(),
762 self.raw_conf.referee_bound,
763 self.raw_conf.max_block_size_in_bytes,
764 self.raw_conf.transaction_epoch_bound,
765 self.raw_conf.tx_pool_nonce_bits,
766 self.raw_conf.pos_reference_enable_height,
767 machine,
768 )
769 }
770
771 pub fn tx_gen_config(&self) -> Option<TransactionGeneratorConfig> {
772 if self.is_test_or_dev_mode() &&
773 self.raw_conf.genesis_secrets.is_some()
775 {
776 Some(TransactionGeneratorConfig::new(
777 self.raw_conf.generate_tx,
778 self.raw_conf.generate_tx_period_us.expect("has default"),
779 self.raw_conf.txgen_account_count,
780 ))
781 } else {
782 None
783 }
784 }
785
786 pub fn storage_config(&self, node_type: &NodeType) -> StorageConfiguration {
787 let conflux_data_path = Path::new(&self.raw_conf.conflux_data_dir);
788 StorageConfiguration {
789 additional_maintained_snapshot_count: self
790 .raw_conf
791 .additional_maintained_snapshot_count,
792 consensus_param: ConsensusParam {
793 snapshot_epoch_count: if self.is_test_mode() {
794 self.raw_conf.dev_snapshot_epoch_count
795 } else {
796 SNAPSHOT_EPOCHS_CAPACITY
797 },
798 era_epoch_count: self.raw_conf.era_epoch_count,
799 },
800 debug_snapshot_checker_threads:
801 DEFAULT_DEBUG_SNAPSHOT_CHECKER_THREADS,
802 delta_mpts_cache_recent_lfu_factor: self
803 .raw_conf
804 .storage_delta_mpts_cache_recent_lfu_factor,
805 delta_mpts_cache_size: self.raw_conf.storage_delta_mpts_cache_size,
806 delta_mpts_cache_start_size: self
807 .raw_conf
808 .storage_delta_mpts_cache_start_size,
809 delta_mpts_node_map_vec_size: self
810 .raw_conf
811 .storage_delta_mpts_node_map_vec_size,
812 delta_mpts_slab_idle_size: self
813 .raw_conf
814 .storage_delta_mpts_slab_idle_size,
815 single_mpt_cache_start_size: self
816 .raw_conf
817 .storage_single_mpt_cache_start_size,
818 single_mpt_cache_size: self.raw_conf.storage_single_mpt_cache_size,
819 single_mpt_slab_idle_size: self
820 .raw_conf
821 .storage_single_mpt_slab_idle_size,
822 max_open_snapshots: self.raw_conf.storage_max_open_snapshots,
823 path_delta_mpts_dir: conflux_data_path
824 .join(&*storage_dir::DELTA_MPTS_DIR),
825 path_snapshot_dir: conflux_data_path
826 .join(&*storage_dir::SNAPSHOT_DIR),
827 path_snapshot_info_db: conflux_data_path
828 .join(&*storage_dir::SNAPSHOT_INFO_DB_PATH),
829 path_storage_dir: conflux_data_path
830 .join(&*storage_dir::STORAGE_DIR),
831 provide_more_snapshot_for_sync: self
832 .raw_conf
833 .provide_more_snapshot_for_sync
834 .clone(),
835 max_open_mpt_count: self.raw_conf.storage_max_open_mpt_count,
836 enable_single_mpt_storage: match node_type {
837 NodeType::Archive => self.raw_conf.enable_single_mpt_storage,
838 _ => {
839 if self.raw_conf.enable_single_mpt_storage {
840 error!("enable_single_mpt_storage is only supported for Archive nodes!")
841 }
842 false
843 }
844 },
845 single_mpt_space: self.raw_conf.single_mpt_space,
846 cip90a: self
847 .raw_conf
848 .cip90_transition_height
849 .unwrap_or(self.raw_conf.hydra_transition_height.unwrap_or(0)),
850 keep_snapshot_before_stable_checkpoint: self
851 .raw_conf
852 .keep_snapshot_before_stable_checkpoint,
853 use_isolated_db_for_mpt_table: self
854 .raw_conf
855 .use_isolated_db_for_mpt_table,
856 use_isolated_db_for_mpt_table_height: self
857 .raw_conf
858 .use_isolated_db_for_mpt_table_height,
859 keep_era_genesis_snapshot: self.raw_conf.keep_era_genesis_snapshot,
860 backup_mpt_snapshot: self.raw_conf.backup_mpt_snapshot,
861 }
862 }
863
864 pub fn protocol_config(&self) -> ProtocolConfiguration {
865 ProtocolConfiguration {
866 is_consortium: self.raw_conf.is_consortium,
867 send_tx_period: Duration::from_millis(
868 self.raw_conf.send_tx_period_ms,
869 ),
870 check_request_period: Duration::from_millis(
871 self.raw_conf.check_request_period_ms,
872 ),
873 check_phase_change_period: Duration::from_millis(
874 self.raw_conf.check_phase_change_period_ms,
875 ),
876 heartbeat_period_interval: Duration::from_millis(
877 self.raw_conf.heartbeat_period_interval_ms,
878 ),
879 block_cache_gc_period: Duration::from_millis(
880 self.raw_conf.block_cache_gc_period_ms,
881 ),
882 expire_block_gc_period: Duration::from_secs(
883 self.raw_conf.expire_block_gc_period_s,
884 ),
885 headers_request_timeout: Duration::from_millis(
886 self.raw_conf.headers_request_timeout_ms,
887 ),
888 blocks_request_timeout: Duration::from_millis(
889 self.raw_conf.blocks_request_timeout_ms,
890 ),
891 transaction_request_timeout: Duration::from_millis(
892 self.raw_conf.transaction_request_timeout_ms,
893 ),
894 tx_maintained_for_peer_timeout: Duration::from_millis(
895 self.raw_conf.tx_maintained_for_peer_timeout_ms,
896 ),
897 max_inflight_request_count: self
898 .raw_conf
899 .max_inflight_request_count,
900 request_block_with_public: self.raw_conf.request_block_with_public,
901 received_tx_index_maintain_timeout: Duration::from_millis(
902 self.raw_conf.received_tx_index_maintain_timeout_ms,
903 ),
904 inflight_pending_tx_index_maintain_timeout: Duration::from_millis(
905 self.raw_conf.inflight_pending_tx_index_maintain_timeout_ms,
906 ),
907 max_trans_count_received_in_catch_up: self
908 .raw_conf
909 .max_trans_count_received_in_catch_up,
910 min_peers_tx_propagation: self.raw_conf.min_peers_tx_propagation,
911 max_peers_tx_propagation: self.raw_conf.max_peers_tx_propagation,
912 max_downloading_chunks: self.raw_conf.max_downloading_chunks,
913 max_downloading_chunk_attempts: self
914 .raw_conf
915 .max_downloading_chunk_attempts,
916 test_mode: self.is_test_mode(),
917 dev_mode: self.is_dev_mode(),
918 throttling_config_file: self.raw_conf.throttling_conf.clone(),
919 snapshot_candidate_request_timeout: Duration::from_millis(
920 self.raw_conf.snapshot_candidate_request_timeout_ms,
921 ),
922 snapshot_manifest_request_timeout: Duration::from_millis(
923 self.raw_conf.snapshot_manifest_request_timeout_ms,
924 ),
925 snapshot_chunk_request_timeout: Duration::from_millis(
926 self.raw_conf.snapshot_chunk_request_timeout_ms,
927 ),
928 chunk_size_byte: self.raw_conf.chunk_size_byte,
929 max_chunk_number_in_manifest: self
930 .raw_conf
931 .max_chunk_number_in_manifest,
932 timeout_observing_period_s: self
933 .raw_conf
934 .timeout_observing_period_s,
935 max_allowed_timeout_in_observing_period: self
936 .raw_conf
937 .max_allowed_timeout_in_observing_period,
938 demote_peer_for_timeout: self.raw_conf.demote_peer_for_timeout,
939 heartbeat_timeout: Duration::from_millis(
940 self.raw_conf.heartbeat_timeout_ms,
941 ),
942 max_unprocessed_block_size: self
943 .raw_conf
944 .max_unprocessed_block_size_mb
945 * 1_000_000,
946 sync_expire_block_timeout: Duration::from_secs(
947 self.raw_conf.sync_expire_block_timeout_s,
948 ),
949 allow_phase_change_without_peer: if self.is_dev_mode() {
950 true
951 } else {
952 self.raw_conf.dev_allow_phase_change_without_peer
953 },
954 min_phase_change_normal_peer_count: self
955 .raw_conf
956 .min_phase_change_normal_peer_count,
957 pos_genesis_pivot_decision: self
958 .raw_conf
959 .pos_genesis_pivot_decision
960 .expect("set to genesis if none"),
961 check_status_genesis: self.raw_conf.check_status_genesis,
962 pos_started_as_voter: self.raw_conf.pos_started_as_voter,
963 }
964 }
965
966 pub fn state_sync_config(&self) -> StateSyncConfiguration {
967 StateSyncConfiguration {
968 max_downloading_chunks: self.raw_conf.max_downloading_chunks,
969 candidate_request_timeout: Duration::from_millis(
970 self.raw_conf.snapshot_candidate_request_timeout_ms,
971 ),
972 chunk_request_timeout: Duration::from_millis(
973 self.raw_conf.snapshot_chunk_request_timeout_ms,
974 ),
975 manifest_request_timeout: Duration::from_millis(
976 self.raw_conf.snapshot_manifest_request_timeout_ms,
977 ),
978 max_downloading_manifest_attempts: self
979 .raw_conf
980 .max_downloading_manifest_attempts,
981 }
982 }
983
984 pub fn data_mananger_config(&self) -> DataManagerConfiguration {
985 let mut conf = DataManagerConfiguration {
986 persist_tx_index: self.raw_conf.persist_tx_index,
987 persist_block_number_index: self
988 .raw_conf
989 .persist_block_number_index,
990 tx_cache_index_maintain_timeout: Duration::from_millis(
991 self.raw_conf.tx_cache_index_maintain_timeout_ms,
992 ),
993 db_type: match self.raw_conf.block_db_type.as_str() {
994 "rocksdb" => DbType::Rocksdb,
995 "sqlite" => DbType::Sqlite,
996 _ => panic!("Invalid block_db_type parameter!"),
997 },
998 additional_maintained_block_body_epoch_count: self
999 .raw_conf
1000 .additional_maintained_block_body_epoch_count,
1001 additional_maintained_execution_result_epoch_count: self
1002 .raw_conf
1003 .additional_maintained_execution_result_epoch_count,
1004 additional_maintained_reward_epoch_count: self
1005 .raw_conf
1006 .additional_maintained_reward_epoch_count,
1007 additional_maintained_trace_epoch_count: self
1008 .raw_conf
1009 .additional_maintained_trace_epoch_count,
1010 additional_maintained_transaction_index_epoch_count: self
1011 .raw_conf
1012 .additional_maintained_transaction_index_epoch_count,
1013 checkpoint_gc_time_in_epoch_count: (self
1014 .raw_conf
1015 .checkpoint_gc_time_in_era_count
1016 * self.raw_conf.era_epoch_count as f64)
1017 as usize,
1018 strict_tx_index_gc: self.raw_conf.strict_tx_index_gc,
1019 };
1020
1021 if !matches!(self.raw_conf.node_type, Some(NodeType::Archive)) {
1024 if conf.additional_maintained_block_body_epoch_count.is_none() {
1025 conf.additional_maintained_block_body_epoch_count = Some(0);
1026 }
1027 if conf
1028 .additional_maintained_execution_result_epoch_count
1029 .is_none()
1030 {
1031 conf.additional_maintained_execution_result_epoch_count =
1032 Some(0);
1033 }
1034 if conf
1035 .additional_maintained_transaction_index_epoch_count
1036 .is_none()
1037 {
1038 conf.additional_maintained_transaction_index_epoch_count =
1039 Some(0);
1040 }
1041 if conf.additional_maintained_reward_epoch_count.is_none() {
1042 conf.additional_maintained_reward_epoch_count = Some(0);
1043 }
1044 if conf.additional_maintained_trace_epoch_count.is_none() {
1045 conf.additional_maintained_trace_epoch_count = Some(0);
1046 }
1047 }
1048 if conf.additional_maintained_transaction_index_epoch_count != Some(0) {
1049 conf.persist_tx_index = true;
1050 }
1051 conf
1052 }
1053
1054 pub fn sync_graph_config(&self) -> SyncGraphConfig {
1055 SyncGraphConfig {
1056 future_block_buffer_capacity: self
1057 .raw_conf
1058 .future_block_buffer_capacity,
1059 enable_state_expose: self.raw_conf.enable_state_expose,
1060 is_consortium: self.raw_conf.is_consortium,
1061 }
1062 }
1063
1064 pub fn metrics_config(&self) -> MetricsConfiguration {
1065 MetricsConfiguration {
1066 enabled: self.raw_conf.metrics_enabled,
1067 report_interval: Duration::from_millis(
1068 self.raw_conf.metrics_report_interval_ms,
1069 ),
1070 file_report_output: self.raw_conf.metrics_output_file.clone(),
1071 influxdb_report_host: self.raw_conf.metrics_influxdb_host.clone(),
1072 influxdb_report_db: self.raw_conf.metrics_influxdb_db.clone(),
1073 influxdb_report_username: self
1074 .raw_conf
1075 .metrics_influxdb_username
1076 .clone(),
1077 influxdb_report_password: self
1078 .raw_conf
1079 .metrics_influxdb_password
1080 .clone(),
1081 influxdb_report_node: self.raw_conf.metrics_influxdb_node.clone(),
1082 prometheus_listen_addr: self
1083 .raw_conf
1084 .metrics_prometheus_listen_addr
1085 .clone(),
1086 }
1087 }
1088
1089 pub fn txpool_config(&self) -> TxPoolConfig {
1090 let (min_native_tx_price_default, min_eth_tx_price_default) =
1091 if self.is_test_or_dev_mode() {
1092 (1, 1)
1093 } else {
1094 (ONE_GDRIP_IN_DRIP, 20 * ONE_GDRIP_IN_DRIP)
1095 };
1096 TxPoolConfig {
1097 capacity: self.raw_conf.tx_pool_size,
1098 half_block_gas_limit: RwLock::new(U256::from(
1099 DEFAULT_TARGET_BLOCK_GAS_LIMIT / 2,
1100 )),
1101 min_native_tx_price: self
1102 .raw_conf
1103 .tx_pool_min_native_tx_gas_price
1104 .unwrap_or(min_native_tx_price_default),
1105 allow_gas_over_half_block: self
1106 .raw_conf
1107 .tx_pool_allow_gas_over_half_block,
1108 target_block_gas_limit: self.raw_conf.target_block_gas_limit,
1109 min_eth_tx_price: self
1110 .raw_conf
1111 .tx_pool_min_eth_tx_gas_price
1112 .unwrap_or(min_eth_tx_price_default),
1113 max_packing_batch_gas_limit: self
1114 .raw_conf
1115 .max_packing_batch_gas_limit,
1116 max_packing_batch_size: self.raw_conf.max_packing_batch_size,
1117 packing_pool_degree: self.raw_conf.packing_pool_degree,
1118 }
1119 }
1120
1121 pub fn rpc_impl_config(&self) -> RpcImplConfiguration {
1122 RpcImplConfiguration {
1123 get_logs_filter_max_limit: self.raw_conf.get_logs_filter_max_limit,
1124 dev_pack_tx_immediately: self
1125 .raw_conf
1126 .dev_pack_tx_immediately
1127 .unwrap_or_else(|| {
1128 self.is_dev_mode()
1129 && self.raw_conf.dev_block_interval_ms.is_none()
1130 }),
1131 max_payload_bytes: self.raw_conf.jsonrpc_ws_max_payload_bytes,
1132 enable_metrics: self.raw_conf.rpc_enable_metrics,
1133 poll_lifetime_in_seconds: self.raw_conf.poll_lifetime_in_seconds,
1134 max_estimation_gas_limit: self
1135 .raw_conf
1136 .max_estimation_gas_limit
1137 .map(U256::from),
1138 }
1139 }
1140
1141 pub fn local_http_config(&self) -> HttpConfiguration {
1142 HttpConfiguration::new(
1143 Some((127, 0, 0, 1)),
1144 self.raw_conf.jsonrpc_local_http_port,
1145 self.raw_conf.jsonrpc_http_keep_alive,
1146 self.raw_conf.jsonrpc_http_threads,
1147 self.raw_conf.jsonrpc_cors.clone(),
1148 )
1149 }
1150
1151 pub fn local_ws_config(&self) -> WsConfiguration {
1152 WsConfiguration::new(
1153 Some((127, 0, 0, 1)),
1154 self.raw_conf.jsonrpc_local_ws_port,
1155 self.raw_conf.jsonrpc_ws_max_payload_bytes,
1156 self.raw_conf.jsonrpc_cors.clone(),
1157 )
1158 }
1159
1160 pub fn http_config(&self) -> HttpConfiguration {
1161 HttpConfiguration::new(
1162 None,
1163 self.raw_conf.jsonrpc_http_port,
1164 self.raw_conf.jsonrpc_http_keep_alive,
1165 self.raw_conf.jsonrpc_http_threads,
1166 self.raw_conf.jsonrpc_cors.clone(),
1167 )
1168 }
1169
1170 pub fn ws_config(&self) -> WsConfiguration {
1171 WsConfiguration::new(
1172 None,
1173 self.raw_conf.jsonrpc_ws_port,
1174 self.raw_conf.jsonrpc_ws_max_payload_bytes,
1175 self.raw_conf.jsonrpc_cors.clone(), )
1177 }
1178
1179 pub fn eth_http_config(&self) -> HttpConfiguration {
1180 HttpConfiguration::new(
1181 None,
1182 self.raw_conf.jsonrpc_http_eth_port,
1183 self.raw_conf.jsonrpc_http_keep_alive,
1184 self.raw_conf.jsonrpc_http_threads,
1185 self.raw_conf.jsonrpc_cors.clone(),
1186 )
1187 }
1188
1189 pub fn eth_ws_config(&self) -> WsConfiguration {
1190 WsConfiguration::new(
1191 None,
1192 self.raw_conf.jsonrpc_ws_eth_port,
1193 self.raw_conf.jsonrpc_ws_max_payload_bytes,
1194 self.raw_conf.jsonrpc_cors.clone(), )
1196 }
1197
1198 pub fn jsonrpsee_server_builder(&self) -> ServerConfigBuilder {
1199 ServerConfigBuilder::default()
1200 .max_request_body_size(self.raw_conf.jsonrpc_max_request_body_size)
1201 .max_response_body_size(
1202 self.raw_conf.jsonrpc_max_response_body_size,
1203 )
1204 .max_connections(self.raw_conf.jsonrpc_max_connections)
1205 .max_subscriptions_per_connection(
1206 self.raw_conf.jsonrpc_max_subscriptions_per_connection,
1207 )
1208 .set_message_buffer_capacity(
1209 self.raw_conf.jsonrpc_message_buffer_capacity,
1210 )
1211 }
1212
1213 pub fn execution_config(&self) -> ConsensusExecutionConfiguration {
1214 ConsensusExecutionConfiguration {
1215 executive_trace: self.raw_conf.executive_trace,
1216 }
1217 }
1218
1219 pub fn discovery_protocol(&self) -> DiscoveryConfiguration {
1220 DiscoveryConfiguration {
1221 discover_node_count: self.raw_conf.discovery_discover_node_count,
1222 expire_time: Duration::from_secs(
1223 self.raw_conf.discovery_expire_time_s,
1224 ),
1225 find_node_timeout: Duration::from_millis(
1226 self.raw_conf.discovery_find_node_timeout_ms,
1227 ),
1228 max_nodes_ping: self.raw_conf.discovery_max_nodes_ping,
1229 ping_timeout: Duration::from_millis(
1230 self.raw_conf.discovery_ping_timeout_ms,
1231 ),
1232 throttling_interval: Duration::from_millis(
1233 self.raw_conf.discovery_throttling_interval_ms,
1234 ),
1235 throttling_limit_ping: self
1236 .raw_conf
1237 .discovery_throttling_limit_ping,
1238 throttling_limit_find_nodes: self
1239 .raw_conf
1240 .discovery_throttling_limit_find_nodes,
1241 }
1242 }
1243
1244 pub fn is_test_mode(&self) -> bool {
1245 matches!(self.raw_conf.mode.as_deref(), Some("test"))
1246 }
1247
1248 pub fn is_dev_mode(&self) -> bool {
1249 matches!(self.raw_conf.mode.as_deref(), Some("dev"))
1250 }
1251
1252 pub fn is_test_or_dev_mode(&self) -> bool {
1253 matches!(self.raw_conf.mode.as_deref(), Some("dev") | Some("test"))
1254 }
1255
1256 pub fn is_consortium(&self) -> bool { self.raw_conf.is_consortium }
1257
1258 pub fn light_node_config(&self) -> LightNodeConfiguration {
1259 LightNodeConfiguration {
1260 epoch_request_batch_size: self.raw_conf.ln_epoch_request_batch_size,
1261 epoch_request_timeout: self
1262 .raw_conf
1263 .ln_epoch_request_timeout_sec
1264 .map(Duration::from_secs),
1265 header_request_batch_size: self
1266 .raw_conf
1267 .ln_header_request_batch_size,
1268 header_request_timeout: self
1269 .raw_conf
1270 .ln_header_request_timeout_sec
1271 .map(Duration::from_secs),
1272 max_headers_in_flight: self.raw_conf.ln_max_headers_in_flight,
1273 max_parallel_epochs_to_request: self
1274 .raw_conf
1275 .ln_max_parallel_epochs_to_request,
1276 num_epochs_to_request: self.raw_conf.ln_num_epochs_to_request,
1277 num_waiting_headers_threshold: self
1278 .raw_conf
1279 .ln_num_waiting_headers_threshold,
1280 }
1281 }
1282
1283 pub fn common_params(&self) -> CommonParams {
1284 let mut params = CommonParams::default();
1285
1286 if self.is_test_or_dev_mode() {
1287 params.early_set_internal_contracts_states = true;
1288 }
1289
1290 let non_test_default = SpaceMap::new(
1291 INITIAL_1559_CORE_BASE_PRICE,
1292 INITIAL_1559_ETH_BASE_PRICE,
1293 );
1294 let test_default = SpaceMap::new(1u64, 1);
1295 let config = SpaceMap::new(
1296 self.raw_conf.min_native_base_price,
1297 self.raw_conf.min_eth_base_price,
1298 );
1299 let base_price = SpaceMap::zip3(non_test_default, test_default, config)
1300 .map_all(|(non_test, test, config)| {
1301 if let Some(x) = config {
1302 x
1303 } else if self.is_test_or_dev_mode() {
1304 test
1305 } else {
1306 non_test
1307 }
1308 });
1309 params.min_base_price = base_price.map_all(U256::from);
1310
1311 params.chain_id = self.chain_id_params();
1312 params.anticone_penalty_ratio = self.raw_conf.anticone_penalty_ratio;
1313 params.evm_transaction_block_ratio =
1314 self.raw_conf.evm_transaction_block_ratio;
1315 params.evm_transaction_gas_ratio =
1316 self.raw_conf.evm_transaction_gas_ratio;
1317
1318 params.params_dao_vote_period = self.raw_conf.params_dao_vote_period;
1319
1320 self.set_cips(&mut params);
1321
1322 params
1323 }
1324
1325 pub fn node_type(&self) -> NodeType {
1326 self.raw_conf.node_type.unwrap_or(NodeType::Full)
1327 }
1328
1329 pub fn pos_state_config(&self) -> PosStateConfig {
1330 assert_eq!(self.raw_conf.pos_round_per_term % 2, 0);
1333 PosStateConfig::new(
1334 self.raw_conf.pos_round_per_term,
1335 self.raw_conf.pos_term_max_size,
1336 self.raw_conf.pos_term_elected_size,
1337 self.raw_conf.pos_in_queue_locked_views,
1338 self.raw_conf.pos_out_queue_locked_views,
1339 self.raw_conf.pos_cip99_transition_view,
1340 self.raw_conf.pos_cip99_in_queue_locked_views,
1341 self.raw_conf.pos_cip99_out_queue_locked_views,
1342 self.raw_conf.nonce_limit_transition_view,
1343 20_000, self.raw_conf.pos_cip136_transition_view,
1345 self.raw_conf.pos_cip136_in_queue_locked_views,
1346 self.raw_conf.pos_cip136_out_queue_locked_views,
1347 self.raw_conf.pos_cip136_round_per_term,
1348 self.raw_conf.pos_cip156_transition_view,
1349 self.raw_conf.pos_cip156_dispute_locked_views,
1350 self.raw_conf.pos_cip173_transition_view,
1351 )
1352 }
1353
1354 fn set_cips(&self, params: &mut CommonParams) {
1355 let default_transition_time =
1356 if let Some(num) = self.raw_conf.default_transition_time {
1357 num
1358 } else if self.is_test_or_dev_mode() {
1359 0u64
1360 } else {
1361 u64::MAX
1362 };
1363
1364 let non_genesis_default_transition_time =
1367 match self.raw_conf.default_transition_time {
1368 Some(num) if num > 0 => num,
1369 _ => {
1370 if self.is_test_or_dev_mode() {
1371 1u64
1372 } else {
1373 u64::MAX
1374 }
1375 }
1376 };
1377
1378 params.transition_heights.cip40 =
1382 self.raw_conf.tanzanite_transition_height;
1383 let mut base_block_rewards = BTreeMap::new();
1384 base_block_rewards.insert(0, INITIAL_BASE_MINING_REWARD_IN_UCFX.into());
1385 base_block_rewards.insert(
1386 params.transition_heights.cip40,
1387 MINING_REWARD_TANZANITE_IN_UCFX.into(),
1388 );
1389 params.base_block_rewards = base_block_rewards;
1390
1391 set_conf!(
1395 self.raw_conf.hydra_transition_number.unwrap_or(default_transition_time);
1396 params.transition_numbers => { cip43a, cip64, cip71, cip78a, cip92 }
1397 );
1398 set_conf!(
1399 self.raw_conf.hydra_transition_height.unwrap_or(default_transition_time);
1400 params.transition_heights => { cip76, cip86 }
1401 );
1402 params.transition_numbers.cip43b =
1403 self.raw_conf.cip43_init_end_number.unwrap_or(
1404 if self.is_test_or_dev_mode() {
1405 u64::MAX
1406 } else {
1407 params.transition_numbers.cip43a
1408 },
1409 );
1410 params.transition_numbers.cip62 = if self.is_test_or_dev_mode() {
1411 0u64
1412 } else {
1413 BN128_ENABLE_NUMBER
1414 };
1415 params.transition_numbers.cip78b = self
1416 .raw_conf
1417 .cip78_patch_transition_number
1418 .unwrap_or(params.transition_numbers.cip78a);
1419 params.transition_heights.cip90a = self
1420 .raw_conf
1421 .cip90_transition_height
1422 .or(self.raw_conf.hydra_transition_height)
1423 .unwrap_or(default_transition_time);
1424 params.transition_numbers.cip90b = self
1425 .raw_conf
1426 .cip90_transition_number
1427 .or(self.raw_conf.hydra_transition_number)
1428 .unwrap_or(default_transition_time);
1429
1430 set_conf!(
1434 self.raw_conf.dao_vote_transition_number.unwrap_or(default_transition_time);
1435 params.transition_numbers => { cip97, cip98 }
1436 );
1437 params.transition_numbers.cip94n = self
1438 .raw_conf
1439 .dao_vote_transition_number
1440 .unwrap_or(non_genesis_default_transition_time);
1441 params.transition_heights.cip94h = self
1442 .raw_conf
1443 .dao_vote_transition_height
1444 .unwrap_or(non_genesis_default_transition_time);
1445 params.transition_numbers.cip105 = self
1446 .raw_conf
1447 .cip105_transition_number
1448 .or(self.raw_conf.dao_vote_transition_number)
1449 .unwrap_or(default_transition_time);
1450
1451 params.transition_numbers.cip_sigma_fix = self
1455 .raw_conf
1456 .sigma_fix_transition_number
1457 .unwrap_or(default_transition_time);
1458
1459 params.transition_numbers.cip107 = self
1463 .raw_conf
1464 .cip107_transition_number
1465 .unwrap_or(default_transition_time);
1466 params.transition_heights.cip112 =
1467 *CIP112_TRANSITION_HEIGHT.get().expect("initialized");
1468 params.transition_numbers.cip118 = self
1469 .raw_conf
1470 .cip118_transition_number
1471 .unwrap_or(default_transition_time);
1472 params.transition_numbers.cip119 = self
1473 .raw_conf
1474 .cip119_transition_number
1475 .unwrap_or(default_transition_time);
1476
1477 set_conf!(
1481 self.raw_conf.base_fee_burn_transition_number.unwrap_or(default_transition_time);
1482 params.transition_numbers => { cip131, cip132, cip133b, cip137, cip144, cip145 }
1483 );
1484 set_conf!(
1485 self.raw_conf.base_fee_burn_transition_height.unwrap_or(default_transition_time);
1486 params.transition_heights => { cip130, cip133e }
1487 );
1488 params.transition_heights.cip1559 = self
1490 .raw_conf
1491 .cip1559_transition_height
1492 .or(self.raw_conf.base_fee_burn_transition_height)
1493 .unwrap_or(non_genesis_default_transition_time);
1494 params.transition_heights.cip130 = self
1495 .raw_conf
1496 .cip130_transition_height
1497 .or(self.raw_conf.base_fee_burn_transition_height)
1498 .unwrap_or(default_transition_time);
1499 params.transition_numbers.cancun_opcodes = self
1500 .raw_conf
1501 .cancun_opcodes_transition_number
1502 .or(self.raw_conf.base_fee_burn_transition_number)
1503 .unwrap_or(default_transition_time);
1504
1505 if params.transition_heights.cip1559
1506 < self.raw_conf.pos_reference_enable_height
1507 {
1508 panic!("1559 can not be activated earlier than pos reference: 1559 (epoch {}), pos (epoch {})", params.transition_heights.cip1559, self.raw_conf.pos_reference_enable_height);
1509 }
1510
1511 params.transition_heights.cip_c2_fix = self
1515 .raw_conf
1516 .c2_fix_transition_height
1517 .unwrap_or(default_transition_time);
1518
1519 set_conf!(
1523 self.raw_conf.eoa_code_transition_height.unwrap_or(default_transition_time);
1524 params.transition_heights => { cip150, cip151, cip152, cip154, cip7702, cip645, eip2537, eip2935, eip7623, cip145_fix }
1525 );
1526 if let Some(x) = self.raw_conf.cip151_transition_height {
1527 params.transition_heights.cip151 = x;
1528 }
1529 if let Some(x) = self.raw_conf.cip645_transition_height {
1530 params.transition_heights.cip645 = x;
1531 }
1532 if let Some(x) = self.raw_conf.cip145_fix_transition_height {
1533 params.transition_heights.cip145_fix = x;
1534 }
1535 params.transition_heights.align_evm =
1536 self.raw_conf.align_evm_transition_height;
1537
1538 set_conf!(
1540 self.raw_conf.osaka_opcode_transition_height.unwrap_or(default_transition_time);
1541 params.transition_heights => { cip166, cip167, cip172, cip174, cip175, cip176 }
1542 );
1543 if let Some(x) = self.raw_conf.cip166_transition_height {
1544 params.transition_heights.cip166 = x;
1545 }
1546 if let Some(x) = self.raw_conf.cip167_transition_height {
1547 params.transition_heights.cip167 = x;
1548 }
1549 if let Some(x) = self.raw_conf.cip172_transition_height {
1550 params.transition_heights.cip172 = x;
1551 }
1552 if let Some(x) = self.raw_conf.cip174_transition_height {
1553 params.transition_heights.cip174 = x;
1554 }
1555 if let Some(x) = self.raw_conf.cip175_transition_height {
1556 params.transition_heights.cip175 = x;
1557 }
1558 if let Some(x) = self.raw_conf.cip176_transition_height {
1559 params.transition_heights.cip176 = x;
1560 }
1561 }
1562}
1563
1564pub fn to_bootnodes(bootnodes: &Option<String>) -> Result<Vec<String>, String> {
1566 match *bootnodes {
1567 Some(ref x) if !x.is_empty() => x
1568 .split(',')
1569 .filter(|s| !s.is_empty())
1571 .map(|s| match validate_node_url(s){
1572 None => Ok(s.to_owned()),
1573 Some(network::Error::AddressResolve(_)) => Err(format!(
1574 "Failed to resolve hostname of a boot node: {}",
1575 s
1576 )),
1577 Some(e) => Err(format!(
1578 "Invalid node address format given for a boot node: {} err={:?}",
1579 s, e
1580 )),
1581 })
1582 .collect(),
1583 Some(_) => Ok(vec![]),
1584 None => Ok(vec![]),
1585 }
1586}
1587
1588pub fn parse_config_address_string(
1589 addr: &str, network: &Network,
1590) -> Result<Address, String> {
1591 let base32_err = match cfx_addr_decode(addr) {
1592 Ok(address) => {
1593 return if address.network != *network {
1594 Err(format!(
1595 "address in configuration has unmatching network id: expected network={},\
1596 address.network={}",
1597 network,
1598 address.network
1599 ))
1600 } else {
1601 address
1602 .hex_address
1603 .ok_or("decoded address has wrong byte length".into())
1604 };
1605 }
1606 Err(e) => e,
1607 };
1608 let hex_err = match parse_hex_string(addr) {
1609 Ok(address) => return Ok(address),
1610 Err(e) => e,
1611 };
1612 Err(format!("Address from configuration should be a valid base32 address or a 40-digit hex string!
1614 base32_err={:?}
1615 hex_err={:?}",
1616 base32_err, hex_err))
1617}
1618
1619#[cfg(test)]
1620mod tests {
1621 use cfx_addr::Network;
1622
1623 use crate::configuration::parse_config_address_string;
1624
1625 #[test]
1626 fn test_config_address_string() {
1627 let addr = parse_config_address_string(
1628 "0x1a2f80341409639ea6a35bbcab8299066109aa55",
1629 &Network::Main,
1630 )
1631 .unwrap();
1632 assert_eq!(
1634 addr,
1635 parse_config_address_string(
1636 "1a2f80341409639ea6a35bbcab8299066109aa55",
1637 &Network::Main,
1638 )
1639 .unwrap()
1640 );
1641 assert_eq!(
1643 addr,
1644 parse_config_address_string(
1645 "cfx:aarc9abycue0hhzgyrr53m6cxedgccrmmyybjgh4xg",
1646 &Network::Main,
1647 )
1648 .unwrap()
1649 );
1650 assert_eq!(
1652 addr,
1653 parse_config_address_string(
1654 "cfx:type.user:aarc9abycue0hhzgyrr53m6cxedgccrmmyybjgh4xg",
1655 &Network::Main,
1656 )
1657 .unwrap()
1658 );
1659 }
1660}