1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
use serde::{Deserialize, Serialize};

use crate::{
    entities::{CardanoEra, Epoch, ProtocolParameters, Stake, TotalSPOs},
    era::SupportedEra,
};

/// Message advertised by an aggregator to inform about its status
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct AggregatorStatusMessage {
    /// Current epoch
    pub epoch: Epoch,

    /// Current Cardano era
    pub cardano_era: CardanoEra,

    /// Current Mithril era
    pub mithril_era: SupportedEra,

    /// Cardano node version
    pub cardano_node_version: String,

    /// Aggregator node version
    pub aggregator_node_version: String,

    /// Current Protocol parameters
    #[serde(rename = "protocol")]
    pub protocol_parameters: ProtocolParameters,

    /// Next Protocol parameters
    #[serde(rename = "next_protocol")]
    pub next_protocol_parameters: ProtocolParameters,

    /// The number of signers for the current epoch
    pub total_signers: usize,

    /// The number of signers that will be able to sign on the next epoch
    pub total_next_signers: usize,

    /// The total stakes of the signers for the current epoch
    pub total_stakes_signers: Stake,

    /// The total stakes of the signers that will be able to sign on the next epoch
    pub total_next_stakes_signers: Stake,

    /// The number of Cardano SPOs
    pub total_cardano_spo: TotalSPOs,

    /// The total stake in Cardano
    pub total_cardano_stake: Stake,
}

#[cfg(test)]
mod tests {
    use super::*;

    const ACTUAL_JSON: &str = r#"{
        "epoch": 48,
        "cardano_era": "conway",
        "mithril_era": "pythagoras",
        "cardano_node_version": "1.2.3",
        "aggregator_node_version": "4.5.6",
        "protocol": { "k": 5, "m": 100, "phi_f": 0.65 },
        "next_protocol": { "k": 50, "m": 1000, "phi_f": 0.65 },
        "total_signers": 1234,
        "total_next_signers": 56789,
        "total_stakes_signers": 123456789,
        "total_next_stakes_signers": 987654321,
        "total_cardano_spo": 7777,
        "total_cardano_stake": 888888888
        }"#;

    fn golden_actual_message() -> AggregatorStatusMessage {
        AggregatorStatusMessage {
            epoch: Epoch(48),
            cardano_era: "conway".to_string(),
            mithril_era: SupportedEra::Pythagoras,
            cardano_node_version: "1.2.3".to_string(),
            aggregator_node_version: "4.5.6".to_string(),
            protocol_parameters: ProtocolParameters {
                k: 5,
                m: 100,
                phi_f: 0.65,
            },
            next_protocol_parameters: ProtocolParameters {
                k: 50,
                m: 1000,
                phi_f: 0.65,
            },
            total_signers: 1234,
            total_next_signers: 56789,
            total_stakes_signers: 123456789,
            total_next_stakes_signers: 987654321,
            total_cardano_spo: 7777,
            total_cardano_stake: 888888888,
        }
    }

    // Test the compatibility with current structure.
    #[test]
    fn test_actual_json_deserialized_into_actual_message() {
        let json = ACTUAL_JSON;
        let message: AggregatorStatusMessage = serde_json::from_str(json).expect(
            "This JSON is expected to be successfully parsed into a AggregatorStatusMessage instance.",
        );

        assert_eq!(golden_actual_message(), message);
    }
}