2021-07-27 16:34:21 -07:00
|
|
|
#![allow(deprecated)]
|
2021-03-11 23:25:52 -08:00
|
|
|
#![allow(clippy::integer_arithmetic)]
|
2021-12-03 09:00:31 -08:00
|
|
|
use {
|
|
|
|
crate::{
|
2022-07-22 14:05:59 -07:00
|
|
|
declare_deprecated_sysvar_id, fee_calculator::FeeCalculator, hash::Hash, sysvar::Sysvar,
|
2021-12-03 09:00:31 -08:00
|
|
|
},
|
|
|
|
std::{cmp::Ordering, collections::BinaryHeap, iter::FromIterator, ops::Deref},
|
2019-12-07 11:54:10 -08:00
|
|
|
};
|
2019-11-04 09:51:15 -08:00
|
|
|
|
2021-07-27 16:34:21 -07:00
|
|
|
#[deprecated(
|
2021-10-26 09:06:41 -07:00
|
|
|
since = "1.9.0",
|
2021-07-27 16:34:21 -07:00
|
|
|
note = "Please do not use, will no longer be available in the future"
|
|
|
|
)]
|
2020-03-05 11:03:21 -08:00
|
|
|
pub const MAX_ENTRIES: usize = 150;
|
2019-11-04 09:51:15 -08:00
|
|
|
|
2021-07-27 16:34:21 -07:00
|
|
|
declare_deprecated_sysvar_id!(
|
2019-11-04 12:31:24 -08:00
|
|
|
"SysvarRecentB1ockHashes11111111111111111111",
|
|
|
|
RecentBlockhashes
|
|
|
|
);
|
2019-11-04 09:51:15 -08:00
|
|
|
|
2021-07-27 16:34:21 -07:00
|
|
|
#[deprecated(
|
2021-10-26 09:06:41 -07:00
|
|
|
since = "1.9.0",
|
2021-07-27 16:34:21 -07:00
|
|
|
note = "Please do not use, will no longer be available in the future"
|
|
|
|
)]
|
2019-11-04 09:51:15 -08:00
|
|
|
#[repr(C)]
|
2022-05-22 18:00:42 -07:00
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq)]
|
2020-03-04 11:01:32 -08:00
|
|
|
pub struct Entry {
|
|
|
|
pub blockhash: Hash,
|
|
|
|
pub fee_calculator: FeeCalculator,
|
|
|
|
}
|
|
|
|
impl Entry {
|
2021-10-22 14:32:40 -07:00
|
|
|
pub fn new(blockhash: &Hash, lamports_per_signature: u64) -> Self {
|
2020-03-04 11:01:32 -08:00
|
|
|
Self {
|
|
|
|
blockhash: *blockhash,
|
2021-10-22 14:32:40 -07:00
|
|
|
fee_calculator: FeeCalculator::new(lamports_per_signature),
|
2020-03-04 11:01:32 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-27 16:34:21 -07:00
|
|
|
#[deprecated(
|
2021-10-26 09:06:41 -07:00
|
|
|
since = "1.9.0",
|
2021-07-27 16:34:21 -07:00
|
|
|
note = "Please do not use, will no longer be available in the future"
|
|
|
|
)]
|
2020-03-04 11:01:32 -08:00
|
|
|
#[derive(Clone, Debug)]
|
2021-10-22 14:32:40 -07:00
|
|
|
pub struct IterItem<'a>(pub u64, pub &'a Hash, pub u64);
|
2020-03-04 11:01:32 -08:00
|
|
|
|
|
|
|
impl<'a> Eq for IterItem<'a> {}
|
|
|
|
|
|
|
|
impl<'a> PartialEq for IterItem<'a> {
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
|
|
|
self.0 == other.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Ord for IterItem<'a> {
|
|
|
|
fn cmp(&self, other: &Self) -> Ordering {
|
|
|
|
self.0.cmp(&other.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> PartialOrd for IterItem<'a> {
|
|
|
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
|
|
Some(self.cmp(other))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-01 07:50:47 -07:00
|
|
|
/// Contains recent block hashes and fee calculators.
|
|
|
|
///
|
|
|
|
/// The entries are ordered by descending block height, so the first entry holds
|
|
|
|
/// the most recent block hash, and the last entry holds an old block hash.
|
2021-07-27 16:34:21 -07:00
|
|
|
#[deprecated(
|
2021-10-26 09:06:41 -07:00
|
|
|
since = "1.9.0",
|
2021-07-27 16:34:21 -07:00
|
|
|
note = "Please do not use, will no longer be available in the future"
|
|
|
|
)]
|
2020-03-04 11:01:32 -08:00
|
|
|
#[repr(C)]
|
2022-05-22 18:00:42 -07:00
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
|
2020-03-04 11:01:32 -08:00
|
|
|
pub struct RecentBlockhashes(Vec<Entry>);
|
2019-11-04 09:51:15 -08:00
|
|
|
|
|
|
|
impl Default for RecentBlockhashes {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self(Vec::with_capacity(MAX_ENTRIES))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-04 11:01:32 -08:00
|
|
|
impl<'a> FromIterator<IterItem<'a>> for RecentBlockhashes {
|
2019-11-04 09:51:15 -08:00
|
|
|
fn from_iter<I>(iter: I) -> Self
|
|
|
|
where
|
2020-03-04 11:01:32 -08:00
|
|
|
I: IntoIterator<Item = IterItem<'a>>,
|
2019-11-04 09:51:15 -08:00
|
|
|
{
|
|
|
|
let mut new = Self::default();
|
|
|
|
for i in iter {
|
2020-03-04 11:01:32 -08:00
|
|
|
new.0.push(Entry::new(i.1, i.2))
|
2019-11-04 09:51:15 -08:00
|
|
|
}
|
|
|
|
new
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-22 17:51:22 -08:00
|
|
|
// This is cherry-picked from HEAD of rust-lang's master (ref1) because it's
|
|
|
|
// a nightly-only experimental API.
|
|
|
|
// (binary_heap_into_iter_sorted [rustc issue #59278])
|
|
|
|
// Remove this and use the standard API once BinaryHeap::into_iter_sorted (ref2)
|
|
|
|
// is stabilized.
|
|
|
|
// ref1: https://github.com/rust-lang/rust/blob/2f688ac602d50129388bb2a5519942049096cbff/src/liballoc/collections/binary_heap.rs#L1149
|
|
|
|
// ref2: https://doc.rust-lang.org/std/collections/struct.BinaryHeap.html#into_iter_sorted.v
|
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct IntoIterSorted<T> {
|
|
|
|
inner: BinaryHeap<T>,
|
|
|
|
}
|
2020-10-28 22:01:07 -07:00
|
|
|
impl<T> IntoIterSorted<T> {
|
|
|
|
pub fn new(binary_heap: BinaryHeap<T>) -> Self {
|
|
|
|
Self { inner: binary_heap }
|
|
|
|
}
|
|
|
|
}
|
2020-01-22 17:51:22 -08:00
|
|
|
|
|
|
|
impl<T: Ord> Iterator for IntoIterSorted<T> {
|
|
|
|
type Item = T;
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<T> {
|
|
|
|
self.inner.pop()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
|
|
let exact = self.inner.len();
|
|
|
|
(exact, Some(exact))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-04 12:31:24 -08:00
|
|
|
impl Sysvar for RecentBlockhashes {
|
2019-12-23 12:23:45 -08:00
|
|
|
fn size_of() -> usize {
|
|
|
|
// hard-coded so that we don't have to construct an empty
|
2020-03-05 11:03:21 -08:00
|
|
|
6008 // golden, update if MAX_ENTRIES changes
|
2019-11-04 09:51:15 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Deref for RecentBlockhashes {
|
2020-03-04 11:01:32 -08:00
|
|
|
type Target = Vec<Entry>;
|
2019-11-04 09:51:15 -08:00
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2021-12-03 09:00:31 -08:00
|
|
|
use {super::*, crate::clock::MAX_PROCESSING_AGE};
|
2019-11-04 09:51:15 -08:00
|
|
|
|
2020-03-05 11:03:21 -08:00
|
|
|
#[test]
|
2020-05-15 09:35:43 -07:00
|
|
|
#[allow(clippy::assertions_on_constants)]
|
2020-03-05 11:03:21 -08:00
|
|
|
fn test_sysvar_can_hold_all_active_blockhashes() {
|
|
|
|
// Ensure we can still hold all of the active entries in `BlockhashQueue`
|
|
|
|
assert!(MAX_PROCESSING_AGE <= MAX_ENTRIES);
|
|
|
|
}
|
|
|
|
|
2019-12-23 12:23:45 -08:00
|
|
|
#[test]
|
|
|
|
fn test_size_of() {
|
2021-10-22 14:32:40 -07:00
|
|
|
let entry = Entry::new(&Hash::default(), 0);
|
2019-12-23 12:23:45 -08:00
|
|
|
assert_eq!(
|
2020-03-04 11:01:32 -08:00
|
|
|
bincode::serialized_size(&RecentBlockhashes(vec![entry; MAX_ENTRIES])).unwrap()
|
|
|
|
as usize,
|
2019-12-23 12:23:45 -08:00
|
|
|
RecentBlockhashes::size_of()
|
|
|
|
);
|
|
|
|
}
|
2019-11-04 09:51:15 -08:00
|
|
|
}
|