mithril_common/messages/
aggregator_features.rs

1use std::collections::BTreeSet;
2
3use serde::{Deserialize, Serialize};
4
5use mithril_stm::AggregateSignatureType;
6
7use crate::entities::SignedEntityTypeDiscriminants;
8
9/// Message advertised by an Aggregator to inform about its features
10#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
11pub struct AggregatorFeaturesMessage {
12    /// Version of the OpenAPI specification
13    pub open_api_version: String,
14
15    /// URL of the documentation
16    pub documentation_url: String,
17
18    /// Capabilities of the Aggregator
19    pub capabilities: AggregatorCapabilities,
20}
21
22/// Capabilities of an Aggregator
23#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
24pub struct AggregatorCapabilities {
25    /// Signed entity types that are signed by the aggregator
26    pub signed_entity_types: BTreeSet<SignedEntityTypeDiscriminants>,
27
28    /// Aggregate signature type used by the aggregator
29    #[serde(default)]
30    pub aggregate_signature_type: AggregateSignatureType,
31
32    /// Cardano transactions prover capabilities
33    #[serde(skip_serializing_if = "Option::is_none")]
34    pub cardano_transactions_prover: Option<CardanoTransactionsProverCapabilities>,
35}
36
37/// Cardano transactions prover capabilities
38#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
39pub struct CardanoTransactionsProverCapabilities {
40    /// Maximum number of hashes allowed for a single request
41    pub max_hashes_allowed_by_request: usize,
42}
43
44#[cfg(test)]
45mod tests {
46    use crate::entities::CardanoTransactionsSigningConfig;
47
48    use super::*;
49
50    #[derive(Debug, Serialize, Deserialize, PartialEq)]
51    struct AggregatorFeaturesMessageUntilV0_1_45 {
52        pub open_api_version: String,
53        pub documentation_url: String,
54        pub capabilities: AggregatorCapabilitiesUntilV0_1_45,
55    }
56
57    #[derive(Debug, Serialize, Deserialize, PartialEq)]
58    struct AggregatorCapabilitiesUntilV0_1_45 {
59        pub signed_entity_types: BTreeSet<SignedEntityTypeDiscriminants>,
60        #[serde(skip_serializing_if = "Option::is_none")]
61        pub cardano_transactions_prover: Option<CardanoTransactionsProverCapabilities>,
62        #[serde(skip_serializing_if = "Option::is_none")]
63        pub cardano_transactions_signing_config: Option<CardanoTransactionsSigningConfig>,
64    }
65
66    fn golden_message_until_open_api_0_1_45() -> AggregatorFeaturesMessageUntilV0_1_45 {
67        AggregatorFeaturesMessageUntilV0_1_45 {
68            open_api_version: "0.0.1".to_string(),
69            documentation_url: "https://example.com".to_string(),
70            capabilities: AggregatorCapabilitiesUntilV0_1_45 {
71                signed_entity_types: BTreeSet::from([
72                    SignedEntityTypeDiscriminants::CardanoTransactions,
73                ]),
74                cardano_transactions_prover: Some(CardanoTransactionsProverCapabilities {
75                    max_hashes_allowed_by_request: 100,
76                }),
77                cardano_transactions_signing_config: None,
78            },
79        }
80    }
81
82    #[derive(Debug, Serialize, Deserialize, PartialEq)]
83    struct AggregatorFeaturesMessageUntilV0_6_17 {
84        pub open_api_version: String,
85        pub documentation_url: String,
86        pub capabilities: AggregatorCapabilitiesUntilV0_6_17,
87    }
88
89    #[derive(Debug, Serialize, Deserialize, PartialEq)]
90    struct AggregatorCapabilitiesUntilV0_6_17 {
91        pub signed_entity_types: BTreeSet<SignedEntityTypeDiscriminants>,
92        #[serde(skip_serializing_if = "Option::is_none")]
93        pub cardano_transactions_prover: Option<CardanoTransactionsProverCapabilities>,
94        #[serde(skip_serializing_if = "Option::is_none")]
95        pub cardano_transactions_signing_config: Option<CardanoTransactionsSigningConfig>,
96    }
97
98    fn golden_message_until_open_api_0_6_17() -> AggregatorFeaturesMessageUntilV0_6_17 {
99        AggregatorFeaturesMessageUntilV0_6_17 {
100            open_api_version: "0.0.1".to_string(),
101            documentation_url: "https://example.com".to_string(),
102            capabilities: AggregatorCapabilitiesUntilV0_6_17 {
103                signed_entity_types: BTreeSet::from([
104                    SignedEntityTypeDiscriminants::CardanoTransactions,
105                ]),
106                cardano_transactions_prover: Some(CardanoTransactionsProverCapabilities {
107                    max_hashes_allowed_by_request: 100,
108                }),
109                cardano_transactions_signing_config: None,
110            },
111        }
112    }
113
114    fn golden_message_current() -> AggregatorFeaturesMessage {
115        AggregatorFeaturesMessage {
116            open_api_version: "0.0.1".to_string(),
117            documentation_url: "https://example.com".to_string(),
118            capabilities: AggregatorCapabilities {
119                signed_entity_types: BTreeSet::from([
120                    SignedEntityTypeDiscriminants::CardanoTransactions,
121                ]),
122                aggregate_signature_type: AggregateSignatureType::Concatenation,
123                cardano_transactions_prover: Some(CardanoTransactionsProverCapabilities {
124                    max_hashes_allowed_by_request: 100,
125                }),
126            },
127        }
128    }
129
130    const CURRENT_JSON: &str = r#"{
131        "open_api_version": "0.0.1",
132        "documentation_url": "https://example.com",
133        "capabilities": {
134            "signed_entity_types": ["CardanoTransactions"],
135            "aggregate_signature_type": "Concatenation",
136            "cardano_transactions_prover": {
137                "max_hashes_allowed_by_request": 100
138            }
139        }
140    }"#;
141
142    #[test]
143    fn test_current_json_deserialized_into_message_supported_until_open_api_0_1_45() {
144        let json = CURRENT_JSON;
145        let message: AggregatorFeaturesMessageUntilV0_1_45 = serde_json::from_str(json).unwrap();
146
147        assert_eq!(golden_message_until_open_api_0_1_45(), message);
148    }
149
150    #[test]
151    fn test_current_json_deserialized_into_message_supported_until_open_api_0_6_17() {
152        let json = CURRENT_JSON;
153        let message: AggregatorFeaturesMessageUntilV0_6_17 = serde_json::from_str(json).unwrap();
154
155        assert_eq!(golden_message_until_open_api_0_6_17(), message);
156    }
157
158    #[test]
159    fn test_current_json_deserialized_into_current_message() {
160        let json = CURRENT_JSON;
161        let message: AggregatorFeaturesMessage = serde_json::from_str(json).unwrap();
162
163        assert_eq!(golden_message_current(), message);
164    }
165}