Skip to main content

rialo_s_bincode/
lib.rs

1//! Contains a single utility function for deserializing from [bincode].
2//!
3//! [bincode]: https://docs.rs/bincode
4
5use bincode::config::Options;
6use rialo_s_instruction::error::InstructionError;
7
8/// Deserialize with a limit based the maximum amount of data a program can expect to get.
9/// This function should be used in place of direct deserialization to help prevent OOM errors
10pub fn limited_deserialize<T>(instruction_data: &[u8], limit: u64) -> Result<T, InstructionError>
11where
12    T: serde::de::DeserializeOwned,
13{
14    bincode::options()
15        .with_limit(limit)
16        .with_fixint_encoding() // As per https://github.com/servo/bincode/issues/333, these two options are needed
17        .allow_trailing_bytes() // to retain the behavior of bincode::deserialize with the new `options()` method
18        .deserialize_from(instruction_data)
19        .map_err(|_| InstructionError::InvalidInstructionData)
20}
21
22#[cfg(test)]
23pub mod tests {
24    use rialo_s_system_interface::instruction::SystemInstruction;
25
26    use super::*;
27
28    #[test]
29    fn test_limited_deserialize_advance_nonce_account() {
30        let item = SystemInstruction::AdvanceNonceAccount;
31        let mut serialized = bincode::serialize(&item).unwrap();
32
33        assert_eq!(
34            serialized.len(),
35            4,
36            "`SanitizedMessage::get_durable_nonce()` may need a change"
37        );
38
39        assert_eq!(
40            limited_deserialize::<SystemInstruction>(&serialized, 4).as_ref(),
41            Ok(&item)
42        );
43        assert!(limited_deserialize::<SystemInstruction>(&serialized, 3).is_err());
44
45        serialized.push(0);
46        assert_eq!(
47            limited_deserialize::<SystemInstruction>(&serialized, 4).as_ref(),
48            Ok(&item)
49        );
50    }
51}