mithril_dmq/model/
message.rs

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