solana_program/sysvar/
recent_blockhashes.rs1#![allow(deprecated)]
20#![allow(clippy::arithmetic_side_effects)]
21use {
22 crate::{fee_calculator::FeeCalculator, hash::Hash, sysvar::Sysvar},
23 solana_sysvar_id::declare_deprecated_sysvar_id,
24 std::{cmp::Ordering, collections::BinaryHeap, iter::FromIterator, ops::Deref},
25};
26
27#[deprecated(
28 since = "1.9.0",
29 note = "Please do not use, will no longer be available in the future"
30)]
31pub const MAX_ENTRIES: usize = 150;
32
33declare_deprecated_sysvar_id!(
34 "SysvarRecentB1ockHashes11111111111111111111",
35 RecentBlockhashes
36);
37
38#[deprecated(
39 since = "1.9.0",
40 note = "Please do not use, will no longer be available in the future"
41)]
42#[repr(C)]
43#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq)]
44pub struct Entry {
45 pub blockhash: Hash,
46 pub fee_calculator: FeeCalculator,
47}
48impl Entry {
49 pub fn new(blockhash: &Hash, lamports_per_signature: u64) -> Self {
50 Self {
51 blockhash: *blockhash,
52 fee_calculator: FeeCalculator::new(lamports_per_signature),
53 }
54 }
55}
56
57#[deprecated(
58 since = "1.9.0",
59 note = "Please do not use, will no longer be available in the future"
60)]
61#[derive(Clone, Debug)]
62pub struct IterItem<'a>(pub u64, pub &'a Hash, pub u64);
63
64impl<'a> Eq for IterItem<'a> {}
65
66impl<'a> PartialEq for IterItem<'a> {
67 fn eq(&self, other: &Self) -> bool {
68 self.0 == other.0
69 }
70}
71
72impl<'a> Ord for IterItem<'a> {
73 fn cmp(&self, other: &Self) -> Ordering {
74 self.0.cmp(&other.0)
75 }
76}
77
78impl<'a> PartialOrd for IterItem<'a> {
79 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
80 Some(self.cmp(other))
81 }
82}
83
84#[deprecated(
89 since = "1.9.0",
90 note = "Please do not use, will no longer be available in the future"
91)]
92#[repr(C)]
93#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
94pub struct RecentBlockhashes(Vec<Entry>);
95
96impl Default for RecentBlockhashes {
97 fn default() -> Self {
98 Self(Vec::with_capacity(MAX_ENTRIES))
99 }
100}
101
102impl<'a> FromIterator<IterItem<'a>> for RecentBlockhashes {
103 fn from_iter<I>(iter: I) -> Self
104 where
105 I: IntoIterator<Item = IterItem<'a>>,
106 {
107 let mut new = Self::default();
108 for i in iter {
109 new.0.push(Entry::new(i.1, i.2))
110 }
111 new
112 }
113}
114
115#[derive(Clone, Debug)]
124pub struct IntoIterSorted<T> {
125 inner: BinaryHeap<T>,
126}
127impl<T> IntoIterSorted<T> {
128 pub fn new(binary_heap: BinaryHeap<T>) -> Self {
129 Self { inner: binary_heap }
130 }
131}
132
133impl<T: Ord> Iterator for IntoIterSorted<T> {
134 type Item = T;
135
136 #[inline]
137 fn next(&mut self) -> Option<T> {
138 self.inner.pop()
139 }
140
141 #[inline]
142 fn size_hint(&self) -> (usize, Option<usize>) {
143 let exact = self.inner.len();
144 (exact, Some(exact))
145 }
146}
147
148impl Sysvar for RecentBlockhashes {
149 fn size_of() -> usize {
150 6008 }
153}
154
155impl Deref for RecentBlockhashes {
156 type Target = Vec<Entry>;
157 fn deref(&self) -> &Self::Target {
158 &self.0
159 }
160}
161
162#[cfg(test)]
163mod tests {
164 use {super::*, solana_clock::MAX_PROCESSING_AGE};
165
166 #[test]
167 #[allow(clippy::assertions_on_constants)]
168 fn test_sysvar_can_hold_all_active_blockhashes() {
169 assert!(MAX_PROCESSING_AGE <= MAX_ENTRIES);
171 }
172
173 #[test]
174 fn test_size_of() {
175 let entry = Entry::new(&Hash::default(), 0);
176 assert_eq!(
177 bincode::serialized_size(&RecentBlockhashes(vec![entry; MAX_ENTRIES])).unwrap()
178 as usize,
179 RecentBlockhashes::size_of()
180 );
181 }
182}