mithril_aggregator/entities/
open_message.rs

1use chrono::{DateTime, Utc};
2
3use mithril_common::entities::{
4    Epoch, PartyId, ProtocolMessage, SignedEntityType, SingleSignatures,
5};
6
7use crate::database::record::{OpenMessageRecord, OpenMessageWithSingleSignaturesRecord};
8
9/// ## OpenMessage
10///
11/// An open message is a message open for signatures. Every signer may send a
12/// single signature for this message from which a multi signature will be
13/// generated if possible.
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct OpenMessage {
16    /// Epoch
17    pub epoch: Epoch,
18
19    /// Type of message
20    pub signed_entity_type: SignedEntityType,
21
22    /// Message used by the Mithril Protocol
23    pub protocol_message: ProtocolMessage,
24
25    /// Has this message been converted into a Certificate?
26    pub is_certified: bool,
27
28    /// Has this open message expired
29    pub is_expired: bool,
30
31    /// associated single signatures
32    pub single_signatures: Vec<SingleSignatures>,
33
34    /// Message creation datetime
35    pub created_at: DateTime<Utc>,
36
37    /// Message expiration datetime, if it exists.
38    pub expires_at: Option<DateTime<Utc>>,
39}
40
41impl OpenMessage {
42    /// Gather all signers party_id for this open message
43    pub fn get_signers_id(&self) -> Vec<PartyId> {
44        self.single_signatures
45            .iter()
46            .map(|sig| sig.party_id.to_owned())
47            .collect()
48    }
49
50    #[cfg(test)]
51    /// Create a dumb OpenMessage instance mainly for test purposes
52    pub fn dummy() -> Self {
53        use mithril_common::test_utils::fake_data;
54
55        let beacon = fake_data::beacon();
56        let epoch = beacon.epoch;
57        let signed_entity_type = SignedEntityType::CardanoImmutableFilesFull(beacon);
58
59        Self {
60            epoch,
61            signed_entity_type,
62            protocol_message: ProtocolMessage::new(),
63            is_certified: false,
64            is_expired: false,
65            single_signatures: vec![
66                fake_data::single_signatures(vec![1, 4, 5]),
67                fake_data::single_signatures(vec![2, 3, 8]),
68            ],
69            created_at: Utc::now(),
70            expires_at: None,
71        }
72    }
73}
74
75impl From<OpenMessageRecord> for OpenMessage {
76    fn from(record: OpenMessageRecord) -> Self {
77        Self {
78            epoch: record.epoch,
79            signed_entity_type: record.signed_entity_type,
80            protocol_message: record.protocol_message,
81            is_certified: record.is_certified,
82            is_expired: record.is_expired,
83            single_signatures: vec![],
84            created_at: record.created_at,
85            expires_at: record.expires_at,
86        }
87    }
88}
89
90impl From<OpenMessageWithSingleSignaturesRecord> for OpenMessage {
91    fn from(record: OpenMessageWithSingleSignaturesRecord) -> Self {
92        Self {
93            epoch: record.epoch,
94            signed_entity_type: record.signed_entity_type,
95            protocol_message: record.protocol_message,
96            is_certified: record.is_certified,
97            is_expired: record.is_expired,
98            single_signatures: record.single_signatures,
99            created_at: record.created_at,
100            expires_at: record.expires_at,
101        }
102    }
103}
104
105#[cfg(test)]
106mod test {
107    use chrono::Utc;
108    use uuid::Uuid;
109
110    use mithril_common::{
111        entities::{Epoch, ProtocolMessage, SignedEntityType},
112        test_utils::fake_data,
113    };
114
115    use crate::database::record::{OpenMessageRecord, OpenMessageWithSingleSignaturesRecord};
116
117    use super::OpenMessage;
118
119    #[test]
120    fn test_from_record() {
121        let created_at = Utc::now();
122        let record = OpenMessageRecord {
123            open_message_id: Uuid::new_v4(),
124            epoch: Epoch(1),
125            signed_entity_type: SignedEntityType::dummy(),
126            protocol_message: ProtocolMessage::default(),
127            is_certified: false,
128            is_expired: false,
129            created_at,
130            expires_at: None,
131        };
132        let expected = OpenMessage {
133            epoch: Epoch(1),
134            signed_entity_type: SignedEntityType::dummy(),
135            protocol_message: ProtocolMessage::default(),
136            is_certified: false,
137            is_expired: false,
138            single_signatures: vec![],
139            created_at,
140            expires_at: None,
141        };
142        let result: OpenMessage = record.into();
143
144        assert_eq!(expected, result);
145    }
146
147    #[test]
148    fn test_from_record_with_single_signatures() {
149        let created_at = Utc::now();
150        let record = OpenMessageWithSingleSignaturesRecord {
151            open_message_id: Uuid::new_v4(),
152            epoch: Epoch(1),
153            signed_entity_type: SignedEntityType::dummy(),
154            protocol_message: ProtocolMessage::default(),
155            is_certified: false,
156            is_expired: false,
157            created_at,
158            expires_at: None,
159            single_signatures: vec![fake_data::single_signatures(vec![1, 4, 5])],
160        };
161        let expected = OpenMessage {
162            epoch: Epoch(1),
163            signed_entity_type: SignedEntityType::dummy(),
164            protocol_message: ProtocolMessage::default(),
165            is_certified: false,
166            is_expired: false,
167            single_signatures: vec![fake_data::single_signatures(vec![1, 4, 5])],
168            created_at,
169            expires_at: None,
170        };
171        let result: OpenMessage = record.into();
172
173        assert_eq!(expected, result);
174    }
175}