diff --git a/core/src/consensus.rs b/core/src/consensus.rs index 7b00538eb4..1434296e56 100644 --- a/core/src/consensus.rs +++ b/core/src/consensus.rs @@ -13,9 +13,7 @@ use solana_sdk::{ }; use solana_vote_program::{ vote_instruction, - vote_state::{ - BlockTimestamp, Lockout, Vote, VoteState, MAX_LOCKOUT_HISTORY, TIMESTAMP_SLOT_INTERVAL, - }, + vote_state::{BlockTimestamp, Lockout, Vote, VoteState, MAX_LOCKOUT_HISTORY}, }; use std::{ collections::{BTreeMap, HashMap, HashSet}, @@ -345,6 +343,20 @@ impl Tower { last_vote } + fn maybe_timestamp(&mut self, current_slot: Slot) -> Option { + if current_slot > self.last_timestamp.slot { + let timestamp = Utc::now().timestamp(); + if timestamp >= self.last_timestamp.timestamp { + self.last_timestamp = BlockTimestamp { + slot: current_slot, + timestamp, + }; + return Some(timestamp); + } + } + None + } + pub fn root(&self) -> Option { self.lockouts.root_slot } @@ -650,21 +662,6 @@ impl Tower { ); } } - - fn maybe_timestamp(&mut self, current_slot: Slot) -> Option { - if self.last_timestamp.slot == 0 - || self.last_timestamp.slot < (current_slot - (current_slot % TIMESTAMP_SLOT_INTERVAL)) - { - let timestamp = Utc::now().timestamp(); - self.last_timestamp = BlockTimestamp { - slot: current_slot, - timestamp, - }; - Some(timestamp) - } else { - None - } - } } #[cfg(test)] @@ -691,12 +688,7 @@ pub mod test { vote_state::{Vote, VoteStateVersions, MAX_LOCKOUT_HISTORY}, vote_transaction, }; - use std::{ - collections::HashMap, - rc::Rc, - sync::RwLock, - {thread::sleep, time::Duration}, - }; + use std::{collections::HashMap, rc::Rc, sync::RwLock}; use trees::{tr, Tree, TreeWalk}; pub(crate) struct VoteSimulator { @@ -1829,17 +1821,15 @@ pub mod test { #[test] fn test_maybe_timestamp() { let mut tower = Tower::default(); - assert!(tower.maybe_timestamp(TIMESTAMP_SLOT_INTERVAL).is_some()); - let BlockTimestamp { slot, timestamp } = tower.last_timestamp; + assert!(tower.maybe_timestamp(0).is_none()); + assert!(tower.maybe_timestamp(1).is_some()); + assert!(tower.maybe_timestamp(0).is_none()); // Refuse to timestamp an older slot + assert!(tower.maybe_timestamp(1).is_none()); // Refuse to timestamp the same slot twice - assert_eq!(tower.maybe_timestamp(1), None); - assert_eq!(tower.maybe_timestamp(slot), None); - assert_eq!(tower.maybe_timestamp(slot + 1), None); + tower.last_timestamp.timestamp -= 1; // Move last_timestamp into the past + assert!(tower.maybe_timestamp(2).is_some()); // slot 2 gets a timestamp - sleep(Duration::from_secs(1)); - assert!(tower - .maybe_timestamp(slot + TIMESTAMP_SLOT_INTERVAL + 1) - .is_some()); - assert!(tower.last_timestamp.timestamp > timestamp); + tower.last_timestamp.timestamp += 1_000_000; // Move last_timestamp well into the future + assert!(tower.maybe_timestamp(3).is_none()); // slot 3 gets no timestamp } } diff --git a/core/src/rpc_error.rs b/core/src/rpc_error.rs index f9c0f15c81..c634971b2b 100644 --- a/core/src/rpc_error.rs +++ b/core/src/rpc_error.rs @@ -46,7 +46,7 @@ impl From for Error { }, RpcCustomError::BlockNotAvailable { slot } => Self { code: ErrorCode::ServerError(JSON_RPC_SERVER_ERROR_4), - message: format!("Block not available for slot {}", slot,), + message: format!("Block not available for slot {}", slot), data: None, }, } diff --git a/ledger/src/blockstore.rs b/ledger/src/blockstore.rs index 89ac5decdd..3b46305129 100644 --- a/ledger/src/blockstore.rs +++ b/ledger/src/blockstore.rs @@ -41,7 +41,7 @@ use solana_transaction_status::{ EncodedTransaction, Rewards, TransactionStatusMeta, TransactionWithStatusMeta, UiTransactionEncoding, UiTransactionStatusMeta, }; -use solana_vote_program::{vote_instruction::VoteInstruction, vote_state::TIMESTAMP_SLOT_INTERVAL}; +use solana_vote_program::vote_instruction::VoteInstruction; use std::{ cell::RefCell, cmp, @@ -78,6 +78,7 @@ thread_local!(static PAR_THREAD_POOL_ALL_CPUS: RefCell = RefCell::ne pub const MAX_COMPLETED_SLOTS_IN_CHANNEL: usize = 100_000; pub const MAX_TURBINE_PROPAGATION_IN_MS: u64 = 100; pub const MAX_TURBINE_DELAY_IN_TICKS: u64 = MAX_TURBINE_PROPAGATION_IN_MS / MS_PER_TICK; +const TIMESTAMP_SLOT_INTERVAL: u64 = 4500; const TIMESTAMP_SLOT_RANGE: usize = 16; // An upper bound on maximum number of data shreds we can handle in a slot diff --git a/programs/vote/src/vote_state/mod.rs b/programs/vote/src/vote_state/mod.rs index 2b783d2dec..eeb9fa8416 100644 --- a/programs/vote/src/vote_state/mod.rs +++ b/programs/vote/src/vote_state/mod.rs @@ -32,10 +32,6 @@ pub const INITIAL_LOCKOUT: usize = 2; // smaller numbers makes pub const MAX_EPOCH_CREDITS_HISTORY: usize = 64; -// Frequency of timestamp Votes. In v0.22.0, this is approximately 30min with cluster clock -// defaults, intended to limit block time drift to < 1hr -pub const TIMESTAMP_SLOT_INTERVAL: u64 = 4500; - #[frozen_abi(digest = "69hYtmmcuqPbhpc64ZaNJDidaUcg66CW6wzPFiuYZ3To")] #[derive(Serialize, Default, Deserialize, Debug, PartialEq, Eq, Clone, AbiExample)] pub struct Vote {