1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use crate::{declare_sysvar_id, hash::Hash, sysvar::Sysvar};

use serde::{
    de::{SeqAccess, Visitor},
    ser::SerializeTuple,
    Deserializer, Serializer,
};
use std::fmt;
use std::marker::PhantomData;

pub const MAX_ENTRIES: usize = 256;

declare_sysvar_id!(
    "SysvarRecentEVMB1ockHashes11111111111111111",
    RecentBlockhashes
);

#[repr(C)]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct RecentBlockhashes(#[serde(with = "RecentBlockhashes")] pub [Hash; MAX_ENTRIES]);

impl Default for RecentBlockhashes {
    fn default() -> Self {
        Self([Hash::new_from_array([0; 32]); MAX_ENTRIES])
    }
}

impl RecentBlockhashes {
    fn deserialize<'de, D>(deserializer: D) -> Result<[Hash; MAX_ENTRIES], D::Error>
    where
        D: Deserializer<'de>,
    {
        struct ArrayVisitor<T> {
            element: PhantomData<T>,
        }
        use serde::de::Deserialize;
        impl<'de, T> Visitor<'de> for ArrayVisitor<T>
        where
            T: Default + Copy + Deserialize<'de>,
        {
            type Value = [T; MAX_ENTRIES];

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str(concat!("an array of length ", 256))
            }

            fn visit_seq<A>(self, mut seq: A) -> Result<[T; MAX_ENTRIES], A::Error>
            where
                A: SeqAccess<'de>,
            {
                let mut arr = [T::default(); MAX_ENTRIES];
                for (i, item) in arr.iter_mut().enumerate() {
                    *item = seq
                        .next_element()?
                        .ok_or_else(|| serde::de::Error::invalid_length(i, &self))?;
                }
                Ok(arr)
            }
        }

        let visitor = ArrayVisitor {
            element: PhantomData,
        };
        deserializer.deserialize_tuple(MAX_ENTRIES, visitor)
    }

    fn serialize<S>(data: &[Hash; MAX_ENTRIES], serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut seq = serializer.serialize_tuple(data.len())?;
        for elem in &data[..] {
            seq.serialize_element(elem)?;
        }
        seq.end()
    }
}

impl Sysvar for RecentBlockhashes {
    fn size_of() -> usize {
        MAX_ENTRIES * 32
    }
}

#[cfg(test)]
mod test {
    use super::*;
    #[test]
    fn test_seriazize_evm_blockhashes() {
        let blockhashes = RecentBlockhashes::default();
        assert_eq!(
            bincode::serialize(&blockhashes).unwrap().len(),
            MAX_ENTRIES * 32
        )
    }
}