node/daemon_json/
mod.rs

1use serde::{Deserialize, Serialize};
2
3mod json_daemon;
4mod json_genesis;
5mod json_ledger;
6pub use json_daemon::Daemon;
7pub use json_genesis::Genesis;
8pub use json_ledger::{
9    build_ledger_name, Account, AccountConfigError, AccountPermissions, AccountTiming, Ledger,
10    Zkapp,
11};
12
13/// This type represents a JSON object loaded from daemon.json
14/// file. It does not describe its full structure, as it's not
15/// necessary for our purpose here. We only need to extract
16/// certain information from it.
17/// In practice, this format is never really used to convey
18/// the network's configuration, as the standard practice is to
19/// compile that into the OCaml node's binary.
20/// In theory, though, the underlying JSON file could contain
21/// more information that the following format describes. If
22/// that happens, the format can be extended to accommodate.
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct DaemonJson {
25    pub daemon: Option<Daemon>,
26    pub ledger: Option<Ledger>,
27    pub genesis: Option<Genesis>,
28    pub epoch_data: Option<Epochs>,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct Epochs {
33    pub staking: EpochData,
34    pub next: Option<EpochData>,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct EpochData {
39    pub accounts: Option<Vec<Account>>,
40    pub hash: Option<String>,
41    pub s3_data_hash: Option<String>,
42    pub seed: String,
43}
44
45impl EpochData {
46    pub fn ledger_name(&self) -> String {
47        self.hash.clone().unwrap_or_else(|| {
48            build_ledger_name(
49                self.accounts.as_ref().map(Vec::len).unwrap_or(0),
50                self.accounts
51                    .clone()
52                    .unwrap_or_default()
53                    .iter()
54                    .map(|a| a.balance.clone())
55                    .enumerate(),
56            )
57        })
58    }
59}
60
61#[cfg(test)]
62mod test {
63
64    use ledger::{scan_state::currency::Balance, Timing};
65    use openmina_node_account::AccountPublicKey;
66    use std::str::FromStr;
67
68    use crate::daemon_json::DaemonJson;
69
70    #[test]
71    fn test_daemon_json_read() {
72        let test_filename = "testing/data/daemon.json";
73        println!(
74            "Reading from: {}",
75            std::env::current_dir().unwrap().display()
76        );
77        let test_file = std::fs::File::open(test_filename).unwrap();
78        let daemon_json: DaemonJson = serde_json::from_reader(test_file).unwrap();
79        let ledger = daemon_json.ledger.unwrap();
80        assert_eq!(ledger.name, Some("devnet".to_string()));
81        let addr1 =
82            AccountPublicKey::from_str("B62qnLVz8wM7MfJsuYbjFf4UWbwrUBEL5ZdawExxxFhnGXB6siqokyM")
83                .unwrap();
84        let acc1 = ledger.find_account(&addr1).unwrap();
85        assert_eq!(acc1.balance(), Balance::from_u64(83_333_000_000_000));
86        assert_eq!(acc1.delegate().unwrap(), Some(acc1.public_key().unwrap()));
87        assert!(acc1.secret_key().unwrap().is_none());
88        assert_eq!(acc1.timing().unwrap(), Timing::Untimed);
89        let addr2 =
90            AccountPublicKey::from_str("B62qnJcRzJpdaXvi6ok3iH7BbP3R6oZtT1C9qTyUr9hNHWRf3eUAJxC")
91                .unwrap();
92        let acc2 = ledger.find_account(&addr2).unwrap();
93        assert_eq!(acc2.balance(), Balance::from_u64(2_000_000_000_000_000));
94        assert_eq!(acc2.delegate().unwrap(), Some(acc1.public_key().unwrap()));
95        if let Timing::Timed {
96            initial_minimum_balance,
97            ..
98        } = acc2.timing().unwrap()
99        {
100            assert_eq!(
101                initial_minimum_balance,
102                Balance::from_u64(1_000_000_000_000_000)
103            );
104        } else {
105            panic!("Expected Timed account");
106        }
107        let daemon = daemon_json.daemon.unwrap();
108        assert_eq!(daemon.tx_pool_max_size(), 3000);
109        assert_eq!(daemon.peer_list_url(), None);
110        assert_eq!(daemon.slot_tx_end(), None);
111        assert_eq!(daemon.slot_chain_end(), None);
112    }
113}