Add `getSnapshotSlot` RPC method
This commit is contained in:
parent
dacb95083d
commit
4003f86f04
|
@ -274,6 +274,10 @@ impl RpcClient {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_snapshot_slot(&self) -> ClientResult<Slot> {
|
||||||
|
self.send(RpcRequest::GetSnapshotSlot, Value::Null)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_signature_status(
|
pub fn get_signature_status(
|
||||||
&self,
|
&self,
|
||||||
signature: &Signature,
|
signature: &Signature,
|
||||||
|
|
|
@ -11,6 +11,7 @@ pub const JSON_RPC_SERVER_ERROR_BLOCK_NOT_AVAILABLE: i64 = -32004;
|
||||||
pub const JSON_RPC_SERVER_ERROR_NODE_UNHEALTHLY: i64 = -32005;
|
pub const JSON_RPC_SERVER_ERROR_NODE_UNHEALTHLY: i64 = -32005;
|
||||||
pub const JSON_RPC_SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE: i64 = -32006;
|
pub const JSON_RPC_SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE: i64 = -32006;
|
||||||
pub const JSON_RPC_SERVER_ERROR_SLOT_SKIPPED: i64 = -32007;
|
pub const JSON_RPC_SERVER_ERROR_SLOT_SKIPPED: i64 = -32007;
|
||||||
|
pub const JSON_RPC_SERVER_ERROR_NO_SNAPSHOT: i64 = -32008;
|
||||||
|
|
||||||
pub enum RpcCustomError {
|
pub enum RpcCustomError {
|
||||||
BlockCleanedUp {
|
BlockCleanedUp {
|
||||||
|
@ -32,6 +33,7 @@ pub enum RpcCustomError {
|
||||||
SlotSkipped {
|
SlotSkipped {
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
},
|
},
|
||||||
|
NoSnapshot,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
@ -95,6 +97,11 @@ impl From<RpcCustomError> for Error {
|
||||||
),
|
),
|
||||||
data: None,
|
data: None,
|
||||||
},
|
},
|
||||||
|
RpcCustomError::NoSnapshot => Self {
|
||||||
|
code: ErrorCode::ServerError(JSON_RPC_SERVER_ERROR_NO_SNAPSHOT),
|
||||||
|
message: "No snapshot".to_string(),
|
||||||
|
data: None,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ pub enum RpcRequest {
|
||||||
GetMultipleAccounts,
|
GetMultipleAccounts,
|
||||||
GetProgramAccounts,
|
GetProgramAccounts,
|
||||||
GetRecentBlockhash,
|
GetRecentBlockhash,
|
||||||
|
GetSnapshotSlot,
|
||||||
GetSignatureStatuses,
|
GetSignatureStatuses,
|
||||||
GetSlot,
|
GetSlot,
|
||||||
GetSlotLeader,
|
GetSlotLeader,
|
||||||
|
@ -91,6 +92,7 @@ impl fmt::Display for RpcRequest {
|
||||||
RpcRequest::GetMultipleAccounts => "getMultipleAccounts",
|
RpcRequest::GetMultipleAccounts => "getMultipleAccounts",
|
||||||
RpcRequest::GetProgramAccounts => "getProgramAccounts",
|
RpcRequest::GetProgramAccounts => "getProgramAccounts",
|
||||||
RpcRequest::GetRecentBlockhash => "getRecentBlockhash",
|
RpcRequest::GetRecentBlockhash => "getRecentBlockhash",
|
||||||
|
RpcRequest::GetSnapshotSlot => "getSnapshotSlot",
|
||||||
RpcRequest::GetSignatureStatuses => "getSignatureStatuses",
|
RpcRequest::GetSignatureStatuses => "getSignatureStatuses",
|
||||||
RpcRequest::GetSlot => "getSlot",
|
RpcRequest::GetSlot => "getSlot",
|
||||||
RpcRequest::GetSlotLeader => "getSlotLeader",
|
RpcRequest::GetSlotLeader => "getSlotLeader",
|
||||||
|
|
|
@ -41,9 +41,10 @@ use solana_runtime::{
|
||||||
accounts::AccountAddressFilter,
|
accounts::AccountAddressFilter,
|
||||||
accounts_index::{AccountIndex, IndexKey},
|
accounts_index::{AccountIndex, IndexKey},
|
||||||
bank::Bank,
|
bank::Bank,
|
||||||
bank_forks::BankForks,
|
bank_forks::{BankForks, SnapshotConfig},
|
||||||
commitment::{BlockCommitmentArray, BlockCommitmentCache, CommitmentSlots},
|
commitment::{BlockCommitmentArray, BlockCommitmentCache, CommitmentSlots},
|
||||||
inline_spl_token_v2_0::{SPL_TOKEN_ACCOUNT_MINT_OFFSET, SPL_TOKEN_ACCOUNT_OWNER_OFFSET},
|
inline_spl_token_v2_0::{SPL_TOKEN_ACCOUNT_MINT_OFFSET, SPL_TOKEN_ACCOUNT_OWNER_OFFSET},
|
||||||
|
snapshot_utils::get_highest_snapshot_archive_path,
|
||||||
};
|
};
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::Account,
|
account::Account,
|
||||||
|
@ -122,6 +123,7 @@ pub struct JsonRpcRequestProcessor {
|
||||||
block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
|
block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
|
||||||
blockstore: Arc<Blockstore>,
|
blockstore: Arc<Blockstore>,
|
||||||
config: JsonRpcConfig,
|
config: JsonRpcConfig,
|
||||||
|
snapshot_config: Option<SnapshotConfig>,
|
||||||
validator_exit: Arc<RwLock<Option<ValidatorExit>>>,
|
validator_exit: Arc<RwLock<Option<ValidatorExit>>>,
|
||||||
health: Arc<RpcHealth>,
|
health: Arc<RpcHealth>,
|
||||||
cluster_info: Arc<ClusterInfo>,
|
cluster_info: Arc<ClusterInfo>,
|
||||||
|
@ -199,6 +201,7 @@ impl JsonRpcRequestProcessor {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
config: JsonRpcConfig,
|
config: JsonRpcConfig,
|
||||||
|
snapshot_config: Option<SnapshotConfig>,
|
||||||
bank_forks: Arc<RwLock<BankForks>>,
|
bank_forks: Arc<RwLock<BankForks>>,
|
||||||
block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
|
block_commitment_cache: Arc<RwLock<BlockCommitmentCache>>,
|
||||||
blockstore: Arc<Blockstore>,
|
blockstore: Arc<Blockstore>,
|
||||||
|
@ -214,6 +217,7 @@ impl JsonRpcRequestProcessor {
|
||||||
(
|
(
|
||||||
Self {
|
Self {
|
||||||
config,
|
config,
|
||||||
|
snapshot_config,
|
||||||
bank_forks,
|
bank_forks,
|
||||||
block_commitment_cache,
|
block_commitment_cache,
|
||||||
blockstore,
|
blockstore,
|
||||||
|
@ -246,6 +250,7 @@ impl JsonRpcRequestProcessor {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
config: JsonRpcConfig::default(),
|
config: JsonRpcConfig::default(),
|
||||||
|
snapshot_config: None,
|
||||||
bank_forks,
|
bank_forks,
|
||||||
block_commitment_cache: Arc::new(RwLock::new(BlockCommitmentCache::new(
|
block_commitment_cache: Arc::new(RwLock::new(BlockCommitmentCache::new(
|
||||||
HashMap::new(),
|
HashMap::new(),
|
||||||
|
@ -463,7 +468,7 @@ impl JsonRpcRequestProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_slot(&self, commitment: Option<CommitmentConfig>) -> u64 {
|
fn get_slot(&self, commitment: Option<CommitmentConfig>) -> Slot {
|
||||||
self.bank(commitment).slot()
|
self.bank(commitment).slot()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1799,6 +1804,9 @@ pub trait RpcSol {
|
||||||
meta: Self::Metadata,
|
meta: Self::Metadata,
|
||||||
) -> Result<RpcResponse<RpcFeeRateGovernor>>;
|
) -> Result<RpcResponse<RpcFeeRateGovernor>>;
|
||||||
|
|
||||||
|
#[rpc(meta, name = "getSnapshotSlot")]
|
||||||
|
fn get_snapshot_slot(&self, meta: Self::Metadata) -> Result<Slot>;
|
||||||
|
|
||||||
#[rpc(meta, name = "getSignatureStatuses")]
|
#[rpc(meta, name = "getSignatureStatuses")]
|
||||||
fn get_signature_statuses(
|
fn get_signature_statuses(
|
||||||
&self,
|
&self,
|
||||||
|
@ -1808,7 +1816,7 @@ pub trait RpcSol {
|
||||||
) -> Result<RpcResponse<Vec<Option<TransactionStatus>>>>;
|
) -> Result<RpcResponse<Vec<Option<TransactionStatus>>>>;
|
||||||
|
|
||||||
#[rpc(meta, name = "getSlot")]
|
#[rpc(meta, name = "getSlot")]
|
||||||
fn get_slot(&self, meta: Self::Metadata, commitment: Option<CommitmentConfig>) -> Result<u64>;
|
fn get_slot(&self, meta: Self::Metadata, commitment: Option<CommitmentConfig>) -> Result<Slot>;
|
||||||
|
|
||||||
#[rpc(meta, name = "getTransactionCount")]
|
#[rpc(meta, name = "getTransactionCount")]
|
||||||
fn get_transaction_count(
|
fn get_transaction_count(
|
||||||
|
@ -2354,6 +2362,17 @@ impl RpcSol for RpcSolImpl {
|
||||||
Ok(meta.get_signature_status(signature, commitment))
|
Ok(meta.get_signature_status(signature, commitment))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_snapshot_slot(&self, meta: Self::Metadata) -> Result<Slot> {
|
||||||
|
debug!("get_snapshot_slot rpc request received");
|
||||||
|
|
||||||
|
meta.snapshot_config
|
||||||
|
.and_then(|snapshot_config| {
|
||||||
|
get_highest_snapshot_archive_path(&snapshot_config.snapshot_package_output_path)
|
||||||
|
.map(|(_, (slot, _, _))| slot)
|
||||||
|
})
|
||||||
|
.ok_or_else(|| RpcCustomError::NoSnapshot.into())
|
||||||
|
}
|
||||||
|
|
||||||
fn get_signature_statuses(
|
fn get_signature_statuses(
|
||||||
&self,
|
&self,
|
||||||
meta: Self::Metadata,
|
meta: Self::Metadata,
|
||||||
|
@ -2377,7 +2396,7 @@ impl RpcSol for RpcSolImpl {
|
||||||
meta.get_signature_statuses(signatures, config)
|
meta.get_signature_statuses(signatures, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_slot(&self, meta: Self::Metadata, commitment: Option<CommitmentConfig>) -> Result<u64> {
|
fn get_slot(&self, meta: Self::Metadata, commitment: Option<CommitmentConfig>) -> Result<Slot> {
|
||||||
debug!("get_slot rpc request received");
|
debug!("get_slot rpc request received");
|
||||||
Ok(meta.get_slot(commitment))
|
Ok(meta.get_slot(commitment))
|
||||||
}
|
}
|
||||||
|
@ -3080,6 +3099,7 @@ pub mod tests {
|
||||||
identity_pubkey: *pubkey,
|
identity_pubkey: *pubkey,
|
||||||
..JsonRpcConfig::default()
|
..JsonRpcConfig::default()
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
bank_forks.clone(),
|
bank_forks.clone(),
|
||||||
block_commitment_cache.clone(),
|
block_commitment_cache.clone(),
|
||||||
blockstore,
|
blockstore,
|
||||||
|
@ -4480,6 +4500,7 @@ pub mod tests {
|
||||||
let tpu_address = cluster_info.my_contact_info().tpu;
|
let tpu_address = cluster_info.my_contact_info().tpu;
|
||||||
let (meta, receiver) = JsonRpcRequestProcessor::new(
|
let (meta, receiver) = JsonRpcRequestProcessor::new(
|
||||||
JsonRpcConfig::default(),
|
JsonRpcConfig::default(),
|
||||||
|
None,
|
||||||
bank_forks.clone(),
|
bank_forks.clone(),
|
||||||
block_commitment_cache,
|
block_commitment_cache,
|
||||||
blockstore,
|
blockstore,
|
||||||
|
@ -4676,6 +4697,7 @@ pub mod tests {
|
||||||
let bank_forks = new_bank_forks().0;
|
let bank_forks = new_bank_forks().0;
|
||||||
let (request_processor, receiver) = JsonRpcRequestProcessor::new(
|
let (request_processor, receiver) = JsonRpcRequestProcessor::new(
|
||||||
JsonRpcConfig::default(),
|
JsonRpcConfig::default(),
|
||||||
|
None,
|
||||||
bank_forks.clone(),
|
bank_forks.clone(),
|
||||||
block_commitment_cache,
|
block_commitment_cache,
|
||||||
blockstore,
|
blockstore,
|
||||||
|
@ -4708,6 +4730,7 @@ pub mod tests {
|
||||||
let tpu_address = cluster_info.my_contact_info().tpu;
|
let tpu_address = cluster_info.my_contact_info().tpu;
|
||||||
let (request_processor, receiver) = JsonRpcRequestProcessor::new(
|
let (request_processor, receiver) = JsonRpcRequestProcessor::new(
|
||||||
config,
|
config,
|
||||||
|
None,
|
||||||
bank_forks.clone(),
|
bank_forks.clone(),
|
||||||
block_commitment_cache,
|
block_commitment_cache,
|
||||||
blockstore,
|
blockstore,
|
||||||
|
@ -4799,6 +4822,7 @@ pub mod tests {
|
||||||
let tpu_address = cluster_info.my_contact_info().tpu;
|
let tpu_address = cluster_info.my_contact_info().tpu;
|
||||||
let (request_processor, receiver) = JsonRpcRequestProcessor::new(
|
let (request_processor, receiver) = JsonRpcRequestProcessor::new(
|
||||||
config,
|
config,
|
||||||
|
None,
|
||||||
bank_forks.clone(),
|
bank_forks.clone(),
|
||||||
block_commitment_cache,
|
block_commitment_cache,
|
||||||
blockstore,
|
blockstore,
|
||||||
|
@ -6027,6 +6051,7 @@ pub mod tests {
|
||||||
|
|
||||||
let (meta, _receiver) = JsonRpcRequestProcessor::new(
|
let (meta, _receiver) = JsonRpcRequestProcessor::new(
|
||||||
JsonRpcConfig::default(),
|
JsonRpcConfig::default(),
|
||||||
|
None,
|
||||||
bank_forks.clone(),
|
bank_forks.clone(),
|
||||||
block_commitment_cache,
|
block_commitment_cache,
|
||||||
blockstore,
|
blockstore,
|
||||||
|
|
|
@ -329,6 +329,7 @@ impl JsonRpcService {
|
||||||
|
|
||||||
let (request_processor, receiver) = JsonRpcRequestProcessor::new(
|
let (request_processor, receiver) = JsonRpcRequestProcessor::new(
|
||||||
config,
|
config,
|
||||||
|
snapshot_config.clone(),
|
||||||
bank_forks.clone(),
|
bank_forks.clone(),
|
||||||
block_commitment_cache,
|
block_commitment_cache,
|
||||||
blockstore,
|
blockstore,
|
||||||
|
|
|
@ -1968,6 +1968,38 @@ Result:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### getSnapshotSlot
|
||||||
|
|
||||||
|
Returns the highest slot that the node has a snapshot for
|
||||||
|
|
||||||
|
#### Parameters:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
#### Results:
|
||||||
|
|
||||||
|
- `<u64>` - Snapshot slot
|
||||||
|
|
||||||
|
#### Example:
|
||||||
|
|
||||||
|
Request:
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8899 -X POST -H "Content-Type: application/json" -d '
|
||||||
|
{"jsonrpc":"2.0","id":1, "method":"getSnapshotSlot"}
|
||||||
|
'
|
||||||
|
```
|
||||||
|
|
||||||
|
Result:
|
||||||
|
```json
|
||||||
|
{"jsonrpc":"2.0","result":100,"id":1}
|
||||||
|
```
|
||||||
|
|
||||||
|
Result when the node has no snapshot:
|
||||||
|
```json
|
||||||
|
{"jsonrpc":"2.0","error":{"code":-32008,"message":"No snapshot"},"id":1}
|
||||||
|
```
|
||||||
|
|
||||||
### getSignatureStatuses
|
### getSignatureStatuses
|
||||||
|
|
||||||
Returns the statuses of a list of signatures. Unless the
|
Returns the statuses of a list of signatures. Unless the
|
||||||
|
|
|
@ -380,10 +380,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let snapshot_slot =
|
let snapshot_slot = rpc_client.get_snapshot_slot().ok();
|
||||||
solana_runtime::snapshot_utils::get_highest_snapshot_archive_path(&ledger_path)
|
|
||||||
.map(|(_, (slot, _, _))| slot)
|
|
||||||
.unwrap_or(0);
|
|
||||||
|
|
||||||
for _i in 0..10 {
|
for _i in 0..10 {
|
||||||
match get_validator_stats(&rpc_client, &identity) {
|
match get_validator_stats(&rpc_client, &identity) {
|
||||||
|
@ -400,16 +397,25 @@ fn main() {
|
||||||
progress_bar.set_message(&format!(
|
progress_bar.set_message(&format!(
|
||||||
"{:02}:{:02}:{:02} \
|
"{:02}:{:02}:{:02} \
|
||||||
{}| \
|
{}| \
|
||||||
Processed Slot: {} | Confirmed Slot: {} | Finalized Slot: {} | Snapshot Slot: {} | \
|
Processed Slot: {} | Confirmed Slot: {} | Finalized Slot: {} | \
|
||||||
|
Snapshot Slot: {} | \
|
||||||
Transactions: {} | {}",
|
Transactions: {} | {}",
|
||||||
uptime.num_hours(), uptime.num_minutes() % 60, uptime.num_seconds() % 60,
|
uptime.num_hours(),
|
||||||
|
uptime.num_minutes() % 60,
|
||||||
|
uptime.num_seconds() % 60,
|
||||||
if health == "ok" {
|
if health == "ok" {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
} else {
|
} else {
|
||||||
format!("| {} ", style(health).bold().red())
|
format!("| {} ", style(health).bold().red())
|
||||||
},
|
},
|
||||||
processed_slot, confirmed_slot, finalized_slot, snapshot_slot,
|
processed_slot,
|
||||||
transaction_count, identity_balance
|
confirmed_slot,
|
||||||
|
finalized_slot,
|
||||||
|
snapshot_slot
|
||||||
|
.map(|s| s.to_string())
|
||||||
|
.unwrap_or_else(|| "-".to_string()),
|
||||||
|
transaction_count,
|
||||||
|
identity_balance
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
|
Loading…
Reference in New Issue