hpl_interface/types/
message.rs1use 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}