Add commitment Root variant, and add fleshed out --commitment arg to Cli (#9806)

automerge
This commit is contained in:
Tyera Eulberg 2020-04-29 22:55:33 -06:00 committed by GitHub
parent a91236012d
commit 6deaf649ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 93 additions and 128 deletions

View File

@ -0,0 +1,17 @@
use crate::ArgConstant;
use clap::Arg;
pub const COMMITMENT_ARG: ArgConstant<'static> = ArgConstant {
name: "commitment",
long: "commitment",
help: "Return information at the selected commitment level",
};
pub fn commitment_arg<'a, 'b>() -> Arg<'a, 'b> {
Arg::with_name(COMMITMENT_ARG.name)
.long(COMMITMENT_ARG.long)
.takes_value(true)
.possible_values(&["default", "max", "recent", "root"])
.value_name("COMMITMENT_LEVEL")
.help(COMMITMENT_ARG.help)
}

View File

@ -7,6 +7,7 @@ use clap::ArgMatches;
use solana_remote_wallet::remote_wallet::RemoteWalletManager; use solana_remote_wallet::remote_wallet::RemoteWalletManager;
use solana_sdk::{ use solana_sdk::{
clock::UnixTimestamp, clock::UnixTimestamp,
commitment_config::CommitmentConfig,
native_token::sol_to_lamports, native_token::sol_to_lamports,
pubkey::Pubkey, pubkey::Pubkey,
signature::{read_keypair_file, Keypair, Signature, Signer}, signature::{read_keypair_file, Keypair, Signature, Signer},
@ -177,6 +178,15 @@ pub fn lamports_of_sol(matches: &ArgMatches<'_>, name: &str) -> Option<u64> {
value_of(matches, name).map(sol_to_lamports) value_of(matches, name).map(sol_to_lamports)
} }
pub fn commitment_of(matches: &ArgMatches<'_>, name: &str) -> Option<CommitmentConfig> {
matches.value_of(name).map(|value| match value {
"max" => CommitmentConfig::max(),
"recent" => CommitmentConfig::recent(),
"root" => CommitmentConfig::root(),
_ => CommitmentConfig::default(),
})
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View File

@ -42,6 +42,7 @@ impl std::fmt::Debug for DisplayError {
} }
} }
pub mod commitment;
pub mod input_parsers; pub mod input_parsers;
pub mod input_validators; pub mod input_validators;
pub mod keypair; pub mod keypair;

View File

@ -10,7 +10,12 @@ use chrono::{DateTime, NaiveDateTime, SecondsFormat, Utc};
use clap::{value_t, value_t_or_exit, App, Arg, ArgMatches, SubCommand}; use clap::{value_t, value_t_or_exit, App, Arg, ArgMatches, SubCommand};
use console::{style, Emoji}; use console::{style, Emoji};
use indicatif::{ProgressBar, ProgressStyle}; use indicatif::{ProgressBar, ProgressStyle};
use solana_clap_utils::{input_parsers::*, input_validators::*, keypair::signer_from_path}; use solana_clap_utils::{
commitment::{commitment_arg, COMMITMENT_ARG},
input_parsers::*,
input_validators::*,
keypair::signer_from_path,
};
use solana_client::{ use solana_client::{
pubsub_client::{PubsubClient, SlotInfoMessage}, pubsub_client::{PubsubClient, SlotInfoMessage},
rpc_client::RpcClient, rpc_client::RpcClient,
@ -68,20 +73,13 @@ impl ClusterQuerySubCommands for App<'_, '_> {
.validator(is_url) .validator(is_url)
.help("JSON RPC URL for validator, which is useful for validators with a private RPC service") .help("JSON RPC URL for validator, which is useful for validators with a private RPC service")
) )
.arg(
Arg::with_name("confirmed")
.long("confirmed")
.takes_value(false)
.help(
"Return information at maximum-lockout commitment level",
),
)
.arg( .arg(
Arg::with_name("follow") Arg::with_name("follow")
.long("follow") .long("follow")
.takes_value(false) .takes_value(false)
.help("Continue reporting progress even after the validator has caught up"), .help("Continue reporting progress even after the validator has caught up"),
), )
.arg(commitment_arg()),
) )
.subcommand( .subcommand(
SubCommand::with_name("cluster-version") SubCommand::with_name("cluster-version")
@ -105,14 +103,7 @@ impl ClusterQuerySubCommands for App<'_, '_> {
SubCommand::with_name("epoch-info") SubCommand::with_name("epoch-info")
.about("Get information about the current epoch") .about("Get information about the current epoch")
.alias("get-epoch-info") .alias("get-epoch-info")
.arg( .arg(commitment_arg()),
Arg::with_name("confirmed")
.long("confirmed")
.takes_value(false)
.help(
"Return information at maximum-lockout commitment level",
),
),
) )
.subcommand( .subcommand(
SubCommand::with_name("genesis-hash") SubCommand::with_name("genesis-hash")
@ -122,48 +113,20 @@ impl ClusterQuerySubCommands for App<'_, '_> {
.subcommand( .subcommand(
SubCommand::with_name("slot").about("Get current slot") SubCommand::with_name("slot").about("Get current slot")
.alias("get-slot") .alias("get-slot")
.arg( .arg(commitment_arg()),
Arg::with_name("confirmed")
.long("confirmed")
.takes_value(false)
.help(
"Return slot at maximum-lockout commitment level",
),
),
) )
.subcommand( .subcommand(
SubCommand::with_name("epoch").about("Get current epoch") SubCommand::with_name("epoch").about("Get current epoch")
.arg( .arg(commitment_arg()),
Arg::with_name("confirmed")
.long("confirmed")
.takes_value(false)
.help(
"Return epoch at maximum-lockout commitment level",
),
),
) )
.subcommand( .subcommand(
SubCommand::with_name("total-supply").about("Get total number of SOL") SubCommand::with_name("total-supply").about("Get total number of SOL")
.arg( .arg(commitment_arg()),
Arg::with_name("confirmed")
.long("confirmed")
.takes_value(false)
.help(
"Return count at maximum-lockout commitment level",
),
),
) )
.subcommand( .subcommand(
SubCommand::with_name("transaction-count").about("Get current transaction count") SubCommand::with_name("transaction-count").about("Get current transaction count")
.alias("get-transaction-count") .alias("get-transaction-count")
.arg( .arg(commitment_arg()),
Arg::with_name("confirmed")
.long("confirmed")
.takes_value(false)
.help(
"Return count at maximum-lockout commitment level",
),
),
) )
.subcommand( .subcommand(
SubCommand::with_name("ping") SubCommand::with_name("ping")
@ -204,12 +167,12 @@ impl ClusterQuerySubCommands for App<'_, '_> {
.help("Wait up to timeout seconds for transaction confirmation"), .help("Wait up to timeout seconds for transaction confirmation"),
) )
.arg( .arg(
Arg::with_name("confirmed") Arg::with_name(COMMITMENT_ARG.name)
.long("confirmed") .long(COMMITMENT_ARG.long)
.takes_value(false) .takes_value(true)
.help( .possible_values(&["default", "max", "recent", "root"])
"Wait until the transaction is confirmed at maximum-lockout commitment level", .value_name("COMMITMENT_LEVEL")
), .help("Wait until the transaction is confirmed at selected commitment level"),
), ),
) )
.subcommand( .subcommand(
@ -259,20 +222,13 @@ impl ClusterQuerySubCommands for App<'_, '_> {
SubCommand::with_name("validators") SubCommand::with_name("validators")
.about("Show summary information about the current validators") .about("Show summary information about the current validators")
.alias("show-validators") .alias("show-validators")
.arg(
Arg::with_name("confirmed")
.long("confirmed")
.takes_value(false)
.help(
"Return information at maximum-lockout commitment level",
),
)
.arg( .arg(
Arg::with_name("lamports") Arg::with_name("lamports")
.long("lamports") .long("lamports")
.takes_value(false) .takes_value(false)
.help("Display balance in lamports instead of SOL"), .help("Display balance in lamports instead of SOL"),
), )
.arg(commitment_arg()),
) )
.subcommand( .subcommand(
SubCommand::with_name("transaction-history") SubCommand::with_name("transaction-history")
@ -316,11 +272,8 @@ pub fn parse_catchup(
) -> Result<CliCommandInfo, CliError> { ) -> Result<CliCommandInfo, CliError> {
let node_pubkey = pubkey_of_signer(matches, "node_pubkey", wallet_manager)?.unwrap(); let node_pubkey = pubkey_of_signer(matches, "node_pubkey", wallet_manager)?.unwrap();
let node_json_rpc_url = value_t!(matches, "node_json_rpc_url", String).ok(); let node_json_rpc_url = value_t!(matches, "node_json_rpc_url", String).ok();
let commitment_config = if matches.is_present("confirmed") { let commitment_config =
CommitmentConfig::default() commitment_of(matches, COMMITMENT_ARG.long).unwrap_or_else(CommitmentConfig::recent);
} else {
CommitmentConfig::recent()
};
let follow = matches.is_present("follow"); let follow = matches.is_present("follow");
Ok(CliCommandInfo { Ok(CliCommandInfo {
command: CliCommand::Catchup { command: CliCommand::Catchup {
@ -346,11 +299,8 @@ pub fn parse_cluster_ping(
None None
}; };
let timeout = Duration::from_secs(value_t_or_exit!(matches, "timeout", u64)); let timeout = Duration::from_secs(value_t_or_exit!(matches, "timeout", u64));
let commitment_config = if matches.is_present("confirmed") { let commitment_config =
CommitmentConfig::default() commitment_of(matches, COMMITMENT_ARG.long).unwrap_or_else(CommitmentConfig::recent);
} else {
CommitmentConfig::recent()
};
Ok(CliCommandInfo { Ok(CliCommandInfo {
command: CliCommand::Ping { command: CliCommand::Ping {
lamports, lamports,
@ -377,11 +327,8 @@ pub fn parse_get_block_time(matches: &ArgMatches<'_>) -> Result<CliCommandInfo,
} }
pub fn parse_get_epoch_info(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> { pub fn parse_get_epoch_info(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let commitment_config = if matches.is_present("confirmed") { let commitment_config =
CommitmentConfig::default() commitment_of(matches, COMMITMENT_ARG.long).unwrap_or_else(CommitmentConfig::recent);
} else {
CommitmentConfig::recent()
};
Ok(CliCommandInfo { Ok(CliCommandInfo {
command: CliCommand::GetEpochInfo { commitment_config }, command: CliCommand::GetEpochInfo { commitment_config },
signers: vec![], signers: vec![],
@ -389,11 +336,8 @@ pub fn parse_get_epoch_info(matches: &ArgMatches<'_>) -> Result<CliCommandInfo,
} }
pub fn parse_get_slot(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> { pub fn parse_get_slot(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let commitment_config = if matches.is_present("confirmed") { let commitment_config =
CommitmentConfig::default() commitment_of(matches, COMMITMENT_ARG.long).unwrap_or_else(CommitmentConfig::recent);
} else {
CommitmentConfig::recent()
};
Ok(CliCommandInfo { Ok(CliCommandInfo {
command: CliCommand::GetSlot { commitment_config }, command: CliCommand::GetSlot { commitment_config },
signers: vec![], signers: vec![],
@ -401,11 +345,8 @@ pub fn parse_get_slot(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliErr
} }
pub fn parse_get_epoch(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> { pub fn parse_get_epoch(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let commitment_config = if matches.is_present("confirmed") { let commitment_config =
CommitmentConfig::default() commitment_of(matches, COMMITMENT_ARG.long).unwrap_or_else(CommitmentConfig::recent);
} else {
CommitmentConfig::recent()
};
Ok(CliCommandInfo { Ok(CliCommandInfo {
command: CliCommand::GetEpoch { commitment_config }, command: CliCommand::GetEpoch { commitment_config },
signers: vec![], signers: vec![],
@ -413,11 +354,8 @@ pub fn parse_get_epoch(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliEr
} }
pub fn parse_total_supply(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> { pub fn parse_total_supply(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let commitment_config = if matches.is_present("confirmed") { let commitment_config =
CommitmentConfig::default() commitment_of(matches, COMMITMENT_ARG.long).unwrap_or_else(CommitmentConfig::recent);
} else {
CommitmentConfig::recent()
};
Ok(CliCommandInfo { Ok(CliCommandInfo {
command: CliCommand::TotalSupply { commitment_config }, command: CliCommand::TotalSupply { commitment_config },
signers: vec![], signers: vec![],
@ -425,11 +363,8 @@ pub fn parse_total_supply(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, Cl
} }
pub fn parse_get_transaction_count(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> { pub fn parse_get_transaction_count(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let commitment_config = if matches.is_present("confirmed") { let commitment_config =
CommitmentConfig::default() commitment_of(matches, COMMITMENT_ARG.long).unwrap_or_else(CommitmentConfig::recent);
} else {
CommitmentConfig::recent()
};
Ok(CliCommandInfo { Ok(CliCommandInfo {
command: CliCommand::GetTransactionCount { commitment_config }, command: CliCommand::GetTransactionCount { commitment_config },
signers: vec![], signers: vec![],
@ -455,11 +390,8 @@ pub fn parse_show_stakes(
pub fn parse_show_validators(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> { pub fn parse_show_validators(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let use_lamports_unit = matches.is_present("lamports"); let use_lamports_unit = matches.is_present("lamports");
let commitment_config = if matches.is_present("confirmed") { let commitment_config =
CommitmentConfig::default() commitment_of(matches, COMMITMENT_ARG.long).unwrap_or_else(CommitmentConfig::recent);
} else {
CommitmentConfig::recent()
};
Ok(CliCommandInfo { Ok(CliCommandInfo {
command: CliCommand::ShowValidators { command: CliCommand::ShowValidators {
@ -1396,7 +1328,8 @@ mod tests {
"2", "2",
"-t", "-t",
"3", "3",
"--confirmed", "--commitment",
"max",
]); ]);
assert_eq!( assert_eq!(
parse_command(&test_ping, &default_keypair_file, &mut None).unwrap(), parse_command(&test_ping, &default_keypair_file, &mut None).unwrap(),
@ -1406,7 +1339,7 @@ mod tests {
interval: Duration::from_secs(1), interval: Duration::from_secs(1),
count: Some(2), count: Some(2),
timeout: Duration::from_secs(3), timeout: Duration::from_secs(3),
commitment_config: CommitmentConfig::default(), commitment_config: CommitmentConfig::max(),
}, },
signers: vec![default_keypair.into()], signers: vec![default_keypair.into()],
} }

View File

@ -7,7 +7,11 @@ use crate::{
cli_output::{CliEpochVotingHistory, CliLockout, CliVoteAccount}, cli_output::{CliEpochVotingHistory, CliLockout, CliVoteAccount},
}; };
use clap::{value_t_or_exit, App, Arg, ArgMatches, SubCommand}; use clap::{value_t_or_exit, App, Arg, ArgMatches, SubCommand};
use solana_clap_utils::{input_parsers::*, input_validators::*}; use solana_clap_utils::{
commitment::{commitment_arg, COMMITMENT_ARG},
input_parsers::*,
input_validators::*,
};
use solana_client::rpc_client::RpcClient; use solana_client::rpc_client::RpcClient;
use solana_remote_wallet::remote_wallet::RemoteWalletManager; use solana_remote_wallet::remote_wallet::RemoteWalletManager;
use solana_sdk::{ use solana_sdk::{
@ -160,14 +164,6 @@ impl VoteSubCommands for App<'_, '_> {
SubCommand::with_name("vote-account") SubCommand::with_name("vote-account")
.about("Show the contents of a vote account") .about("Show the contents of a vote account")
.alias("show-vote-account") .alias("show-vote-account")
.arg(
Arg::with_name("confirmed")
.long("confirmed")
.takes_value(false)
.help(
"Return information at maximum-lockout commitment level",
),
)
.arg( .arg(
pubkey!(Arg::with_name("vote_account_pubkey") pubkey!(Arg::with_name("vote_account_pubkey")
.index(1) .index(1)
@ -180,7 +176,8 @@ impl VoteSubCommands for App<'_, '_> {
.long("lamports") .long("lamports")
.takes_value(false) .takes_value(false)
.help("Display balance in lamports instead of SOL"), .help("Display balance in lamports instead of SOL"),
), )
.arg(commitment_arg()),
) )
.subcommand( .subcommand(
SubCommand::with_name("withdraw-from-vote-account") SubCommand::with_name("withdraw-from-vote-account")
@ -318,11 +315,8 @@ pub fn parse_vote_get_account_command(
let vote_account_pubkey = let vote_account_pubkey =
pubkey_of_signer(matches, "vote_account_pubkey", wallet_manager)?.unwrap(); pubkey_of_signer(matches, "vote_account_pubkey", wallet_manager)?.unwrap();
let use_lamports_unit = matches.is_present("lamports"); let use_lamports_unit = matches.is_present("lamports");
let commitment_config = if matches.is_present("confirmed") { let commitment_config =
CommitmentConfig::default() commitment_of(matches, COMMITMENT_ARG.long).unwrap_or_else(CommitmentConfig::recent);
} else {
CommitmentConfig::recent()
};
Ok(CliCommandInfo { Ok(CliCommandInfo {
command: CliCommand::ShowVoteAccount { command: CliCommand::ShowVoteAccount {
pubkey: vote_account_pubkey, pubkey: vote_account_pubkey,

View File

@ -87,6 +87,10 @@ impl JsonRpcRequestProcessor {
let bank = r_bank_forks.working_bank(); let bank = r_bank_forks.working_bank();
debug!("RPC using working_bank: {:?}", bank.slot()); debug!("RPC using working_bank: {:?}", bank.slot());
Ok(bank) Ok(bank)
} else if commitment.is_some() && commitment.unwrap().commitment == CommitmentLevel::Root {
let slot = r_bank_forks.root();
debug!("RPC using node root: {:?}", slot);
Ok(r_bank_forks.get(slot).cloned().unwrap())
} else { } else {
let cluster_root = self let cluster_root = self
.block_commitment_cache .block_commitment_cache
@ -169,9 +173,7 @@ impl JsonRpcRequestProcessor {
pub fn get_epoch_schedule(&self) -> Result<EpochSchedule> { pub fn get_epoch_schedule(&self) -> Result<EpochSchedule> {
// Since epoch schedule data comes from the genesis config, any commitment level should be // Since epoch schedule data comes from the genesis config, any commitment level should be
// fine // fine
Ok(*self Ok(*self.bank(Some(CommitmentConfig::root()))?.epoch_schedule())
.bank(Some(CommitmentConfig::recent()))?
.epoch_schedule())
} }
pub fn get_balance( pub fn get_balance(

View File

@ -95,7 +95,8 @@ Requests can be sent in batches by sending an array of JSON-RPC request objects
Solana nodes choose which bank state to query based on a commitment requirement Solana nodes choose which bank state to query based on a commitment requirement
set by the client. Clients may specify either: set by the client. Clients may specify either:
* `{"commitment":"max"}` - the node will query the most recent bank having reached `MAX_LOCKOUT_HISTORY` confirmations * `{"commitment":"max"}` - the node will query the most recent bank confirmed by the cluster as having reached `MAX_LOCKOUT_HISTORY` confirmations
* `{"commitment":"root"}` - the node will query the most recent bank having reached `MAX_LOCKOUT_HISTORY` confirmations on this node
* `{"commitment":"recent"}` - the node will query its most recent bank state * `{"commitment":"recent"}` - the node will query its most recent bank state
The commitment parameter should be included as the last element in the `params` array: The commitment parameter should be included as the last element in the `params` array:
@ -196,7 +197,7 @@ The result field will be a JSON object containing:
* `commitment` - commitment, comprising either: * `commitment` - commitment, comprising either:
* `<null>` - Unknown block * `<null>` - Unknown block
* `<array>` - commitment, array of u64 integers logging the amount of cluster stake in lamports that has voted on the block at each depth from 0 to `MAX_LOCKOUT_HISTORY` * `<array>` - commitment, array of u64 integers logging the amount of cluster stake in lamports that has voted on the block at each depth from 0 to `MAX_LOCKOUT_HISTORY` + 1
* `totalStake` - total active stake, in lamports, of the current epoch * `totalStake` - total active stake, in lamports, of the current epoch
#### Example: #### Example:
@ -206,7 +207,7 @@ The result field will be a JSON object containing:
curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getBlockCommitment","params":[5]}' http://localhost:8899 curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getBlockCommitment","params":[5]}' http://localhost:8899
// Result // Result
{"jsonrpc":"2.0","result":{"commitment":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,32],"totalStake": 42},"id":1} {"jsonrpc":"2.0","result":{"commitment":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,32],"totalStake": 42},"id":1}
``` ```
### getBlockTime ### getBlockTime

View File

@ -25,6 +25,12 @@ impl CommitmentConfig {
} }
} }
pub fn root() -> Self {
Self {
commitment: CommitmentLevel::Root,
}
}
pub fn ok(self) -> Option<Self> { pub fn ok(self) -> Option<Self> {
if self == Self::default() { if self == Self::default() {
None None
@ -39,4 +45,5 @@ impl CommitmentConfig {
pub enum CommitmentLevel { pub enum CommitmentLevel {
Max, Max,
Recent, Recent,
Root,
} }