Skip to main content

phos_data_network/config/
mod.rs

1use 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}