casper_types/bytesrepr/
bytes.rs

1use alloc::{
2    string::String,
3    vec::{IntoIter, Vec},
4};
5use core::{
6    cmp, fmt,
7    iter::FromIterator,
8    ops::{Deref, Index, Range, RangeFrom, RangeFull, RangeTo},
9    slice,
10};
11
12use rand::{
13    distributions::{Distribution, Standard},
14    Rng,
15};
16use serde::{
17    de::{Error as SerdeError, SeqAccess, Visitor},
18    Deserialize, Deserializer, Serialize, Serializer,
19};
20
21use super::{Error, FromBytes, ToBytes};
22use crate::{checksummed_hex, CLType, CLTyped};
23
24/// A newtype wrapper for bytes that has efficient serialization routines.
25#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Default, Hash)]
26pub struct Bytes(Vec<u8>);
27
28impl Bytes {
29    /// Constructs a new, empty vector of bytes.
30    pub fn new() -> Bytes {
31        Bytes::default()
32    }
33
34    /// Returns reference to inner container.
35    #[inline]
36    pub fn inner_bytes(&self) -> &Vec<u8> {
37        &self.0
38    }
39
40    /// Extracts a slice containing the entire vector.
41    pub fn as_slice(&self) -> &[u8] {
42        self
43    }
44}
45
46impl Deref for Bytes {
47    type Target = [u8];
48
49    fn deref(&self) -> &Self::Target {
50        self.0.deref()
51    }
52}
53
54impl From<Vec<u8>> for Bytes {
55    fn from(vec: Vec<u8>) -> Self {
56        Self(vec)
57    }
58}
59
60impl From<Bytes> for Vec<u8> {
61    fn from(bytes: Bytes) -> Self {
62        bytes.0
63    }
64}
65
66impl From<&[u8]> for Bytes {
67    fn from(bytes: &[u8]) -> Self {
68        Self(bytes.to_vec())
69    }
70}
71
72impl CLTyped for Bytes {
73    fn cl_type() -> CLType {
74        <Vec<u8>>::cl_type()
75    }
76}
77
78impl AsRef<[u8]> for Bytes {
79    fn as_ref(&self) -> &[u8] {
80        self.0.as_ref()
81    }
82}
83
84impl ToBytes for Bytes {
85    #[inline(always)]
86    fn to_bytes(&self) -> Result<Vec<u8>, Error> {
87        super::vec_u8_to_bytes(&self.0)
88    }
89
90    #[inline(always)]
91    fn into_bytes(self) -> Result<Vec<u8>, Error> {
92        super::vec_u8_to_bytes(&self.0)
93    }
94
95    #[inline(always)]
96    fn serialized_length(&self) -> usize {
97        super::vec_u8_serialized_length(&self.0)
98    }
99
100    #[inline(always)]
101    fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), Error> {
102        super::write_u8_slice(self.as_slice(), writer)
103    }
104}
105
106impl FromBytes for Bytes {
107    fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), super::Error> {
108        let (size, remainder) = u32::from_bytes(bytes)?;
109        let (result, remainder) = super::safe_split_at(remainder, size as usize)?;
110        Ok((Bytes(result.to_vec()), remainder))
111    }
112
113    fn from_vec(stream: Vec<u8>) -> Result<(Self, Vec<u8>), Error> {
114        let (size, mut stream) = u32::from_vec(stream)?;
115
116        if size as usize > stream.len() {
117            Err(Error::EarlyEndOfStream)
118        } else {
119            let remainder = stream.split_off(size as usize);
120            Ok((Bytes(stream), remainder))
121        }
122    }
123}
124
125impl Index<usize> for Bytes {
126    type Output = u8;
127
128    fn index(&self, index: usize) -> &u8 {
129        let Bytes(ref dat) = self;
130        &dat[index]
131    }
132}
133
134impl Index<Range<usize>> for Bytes {
135    type Output = [u8];
136
137    fn index(&self, index: Range<usize>) -> &[u8] {
138        let Bytes(dat) = self;
139        &dat[index]
140    }
141}
142
143impl Index<RangeTo<usize>> for Bytes {
144    type Output = [u8];
145
146    fn index(&self, index: RangeTo<usize>) -> &[u8] {
147        let Bytes(dat) = self;
148        &dat[index]
149    }
150}
151
152impl Index<RangeFrom<usize>> for Bytes {
153    type Output = [u8];
154
155    fn index(&self, index: RangeFrom<usize>) -> &[u8] {
156        let Bytes(dat) = self;
157        &dat[index]
158    }
159}
160
161impl Index<RangeFull> for Bytes {
162    type Output = [u8];
163
164    fn index(&self, _: RangeFull) -> &[u8] {
165        let Bytes(dat) = self;
166        &dat[..]
167    }
168}
169
170impl FromIterator<u8> for Bytes {
171    #[inline]
172    fn from_iter<I: IntoIterator<Item = u8>>(iter: I) -> Bytes {
173        let vec = Vec::from_iter(iter);
174        Bytes(vec)
175    }
176}
177
178impl<'a> IntoIterator for &'a Bytes {
179    type Item = &'a u8;
180
181    type IntoIter = slice::Iter<'a, u8>;
182
183    fn into_iter(self) -> Self::IntoIter {
184        self.0.iter()
185    }
186}
187
188impl IntoIterator for Bytes {
189    type Item = u8;
190
191    type IntoIter = IntoIter<u8>;
192
193    fn into_iter(self) -> Self::IntoIter {
194        self.0.into_iter()
195    }
196}
197
198#[cfg(feature = "datasize")]
199impl datasize::DataSize for Bytes {
200    const IS_DYNAMIC: bool = true;
201
202    const STATIC_HEAP_SIZE: usize = 0;
203
204    fn estimate_heap_size(&self) -> usize {
205        self.0.capacity() * std::mem::size_of::<u8>()
206    }
207}
208
209const RANDOM_BYTES_MAX_LENGTH: usize = 100;
210
211impl Distribution<Bytes> for Standard {
212    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Bytes {
213        let len = rng.gen_range(0..RANDOM_BYTES_MAX_LENGTH);
214        let mut result = Vec::with_capacity(len);
215        for _ in 0..len {
216            result.push(rng.gen());
217        }
218        result.into()
219    }
220}
221
222struct BytesVisitor;
223
224impl<'de> Visitor<'de> for BytesVisitor {
225    type Value = Bytes;
226
227    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
228        formatter.write_str("byte array")
229    }
230
231    fn visit_seq<V>(self, mut visitor: V) -> Result<Bytes, V::Error>
232    where
233        V: SeqAccess<'de>,
234    {
235        let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096);
236        let mut bytes = Vec::with_capacity(len);
237
238        while let Some(b) = visitor.next_element()? {
239            bytes.push(b);
240        }
241
242        Ok(Bytes::from(bytes))
243    }
244
245    fn visit_bytes<E>(self, v: &[u8]) -> Result<Bytes, E>
246    where
247        E: SerdeError,
248    {
249        Ok(Bytes::from(v))
250    }
251
252    fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Bytes, E>
253    where
254        E: SerdeError,
255    {
256        Ok(Bytes::from(v))
257    }
258
259    fn visit_str<E>(self, v: &str) -> Result<Bytes, E>
260    where
261        E: SerdeError,
262    {
263        Ok(Bytes::from(v.as_bytes()))
264    }
265
266    fn visit_string<E>(self, v: String) -> Result<Bytes, E>
267    where
268        E: SerdeError,
269    {
270        Ok(Bytes::from(v.into_bytes()))
271    }
272}
273
274impl<'de> Deserialize<'de> for Bytes {
275    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
276    where
277        D: Deserializer<'de>,
278    {
279        if deserializer.is_human_readable() {
280            let hex_string = String::deserialize(deserializer)?;
281            checksummed_hex::decode(hex_string)
282                .map(Bytes)
283                .map_err(SerdeError::custom)
284        } else {
285            let bytes = deserializer.deserialize_byte_buf(BytesVisitor)?;
286            Ok(bytes)
287        }
288    }
289}
290
291impl Serialize for Bytes {
292    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
293    where
294        S: Serializer,
295    {
296        if serializer.is_human_readable() {
297            base16::encode_lower(&self.0).serialize(serializer)
298        } else {
299            serializer.serialize_bytes(&self.0)
300        }
301    }
302}
303
304#[cfg(test)]
305mod tests {
306    use crate::bytesrepr::{self, Error, FromBytes, ToBytes, U32_SERIALIZED_LENGTH};
307    use alloc::vec::Vec;
308
309    use serde_json::json;
310    use serde_test::{assert_tokens, Configure, Token};
311
312    use super::Bytes;
313
314    const TRUTH: &[u8] = &[0xde, 0xad, 0xbe, 0xef];
315
316    #[test]
317    fn vec_u8_from_bytes() {
318        let data: Bytes = vec![1, 2, 3, 4, 5].into();
319        let data_bytes = data.to_bytes().unwrap();
320        assert!(Bytes::from_bytes(&data_bytes[..U32_SERIALIZED_LENGTH / 2]).is_err());
321        assert!(Bytes::from_bytes(&data_bytes[..U32_SERIALIZED_LENGTH]).is_err());
322        assert!(Bytes::from_bytes(&data_bytes[..U32_SERIALIZED_LENGTH + 2]).is_err());
323    }
324
325    #[test]
326    fn should_serialize_deserialize_bytes() {
327        let data: Bytes = vec![1, 2, 3, 4, 5].into();
328        bytesrepr::test_serialization_roundtrip(&data);
329    }
330
331    #[test]
332    fn should_fail_to_serialize_deserialize_malicious_bytes() {
333        let data: Bytes = vec![1, 2, 3, 4, 5].into();
334        let mut serialized = data.to_bytes().expect("should serialize data");
335        serialized = serialized[..serialized.len() - 1].to_vec();
336        let res: Result<(_, &[u8]), Error> = Bytes::from_bytes(&serialized);
337        assert_eq!(res.unwrap_err(), Error::EarlyEndOfStream);
338    }
339
340    #[test]
341    fn should_serialize_deserialize_bytes_and_keep_rem() {
342        let data: Bytes = vec![1, 2, 3, 4, 5].into();
343        let expected_rem: Vec<u8> = vec![6, 7, 8, 9, 10];
344        let mut serialized = data.to_bytes().expect("should serialize data");
345        serialized.extend(&expected_rem);
346        let (deserialized, rem): (Bytes, &[u8]) =
347            FromBytes::from_bytes(&serialized).expect("should deserialize data");
348        assert_eq!(data, deserialized);
349        assert_eq!(&rem, &expected_rem);
350    }
351
352    #[test]
353    fn should_ser_de_human_readable() {
354        let truth = vec![0xde, 0xad, 0xbe, 0xef];
355
356        let bytes_ser: Bytes = truth.clone().into();
357
358        let json_object = serde_json::to_value(bytes_ser).unwrap();
359        assert_eq!(json_object, json!("deadbeef"));
360
361        let bytes_de: Bytes = serde_json::from_value(json_object).unwrap();
362        assert_eq!(bytes_de, Bytes::from(truth));
363    }
364
365    #[test]
366    fn should_ser_de_readable() {
367        let truth: Bytes = TRUTH.into();
368        assert_tokens(&truth.readable(), &[Token::Str("deadbeef")]);
369    }
370
371    #[test]
372    fn should_ser_de_compact() {
373        let truth: Bytes = TRUTH.into();
374        assert_tokens(&truth.compact(), &[Token::Bytes(TRUTH)]);
375    }
376}
377
378#[cfg(test)]
379pub mod gens {
380    use super::Bytes;
381    use proptest::{
382        collection::{vec, SizeRange},
383        prelude::*,
384    };
385
386    pub fn bytes_arb(size: impl Into<SizeRange>) -> impl Strategy<Value = Bytes> {
387        vec(any::<u8>(), size).prop_map(Bytes::from)
388    }
389}