solana_sdk/
recent_blockhashes_account.rs1#[allow(deprecated)]
2use solana_program::sysvar::recent_blockhashes::{
3 IntoIterSorted, IterItem, RecentBlockhashes, MAX_ENTRIES,
4};
5use {
6 crate::{
7 account::{
8 create_account_shared_data_with_fields, to_account, AccountSharedData,
9 InheritableAccountFields, DUMMY_INHERITABLE_ACCOUNT_FIELDS,
10 },
11 clock::INITIAL_RENT_EPOCH,
12 },
13 std::{collections::BinaryHeap, iter::FromIterator},
14};
15
16#[deprecated(
17 since = "1.9.0",
18 note = "Please do not use, will no longer be available in the future"
19)]
20#[allow(deprecated)]
21pub fn update_account<'a, I>(
22 account: &mut AccountSharedData,
23 recent_blockhash_iter: I,
24) -> Option<()>
25where
26 I: IntoIterator<Item = IterItem<'a>>,
27{
28 let sorted = BinaryHeap::from_iter(recent_blockhash_iter);
29 #[allow(deprecated)]
30 let sorted_iter = IntoIterSorted::new(sorted);
31 #[allow(deprecated)]
32 let recent_blockhash_iter = sorted_iter.take(MAX_ENTRIES);
33 #[allow(deprecated)]
34 let recent_blockhashes: RecentBlockhashes = recent_blockhash_iter.collect();
35 to_account(&recent_blockhashes, account)
36}
37
38#[deprecated(
39 since = "1.5.17",
40 note = "Please use `create_account_with_data_for_test` instead"
41)]
42#[allow(deprecated)]
43pub fn create_account_with_data<'a, I>(lamports: u64, recent_blockhash_iter: I) -> AccountSharedData
44where
45 I: IntoIterator<Item = IterItem<'a>>,
46{
47 #[allow(deprecated)]
48 create_account_with_data_and_fields(recent_blockhash_iter, (lamports, INITIAL_RENT_EPOCH))
49}
50
51#[deprecated(
52 since = "1.9.0",
53 note = "Please do not use, will no longer be available in the future"
54)]
55#[allow(deprecated)]
56pub fn create_account_with_data_and_fields<'a, I>(
57 recent_blockhash_iter: I,
58 fields: InheritableAccountFields,
59) -> AccountSharedData
60where
61 I: IntoIterator<Item = IterItem<'a>>,
62{
63 let mut account = create_account_shared_data_with_fields::<RecentBlockhashes>(
64 &RecentBlockhashes::default(),
65 fields,
66 );
67 update_account(&mut account, recent_blockhash_iter).unwrap();
68 account
69}
70
71#[deprecated(
72 since = "1.9.0",
73 note = "Please do not use, will no longer be available in the future"
74)]
75#[allow(deprecated)]
76pub fn create_account_with_data_for_test<'a, I>(recent_blockhash_iter: I) -> AccountSharedData
77where
78 I: IntoIterator<Item = IterItem<'a>>,
79{
80 create_account_with_data_and_fields(recent_blockhash_iter, DUMMY_INHERITABLE_ACCOUNT_FIELDS)
81}
82
83#[cfg(test)]
84mod tests {
85 #![allow(deprecated)]
86 use {
87 super::*,
88 crate::account::from_account,
89 rand::{seq::SliceRandom, thread_rng},
90 solana_program::{
91 hash::{Hash, HASH_BYTES},
92 sysvar::recent_blockhashes::Entry,
93 },
94 };
95
96 #[test]
97 fn test_create_account_empty() {
98 let account = create_account_with_data_for_test(vec![].into_iter());
99 let recent_blockhashes = from_account::<RecentBlockhashes, _>(&account).unwrap();
100 assert_eq!(recent_blockhashes, RecentBlockhashes::default());
101 }
102
103 #[test]
104 fn test_create_account_full() {
105 let def_hash = Hash::default();
106 let def_lamports_per_signature = 0;
107 let account = create_account_with_data_for_test(
108 vec![IterItem(0u64, &def_hash, def_lamports_per_signature); MAX_ENTRIES].into_iter(),
109 );
110 let recent_blockhashes = from_account::<RecentBlockhashes, _>(&account).unwrap();
111 assert_eq!(recent_blockhashes.len(), MAX_ENTRIES);
112 }
113
114 #[test]
115 fn test_create_account_truncate() {
116 let def_hash = Hash::default();
117 let def_lamports_per_signature = 0;
118 let account = create_account_with_data_for_test(
119 vec![IterItem(0u64, &def_hash, def_lamports_per_signature); MAX_ENTRIES + 1]
120 .into_iter(),
121 );
122 let recent_blockhashes = from_account::<RecentBlockhashes, _>(&account).unwrap();
123 assert_eq!(recent_blockhashes.len(), MAX_ENTRIES);
124 }
125
126 #[test]
127 fn test_create_account_unsorted() {
128 let def_lamports_per_signature = 0;
129 let mut unsorted_blocks: Vec<_> = (0..MAX_ENTRIES)
130 .map(|i| {
131 (i as u64, {
132 let mut h = [0; HASH_BYTES];
134 h[HASH_BYTES - 1] = i as u8;
135 Hash::new(&h)
136 })
137 })
138 .collect();
139 unsorted_blocks.shuffle(&mut thread_rng());
140
141 let account = create_account_with_data_for_test(
142 unsorted_blocks
143 .iter()
144 .map(|(i, hash)| IterItem(*i, hash, def_lamports_per_signature)),
145 );
146 let recent_blockhashes = from_account::<RecentBlockhashes, _>(&account).unwrap();
147
148 let mut unsorted_recent_blockhashes: Vec<_> = unsorted_blocks
149 .iter()
150 .map(|(i, hash)| IterItem(*i, hash, def_lamports_per_signature))
151 .collect();
152 unsorted_recent_blockhashes.sort();
153 unsorted_recent_blockhashes.reverse();
154 let expected_recent_blockhashes: Vec<_> = (unsorted_recent_blockhashes
155 .into_iter()
156 .map(|IterItem(_, b, f)| Entry::new(b, f)))
157 .collect();
158
159 assert_eq!(*recent_blockhashes, expected_recent_blockhashes);
160 }
161}