phos_data_network/config/
mod.rs1use std::net::{IpAddr, Ipv4Addr};
2use std::str::FromStr;
3use std::time::Duration;
4use std::{path::PathBuf, process::exit};
5
6use figment::{
7 providers::{Format, Serialized, Toml},
8 Figment,
9};
10use serde::Deserialize;
11use url::Url;
12
13use helios_common::fork_schedule::ForkSchedule;
14use phos_light_client::verifier::{options::Options, types::TrustThreshold};
15
16use self::base::BaseConfig;
17use self::cli::CliConfig;
18use self::networks::Network;
19
20pub use self::types::{ChainConfig, TrustOptions};
21
22pub mod cli;
23pub mod networks;
24
25mod base;
26mod types;
27
28#[derive(Deserialize, Debug)]
29pub struct Config {
30 pub consensus_rpc: Url,
31 pub execution_rpc: Option<Url>,
32 pub verifiable_api: Option<Url>,
33 pub rpc_bind_ip: Option<IpAddr>,
34 pub rpc_port: Option<u16>,
35 pub trust_options: Option<TrustOptions>,
36 pub data_dir: Option<PathBuf>,
37 pub chain: ChainConfig,
38 pub verifier_options: Options,
39 pub execution_forks: ForkSchedule,
40 pub database_type: Option<String>,
41}
42
43impl Config {
44 pub fn from_file(config_path: &PathBuf, network: &str, cli_config: &CliConfig) -> Self {
45 let base_config = Network::from_str(network)
46 .map(|n| n.to_base_config())
47 .unwrap_or(BaseConfig::default());
48
49 let base_provider = Serialized::from(base_config, network);
50 let toml_provider = Toml::file(config_path).nested();
51 let cli_provider = cli_config.as_provider(network);
52
53 let config_res = Figment::new()
54 .merge(base_provider)
55 .merge(toml_provider)
56 .merge(cli_provider)
57 .select(network)
58 .extract();
59
60 match config_res {
61 Ok(config) => config,
62 Err(err) => {
63 match err.kind {
64 figment::error::Kind::MissingField(field) => {
65 let field = field.replace('_', "-");
66 println!("\x1b[91merror\x1b[0m: missing configuration field: {field}");
67 println!("\n\ttry supplying the proper command line argument: --{field}");
68 println!("\talternatively, you can add the field to your helios.toml file");
69 println!("\nfor more information, check the github README");
70 }
71 _ => println!("cannot parse configuration: {err}"),
72 }
73 exit(1);
74 }
75 }
76 }
77
78 pub fn to_base_config(&self) -> BaseConfig {
79 BaseConfig {
80 rpc_bind_ip: self.rpc_bind_ip.unwrap_or(IpAddr::V4(Ipv4Addr::LOCALHOST)),
81 rpc_port: self.rpc_port.unwrap_or(8545),
82 consensus_rpc: Some(self.consensus_rpc.clone()),
83 execution_rpc: self.execution_rpc.clone(),
84 chain: self.chain.clone(),
85 verifier_options: self.verifier_options,
86 execution_forks: self.execution_forks,
87 data_dir: self.data_dir.clone(),
88 }
89 }
90}
91
92impl From<BaseConfig> for Config {
93 fn from(base: BaseConfig) -> Self {
94 Self {
95 rpc_bind_ip: Some(base.rpc_bind_ip),
96 rpc_port: Some(base.rpc_port),
97 consensus_rpc: base
98 .consensus_rpc
99 .unwrap_or_else(|| Url::parse("http://localhost:26657").unwrap()),
100 execution_rpc: base.execution_rpc,
101 verifiable_api: None,
102 trust_options: None,
103 data_dir: base.data_dir,
104 chain: base.chain,
105 verifier_options: base.verifier_options,
106 execution_forks: base.execution_forks,
107 database_type: None,
108 }
109 }
110}
111
112impl Default for Config {
113 fn default() -> Self {
114 Self {
115 consensus_rpc: Url::parse("http://localhost:26657").unwrap(),
116 execution_rpc: None,
117 verifiable_api: None,
118 rpc_bind_ip: None,
119 rpc_port: None,
120 trust_options: None,
121 data_dir: None,
122 chain: ChainConfig::default(),
123 verifier_options: Options {
124 trust_threshold: TrustThreshold::ONE_THIRD,
125 trusting_period: Duration::ZERO,
126 clock_drift: Duration::ZERO,
127 },
128 execution_forks: ForkSchedule::default(),
129 database_type: None,
130 }
131 }
132}