Add Incremental Snapshot support to RPC (#19559)
#### Problem There's no way to get incremental snapshot information from RPC. #### Summary of Changes - Add new RPC method, `getHighestSnapshotSlot` that returns a `SnapshotSlotInfo`, which contains both the highest full snapshot slot, and the highest incremental snapshot slot _based on_ the full snapshot. - Deprecate old RPC method, `getSnapshotSlot` - Update API docs Fixes #19579
This commit is contained in:
parent
f4f14c42bb
commit
8ac94b2cf4
|
@ -8,8 +8,9 @@ use {
|
||||||
rpc_response::{
|
rpc_response::{
|
||||||
Response, RpcAccountBalance, RpcBlockProduction, RpcBlockProductionRange, RpcBlockhash,
|
Response, RpcAccountBalance, RpcBlockProduction, RpcBlockProductionRange, RpcBlockhash,
|
||||||
RpcConfirmedTransactionStatusWithSignature, RpcContactInfo, RpcFees, RpcPerfSample,
|
RpcConfirmedTransactionStatusWithSignature, RpcContactInfo, RpcFees, RpcPerfSample,
|
||||||
RpcResponseContext, RpcSimulateTransactionResult, RpcStakeActivation, RpcSupply,
|
RpcResponseContext, RpcSimulateTransactionResult, RpcSnapshotSlotInfo,
|
||||||
RpcVersionInfo, RpcVoteAccountInfo, RpcVoteAccountStatus, StakeActivationState,
|
RpcStakeActivation, RpcSupply, RpcVersionInfo, RpcVoteAccountInfo,
|
||||||
|
RpcVoteAccountStatus, StakeActivationState,
|
||||||
},
|
},
|
||||||
rpc_sender::RpcSender,
|
rpc_sender::RpcSender,
|
||||||
},
|
},
|
||||||
|
@ -222,6 +223,10 @@ impl RpcSender for MockSender {
|
||||||
"getMaxShredInsertSlot" => json![0],
|
"getMaxShredInsertSlot" => json![0],
|
||||||
"requestAirdrop" => Value::String(Signature::new(&[8; 64]).to_string()),
|
"requestAirdrop" => Value::String(Signature::new(&[8; 64]).to_string()),
|
||||||
"getSnapshotSlot" => Value::Number(Number::from(0)),
|
"getSnapshotSlot" => Value::Number(Number::from(0)),
|
||||||
|
"getHighestSnapshotSlot" => json!(RpcSnapshotSlotInfo {
|
||||||
|
full: 100,
|
||||||
|
incremental: Some(110),
|
||||||
|
}),
|
||||||
"getBlockHeight" => Value::Number(Number::from(1234)),
|
"getBlockHeight" => Value::Number(Number::from(1234)),
|
||||||
"getSlotLeaders" => json!([PUBKEY]),
|
"getSlotLeaders" => json!([PUBKEY]),
|
||||||
"getBlockProduction" => {
|
"getBlockProduction" => {
|
||||||
|
|
|
@ -1018,13 +1018,16 @@ impl RpcClient {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the highest slot that the node has a snapshot for.
|
/// Returns the highest slot information that the node has snapshots for.
|
||||||
|
///
|
||||||
|
/// This will find the highest full snapshot slot, and the highest incremental snapshot slot
|
||||||
|
/// _based on_ the full snapshot slot, if there is one.
|
||||||
///
|
///
|
||||||
/// # RPC Reference
|
/// # RPC Reference
|
||||||
///
|
///
|
||||||
/// This method corresponds directly to the [`getSnapshotSlot`] RPC method.
|
/// This method corresponds directly to the [`getHighestSnapshotSlot`] RPC method.
|
||||||
///
|
///
|
||||||
/// [`getSnapshotSlot`]: https://docs.solana.com/developing/clients/jsonrpc-api#getsnapshotslot
|
/// [`getHighestSnapshotSlot`]: https://docs.solana.com/developing/clients/jsonrpc-api#gethighestsnapshotslot
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -1034,9 +1037,18 @@ impl RpcClient {
|
||||||
/// # client_error::ClientError,
|
/// # client_error::ClientError,
|
||||||
/// # };
|
/// # };
|
||||||
/// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
|
/// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
|
||||||
/// let slot = rpc_client.get_snapshot_slot()?;
|
/// let snapshot_slot_info = rpc_client.get_highest_snapshot_slot()?;
|
||||||
/// # Ok::<(), ClientError>(())
|
/// # Ok::<(), ClientError>(())
|
||||||
/// ```
|
/// ```
|
||||||
|
pub fn get_highest_snapshot_slot(&self) -> ClientResult<RpcSnapshotSlotInfo> {
|
||||||
|
self.send(RpcRequest::GetHighestSnapshotSlot, Value::Null)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deprecated(
|
||||||
|
since = "1.8.0",
|
||||||
|
note = "Please use RpcClient::get_highest_snapshot_slot() instead"
|
||||||
|
)]
|
||||||
|
#[allow(deprecated)]
|
||||||
pub fn get_snapshot_slot(&self) -> ClientResult<Slot> {
|
pub fn get_snapshot_slot(&self) -> ClientResult<Slot> {
|
||||||
self.send(RpcRequest::GetSnapshotSlot, Value::Null)
|
self.send(RpcRequest::GetSnapshotSlot, Value::Null)
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,11 @@ pub enum RpcRequest {
|
||||||
)]
|
)]
|
||||||
GetRecentBlockhash,
|
GetRecentBlockhash,
|
||||||
GetRecentPerformanceSamples,
|
GetRecentPerformanceSamples,
|
||||||
|
GetHighestSnapshotSlot,
|
||||||
|
#[deprecated(
|
||||||
|
since = "1.8.0",
|
||||||
|
note = "Please use RpcRequest::GetHighestSnapshotSlot instead"
|
||||||
|
)]
|
||||||
GetSnapshotSlot,
|
GetSnapshotSlot,
|
||||||
GetSignaturesForAddress,
|
GetSignaturesForAddress,
|
||||||
GetSignatureStatuses,
|
GetSignatureStatuses,
|
||||||
|
@ -151,6 +156,7 @@ impl fmt::Display for RpcRequest {
|
||||||
RpcRequest::GetProgramAccounts => "getProgramAccounts",
|
RpcRequest::GetProgramAccounts => "getProgramAccounts",
|
||||||
RpcRequest::GetRecentBlockhash => "getRecentBlockhash",
|
RpcRequest::GetRecentBlockhash => "getRecentBlockhash",
|
||||||
RpcRequest::GetRecentPerformanceSamples => "getRecentPerformanceSamples",
|
RpcRequest::GetRecentPerformanceSamples => "getRecentPerformanceSamples",
|
||||||
|
RpcRequest::GetHighestSnapshotSlot => "getHighestSnapshotSlot",
|
||||||
RpcRequest::GetSnapshotSlot => "getSnapshotSlot",
|
RpcRequest::GetSnapshotSlot => "getSnapshotSlot",
|
||||||
RpcRequest::GetSignaturesForAddress => "getSignaturesForAddress",
|
RpcRequest::GetSignaturesForAddress => "getSignaturesForAddress",
|
||||||
RpcRequest::GetSignatureStatuses => "getSignatureStatuses",
|
RpcRequest::GetSignatureStatuses => "getSignatureStatuses",
|
||||||
|
|
|
@ -435,3 +435,9 @@ impl From<ConfirmedTransactionStatusWithSignature> for RpcConfirmedTransactionSt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq)]
|
||||||
|
pub struct RpcSnapshotSlotInfo {
|
||||||
|
pub full: Slot,
|
||||||
|
pub incremental: Option<Slot>,
|
||||||
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ gives a convenient interface for the RPC methods.
|
||||||
- [getFirstAvailableBlock](jsonrpc-api.md#getfirstavailableblock)
|
- [getFirstAvailableBlock](jsonrpc-api.md#getfirstavailableblock)
|
||||||
- [getGenesisHash](jsonrpc-api.md#getgenesishash)
|
- [getGenesisHash](jsonrpc-api.md#getgenesishash)
|
||||||
- [getHealth](jsonrpc-api.md#gethealth)
|
- [getHealth](jsonrpc-api.md#gethealth)
|
||||||
|
- [getHighestSnapshotSlot](jsonrpc-api.md#gethighestsnapshotslot)
|
||||||
- [getIdentity](jsonrpc-api.md#getidentity)
|
- [getIdentity](jsonrpc-api.md#getidentity)
|
||||||
- [getInflationGovernor](jsonrpc-api.md#getinflationgovernor)
|
- [getInflationGovernor](jsonrpc-api.md#getinflationgovernor)
|
||||||
- [getInflationRate](jsonrpc-api.md#getinflationrate)
|
- [getInflationRate](jsonrpc-api.md#getinflationrate)
|
||||||
|
@ -53,7 +54,6 @@ gives a convenient interface for the RPC methods.
|
||||||
- [getSlotLeader](jsonrpc-api.md#getslotleader)
|
- [getSlotLeader](jsonrpc-api.md#getslotleader)
|
||||||
- [getSlotLeaders](jsonrpc-api.md#getslotleaders)
|
- [getSlotLeaders](jsonrpc-api.md#getslotleaders)
|
||||||
- [getStakeActivation](jsonrpc-api.md#getstakeactivation)
|
- [getStakeActivation](jsonrpc-api.md#getstakeactivation)
|
||||||
- [getSnapshotSlot](jsonrpc-api.md#getsnapshotslot)
|
|
||||||
- [getSupply](jsonrpc-api.md#getsupply)
|
- [getSupply](jsonrpc-api.md#getsupply)
|
||||||
- [getTokenAccountBalance](jsonrpc-api.md#gettokenaccountbalance)
|
- [getTokenAccountBalance](jsonrpc-api.md#gettokenaccountbalance)
|
||||||
- [getTokenAccountsByDelegate](jsonrpc-api.md#gettokenaccountsbydelegate)
|
- [getTokenAccountsByDelegate](jsonrpc-api.md#gettokenaccountsbydelegate)
|
||||||
|
@ -101,6 +101,7 @@ Unstable methods may see breaking changes in patch releases and may not be suppo
|
||||||
- [getFeeRateGovernor](jsonrpc-api.md#getfeerategovernor)
|
- [getFeeRateGovernor](jsonrpc-api.md#getfeerategovernor)
|
||||||
- [getFees](jsonrpc-api.md#getfees)
|
- [getFees](jsonrpc-api.md#getfees)
|
||||||
- [getRecentBlockhash](jsonrpc-api.md#getrecentblockhash)
|
- [getRecentBlockhash](jsonrpc-api.md#getrecentblockhash)
|
||||||
|
- [getSnapshotSlot](jsonrpc-api.md#getsnapshotslot)
|
||||||
|
|
||||||
## Request Formatting
|
## Request Formatting
|
||||||
|
|
||||||
|
@ -1296,6 +1297,46 @@ Unhealthy Result (if additional information is available)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### getHighestSnapshotSlot
|
||||||
|
|
||||||
|
**NEW: This method is only available in solana-core v1.8 or newer. Please use
|
||||||
|
[getSnapshotSlot](jsonrpc-api.md#getsnapshotslot) for solana-core v1.7**
|
||||||
|
|
||||||
|
Returns the highest slot information that the node has snapshots for.
|
||||||
|
|
||||||
|
This will find the highest full snapshot slot, and the highest incremental
|
||||||
|
snapshot slot _based on_ the full snapshot slot, if there is one.
|
||||||
|
|
||||||
|
#### Parameters:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
#### Results:
|
||||||
|
|
||||||
|
- `<object>`
|
||||||
|
- `full: <u64>` - Highest full snapshot slot
|
||||||
|
- `incremental: <u64 | undefined>` - Highest incremental snapshot slot _based on_ `full`
|
||||||
|
|
||||||
|
|
||||||
|
#### Example:
|
||||||
|
|
||||||
|
Request:
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8899 -X POST -H "Content-Type: application/json" -d '
|
||||||
|
{"jsonrpc":"2.0","id":1,"method":"getHighestSnapshotSlot"}
|
||||||
|
'
|
||||||
|
```
|
||||||
|
|
||||||
|
Result:
|
||||||
|
```json
|
||||||
|
{"jsonrpc":"2.0","result":{"full":100,"incremental":110},"id":1}
|
||||||
|
```
|
||||||
|
|
||||||
|
Result when the node has no snapshot:
|
||||||
|
```json
|
||||||
|
{"jsonrpc":"2.0","error":{"code":-32008,"message":"No snapshot"},"id":1}
|
||||||
|
```
|
||||||
|
|
||||||
### getIdentity
|
### getIdentity
|
||||||
|
|
||||||
Returns the identity pubkey for the current node
|
Returns the identity pubkey for the current node
|
||||||
|
@ -2121,38 +2162,6 @@ 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}
|
|
||||||
```
|
|
||||||
|
|
||||||
### getSignaturesForAddress
|
### getSignaturesForAddress
|
||||||
|
|
||||||
**NEW: This method is only available in solana-core v1.7 or newer. Please use
|
**NEW: This method is only available in solana-core v1.7 or newer. Please use
|
||||||
|
@ -4778,3 +4787,37 @@ Result:
|
||||||
"id": 1
|
"id": 1
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### getSnapshotSlot
|
||||||
|
|
||||||
|
**DEPRECATED: Please use [getHighestSnapshotSlot](jsonrpc-api.md#gethighestsnapshotslot) instead**
|
||||||
|
This method is expected to be removed in solana-core v1.9
|
||||||
|
|
||||||
|
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}
|
||||||
|
```
|
||||||
|
|
|
@ -2276,8 +2276,8 @@ pub mod rpc_minimal {
|
||||||
commitment: Option<CommitmentConfig>,
|
commitment: Option<CommitmentConfig>,
|
||||||
) -> Result<u64>;
|
) -> Result<u64>;
|
||||||
|
|
||||||
#[rpc(meta, name = "getSnapshotSlot")]
|
#[rpc(meta, name = "getHighestSnapshotSlot")]
|
||||||
fn get_snapshot_slot(&self, meta: Self::Metadata) -> Result<Slot>;
|
fn get_highest_snapshot_slot(&self, meta: Self::Metadata) -> Result<RpcSnapshotSlotInfo>;
|
||||||
|
|
||||||
#[rpc(meta, name = "getTransactionCount")]
|
#[rpc(meta, name = "getTransactionCount")]
|
||||||
fn get_transaction_count(
|
fn get_transaction_count(
|
||||||
|
@ -2373,16 +2373,31 @@ pub mod rpc_minimal {
|
||||||
Ok(meta.get_block_height(commitment))
|
Ok(meta.get_block_height(commitment))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_snapshot_slot(&self, meta: Self::Metadata) -> Result<Slot> {
|
fn get_highest_snapshot_slot(&self, meta: Self::Metadata) -> Result<RpcSnapshotSlotInfo> {
|
||||||
debug!("get_snapshot_slot rpc request received");
|
debug!("get_highest_snapshot_slot rpc request received");
|
||||||
|
|
||||||
meta.snapshot_config
|
if meta.snapshot_config.is_none() {
|
||||||
.and_then(|snapshot_config| {
|
return Err(RpcCustomError::NoSnapshot.into());
|
||||||
snapshot_utils::get_highest_full_snapshot_archive_slot(
|
}
|
||||||
&snapshot_config.snapshot_archives_dir,
|
|
||||||
)
|
let snapshot_archives_dir = meta
|
||||||
})
|
.snapshot_config
|
||||||
.ok_or_else(|| RpcCustomError::NoSnapshot.into())
|
.map(|snapshot_config| snapshot_config.snapshot_archives_dir)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let full_snapshot_slot =
|
||||||
|
snapshot_utils::get_highest_full_snapshot_archive_slot(&snapshot_archives_dir)
|
||||||
|
.ok_or(RpcCustomError::NoSnapshot)?;
|
||||||
|
let incremental_snapshot_slot =
|
||||||
|
snapshot_utils::get_highest_incremental_snapshot_archive_slot(
|
||||||
|
&snapshot_archives_dir,
|
||||||
|
full_snapshot_slot,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(RpcSnapshotSlotInfo {
|
||||||
|
full: full_snapshot_slot,
|
||||||
|
incremental: incremental_snapshot_slot,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_transaction_count(
|
fn get_transaction_count(
|
||||||
|
@ -3686,6 +3701,9 @@ pub mod rpc_deprecated_v1_8 {
|
||||||
&self,
|
&self,
|
||||||
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>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DeprecatedV1_8Impl;
|
pub struct DeprecatedV1_8Impl;
|
||||||
|
@ -3729,6 +3747,18 @@ pub mod rpc_deprecated_v1_8 {
|
||||||
debug!("get_fee_rate_governor rpc request received");
|
debug!("get_fee_rate_governor rpc request received");
|
||||||
Ok(meta.get_fee_rate_governor())
|
Ok(meta.get_fee_rate_governor())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_snapshot_slot(&self, meta: Self::Metadata) -> Result<Slot> {
|
||||||
|
debug!("get_snapshot_slot rpc request received");
|
||||||
|
|
||||||
|
meta.snapshot_config
|
||||||
|
.and_then(|snapshot_config| {
|
||||||
|
snapshot_utils::get_highest_full_snapshot_archive_slot(
|
||||||
|
&snapshot_config.snapshot_archives_dir,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.ok_or_else(|| RpcCustomError::NoSnapshot.into())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,8 @@ pub struct JsonRpcService {
|
||||||
|
|
||||||
struct RpcRequestMiddleware {
|
struct RpcRequestMiddleware {
|
||||||
ledger_path: PathBuf,
|
ledger_path: PathBuf,
|
||||||
snapshot_archive_path_regex: Regex,
|
full_snapshot_archive_path_regex: Regex,
|
||||||
|
incremental_snapshot_archive_path_regex: Regex,
|
||||||
snapshot_config: Option<SnapshotConfig>,
|
snapshot_config: Option<SnapshotConfig>,
|
||||||
bank_forks: Arc<RwLock<BankForks>>,
|
bank_forks: Arc<RwLock<BankForks>>,
|
||||||
health: Arc<RpcHealth>,
|
health: Arc<RpcHealth>,
|
||||||
|
@ -74,8 +75,12 @@ impl RpcRequestMiddleware {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ledger_path,
|
ledger_path,
|
||||||
snapshot_archive_path_regex: Regex::new(
|
full_snapshot_archive_path_regex: Regex::new(
|
||||||
r"^/snapshot-\d+-[[:alnum:]]+\.(tar|tar\.bz2|tar\.zst|tar\.gz)$",
|
snapshot_utils::FULL_SNAPSHOT_ARCHIVE_FILENAME_REGEX,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
incremental_snapshot_archive_path_regex: Regex::new(
|
||||||
|
snapshot_utils::INCREMENTAL_SNAPSHOT_ARCHIVE_FILENAME_REGEX,
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
snapshot_config,
|
snapshot_config,
|
||||||
|
@ -108,16 +113,23 @@ impl RpcRequestMiddleware {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_file_get_path(&self, path: &str) -> bool {
|
fn is_file_get_path(&self, path: &str) -> bool {
|
||||||
match path {
|
if path == DEFAULT_GENESIS_DOWNLOAD_PATH {
|
||||||
DEFAULT_GENESIS_DOWNLOAD_PATH => true,
|
return true;
|
||||||
_ => {
|
|
||||||
if self.snapshot_config.is_some() {
|
|
||||||
self.snapshot_archive_path_regex.is_match(path)
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.snapshot_config.is_none() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let starting_character = '/';
|
||||||
|
if !path.starts_with(starting_character) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let path = path.trim_start_matches(starting_character);
|
||||||
|
|
||||||
|
self.full_snapshot_archive_path_regex.is_match(path)
|
||||||
|
|| self.incremental_snapshot_archive_path_regex.is_match(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
|
@ -497,6 +509,7 @@ mod tests {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
|
clock::Slot,
|
||||||
genesis_config::{ClusterType, DEFAULT_GENESIS_ARCHIVE},
|
genesis_config::{ClusterType, DEFAULT_GENESIS_ARCHIVE},
|
||||||
signature::Signer,
|
signature::Signer,
|
||||||
signer::keypair::Keypair,
|
signer::keypair::Keypair,
|
||||||
|
@ -602,8 +615,8 @@ mod tests {
|
||||||
let rrm_with_snapshot_config = RpcRequestMiddleware::new(
|
let rrm_with_snapshot_config = RpcRequestMiddleware::new(
|
||||||
PathBuf::from("/"),
|
PathBuf::from("/"),
|
||||||
Some(SnapshotConfig {
|
Some(SnapshotConfig {
|
||||||
full_snapshot_archive_interval_slots: 0,
|
full_snapshot_archive_interval_slots: Slot::MAX,
|
||||||
incremental_snapshot_archive_interval_slots: u64::MAX,
|
incremental_snapshot_archive_interval_slots: Slot::MAX,
|
||||||
snapshot_archives_dir: PathBuf::from("/"),
|
snapshot_archives_dir: PathBuf::from("/"),
|
||||||
bank_snapshots_dir: PathBuf::from("/"),
|
bank_snapshots_dir: PathBuf::from("/"),
|
||||||
archive_format: ArchiveFormat::TarBzip2,
|
archive_format: ArchiveFormat::TarBzip2,
|
||||||
|
@ -622,6 +635,10 @@ mod tests {
|
||||||
assert!(!rrm.is_file_get_path(
|
assert!(!rrm.is_file_get_path(
|
||||||
"/snapshot-100-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2"
|
"/snapshot-100-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2"
|
||||||
));
|
));
|
||||||
|
assert!(!rrm.is_file_get_path(
|
||||||
|
"/incremental-snapshot-100-200-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2"
|
||||||
|
));
|
||||||
|
|
||||||
assert!(rrm_with_snapshot_config.is_file_get_path(
|
assert!(rrm_with_snapshot_config.is_file_get_path(
|
||||||
"/snapshot-100-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2"
|
"/snapshot-100-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2"
|
||||||
));
|
));
|
||||||
|
@ -633,11 +650,32 @@ mod tests {
|
||||||
assert!(rrm_with_snapshot_config
|
assert!(rrm_with_snapshot_config
|
||||||
.is_file_get_path("/snapshot-100-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar"));
|
.is_file_get_path("/snapshot-100-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar"));
|
||||||
|
|
||||||
|
assert!(rrm_with_snapshot_config.is_file_get_path(
|
||||||
|
"/incremental-snapshot-100-200-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2"
|
||||||
|
));
|
||||||
|
assert!(rrm_with_snapshot_config.is_file_get_path(
|
||||||
|
"/incremental-snapshot-100-200-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.zst"
|
||||||
|
));
|
||||||
|
assert!(rrm_with_snapshot_config.is_file_get_path(
|
||||||
|
"/incremental-snapshot-100-200-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.gz"
|
||||||
|
));
|
||||||
|
assert!(rrm_with_snapshot_config.is_file_get_path(
|
||||||
|
"/incremental-snapshot-100-200-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar"
|
||||||
|
));
|
||||||
|
|
||||||
assert!(!rrm_with_snapshot_config.is_file_get_path(
|
assert!(!rrm_with_snapshot_config.is_file_get_path(
|
||||||
"/snapshot-notaslotnumber-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2"
|
"/snapshot-notaslotnumber-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2"
|
||||||
));
|
));
|
||||||
|
assert!(!rrm_with_snapshot_config.is_file_get_path(
|
||||||
|
"/incremental-snapshot-notaslotnumber-200-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2"
|
||||||
|
));
|
||||||
|
assert!(!rrm_with_snapshot_config.is_file_get_path(
|
||||||
|
"/incremental-snapshot-100-notaslotnumber-AvFf9oS8A8U78HdjT9YG2sTTThLHJZmhaMn2g8vkWYnr.tar.bz2"
|
||||||
|
));
|
||||||
|
|
||||||
assert!(!rrm_with_snapshot_config.is_file_get_path("../../../test/snapshot-123-xxx.tar"));
|
assert!(!rrm_with_snapshot_config.is_file_get_path("../../../test/snapshot-123-xxx.tar"));
|
||||||
|
assert!(!rrm_with_snapshot_config
|
||||||
|
.is_file_get_path("../../../test/incremental-snapshot-123-456-xxx.tar"));
|
||||||
|
|
||||||
assert!(!rrm.is_file_get_path("/"));
|
assert!(!rrm.is_file_get_path("/"));
|
||||||
assert!(!rrm.is_file_get_path(".."));
|
assert!(!rrm.is_file_get_path(".."));
|
||||||
|
|
|
@ -113,13 +113,13 @@ impl Dashboard {
|
||||||
}
|
}
|
||||||
|
|
||||||
let progress_bar = new_spinner_progress_bar();
|
let progress_bar = new_spinner_progress_bar();
|
||||||
let mut snapshot_slot = None;
|
let mut snapshot_slot_info = None;
|
||||||
for i in 0.. {
|
for i in 0.. {
|
||||||
if exit.load(Ordering::Relaxed) {
|
if exit.load(Ordering::Relaxed) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if i % 10 == 0 {
|
if i % 10 == 0 {
|
||||||
snapshot_slot = rpc_client.get_snapshot_slot().ok();
|
snapshot_slot_info = rpc_client.get_highest_snapshot_slot().ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
match get_validator_stats(&rpc_client, &identity) {
|
match get_validator_stats(&rpc_client, &identity) {
|
||||||
|
@ -147,7 +147,7 @@ impl Dashboard {
|
||||||
progress_bar.set_message(format!(
|
progress_bar.set_message(format!(
|
||||||
"{}{}{}| \
|
"{}{}{}| \
|
||||||
Processed Slot: {} | Confirmed Slot: {} | Finalized Slot: {} | \
|
Processed Slot: {} | Confirmed Slot: {} | Finalized Slot: {} | \
|
||||||
Snapshot Slot: {} | \
|
Full Snapshot Slot: {} | Incremental Snapshot Slot: {} \
|
||||||
Transactions: {} | {}",
|
Transactions: {} | {}",
|
||||||
uptime,
|
uptime,
|
||||||
if health == "ok" {
|
if health == "ok" {
|
||||||
|
@ -163,9 +163,17 @@ impl Dashboard {
|
||||||
processed_slot,
|
processed_slot,
|
||||||
confirmed_slot,
|
confirmed_slot,
|
||||||
finalized_slot,
|
finalized_slot,
|
||||||
snapshot_slot
|
snapshot_slot_info
|
||||||
.map(|s| s.to_string())
|
.as_ref()
|
||||||
.unwrap_or_else(|| "-".to_string()),
|
.map(|snapshot_slot_info| snapshot_slot_info.full.to_string())
|
||||||
|
.unwrap_or_else(|| '-'.to_string()),
|
||||||
|
snapshot_slot_info
|
||||||
|
.as_ref()
|
||||||
|
.map(|snapshot_slot_info| snapshot_slot_info
|
||||||
|
.incremental
|
||||||
|
.map(|incremental| incremental.to_string()))
|
||||||
|
.flatten()
|
||||||
|
.unwrap_or_else(|| '-'.to_string()),
|
||||||
transaction_count,
|
transaction_count,
|
||||||
identity_balance
|
identity_balance
|
||||||
));
|
));
|
||||||
|
|
|
@ -149,7 +149,7 @@ fn wait_for_restart_window(
|
||||||
let progress_bar = new_spinner_progress_bar();
|
let progress_bar = new_spinner_progress_bar();
|
||||||
let monitor_start_time = SystemTime::now();
|
let monitor_start_time = SystemTime::now();
|
||||||
loop {
|
loop {
|
||||||
let snapshot_slot = rpc_client.get_snapshot_slot().ok();
|
let snapshot_slot_info = rpc_client.get_highest_snapshot_slot().ok();
|
||||||
let epoch_info = rpc_client.get_epoch_info_with_commitment(CommitmentConfig::processed())?;
|
let epoch_info = rpc_client.get_epoch_info_with_commitment(CommitmentConfig::processed())?;
|
||||||
let healthy = rpc_client.get_health().ok().is_some();
|
let healthy = rpc_client.get_health().ok().is_some();
|
||||||
let delinquent_stake_percentage = {
|
let delinquent_stake_percentage = {
|
||||||
|
@ -278,13 +278,14 @@ fn wait_for_restart_window(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let full_snapshot_slot =
|
||||||
|
snapshot_slot_info.map(|snapshot_slot_info| snapshot_slot_info.full);
|
||||||
match in_leader_schedule_hole {
|
match in_leader_schedule_hole {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
if restart_snapshot == None {
|
if restart_snapshot == None {
|
||||||
restart_snapshot = snapshot_slot;
|
restart_snapshot = full_snapshot_slot;
|
||||||
}
|
}
|
||||||
|
if restart_snapshot == full_snapshot_slot && !monitoring_another_validator {
|
||||||
if restart_snapshot == snapshot_slot && !monitoring_another_validator {
|
|
||||||
"Waiting for a new snapshot".to_string()
|
"Waiting for a new snapshot".to_string()
|
||||||
} else if delinquent_stake_percentage >= min_delinquency_percentage {
|
} else if delinquent_stake_percentage >= min_delinquency_percentage {
|
||||||
style("Delinquency too high").red().to_string()
|
style("Delinquency too high").red().to_string()
|
||||||
|
@ -315,10 +316,10 @@ fn wait_for_restart_window(
|
||||||
"".to_string()
|
"".to_string()
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"| Snapshot Slot: {}",
|
"| Full Snapshot Slot: {}",
|
||||||
snapshot_slot
|
snapshot_slot_info
|
||||||
.map(|s| s.to_string())
|
.map(|snapshot_slot_info| snapshot_slot_info.full.to_string())
|
||||||
.unwrap_or_else(|| "-".to_string())
|
.unwrap_or_else(|| '-'.to_string()),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
delinquent_stake_percentage * 100.,
|
delinquent_stake_percentage * 100.,
|
||||||
|
|
Loading…
Reference in New Issue