pyth_lazer_protocol/
message.rs1use {
2 crate::payload::{EVM_FORMAT_MAGIC, SOLANA_FORMAT_MAGIC_LE},
3 anyhow::bail,
4 byteorder::{ReadBytesExt, WriteBytesExt, BE, LE},
5 std::io::{Cursor, Read, Write},
6};
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10pub struct EvmMessage {
11 pub payload: Vec<u8>,
12 pub signature: [u8; 64],
13 pub recovery_id: u8,
14}
15
16impl EvmMessage {
17 pub fn serialize(&self, mut writer: impl Write) -> anyhow::Result<()> {
18 writer.write_u32::<BE>(EVM_FORMAT_MAGIC)?;
19 writer.write_all(&self.signature)?;
20 writer.write_u8(self.recovery_id)?;
21 writer.write_u16::<BE>(self.payload.len().try_into()?)?;
22 writer.write_all(&self.payload)?;
23 Ok(())
24 }
25
26 pub fn deserialize_slice(data: &[u8]) -> anyhow::Result<Self> {
27 Self::deserialize(Cursor::new(data))
28 }
29
30 pub fn deserialize(mut reader: impl Read) -> anyhow::Result<Self> {
31 let magic = reader.read_u32::<BE>()?;
32 if magic != EVM_FORMAT_MAGIC {
33 bail!("magic mismatch");
34 }
35 let mut signature = [0u8; 64];
36 reader.read_exact(&mut signature)?;
37 let recovery_id = reader.read_u8()?;
38 let payload_len: usize = reader.read_u16::<BE>()?.into();
39 let mut payload = vec![0u8; payload_len];
40 reader.read_exact(&mut payload)?;
41 Ok(Self {
42 payload,
43 signature,
44 recovery_id,
45 })
46 }
47}
48
49#[derive(Debug, Clone, PartialEq, Eq, Hash)]
51pub struct SolanaMessage {
52 pub payload: Vec<u8>,
53 pub signature: [u8; 64],
54 pub public_key: [u8; 32],
55}
56
57impl SolanaMessage {
58 pub fn serialize(&self, mut writer: impl Write) -> anyhow::Result<()> {
59 writer.write_u32::<LE>(SOLANA_FORMAT_MAGIC_LE)?;
60 writer.write_all(&self.signature)?;
61 writer.write_all(&self.public_key)?;
62 writer.write_u16::<LE>(self.payload.len().try_into()?)?;
63 writer.write_all(&self.payload)?;
64 Ok(())
65 }
66
67 pub fn deserialize_slice(data: &[u8]) -> anyhow::Result<Self> {
68 Self::deserialize(Cursor::new(data))
69 }
70
71 pub fn deserialize(mut reader: impl Read) -> anyhow::Result<Self> {
72 let magic = reader.read_u32::<LE>()?;
73 if magic != SOLANA_FORMAT_MAGIC_LE {
74 bail!("magic mismatch");
75 }
76 let mut signature = [0u8; 64];
77 reader.read_exact(&mut signature)?;
78 let mut public_key = [0u8; 32];
79 reader.read_exact(&mut public_key)?;
80 let payload_len: usize = reader.read_u16::<LE>()?.into();
81 let mut payload = vec![0u8; payload_len];
82 reader.read_exact(&mut payload)?;
83 Ok(Self {
84 payload,
85 signature,
86 public_key,
87 })
88 }
89}
90
91#[test]
92fn test_evm_serde() {
93 let m1 = EvmMessage {
94 payload: vec![1, 2, 4, 3],
95 signature: [5; 64],
96 recovery_id: 1,
97 };
98 let mut buf = Vec::new();
99 m1.serialize(&mut buf).unwrap();
100 assert_eq!(m1, EvmMessage::deserialize_slice(&buf).unwrap());
101}
102
103#[test]
104fn test_solana_serde() {
105 let m1 = SolanaMessage {
106 payload: vec![1, 2, 4, 3],
107 signature: [5; 64],
108 public_key: [6; 32],
109 };
110 let mut buf = Vec::new();
111 m1.serialize(&mut buf).unwrap();
112 assert_eq!(m1, SolanaMessage::deserialize_slice(&buf).unwrap());
113}