Rpc: Filter blockstore data by cluster-confirmed root (#9873) (#9880)

automerge
This commit is contained in:
mergify[bot]
2020-05-04 22:37:00 -07:00
committed by GitHub
parent 2acf4d874d
commit 52009788ee

View File

@ -31,7 +31,7 @@ use solana_transaction_status::{
}; };
use solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY}; use solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY};
use std::{ use std::{
cmp::max, cmp::{max, min},
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
net::{SocketAddr, UdpSocket}, net::{SocketAddr, UdpSocket},
str::FromStr, str::FromStr,
@ -406,7 +406,14 @@ impl JsonRpcRequestProcessor {
slot: Slot, slot: Slot,
encoding: Option<TransactionEncoding>, encoding: Option<TransactionEncoding>,
) -> Result<Option<ConfirmedBlock>> { ) -> Result<Option<ConfirmedBlock>> {
if self.config.enable_rpc_transaction_history { if self.config.enable_rpc_transaction_history
&& slot
<= self
.block_commitment_cache
.read()
.unwrap()
.largest_confirmed_root()
{
Ok(self.blockstore.get_confirmed_block(slot, encoding).ok()) Ok(self.blockstore.get_confirmed_block(slot, encoding).ok())
} else { } else {
Ok(None) Ok(None)
@ -418,11 +425,13 @@ impl JsonRpcRequestProcessor {
start_slot: Slot, start_slot: Slot,
end_slot: Option<Slot>, end_slot: Option<Slot>,
) -> Result<Vec<Slot>> { ) -> Result<Vec<Slot>> {
let end_slot = if let Some(end_slot) = end_slot { let end_slot = min(
end_slot end_slot.unwrap_or(std::u64::MAX),
} else { self.block_commitment_cache
self.bank(None)?.slot() .read()
}; .unwrap()
.largest_confirmed_root(),
);
if end_slot < start_slot { if end_slot < start_slot {
return Ok(vec![]); return Ok(vec![]);
} }
@ -435,22 +444,32 @@ impl JsonRpcRequestProcessor {
} }
pub fn get_block_time(&self, slot: Slot) -> Result<Option<UnixTimestamp>> { pub fn get_block_time(&self, slot: Slot) -> Result<Option<UnixTimestamp>> {
// This calculation currently assumes that bank.slots_per_year will remain unchanged after if slot
// genesis (ie. that this bank's slot_per_year will be applicable to any rooted slot being <= self
// queried). If these values will be variable in the future, those timing parameters will .block_commitment_cache
// need to be stored persistently, and the slot_duration calculation will likely need to be .read()
// moved upstream into blockstore. Also, an explicit commitment level will need to be set. .unwrap()
let bank = self.bank(None)?; .largest_confirmed_root()
let slot_duration = slot_duration_from_slots_per_year(bank.slots_per_year()); {
let epoch = bank.epoch_schedule().get_epoch(slot); // This calculation currently assumes that bank.slots_per_year will remain unchanged after
let stakes = HashMap::new(); // genesis (ie. that this bank's slot_per_year will be applicable to any rooted slot being
let stakes = bank.epoch_vote_accounts(epoch).unwrap_or(&stakes); // queried). If these values will be variable in the future, those timing parameters will
// need to be stored persistently, and the slot_duration calculation will likely need to be
// moved upstream into blockstore. Also, an explicit commitment level will need to be set.
let bank = self.bank(None)?;
let slot_duration = slot_duration_from_slots_per_year(bank.slots_per_year());
let epoch = bank.epoch_schedule().get_epoch(slot);
let stakes = HashMap::new();
let stakes = bank.epoch_vote_accounts(epoch).unwrap_or(&stakes);
Ok(self Ok(self
.blockstore .blockstore
.get_block_time(slot, slot_duration, stakes) .get_block_time(slot, slot_duration, stakes)
.ok() .ok()
.unwrap_or(None)) .unwrap_or(None))
} else {
Ok(None)
}
} }
pub fn get_signature_confirmation_status( pub fn get_signature_confirmation_status(
@ -504,6 +523,13 @@ impl JsonRpcRequestProcessor {
self.blockstore self.blockstore
.get_transaction_status(signature) .get_transaction_status(signature)
.map_err(|_| Error::internal_error())? .map_err(|_| Error::internal_error())?
.filter(|(slot, _status_meta)| {
slot <= &self
.block_commitment_cache
.read()
.unwrap()
.largest_confirmed_root()
})
.map(|(slot, status_meta)| { .map(|(slot, status_meta)| {
let err = status_meta.status.clone().err(); let err = status_meta.status.clone().err();
TransactionStatus { TransactionStatus {
@ -561,7 +587,15 @@ impl JsonRpcRequestProcessor {
Ok(self Ok(self
.blockstore .blockstore
.get_confirmed_transaction(signature, encoding) .get_confirmed_transaction(signature, encoding)
.unwrap_or(None)) .unwrap_or(None)
.filter(|confirmed_transaction| {
confirmed_transaction.slot
<= self
.block_commitment_cache
.read()
.unwrap()
.largest_confirmed_root()
}))
} else { } else {
Ok(None) Ok(None)
} }
@ -574,6 +608,13 @@ impl JsonRpcRequestProcessor {
end_slot: Slot, end_slot: Slot,
) -> Result<Vec<Signature>> { ) -> Result<Vec<Signature>> {
if self.config.enable_rpc_transaction_history { if self.config.enable_rpc_transaction_history {
let end_slot = min(
end_slot,
self.block_commitment_cache
.read()
.unwrap()
.largest_confirmed_root(),
);
Ok(self Ok(self
.blockstore .blockstore
.get_confirmed_signatures_for_address(pubkey, start_slot, end_slot) .get_confirmed_signatures_for_address(pubkey, start_slot, end_slot)
@ -2819,11 +2860,21 @@ pub mod tests {
fn test_get_block_time() { fn test_get_block_time() {
let bob_pubkey = Pubkey::new_rand(); let bob_pubkey = Pubkey::new_rand();
let base_timestamp = 1576183541; let base_timestamp = 1576183541;
let RpcHandler { io, meta, bank, .. } = start_rpc_handler_with_tx_and_blockstore( let RpcHandler {
io,
meta,
bank,
block_commitment_cache,
..
} = start_rpc_handler_with_tx_and_blockstore(
&bob_pubkey, &bob_pubkey,
vec![1, 2, 3, 4, 5, 6, 7], vec![1, 2, 3, 4, 5, 6, 7],
base_timestamp, base_timestamp,
); );
block_commitment_cache
.write()
.unwrap()
.set_get_largest_confirmed_root(7);
let slot_duration = slot_duration_from_slots_per_year(bank.slots_per_year()); let slot_duration = slot_duration_from_slots_per_year(bank.slots_per_year());