mithril_aggregator/entities/
open_message.rs

1use chrono::{DateTime, Utc};
2
3use mithril_common::entities::{
4    Epoch, PartyId, ProtocolMessage, SignedEntityType, SingleSignature,
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<SingleSignature>,
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
51impl From<OpenMessageRecord> for OpenMessage {
52    fn from(record: OpenMessageRecord) -> Self {
53        Self {
54            epoch: record.epoch,
55            signed_entity_type: record.signed_entity_type,
56            protocol_message: record.protocol_message,
57            is_certified: record.is_certified,
58            is_expired: record.is_expired,
59            single_signatures: vec![],
60            created_at: record.created_at,
61            expires_at: record.expires_at,
62        }
63    }
64}
65
66impl From<OpenMessageWithSingleSignaturesRecord> for OpenMessage {
67    fn from(record: OpenMessageWithSingleSignaturesRecord) -> Self {
68        Self {
69            epoch: record.epoch,
70            signed_entity_type: record.signed_entity_type,
71            protocol_message: record.protocol_message,
72            is_certified: record.is_certified,
73            is_expired: record.is_expired,
74            single_signatures: record.single_signatures,
75            created_at: record.created_at,
76            expires_at: record.expires_at,
77        }
78    }
79}
80
81#[cfg(test)]
82mod test {
83    use chrono::Utc;
84    use uuid::Uuid;
85
86    use mithril_common::{
87        entities::{Epoch, ProtocolMessage, SignedEntityType},
88        test::double::{Dummy, fake_data},
89    };
90
91    use crate::database::record::{OpenMessageRecord, OpenMessageWithSingleSignaturesRecord};
92
93    use super::OpenMessage;
94
95    #[test]
96    fn test_from_record() {
97        let created_at = Utc::now();
98        let record = OpenMessageRecord {
99            open_message_id: OpenMessageRecord::new_id(),
100            epoch: Epoch(1),
101            signed_entity_type: SignedEntityType::dummy(),
102            protocol_message: ProtocolMessage::default(),
103            is_certified: false,
104            is_expired: false,
105            created_at,
106            expires_at: None,
107        };
108        let expected = OpenMessage {
109            epoch: Epoch(1),
110            signed_entity_type: SignedEntityType::dummy(),
111            protocol_message: ProtocolMessage::default(),
112            is_certified: false,
113            is_expired: false,
114            single_signatures: vec![],
115            created_at,
116            expires_at: None,
117        };
118        let result: OpenMessage = record.into();
119
120        assert_eq!(expected, result);
121    }
122
123    #[test]
124    fn test_from_record_with_single_signatures() {
125        let created_at = Utc::now();
126        let record = OpenMessageWithSingleSignaturesRecord {
127            open_message_id: Uuid::new_v4(),
128            epoch: Epoch(1),
129            signed_entity_type: SignedEntityType::dummy(),
130            protocol_message: ProtocolMessage::default(),
131            is_certified: false,
132            is_expired: false,
133            created_at,
134            expires_at: None,
135            single_signatures: vec![fake_data::single_signature(vec![1, 4, 5])],
136        };
137        let expected = OpenMessage {
138            epoch: Epoch(1),
139            signed_entity_type: SignedEntityType::dummy(),
140            protocol_message: ProtocolMessage::default(),
141            is_certified: false,
142            is_expired: false,
143            single_signatures: vec![fake_data::single_signature(vec![1, 4, 5])],
144            created_at,
145            expires_at: None,
146        };
147        let result: OpenMessage = record.into();
148
149        assert_eq!(expected, result);
150    }
151}