Skip to main content

avalanche_types/subnet/config/
mod.rs

1pub mod consensus;
2pub mod gossip;
3
4use std::{
5    fs::{self, File},
6    io::{self, Error, ErrorKind, Write},
7    path::Path,
8};
9
10use serde::{Deserialize, Serialize};
11
12/// To be persisted in "subnet_config_dir".
13///
14/// ref. <https://pkg.go.dev/github.com/ava-labs/avalanchego/chains#SubnetConfig>
15///
16/// If a Subnet's chain id is 2ebCneCbwthjQ1rYT41nhd7M76Hc6YmosMAQrTFhBq8qeqh6tt,
17/// the config file for this chain is located at {subnet-config-dir}/2ebCneCbwthjQ1rYT41nhd7M76Hc6YmosMAQrTFhBq8qeqh6tt.json
18#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
19#[serde(rename_all = "camelCase")]
20pub struct Config {
21    /// Embeds "gossip_config" at the same level as other fields.
22    #[serde(flatten)]
23    pub gossip_sender_config: gossip::SenderConfig,
24
25    #[serde(default)]
26    pub validator_only: bool,
27
28    /// Embeds "gossip_config" at the same level as other fields.
29    pub consensus_parameters: consensus::Parameters,
30
31    #[serde(default)]
32    pub proposer_min_block_delay: u64,
33}
34
35impl Default for Config {
36    /// The defaults do not match with the ones in avalanchego,
37    /// as this is for avalanche-ops based deployments.
38    fn default() -> Self {
39        Self {
40            gossip_sender_config: gossip::SenderConfig::default(),
41            validator_only: false,
42            consensus_parameters: consensus::Parameters::default(),
43            proposer_min_block_delay: 1000 * 1000 * 1000, // 1-second
44        }
45    }
46}
47
48impl Config {
49    pub fn encode_json(&self) -> io::Result<String> {
50        serde_json::to_string(&self)
51            .map_err(|e| Error::new(ErrorKind::Other, format!("failed to serialize JSON {}", e)))
52    }
53
54    /// Saves the current subnet config to disk
55    /// and overwrites the file.
56    pub fn sync(&self, file_path: &str) -> io::Result<()> {
57        log::info!("syncing subnet config to '{}'", file_path);
58        let path = Path::new(file_path);
59        if let Some(parent_dir) = path.parent() {
60            log::info!("creating parent dir '{}'", parent_dir.display());
61            fs::create_dir_all(parent_dir)?;
62        }
63
64        let d = serde_json::to_vec(self)
65            .map_err(|e| Error::new(ErrorKind::Other, format!("failed to serialize JSON {}", e)))?;
66
67        let mut f = File::create(file_path)?;
68        f.write_all(&d)?;
69
70        Ok(())
71    }
72}
73
74/// RUST_LOG=debug cargo test --package avalanche-types --lib -- subnet::config::test_config --exact --show-output
75#[test]
76fn test_config() {
77    let _ = env_logger::builder().is_test(true).try_init();
78
79    let tmp_path = random_manager::tmp_path(10, Some(".json")).unwrap();
80    let cfg = Config::default();
81    cfg.sync(&tmp_path).unwrap();
82}