mithril_dmq/model/
message.rs

1use std::fmt::Debug;
2use std::ops::{Deref, DerefMut};
3
4use pallas_codec::minicbor::{Decode, Decoder, Encode, Encoder};
5use pallas_network::miniprotocols::localmsgsubmission::DmqMsg;
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7
8/// Wrapper for a DMQ message which can be serialized and deserialized.
9#[derive(Clone, PartialEq, Eq)]
10pub struct DmqMessage(DmqMsg);
11
12#[derive(Serialize, Deserialize)]
13struct RawBytes(#[serde(with = "serde_bytes")] Vec<u8>);
14
15impl Deref for DmqMessage {
16    type Target = DmqMsg;
17
18    fn deref(&self) -> &Self::Target {
19        &self.0
20    }
21}
22
23impl DerefMut for DmqMessage {
24    fn deref_mut(&mut self) -> &mut Self::Target {
25        &mut self.0
26    }
27}
28
29impl From<DmqMsg> for DmqMessage {
30    fn from(msg: DmqMsg) -> Self {
31        Self(msg)
32    }
33}
34
35impl From<DmqMessage> for DmqMsg {
36    fn from(msg: DmqMessage) -> Self {
37        msg.0
38    }
39}
40
41impl Serialize for DmqMessage {
42    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
43    where
44        S: Serializer,
45    {
46        let raw_bytes = RawBytes({
47            let mut e = Encoder::new(Vec::new());
48            self.0.encode(&mut e, &mut ()).map_err(|e| {
49                serde::ser::Error::custom(format!("DMQ message serialization error: {e}"))
50            })?;
51            Ok(e.into_writer())
52        }?);
53
54        raw_bytes.serialize(serializer)
55    }
56}
57
58impl<'de> Deserialize<'de> for DmqMessage {
59    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
60    where
61        D: Deserializer<'de>,
62    {
63        let raw_bytes = RawBytes::deserialize(deserializer)?;
64        let res = DmqMsg::decode(&mut Decoder::new(&raw_bytes.0), &mut ())
65            .map_err(|e| {
66                serde::de::Error::custom(format!("DMQ message deserialization error: {e}"))
67            })?
68            .into();
69
70        Ok(res)
71    }
72}
73
74impl Debug for DmqMessage {
75    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76        let is_pretty_printing = f.alternate();
77        let mut debug = f.debug_struct("DmqMessage");
78        debug
79            .field("id", &hex::encode(&self.msg_payload.msg_id))
80            .field("kes_period", &self.msg_payload.kes_period)
81            .field("expires_at", &self.msg_payload.expires_at);
82
83        match is_pretty_printing {
84            true => debug
85                .field("body", &format_args!("{:?}", self.msg_payload.msg_body))
86                .finish(),
87            false => debug.finish_non_exhaustive(),
88        }
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use pallas_network::miniprotocols::localmsgsubmission::{
95        DmqMsgOperationalCertificate, DmqMsgPayload,
96    };
97
98    use super::*;
99
100    #[test]
101    fn test_dmq_message_serialize_deserialize() {
102        let dmq_msg = DmqMsg {
103            msg_payload: DmqMsgPayload {
104                msg_id: vec![0, 1],
105                msg_body: vec![0, 1, 2],
106                kes_period: 10,
107                expires_at: 100,
108            },
109            kes_signature: vec![0, 1, 2, 3],
110            operational_certificate: DmqMsgOperationalCertificate {
111                kes_vk: vec![12, 13, 14],
112                issue_number: 15,
113                start_kes_period: 16,
114                cert_sig: vec![17],
115            },
116            cold_verification_key: vec![0, 1, 2, 3, 4, 5],
117        };
118
119        let dmq_message = DmqMessage::from(dmq_msg.clone());
120        let serialized = bincode::serde::encode_to_vec(&dmq_message, bincode::config::standard())
121            .expect("Serialization failed");
122
123        let (deserialized, _) =
124            bincode::serde::decode_from_slice(&serialized, bincode::config::standard())
125                .expect("Deserialization failed");
126
127        assert_eq!(dmq_message, deserialized);
128        assert_eq!(dmq_message.0, dmq_msg);
129    }
130}