dpp/util/
deserializer.rs

1#[cfg(feature = "cbor")]
2use crate::consensus::basic::decode::ProtocolVersionParsingError;
3#[cfg(feature = "cbor")]
4use crate::consensus::basic::BasicError;
5#[cfg(feature = "cbor")]
6use crate::consensus::ConsensusError;
7use integer_encoding::VarInt;
8use platform_version::version::FeatureVersion;
9
10use crate::errors::ProtocolError;
11
12/// A protocol version
13pub type ProtocolVersion = u32;
14
15pub fn get_protocol_version(version_bytes: &[u8]) -> Result<ProtocolVersion, ProtocolError> {
16    u32::decode_var(version_bytes)
17        .ok_or_else(|| {
18            ProtocolError::UnknownProtocolVersionError(
19                "protocol version could not be decoded as a varint".to_string(),
20            )
21        })
22        .map(|(protocol_version, _size)| protocol_version)
23}
24
25/// The outcome of splitting a message that has a protocol version
26pub struct SplitFeatureVersionOutcome<'a> {
27    /// The protocol version
28    pub feature_version: FeatureVersion,
29    /// The protocol version size
30    pub protocol_version_size: usize,
31    /// The main message bytes of the protocol version
32    pub main_message_bytes: &'a [u8],
33}
34
35#[cfg(feature = "cbor")]
36pub fn split_cbor_feature_version(
37    message_bytes: &[u8],
38) -> Result<SplitFeatureVersionOutcome<'_>, ProtocolError> {
39    let (feature_version, protocol_version_size) =
40        u16::decode_var(message_bytes).ok_or(ConsensusError::BasicError(
41            BasicError::ProtocolVersionParsingError(ProtocolVersionParsingError::new(
42                "protocol version could not be decoded as a varint".to_string(),
43            )),
44        ))?;
45
46    // We actually encode protocol version as is. get method of protocol version always expects
47    // protocol version to be at least 1, an it will give back version 0 if 1 is passed.
48    let (_, main_message_bytes) = message_bytes.split_at(protocol_version_size);
49
50    Ok(SplitFeatureVersionOutcome {
51        feature_version,
52        protocol_version_size,
53        main_message_bytes,
54    })
55}
56
57pub mod serde_entropy {
58    use base64::prelude::BASE64_STANDARD;
59    use base64::Engine;
60    use std::convert::TryInto;
61
62    use serde::{Deserialize, Deserializer, Serializer};
63
64    pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<[u8; 32], D::Error> {
65        let data: String = Deserialize::deserialize(d)?;
66        BASE64_STANDARD
67            .decode(&data)
68            .map_err(|e| {
69                serde::de::Error::custom(format!("Unable to decode {}' with base64 - {}", data, e))
70            })?
71            .try_into()
72            .map_err(|_| {
73                serde::de::Error::custom(format!(
74                    "Unable to convert the '{:?}' into 32 bytes array",
75                    data
76                ))
77            })
78    }
79
80    pub fn serialize<S>(buffer: &[u8], serializer: S) -> Result<S::Ok, S::Error>
81    where
82        S: Serializer,
83    {
84        serializer.serialize_str(&BASE64_STANDARD.encode(buffer))
85    }
86}