uip_solana_sdk/
deser.rs

1use solana_program::pubkey::Pubkey;
2
3use crate::utils::split_at_checked;
4
5/// Trait for types that can be deserialized by reference from a byte slice
6/// without cloning data from the underlying buffer.
7pub(crate) trait DeserializeRef<'a>: Sized {
8    /// Deserialize an instance of `Self` by borrowing from the front of `slice`.
9    /// On success, advances `*slice` past the consumed bytes and returns
10    /// `Some(Self)`. Returns `None` if there are not enough bytes or the data
11    /// is malformed.
12    fn deserialize_ref(slice: &mut &'a [u8]) -> Option<Self>;
13}
14
15/// Non-owned Message Data and message hash.
16pub struct MessageDataRef<'a> {
17    /// The hash of the message.
18    pub msg_hash: &'a [u8; 32],
19
20    pub total_fee: u128,
21    /// The encoded target function selector.
22    pub selector: &'a [u8; 32],
23    /// Sender contract address.
24    pub sender_addr: &'a [u8],
25    /// Destination contract address.
26    pub dest_addr: Pubkey,
27    /// The message payload.
28    pub payload: &'a [u8],
29    /// Reserved field for future use.
30    pub reserved: &'a [u8],
31    /// Additional transmitter parameters.
32    pub transmitter_params: &'a [u8],
33
34    /// Source chain identifier.
35    pub src_chain_id: u128,
36    /// Proposal transaction block number.
37    pub src_block_number: u128,
38    /// Proposal transaction ID.
39    pub src_op_tx_id: &'a [[u8; 32]; 2],
40}
41
42impl<'a> DeserializeRef<'a> for MessageDataRef<'a> {
43    fn deserialize_ref(data: &mut &'a [u8]) -> Option<Self> {
44        let mut read_data = |count| {
45            let (left, right) = split_at_checked(data, count)?;
46            *data = right;
47            Some(left)
48        };
49
50        let msg_hash = read_data(32)?.try_into().unwrap();
51
52        let total_fee = u128::from_le_bytes(read_data(16)?.try_into().unwrap());
53        let selector = read_data(32)?.try_into().unwrap();
54
55        let sender_len = u32::from_le_bytes(read_data(4)?.try_into().unwrap()) as usize;
56        let sender_addr = read_data(sender_len)?;
57
58        let dest_addr = Pubkey::new_from_array(read_data(32)?.try_into().unwrap());
59
60        let payload_len = u32::from_le_bytes(read_data(4)?.try_into().unwrap()) as usize;
61        let payload = read_data(payload_len)?;
62
63        let reserved_len = u32::from_le_bytes(read_data(4)?.try_into().unwrap()) as usize;
64        let reserved = read_data(reserved_len)?;
65
66        let transmitter_len = u32::from_le_bytes(read_data(4)?.try_into().unwrap()) as usize;
67        let transmitter_params = read_data(transmitter_len)?;
68
69        let src_chain_id = u128::from_le_bytes(read_data(16)?.try_into().unwrap());
70
71        let src_block_number = u128::from_le_bytes(read_data(16)?.try_into().unwrap());
72        let src_op_tx_id: &[u8; 64] = read_data(64)?.try_into().unwrap();
73        let src_op_tx_id: &[[u8; 32]; 2] = bytemuck::cast_ref(src_op_tx_id);
74
75        Some(MessageDataRef {
76            payload,
77            src_chain_id,
78            sender_addr,
79            msg_hash,
80            total_fee,
81            selector,
82            dest_addr,
83            reserved,
84            transmitter_params,
85            src_block_number,
86            src_op_tx_id,
87        })
88    }
89}