redgold_schema/
servers.rs

1use crate::conf::server_config::NodePartyConfig;
2use crate::helpers::easy_json::json_pretty;
3use crate::observability::errors::EnhanceErrorInfo;
4use crate::structs::{Address, ErrorInfo, NetworkEnvironment, NodeMetadata, NodeType, PeerMetadata, PublicKey, TransportInfo, VersionInfo};
5use crate::{ErrorInfoContext, RgResult};
6use serde::Deserialize;
7use serde::Serialize;
8use std::collections::HashMap;
9use std::fs;
10use std::path::PathBuf;
11use std::str::FromStr;
12
13#[derive(Clone, Serialize, Deserialize, Debug, Eq, PartialEq, Default)]
14pub struct ServerOldFormat {
15    pub name: String,
16    pub host: String,
17    pub index: i64,
18    pub peer_id_index: i64,
19    pub network_environment: String,
20    pub username: Option<String>,
21    pub ipv4: Option<String>,
22    pub node_name: Option<String>,
23    pub external_host: Option<String>,
24    pub reward_address: Option<String>,
25    pub jump_host: Option<String>,
26    pub party_config: Option<NodePartyConfig>,
27}
28
29impl ServerOldFormat {
30    pub fn network_environment(&self) -> NetworkEnvironment {
31        NetworkEnvironment::parse(self.network_environment.clone())
32    }
33
34    pub fn node_metadata(
35        &self,
36        nmd: &mut NodeMetadata
37    ) -> RgResult<()> {
38        let s = self;
39        nmd.node_name = s.node_name.clone();
40        let mut info = TransportInfo::default();
41        let ti = nmd.transport_info.as_mut().unwrap_or(&mut info);
42        ti.external_host = s.external_host.clone();
43        ti.external_ipv4 = s.ipv4.clone();
44        ti.nat_restricted = Some(false);
45        nmd.transport_info = Some(ti.clone());
46        Ok(())
47    }
48
49    pub fn peer_data(
50        servers: Vec<ServerOldFormat>,
51        peer_data: &mut PeerMetadata,
52        peer_id_index: i64,
53        pk: HashMap<i64, PublicKey>,
54        checksum: String,
55        net: NetworkEnvironment,
56        reward_address: Option<Address>
57    ) -> &mut PeerMetadata {
58        let mut nmds = vec![];
59        peer_data.network_environment = net.clone() as i32;
60        peer_data.reward_address = reward_address;
61        for s in servers {
62            if s.peer_id_index == peer_id_index {
63                let mut nmd = NodeMetadata::default();
64                s.node_metadata(&mut nmd).expect("works");
65                nmd.peer_id = peer_data.peer_id.clone();
66                nmd.public_key = pk.get(&s.index).cloned();
67                let mut vi = VersionInfo::default();
68                vi.executable_checksum = checksum.clone();
69                nmd.version_info = Some(vi);
70                nmd.node_type = Some(NodeType::Static as i32);
71                let option = nmd.transport_info.as_mut();
72                option.expect("ti").port_offset = Some(net.default_port_offset() as i64);
73                nmds.push(nmd);
74            }
75        }
76        peer_data.node_metadata = nmds;
77        peer_data
78    }
79}
80
81fn parse_servers(str: &str) -> RgResult<Vec<ServerOldFormat>> {
82    let mut rdr = csv::Reader::from_reader(str.as_bytes());
83    let mut res = vec![];
84    for result in rdr.deserialize() {
85        // Notice that we need to provide a type hint for automatic
86        // deserialization.
87        let record: ServerOldFormat = result.error_info("server line parse failure")?;
88        res.push(record);
89    }
90    Ok(res)
91}
92
93impl ServerOldFormat {
94    pub fn new(host: impl Into<String>) -> Self {
95        let host_str = host.into();
96        Self {
97            name: "".to_string(),
98            host: host_str.clone(),
99            username: None,
100            ipv4: None,
101            node_name: None,
102            index: 0,
103            peer_id_index: 0,
104            // TODO: Change to mainnet later
105            network_environment: NetworkEnvironment::All.to_std_string(),
106            external_host: Some(host_str),
107            reward_address: None,
108            jump_host: None,
109            party_config: None,
110        }
111    }
112
113    pub fn parse_from_file(path: PathBuf)  -> Result<Vec<Self>, ErrorInfo> {
114        let contents = fs::read_to_string(path).error_info("file read failure")?;
115        Self::parse(contents).add("Servers file load path")
116    }
117
118    pub fn parse(contents: String) -> Result<Vec<Self>, ErrorInfo> {
119        parse_servers(&contents)
120    }
121}
122
123#[test]
124fn parse_server_example() {
125    let str = include_str!("resources/example_servers");
126    let servers = ServerOldFormat::parse(str.to_string()).unwrap();
127    println!("{}", json_pretty(&servers).expect(""))
128}