solana_sysvar/
recent_blockhashes.rs1#![allow(deprecated)]
20#![allow(clippy::arithmetic_side_effects)]
21#[cfg(feature = "bincode")]
22use crate::SysvarSerialize;
23#[cfg(feature = "serde")]
24use serde_derive::{Deserialize, Serialize};
25pub use solana_sdk_ids::sysvar::recent_blockhashes::{check_id, id, ID};
26use {
27 crate::Sysvar,
28 solana_fee_calculator::FeeCalculator,
29 solana_hash::Hash,
30 solana_sysvar_id::impl_sysvar_id,
31 std::{cmp::Ordering, collections::BinaryHeap, iter::FromIterator, ops::Deref},
32};
33
34#[deprecated(
35 since = "1.9.0",
36 note = "Please do not use, will no longer be available in the future"
37)]
38pub const MAX_ENTRIES: usize = 150;
39
40const LEN_PREFIX: usize = size_of::<u64>();
41const ENTRY_SERIALIZED_SIZE: usize = size_of::<Hash>() + size_of::<FeeCalculator>();
42
43pub const SIZE: usize = LEN_PREFIX + (MAX_ENTRIES * ENTRY_SERIALIZED_SIZE);
45const _: () = assert!(SIZE == 6_008);
46
47impl_sysvar_id!(RecentBlockhashes);
48
49#[deprecated(
50 since = "1.9.0",
51 note = "Please do not use, will no longer be available in the future"
52)]
53#[repr(C)]
54#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
55#[cfg_attr(feature = "wincode", derive(wincode::SchemaWrite, wincode::SchemaRead))]
56#[derive(Clone, Debug, Default, PartialEq, Eq)]
57pub struct Entry {
58 pub blockhash: Hash,
59 pub fee_calculator: FeeCalculator,
60}
61impl Entry {
62 pub fn new(blockhash: &Hash, lamports_per_signature: u64) -> Self {
63 Self {
64 blockhash: *blockhash,
65 fee_calculator: FeeCalculator::new(lamports_per_signature),
66 }
67 }
68}
69
70#[deprecated(
71 since = "1.9.0",
72 note = "Please do not use, will no longer be available in the future"
73)]
74#[derive(Clone, Debug)]
75pub struct IterItem<'a>(pub u64, pub &'a Hash, pub u64);
76
77impl Eq for IterItem<'_> {}
78
79impl PartialEq for IterItem<'_> {
80 fn eq(&self, other: &Self) -> bool {
81 self.0 == other.0
82 }
83}
84
85impl Ord for IterItem<'_> {
86 fn cmp(&self, other: &Self) -> Ordering {
87 self.0.cmp(&other.0)
88 }
89}
90
91impl PartialOrd for IterItem<'_> {
92 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
93 Some(self.cmp(other))
94 }
95}
96
97#[deprecated(
102 since = "1.9.0",
103 note = "Please do not use, will no longer be available in the future"
104)]
105#[repr(C)]
106#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
107#[cfg_attr(feature = "wincode", derive(wincode::SchemaWrite, wincode::SchemaRead))]
108#[derive(Clone, Debug, PartialEq, Eq)]
109pub struct RecentBlockhashes(Vec<Entry>);
110
111impl Default for RecentBlockhashes {
112 fn default() -> Self {
113 Self(Vec::with_capacity(MAX_ENTRIES))
114 }
115}
116
117impl<'a> FromIterator<IterItem<'a>> for RecentBlockhashes {
118 fn from_iter<I>(iter: I) -> Self
119 where
120 I: IntoIterator<Item = IterItem<'a>>,
121 {
122 let mut new = Self::default();
123 for i in iter {
124 new.0.push(Entry::new(i.1, i.2))
125 }
126 new
127 }
128}
129
130#[derive(Clone, Debug)]
139pub struct IntoIterSorted<T> {
140 inner: BinaryHeap<T>,
141}
142impl<T> IntoIterSorted<T> {
143 pub fn new(binary_heap: BinaryHeap<T>) -> Self {
144 Self { inner: binary_heap }
145 }
146}
147
148impl<T: Ord> Iterator for IntoIterSorted<T> {
149 type Item = T;
150
151 #[inline]
152 fn next(&mut self) -> Option<T> {
153 self.inner.pop()
154 }
155
156 #[inline]
157 fn size_hint(&self) -> (usize, Option<usize>) {
158 let exact = self.inner.len();
159 (exact, Some(exact))
160 }
161}
162
163impl Sysvar for RecentBlockhashes {}
164
165#[cfg(feature = "bincode")]
166impl SysvarSerialize for RecentBlockhashes {
167 fn size_of() -> usize {
168 SIZE
169 }
170}
171
172impl Deref for RecentBlockhashes {
173 type Target = Vec<Entry>;
174 fn deref(&self) -> &Self::Target {
175 &self.0
176 }
177}
178
179#[cfg(test)]
180mod tests {
181 use {super::*, solana_clock::MAX_PROCESSING_AGE};
182
183 #[test]
184 #[allow(clippy::assertions_on_constants)]
185 fn test_sysvar_can_hold_all_active_blockhashes() {
186 assert!(MAX_PROCESSING_AGE <= MAX_ENTRIES);
188 }
189
190 #[test]
191 fn test_size_of() {
192 let entry = Entry::new(&Hash::default(), 0);
193 assert_eq!(
194 bincode::serialized_size(&RecentBlockhashes(vec![entry; MAX_ENTRIES])).unwrap()
195 as usize,
196 RecentBlockhashes::size_of()
197 );
198 }
199}