Check slot cleaned up for RPC blockstore/slot queries (#9982)
automerge
This commit is contained in:
parent
6660e93c39
commit
965204b8e0
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue