hpl_interface/types/
message.rs

1use cosmwasm_schema::cw_serde;
2use cosmwasm_std::{Addr, HexBinary, StdResult};
3
4use super::bech32_encode;
5
6#[cw_serde]
7pub struct Message {
8    pub version: u8,
9    pub nonce: u32,
10    pub origin_domain: u32,
11    pub sender: HexBinary,
12    pub dest_domain: u32,
13    pub recipient: HexBinary,
14    pub body: HexBinary,
15}
16
17impl Message {
18    pub fn id(&self) -> HexBinary {
19        super::keccak256_hash(&HexBinary::from(self.clone()))
20    }
21
22    pub fn sender_addr(&self, hrp: &str) -> StdResult<Addr> {
23        bech32_encode(hrp, &self.sender)
24    }
25    pub fn recipient_addr(&self, hrp: &str) -> StdResult<Addr> {
26        bech32_encode(hrp, &self.recipient)
27    }
28}
29
30impl From<Message> for HexBinary {
31    fn from(v: Message) -> Self {
32        v.version
33            .to_be_bytes()
34            .iter()
35            .chain(v.nonce.to_be_bytes().iter())
36            .chain(v.origin_domain.to_be_bytes().iter())
37            .chain(v.sender.to_vec().iter())
38            .chain(v.dest_domain.to_be_bytes().iter())
39            .chain(v.recipient.to_vec().iter())
40            .chain(v.body.to_vec().iter())
41            .cloned()
42            .collect::<Vec<u8>>()
43            .into()
44    }
45}
46
47impl From<HexBinary> for Message {
48    fn from(v: HexBinary) -> Self {
49        Self {
50            version: v[0],
51            nonce: u32::from_be_bytes(v[1..5].try_into().unwrap()),
52            origin_domain: u32::from_be_bytes(v[5..9].try_into().unwrap()),
53            sender: v[9..41].to_vec().into(),
54            dest_domain: u32::from_be_bytes(v[41..45].try_into().unwrap()),
55            recipient: v[45..77].to_vec().into(),
56            body: v[77..].to_vec().into(),
57        }
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use cosmwasm_std::HexBinary;
64
65    use super::Message;
66
67    #[test]
68    fn test_encode_decode() {
69        let encode_expected = HexBinary::from_hex("00000021500000aef3000000000000000000000000477d860f8f41bc69ddd32821f2bf2c2af0243f1600aa36a70000000000000000000000005d56b8a669f50193b54319442c6eee5edd66238148656c6c6f21").unwrap();
70
71        let hex = |v: &str| -> HexBinary { HexBinary::from_hex(v).unwrap() };
72
73        let decode_actual: Message = encode_expected.clone().into();
74        let decode_expected = Message {
75            version: 0,
76            nonce: 8528,
77            origin_domain: 44787,
78            sender: hex("000000000000000000000000477d860f8f41bc69ddd32821f2bf2c2af0243f16"),
79            dest_domain: 11155111,
80            recipient: hex("0000000000000000000000005d56b8a669f50193b54319442c6eee5edd662381"),
81            body: hex("48656c6c6f21"),
82        };
83        let encode_actual: HexBinary = decode_expected.clone().into();
84
85        assert_eq!(decode_expected, decode_actual);
86        assert_eq!(encode_expected, encode_actual);
87    }
88
89    #[test]
90    #[should_panic(expected = "range end index 77 out of range for slice of length 67")]
91    fn test_overflow() {
92        let no = HexBinary::from_hex("00000021500000aef3000000000000000000000000477d860f8f41bc69ddd32821f2bf2c2af0243f1600aa36a70000000000000000000000005d56b8a669f50193b543").unwrap();
93
94        let _msg: Message = no.into();
95    }
96}