Check slot cleaned up for RPC blockstore/slot queries (#9982)

automerge
This commit is contained in:
Tyera Eulberg 2020-05-11 15:47:40 -06:00 committed by GitHub
parent 6660e93c39
commit 965204b8e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 87 additions and 21 deletions

View File

@ -40,6 +40,7 @@ mod result;
pub mod retransmit_stage; pub mod retransmit_stage;
pub mod rewards_recorder_service; pub mod rewards_recorder_service;
pub mod rpc; pub mod rpc;
pub mod rpc_error;
pub mod rpc_pubsub; pub mod rpc_pubsub;
pub mod rpc_pubsub_service; pub mod rpc_pubsub_service;
pub mod rpc_service; pub mod rpc_service;

View File

@ -5,11 +5,12 @@ use crate::{
commitment::{BlockCommitmentArray, BlockCommitmentCache}, commitment::{BlockCommitmentArray, BlockCommitmentCache},
contact_info::ContactInfo, contact_info::ContactInfo,
non_circulating_supply::calculate_non_circulating_supply, non_circulating_supply::calculate_non_circulating_supply,
rpc_error::RpcCustomError,
storage_stage::StorageState, storage_stage::StorageState,
validator::ValidatorExit, validator::ValidatorExit,
}; };
use bincode::serialize; use bincode::serialize;
use jsonrpc_core::{Error, ErrorCode, Metadata, Result}; use jsonrpc_core::{Error, Metadata, Result};
use jsonrpc_derive::rpc; use jsonrpc_derive::rpc;
use solana_client::{ use solana_client::{
rpc_request::{ rpc_request::{
@ -18,7 +19,9 @@ use solana_client::{
rpc_response::*, rpc_response::*,
}; };
use solana_faucet::faucet::request_airdrop_transaction; use solana_faucet::faucet::request_airdrop_transaction;
use solana_ledger::{bank_forks::BankForks, blockstore::Blockstore}; use solana_ledger::{
bank_forks::BankForks, blockstore::Blockstore, blockstore_db::BlockstoreError,
};
use solana_perf::packet::PACKET_DATA_SIZE; use solana_perf::packet::PACKET_DATA_SIZE;
use solana_runtime::{accounts::AccountAddressFilter, bank::Bank}; use solana_runtime::{accounts::AccountAddressFilter, bank::Bank};
use solana_sdk::{ use solana_sdk::{
@ -46,7 +49,6 @@ use std::{
time::{Duration, Instant}, time::{Duration, Instant},
}; };
const JSON_RPC_SERVER_ERROR_0: i64 = -32000;
const NUM_LARGEST_ACCOUNTS: usize = 20; const NUM_LARGEST_ACCOUNTS: usize = 20;
type RpcResponse<T> = Result<Response<T>>; type RpcResponse<T> = Result<Response<T>>;
@ -100,18 +102,13 @@ impl JsonRpcRequestProcessor {
.unwrap() .unwrap()
.largest_confirmed_root(); .largest_confirmed_root();
debug!("RPC using block: {:?}", cluster_root); debug!("RPC using block: {:?}", cluster_root);
r_bank_forks r_bank_forks.get(cluster_root).cloned().ok_or_else(|| {
.get(cluster_root) RpcCustomError::NonexistentClusterRoot {
.cloned() cluster_root,
.ok_or_else(|| Error { node_root: r_bank_forks.root(),
code: ErrorCode::ServerError(JSON_RPC_SERVER_ERROR_0), }
message: format!( .into()
"Cluster largest_confirmed_root {} does not exist on node. Node root: {}", })
cluster_root,
r_bank_forks.root(),
),
data: None,
})
} }
} }
@ -421,6 +418,29 @@ impl JsonRpcRequestProcessor {
} }
} }
fn check_slot_cleaned_up<T>(
&self,
result: &std::result::Result<T, BlockstoreError>,
slot: Slot,
) -> Result<()>
where
T: std::fmt::Debug,
{
if result.is_err() {
if let BlockstoreError::SlotCleanedUp = result.as_ref().unwrap_err() {
return Err(RpcCustomError::BlockCleanedUp {
slot,
first_available_block: self
.blockstore
.get_first_available_block()
.unwrap_or_default(),
}
.into());
}
}
Ok(())
}
pub fn get_confirmed_block( pub fn get_confirmed_block(
&self, &self,
slot: Slot, slot: Slot,
@ -434,7 +454,9 @@ impl JsonRpcRequestProcessor {
.unwrap() .unwrap()
.largest_confirmed_root() .largest_confirmed_root()
{ {
Ok(self.blockstore.get_confirmed_block(slot, encoding).ok()) let result = self.blockstore.get_confirmed_block(slot, encoding);
self.check_slot_cleaned_up(&result, slot)?;
Ok(result.ok())
} else { } else {
Ok(None) Ok(None)
} }
@ -482,11 +504,9 @@ impl JsonRpcRequestProcessor {
let stakes = HashMap::new(); let stakes = HashMap::new();
let stakes = bank.epoch_vote_accounts(epoch).unwrap_or(&stakes); let stakes = bank.epoch_vote_accounts(epoch).unwrap_or(&stakes);
Ok(self let result = self.blockstore.get_block_time(slot, slot_duration, stakes);
.blockstore self.check_slot_cleaned_up(&result, slot)?;
.get_block_time(slot, slot_duration, stakes) Ok(result.ok().unwrap_or(None))
.ok()
.unwrap_or(None))
} else { } else {
Ok(None) Ok(None)
} }

45
core/src/rpc_error.rs Normal file
View File

@ -0,0 +1,45 @@
use jsonrpc_core::{Error, ErrorCode};
use solana_sdk::clock::Slot;
const JSON_RPC_SERVER_ERROR_0: i64 = -32000;
const JSON_RPC_SERVER_ERROR_1: i64 = -32001;
pub enum RpcCustomError {
NonexistentClusterRoot {
cluster_root: Slot,
node_root: Slot,
},
BlockCleanedUp {
slot: Slot,
first_available_block: Slot,
},
}
impl From<RpcCustomError> for Error {
fn from(e: RpcCustomError) -> Self {
match e {
RpcCustomError::NonexistentClusterRoot {
cluster_root,
node_root,
} => Self {
code: ErrorCode::ServerError(JSON_RPC_SERVER_ERROR_0),
message: format!(
"Cluster largest_confirmed_root {} does not exist on node. Node root: {}",
cluster_root, node_root,
),
data: None,
},
RpcCustomError::BlockCleanedUp {
slot,
first_available_block,
} => Self {
code: ErrorCode::ServerError(JSON_RPC_SERVER_ERROR_1),
message: format!(
"Block {} cleaned up, does not exist on node. First available block: {}",
slot, first_available_block,
),
data: None,
},
}
}
}