casper_types/global_state/
pointer.rs

1use core::fmt::Debug;
2
3use alloc::vec::Vec;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7    bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH},
8    Digest,
9};
10
11#[cfg(any(feature = "testing", test))]
12use crate::testing::TestRng;
13
14/// Represents a pointer to the next object in a Merkle Trie
15#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
16pub enum Pointer {
17    /// Leaf pointer.
18    LeafPointer(Digest),
19    /// Node pointer.
20    NodePointer(Digest),
21}
22
23impl Pointer {
24    /// Borrows the inner hash from a `Pointer`.
25    pub fn hash(&self) -> &Digest {
26        match self {
27            Pointer::LeafPointer(hash) => hash,
28            Pointer::NodePointer(hash) => hash,
29        }
30    }
31
32    /// Takes ownership of the hash, consuming this `Pointer`.
33    pub fn into_hash(self) -> Digest {
34        match self {
35            Pointer::LeafPointer(hash) => hash,
36            Pointer::NodePointer(hash) => hash,
37        }
38    }
39
40    /// Creates a new owned `Pointer` with a new `Digest`.
41    pub fn update(&self, hash: Digest) -> Self {
42        match self {
43            Pointer::LeafPointer(_) => Pointer::LeafPointer(hash),
44            Pointer::NodePointer(_) => Pointer::NodePointer(hash),
45        }
46    }
47
48    /// Returns the `tag` value for a variant of `Pointer`.
49    fn tag(&self) -> u8 {
50        match self {
51            Pointer::LeafPointer(_) => 0,
52            Pointer::NodePointer(_) => 1,
53        }
54    }
55
56    /// Returns a random `Pointer`.
57    #[cfg(any(feature = "testing", test))]
58    pub fn random(rng: &mut TestRng) -> Self {
59        use rand::Rng;
60
61        match rng.gen_range(0..2) {
62            0 => Pointer::LeafPointer(Digest::random(rng)),
63            1 => Pointer::NodePointer(Digest::random(rng)),
64            _ => unreachable!(),
65        }
66    }
67}
68
69impl ToBytes for Pointer {
70    fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
71        let mut ret = bytesrepr::unchecked_allocate_buffer(self);
72        self.write_bytes(&mut ret)?;
73        Ok(ret)
74    }
75
76    #[inline(always)]
77    fn serialized_length(&self) -> usize {
78        U8_SERIALIZED_LENGTH + Digest::LENGTH
79    }
80
81    #[inline]
82    fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
83        writer.push(self.tag());
84        writer.extend_from_slice(self.hash().as_ref());
85        Ok(())
86    }
87}
88
89impl FromBytes for Pointer {
90    fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
91        let (tag, rem) = u8::from_bytes(bytes)?;
92        match tag {
93            0 => {
94                let (hash, rem) = Digest::from_bytes(rem)?;
95                Ok((Pointer::LeafPointer(hash), rem))
96            }
97            1 => {
98                let (hash, rem) = Digest::from_bytes(rem)?;
99                Ok((Pointer::NodePointer(hash), rem))
100            }
101            _ => Err(bytesrepr::Error::Formatting),
102        }
103    }
104}