Add wait for max stake command (#13532)
This commit is contained in:
parent
30ef53cb13
commit
598e5f58d5
|
@ -149,6 +149,9 @@ pub enum CliCommand {
|
||||||
limit: usize,
|
limit: usize,
|
||||||
show_transactions: bool,
|
show_transactions: bool,
|
||||||
},
|
},
|
||||||
|
WaitForMaxStake {
|
||||||
|
max_stake_percent: f32,
|
||||||
|
},
|
||||||
// Nonce commands
|
// Nonce commands
|
||||||
AuthorizeNonceAccount {
|
AuthorizeNonceAccount {
|
||||||
nonce_account: Pubkey,
|
nonce_account: Pubkey,
|
||||||
|
@ -624,6 +627,13 @@ pub fn parse_command(
|
||||||
signers,
|
signers,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
("wait-for-max-stake", Some(matches)) => {
|
||||||
|
let max_stake_percent = value_t_or_exit!(matches, "max_percent", f32);
|
||||||
|
Ok(CliCommandInfo {
|
||||||
|
command: CliCommand::WaitForMaxStake { max_stake_percent },
|
||||||
|
signers: vec![],
|
||||||
|
})
|
||||||
|
}
|
||||||
// Stake Commands
|
// Stake Commands
|
||||||
("create-stake-account", Some(matches)) => {
|
("create-stake-account", Some(matches)) => {
|
||||||
parse_stake_create_account(matches, default_signer, wallet_manager)
|
parse_stake_create_account(matches, default_signer, wallet_manager)
|
||||||
|
@ -1565,6 +1575,9 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
|
||||||
*use_lamports_unit,
|
*use_lamports_unit,
|
||||||
vote_account_pubkeys.as_deref(),
|
vote_account_pubkeys.as_deref(),
|
||||||
),
|
),
|
||||||
|
CliCommand::WaitForMaxStake { max_stake_percent } => {
|
||||||
|
process_wait_for_max_stake(&rpc_client, config, *max_stake_percent)
|
||||||
|
}
|
||||||
CliCommand::ShowValidators { use_lamports_unit } => {
|
CliCommand::ShowValidators { use_lamports_unit } => {
|
||||||
process_show_validators(&rpc_client, config, *use_lamports_unit)
|
process_show_validators(&rpc_client, config, *use_lamports_unit)
|
||||||
}
|
}
|
||||||
|
|
|
@ -318,6 +318,17 @@ impl ClusterQuerySubCommands for App<'_, '_> {
|
||||||
.help("Display the full transactions"),
|
.help("Display the full transactions"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
.subcommand(
|
||||||
|
SubCommand::with_name("wait-for-max-stake")
|
||||||
|
.about("Wait for the max stake of any one node to drop below a percentage of total.")
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("max_percent")
|
||||||
|
.long("max-percent")
|
||||||
|
.value_name("PERCENT")
|
||||||
|
.takes_value(true)
|
||||||
|
.index(1),
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1400,6 +1411,16 @@ pub fn process_show_stakes(
|
||||||
.formatted_string(&CliStakeVec::new(stake_accounts)))
|
.formatted_string(&CliStakeVec::new(stake_accounts)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn process_wait_for_max_stake(
|
||||||
|
rpc_client: &RpcClient,
|
||||||
|
config: &CliConfig,
|
||||||
|
max_stake_percent: f32,
|
||||||
|
) -> ProcessResult {
|
||||||
|
let now = std::time::Instant::now();
|
||||||
|
rpc_client.wait_for_max_stake(config.commitment, max_stake_percent)?;
|
||||||
|
Ok(format!("Done waiting, took: {}s", now.elapsed().as_secs()))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn process_show_validators(
|
pub fn process_show_validators(
|
||||||
rpc_client: &RpcClient,
|
rpc_client: &RpcClient,
|
||||||
config: &CliConfig,
|
config: &CliConfig,
|
||||||
|
|
|
@ -353,6 +353,38 @@ impl RpcClient {
|
||||||
self.send(RpcRequest::GetVoteAccounts, json!([commitment_config]))
|
self.send(RpcRequest::GetVoteAccounts, json!([commitment_config]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn wait_for_max_stake(
|
||||||
|
&self,
|
||||||
|
commitment: CommitmentConfig,
|
||||||
|
max_stake_percent: f32,
|
||||||
|
) -> ClientResult<()> {
|
||||||
|
let mut current_percent;
|
||||||
|
loop {
|
||||||
|
let vote_accounts = self.get_vote_accounts_with_commitment(commitment)?;
|
||||||
|
|
||||||
|
let mut max = 0;
|
||||||
|
let total_active_stake = vote_accounts
|
||||||
|
.current
|
||||||
|
.iter()
|
||||||
|
.chain(vote_accounts.delinquent.iter())
|
||||||
|
.map(|vote_account| {
|
||||||
|
max = std::cmp::max(max, vote_account.activated_stake);
|
||||||
|
vote_account.activated_stake
|
||||||
|
})
|
||||||
|
.sum::<u64>();
|
||||||
|
current_percent = 100f32 * max as f32 / total_active_stake as f32;
|
||||||
|
if current_percent < max_stake_percent {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
info!(
|
||||||
|
"Waiting for stake to drop below {} current: {:.1}",
|
||||||
|
max_stake_percent, current_percent
|
||||||
|
);
|
||||||
|
sleep(Duration::from_secs(10));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_cluster_nodes(&self) -> ClientResult<Vec<RpcContactInfo>> {
|
pub fn get_cluster_nodes(&self) -> ClientResult<Vec<RpcContactInfo>> {
|
||||||
self.send(RpcRequest::GetClusterNodes, Value::Null)
|
self.send(RpcRequest::GetClusterNodes, Value::Null)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1340,6 +1340,26 @@ fn test_faulty_node(faulty_node_type: BroadcastStageType) {
|
||||||
cluster.check_for_new_roots(16, &"test_faulty_node");
|
cluster.check_for_new_roots(16, &"test_faulty_node");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_wait_for_max_stake() {
|
||||||
|
solana_logger::setup();
|
||||||
|
let mut validator_config = ValidatorConfig::default();
|
||||||
|
validator_config.rpc_config.enable_validator_exit = true;
|
||||||
|
let config = ClusterConfig {
|
||||||
|
cluster_lamports: 10_000,
|
||||||
|
node_stakes: vec![100; 4],
|
||||||
|
validator_configs: vec![validator_config; 4],
|
||||||
|
..ClusterConfig::default()
|
||||||
|
};
|
||||||
|
let cluster = LocalCluster::new(&config);
|
||||||
|
let client = RpcClient::new_socket(cluster.entry_point_info.rpc);
|
||||||
|
|
||||||
|
assert!(client
|
||||||
|
.wait_for_max_stake(CommitmentConfig::default(), 33.0f32)
|
||||||
|
.is_ok());
|
||||||
|
assert!(client.get_slot().unwrap() > 10);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
// Test that when a leader is leader for banks B_i..B_{i+n}, and B_i is not
|
// Test that when a leader is leader for banks B_i..B_{i+n}, and B_i is not
|
||||||
// votable, then B_{i+1} still chains to B_i
|
// votable, then B_{i+1} still chains to B_i
|
||||||
|
|
|
@ -69,18 +69,8 @@ function wait_for_bootstrap_validator_stake_drop {
|
||||||
source "${REPO_ROOT}"/net/common.sh
|
source "${REPO_ROOT}"/net/common.sh
|
||||||
loadConfigFile
|
loadConfigFile
|
||||||
|
|
||||||
while true; do
|
|
||||||
# shellcheck disable=SC2154
|
# shellcheck disable=SC2154
|
||||||
bootstrap_validator_validator_info="$(ssh "${sshOptions[@]}" "${validatorIpList[0]}" '$HOME/.cargo/bin/solana --url http://127.0.0.1:8899 validators | grep "$($HOME/.cargo/bin/solana-keygen pubkey ~/solana/config/bootstrap-validator/identity.json)"')"
|
ssh "${sshOptions[@]}" "${validatorIpList[0]}" '$HOME/.cargo/bin/solana wait-for-max-stake $max_stake --url http://127.0.0.1:8899'
|
||||||
bootstrap_validator_stake_percentage="$(echo "$bootstrap_validator_validator_info" | awk '{gsub(/[\(,\),\%]/,""); print $9}')"
|
|
||||||
|
|
||||||
if [[ $(echo "$bootstrap_validator_stake_percentage < $max_stake" | bc) -ne 0 ]]; then
|
|
||||||
echo "Bootstrap validator stake has fallen below $max_stake to $bootstrap_validator_stake_percentage"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
echo "Max bootstrap validator stake: $max_stake. Current stake: $bootstrap_validator_stake_percentage. Sleeping 30s for stake to distribute."
|
|
||||||
sleep 30
|
|
||||||
done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_slot {
|
function get_slot {
|
||||||
|
|
Loading…
Reference in New Issue