Use bank timestamp to populate Blockstore::blocktime_cf when correction active (#13158)
This commit is contained in:
parent
4bfda3e766
commit
39686ef098
|
@ -1,7 +1,7 @@
|
||||||
use crossbeam_channel::{Receiver, RecvTimeoutError, Sender};
|
use crossbeam_channel::{Receiver, RecvTimeoutError, Sender};
|
||||||
use solana_ledger::blockstore::Blockstore;
|
use solana_ledger::blockstore::Blockstore;
|
||||||
use solana_measure::measure::Measure;
|
use solana_measure::measure::Measure;
|
||||||
use solana_runtime::bank::Bank;
|
use solana_runtime::{bank::Bank, feature_set};
|
||||||
use solana_sdk::timing::slot_duration_from_slots_per_year;
|
use solana_sdk::timing::slot_duration_from_slots_per_year;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
|
@ -60,13 +60,24 @@ impl CacheBlockTimeService {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cache_block_time(bank: Arc<Bank>, blockstore: &Arc<Blockstore>) {
|
fn cache_block_time(bank: Arc<Bank>, blockstore: &Arc<Blockstore>) {
|
||||||
let slot_duration = slot_duration_from_slots_per_year(bank.slots_per_year());
|
if bank
|
||||||
let epoch = bank.epoch_schedule().get_epoch(bank.slot());
|
.feature_set
|
||||||
let stakes = HashMap::new();
|
.is_active(&feature_set::timestamp_correction::id())
|
||||||
let stakes = bank.epoch_vote_accounts(epoch).unwrap_or(&stakes);
|
{
|
||||||
|
if let Err(e) = blockstore.cache_block_time(bank.slot(), bank.clock().unix_timestamp) {
|
||||||
|
error!("cache_block_time failed: slot {:?} {:?}", bank.slot(), e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let slot_duration = slot_duration_from_slots_per_year(bank.slots_per_year());
|
||||||
|
let epoch = bank.epoch_schedule().get_epoch(bank.slot());
|
||||||
|
let stakes = HashMap::new();
|
||||||
|
let stakes = bank.epoch_vote_accounts(epoch).unwrap_or(&stakes);
|
||||||
|
|
||||||
if let Err(e) = blockstore.cache_block_time(bank.slot(), slot_duration, stakes) {
|
if let Err(e) =
|
||||||
error!("cache_block_time failed: slot {:?} {:?}", bank.slot(), e);
|
blockstore.cache_block_time_from_slot_entries(bank.slot(), slot_duration, stakes)
|
||||||
|
{
|
||||||
|
error!("cache_block_time failed: slot {:?} {:?}", bank.slot(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2689,10 +2689,8 @@ pub mod tests {
|
||||||
use jsonrpc_core_client::transports::local;
|
use jsonrpc_core_client::transports::local;
|
||||||
use solana_client::rpc_filter::{Memcmp, MemcmpEncodedBytes};
|
use solana_client::rpc_filter::{Memcmp, MemcmpEncodedBytes};
|
||||||
use solana_ledger::{
|
use solana_ledger::{
|
||||||
blockstore::entries_to_test_shreds,
|
|
||||||
blockstore_meta::PerfSample,
|
blockstore_meta::PerfSample,
|
||||||
blockstore_processor::fill_blockstore_slot_with_ticks,
|
blockstore_processor::fill_blockstore_slot_with_ticks,
|
||||||
entry::next_entry_mut,
|
|
||||||
genesis_utils::{create_genesis_config, GenesisConfigInfo},
|
genesis_utils::{create_genesis_config, GenesisConfigInfo},
|
||||||
};
|
};
|
||||||
use solana_runtime::commitment::BlockCommitment;
|
use solana_runtime::commitment::BlockCommitment;
|
||||||
|
@ -2720,7 +2718,7 @@ pub mod tests {
|
||||||
state::AccountState as TokenAccountState,
|
state::AccountState as TokenAccountState,
|
||||||
state::Mint,
|
state::Mint,
|
||||||
};
|
};
|
||||||
use std::{collections::HashMap, time::Duration};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
const TEST_MINT_LAMPORTS: u64 = 1_000_000;
|
const TEST_MINT_LAMPORTS: u64 = 1_000_000;
|
||||||
const TEST_SLOTS_PER_EPOCH: u64 = DELINQUENT_VALIDATOR_SLOT_DISTANCE + 1;
|
const TEST_SLOTS_PER_EPOCH: u64 = DELINQUENT_VALIDATOR_SLOT_DISTANCE + 1;
|
||||||
|
@ -2739,13 +2737,12 @@ pub mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_rpc_handler_with_tx(pubkey: &Pubkey) -> RpcHandler {
|
fn start_rpc_handler_with_tx(pubkey: &Pubkey) -> RpcHandler {
|
||||||
start_rpc_handler_with_tx_and_blockstore(pubkey, vec![], 0)
|
start_rpc_handler_with_tx_and_blockstore(pubkey, vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_rpc_handler_with_tx_and_blockstore(
|
fn start_rpc_handler_with_tx_and_blockstore(
|
||||||
pubkey: &Pubkey,
|
pubkey: &Pubkey,
|
||||||
blockstore_roots: Vec<Slot>,
|
blockstore_roots: Vec<Slot>,
|
||||||
default_timestamp: i64,
|
|
||||||
) -> RpcHandler {
|
) -> RpcHandler {
|
||||||
let (bank_forks, alice, leader_vote_keypair) = new_bank_forks();
|
let (bank_forks, alice, leader_vote_keypair) = new_bank_forks();
|
||||||
let bank = bank_forks.read().unwrap().working_bank();
|
let bank = bank_forks.read().unwrap().working_bank();
|
||||||
|
@ -2777,29 +2774,6 @@ pub mod tests {
|
||||||
CommitmentSlots::new_from_slot(bank.slot()),
|
CommitmentSlots::new_from_slot(bank.slot()),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
// Add timestamp vote to blockstore
|
|
||||||
let vote = Vote {
|
|
||||||
slots: vec![1],
|
|
||||||
hash: Hash::default(),
|
|
||||||
timestamp: Some(default_timestamp),
|
|
||||||
};
|
|
||||||
let vote_ix = vote_instruction::vote(
|
|
||||||
&leader_vote_keypair.pubkey(),
|
|
||||||
&leader_vote_keypair.pubkey(),
|
|
||||||
vote,
|
|
||||||
);
|
|
||||||
let vote_msg = Message::new(&[vote_ix], Some(&leader_vote_keypair.pubkey()));
|
|
||||||
let vote_tx = Transaction::new(&[&*leader_vote_keypair], vote_msg, Hash::default());
|
|
||||||
let shreds = entries_to_test_shreds(
|
|
||||||
vec![next_entry_mut(&mut Hash::default(), 0, vec![vote_tx])],
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
true,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
blockstore.insert_shreds(shreds, None, false).unwrap();
|
|
||||||
blockstore.set_roots(&[1]).unwrap();
|
|
||||||
|
|
||||||
let mut roots = blockstore_roots;
|
let mut roots = blockstore_roots;
|
||||||
if !roots.is_empty() {
|
if !roots.is_empty() {
|
||||||
roots.retain(|&x| x > 0);
|
roots.retain(|&x| x > 0);
|
||||||
|
@ -2823,9 +2797,14 @@ pub mod tests {
|
||||||
bank_forks.write().unwrap().set_root(*root, &None, Some(0));
|
bank_forks.write().unwrap().set_root(*root, &None, Some(0));
|
||||||
let mut stakes = HashMap::new();
|
let mut stakes = HashMap::new();
|
||||||
stakes.insert(leader_vote_keypair.pubkey(), (1, Account::default()));
|
stakes.insert(leader_vote_keypair.pubkey(), (1, Account::default()));
|
||||||
blockstore
|
let block_time = bank_forks
|
||||||
.cache_block_time(*root, Duration::from_millis(400), &stakes)
|
.read()
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.get(*root)
|
||||||
|
.unwrap()
|
||||||
|
.clock()
|
||||||
|
.unix_timestamp;
|
||||||
|
blockstore.cache_block_time(*root, block_time).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4772,7 +4751,7 @@ pub mod tests {
|
||||||
meta,
|
meta,
|
||||||
block_commitment_cache,
|
block_commitment_cache,
|
||||||
..
|
..
|
||||||
} = start_rpc_handler_with_tx_and_blockstore(&bob_pubkey, roots.clone(), 0);
|
} = start_rpc_handler_with_tx_and_blockstore(&bob_pubkey, roots.clone());
|
||||||
block_commitment_cache
|
block_commitment_cache
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -4849,7 +4828,7 @@ pub mod tests {
|
||||||
meta,
|
meta,
|
||||||
block_commitment_cache,
|
block_commitment_cache,
|
||||||
..
|
..
|
||||||
} = start_rpc_handler_with_tx_and_blockstore(&bob_pubkey, roots, 0);
|
} = start_rpc_handler_with_tx_and_blockstore(&bob_pubkey, roots);
|
||||||
block_commitment_cache
|
block_commitment_cache
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -4906,18 +4885,20 @@ pub mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_block_time() {
|
fn test_get_block_time() {
|
||||||
let bob_pubkey = solana_sdk::pubkey::new_rand();
|
let bob_pubkey = solana_sdk::pubkey::new_rand();
|
||||||
let base_timestamp = 1_576_183_541;
|
|
||||||
let RpcHandler {
|
let RpcHandler {
|
||||||
io,
|
io,
|
||||||
meta,
|
meta,
|
||||||
bank,
|
bank,
|
||||||
block_commitment_cache,
|
block_commitment_cache,
|
||||||
|
bank_forks,
|
||||||
..
|
..
|
||||||
} = start_rpc_handler_with_tx_and_blockstore(
|
} = start_rpc_handler_with_tx_and_blockstore(&bob_pubkey, vec![1, 2, 3, 4, 5, 6, 7]);
|
||||||
&bob_pubkey,
|
let base_timestamp = bank_forks
|
||||||
vec![1, 2, 3, 4, 5, 6, 7],
|
.read()
|
||||||
base_timestamp,
|
.unwrap()
|
||||||
);
|
.get(0)
|
||||||
|
.unwrap()
|
||||||
|
.unix_timestamp_from_genesis();
|
||||||
block_commitment_cache
|
block_commitment_cache
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
@ -1609,7 +1609,15 @@ impl Blockstore {
|
||||||
timestamp_slots
|
timestamp_slots
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cache_block_time(
|
pub fn cache_block_time(&self, slot: Slot, timestamp: UnixTimestamp) -> Result<()> {
|
||||||
|
if !self.is_root(slot) {
|
||||||
|
return Err(BlockstoreError::SlotNotRooted);
|
||||||
|
}
|
||||||
|
self.blocktime_cf.put(slot, ×tamp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEPRECATED as of feature_set::timestamp_correction
|
||||||
|
pub fn cache_block_time_from_slot_entries(
|
||||||
&self,
|
&self,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
slot_duration: Duration,
|
slot_duration: Duration,
|
||||||
|
@ -1648,7 +1656,7 @@ impl Blockstore {
|
||||||
i64
|
i64
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
self.blocktime_cf.put(slot, &stake_weighted_timestamp)
|
self.cache_block_time(slot, stake_weighted_timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_first_available_block(&self) -> Result<Slot> {
|
pub fn get_first_available_block(&self) -> Result<Slot> {
|
||||||
|
@ -5794,7 +5802,7 @@ pub mod tests {
|
||||||
let slot_duration = Duration::from_millis(400);
|
let slot_duration = Duration::from_millis(400);
|
||||||
for slot in &[1, 2, 3, 8] {
|
for slot in &[1, 2, 3, 8] {
|
||||||
assert!(blockstore
|
assert!(blockstore
|
||||||
.cache_block_time(*slot, slot_duration, &stakes)
|
.cache_block_time_from_slot_entries(*slot, slot_duration, &stakes)
|
||||||
.is_err());
|
.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5804,7 +5812,7 @@ pub mod tests {
|
||||||
}
|
}
|
||||||
for slot in &[1, 2, 3, 8] {
|
for slot in &[1, 2, 3, 8] {
|
||||||
blockstore
|
blockstore
|
||||||
.cache_block_time(*slot, slot_duration, &stakes)
|
.cache_block_time_from_slot_entries(*slot, slot_duration, &stakes)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
let block_time_slot_3 = blockstore.get_block_time(3);
|
let block_time_slot_3 = blockstore.get_block_time(3);
|
||||||
|
@ -5864,7 +5872,7 @@ pub mod tests {
|
||||||
let slot_duration = Duration::from_millis(400);
|
let slot_duration = Duration::from_millis(400);
|
||||||
for slot in &[1, 2, 3, 8] {
|
for slot in &[1, 2, 3, 8] {
|
||||||
assert!(blockstore
|
assert!(blockstore
|
||||||
.cache_block_time(*slot, slot_duration, &stakes)
|
.cache_block_time_from_slot_entries(*slot, slot_duration, &stakes)
|
||||||
.is_err());
|
.is_err());
|
||||||
assert_eq!(blockstore.get_block_time(*slot).unwrap(), None);
|
assert_eq!(blockstore.get_block_time(*slot).unwrap(), None);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue