diff --git a/clients/cli/src/client.rs b/clients/cli/src/client.rs index c5dbc48c..ea876fbf 100644 --- a/clients/cli/src/client.rs +++ b/clients/cli/src/client.rs @@ -84,10 +84,11 @@ pub(crate) fn get_stake_state( pub(crate) fn get_stake_pools( rpc_client: &RpcClient, + stake_pool_program_id: &Pubkey, ) -> Result, ClientError> { rpc_client .get_program_accounts_with_config( - &spl_stake_pool::id(), + stake_pool_program_id, RpcProgramAccountsConfig { // 0 is the account type filters: Some(vec![RpcFilterType::Memcmp(Memcmp::new( @@ -106,7 +107,7 @@ pub(crate) fn get_stake_pools( .into_iter() .filter_map(|(address, account)| { let pool_withdraw_authority = - find_withdraw_authority_program_address(&spl_stake_pool::id(), &address).0; + find_withdraw_authority_program_address(stake_pool_program_id, &address).0; match try_from_slice_unchecked::(account.data.as_slice()) { Ok(stake_pool) => { get_validator_list(rpc_client, &stake_pool.validator_list) diff --git a/clients/cli/src/main.rs b/clients/cli/src/main.rs index e56990f1..5e8d0caf 100644 --- a/clients/cli/src/main.rs +++ b/clients/cli/src/main.rs @@ -57,6 +57,7 @@ use { }; pub(crate) struct Config { + stake_pool_program_id: Pubkey, rpc_client: RpcClient, verbose: bool, output_format: OutputFormat, @@ -82,6 +83,14 @@ macro_rules! unique_signers { }; } +fn default_stake_pool_id(json_rpc_url: &str) -> Pubkey { + if json_rpc_url.contains("devnet") { + spl_stake_pool::devnet::id() + } else { + spl_stake_pool::id() + } +} + fn check_fee_payer_balance(config: &Config, required_balance: u64) -> Result<(), Error> { let balance = config.rpc_client.get_balance(&config.fee_payer.pubkey())?; if balance < required_balance { @@ -490,7 +499,7 @@ fn setup_and_initialize_validator_list_with_stake_pool( let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; if let Ok(account) = validator_list_account_info { - if account.owner == spl_stake_pool::id() { + if account.owner == config.stake_pool_program_id { if account.data.iter().all(|&x| x == 0) { println!( "Validator list account {} already exists and is ready to be initialized", @@ -510,13 +519,13 @@ fn setup_and_initialize_validator_list_with_stake_pool( &validator_list_keypair.pubkey(), validator_list_balance, validator_list_size as u64, - &spl_stake_pool::id(), + &config.stake_pool_program_id, )); signers.push(validator_list_keypair); } if let Ok(account) = stake_pool_account_info { - if account.owner == spl_stake_pool::id() { + if account.owner == config.stake_pool_program_id { if account.data.iter().all(|&x| x == 0) { println!( "Stake pool account {} already exists but is not initialized", @@ -536,11 +545,11 @@ fn setup_and_initialize_validator_list_with_stake_pool( &stake_pool_keypair.pubkey(), stake_pool_account_lamports, get_packed_len::() as u64, - &spl_stake_pool::id(), + &config.stake_pool_program_id, )); } instructions.push(spl_stake_pool::instruction::initialize( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &stake_pool_keypair.pubkey(), &config.manager.pubkey(), &config.staker.pubkey(), @@ -632,7 +641,7 @@ fn command_create_pool( // Calculate withdraw authority used for minting pool tokens let (withdraw_authority, _) = find_withdraw_authority_program_address( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &stake_pool_keypair.pubkey(), ); @@ -694,7 +703,7 @@ fn create_token_metadata( let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; let instructions = vec![spl_stake_pool::instruction::create_token_metadata( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &stake_pool.manager, &stake_pool.pool_mint, @@ -720,7 +729,7 @@ fn update_token_metadata( let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; let instructions = vec![spl_stake_pool::instruction::update_token_metadata( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &stake_pool.manager, &stake_pool.pool_mint, @@ -759,7 +768,7 @@ fn command_vsa_add( loop { let seed = NonZeroU32::new(i); let (address, _) = find_stake_program_address( - &spl_stake_pool::id(), + &config.stake_pool_program_id, vote_account, stake_pool_address, seed, @@ -788,7 +797,7 @@ fn command_vsa_add( config, &[ spl_stake_pool::instruction::add_validator_to_pool_with_vote( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &stake_pool, stake_pool_address, vote_account, @@ -819,7 +828,7 @@ fn command_vsa_remove( let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()); let (stake_account_address, _) = find_stake_program_address( - &spl_stake_pool::id(), + &config.stake_pool_program_id, vote_account, stake_pool_address, validator_seed, @@ -833,7 +842,7 @@ fn command_vsa_remove( let instructions = vec![ // Create new validator stake account address spl_stake_pool::instruction::remove_validator_from_pool_with_vote( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &stake_pool, stake_pool_address, vote_account, @@ -871,7 +880,7 @@ fn command_increase_validator_stake( config, &[ spl_stake_pool::instruction::increase_validator_stake_with_vote( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &stake_pool, stake_pool_address, vote_account, @@ -910,7 +919,7 @@ fn command_decrease_validator_stake( config, &[ spl_stake_pool::instruction::decrease_validator_stake_with_vote( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &stake_pool, stake_pool_address, vote_account, @@ -937,7 +946,7 @@ fn command_set_preferred_validator( let transaction = checked_transaction_with_signers( config, &[spl_stake_pool::instruction::set_preferred_validator( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &config.staker.pubkey(), &stake_pool.validator_list, @@ -1014,7 +1023,7 @@ fn command_deposit_stake( // Calculate validator stake account address linked to the pool let (validator_stake_account, _) = find_stake_program_address( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &vote_account, stake_pool_address, validator_seed, @@ -1047,7 +1056,8 @@ fn command_deposit_stake( let referrer_token_account = referrer_token_account.unwrap_or(pool_token_receiver_account); let pool_withdraw_authority = - find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + find_withdraw_authority_program_address(&config.stake_pool_program_id, stake_pool_address) + .0; let mut deposit_instructions = if let Some(stake_deposit_authority) = config.funding_authority.as_ref() { @@ -1062,7 +1072,7 @@ fn command_deposit_stake( } spl_stake_pool::instruction::deposit_stake_with_authority( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &stake_pool.validator_list, &stake_deposit_authority.pubkey(), @@ -1079,7 +1089,7 @@ fn command_deposit_stake( ) } else { spl_stake_pool::instruction::deposit_stake( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &stake_pool.validator_list, &pool_withdraw_authority, @@ -1147,7 +1157,8 @@ fn command_deposit_all_stake( let referrer_token_account = referrer_token_account.unwrap_or(pool_token_receiver_account); let pool_withdraw_authority = - find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + find_withdraw_authority_program_address(&config.stake_pool_program_id, stake_pool_address) + .0; let validator_list = get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; let mut signers = if let Some(stake_deposit_authority) = config.funding_authority.as_ref() { if stake_deposit_authority.pubkey() != stake_pool.stake_deposit_authority { @@ -1184,7 +1195,7 @@ fn command_deposit_all_stake( // Calculate validator stake account address linked to the pool let (validator_stake_account, _) = find_stake_program_address( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &vote_account, stake_pool_address, validator_seed, @@ -1200,7 +1211,7 @@ fn command_deposit_all_stake( let instructions = if let Some(stake_deposit_authority) = config.funding_authority.as_ref() { spl_stake_pool::instruction::deposit_stake_with_authority( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &stake_pool.validator_list, &stake_deposit_authority.pubkey(), @@ -1217,7 +1228,7 @@ fn command_deposit_all_stake( ) } else { spl_stake_pool::instruction::deposit_stake( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &stake_pool.validator_list, &pool_withdraw_authority, @@ -1300,7 +1311,8 @@ fn command_deposit_sol( let referrer_token_account = referrer_token_account.unwrap_or(pool_token_receiver_account); let pool_withdraw_authority = - find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + find_withdraw_authority_program_address(&config.stake_pool_program_id, stake_pool_address) + .0; let deposit_instruction = if let Some(deposit_authority) = config.funding_authority.as_ref() { let expected_sol_deposit_authority = stake_pool.sol_deposit_authority.ok_or_else(|| { @@ -1317,7 +1329,7 @@ fn command_deposit_sol( } spl_stake_pool::instruction::deposit_sol_with_authority( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &deposit_authority.pubkey(), &pool_withdraw_authority, @@ -1332,7 +1344,7 @@ fn command_deposit_sol( ) } else { spl_stake_pool::instruction::deposit_sol( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &pool_withdraw_authority, &stake_pool.reserve_stake, @@ -1370,7 +1382,8 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { let pool_mint = get_token_mint(&config.rpc_client, &stake_pool.pool_mint)?; let epoch_info = config.rpc_client.get_epoch_info()?; let pool_withdraw_authority = - find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + find_withdraw_authority_program_address(&config.stake_pool_program_id, stake_pool_address) + .0; let reserve_stake = config.rpc_client.get_account(&stake_pool.reserve_stake)?; let minimum_reserve_stake_balance = config .rpc_client @@ -1382,13 +1395,13 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult { .map(|validator| { let validator_seed = NonZeroU32::new(validator.validator_seed_suffix.into()); let (stake_account_address, _) = find_stake_program_address( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &validator.vote_account_address, stake_pool_address, validator_seed, ); let (transient_stake_account_address, _) = find_transient_stake_program_address( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &validator.vote_account_address, stake_pool_address, validator.transient_seed_suffix.into(), @@ -1459,7 +1472,7 @@ fn command_update( let (mut update_list_instructions, final_instructions) = if stale_only { spl_stake_pool::instruction::update_stale_stake_pool( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &stake_pool, &validator_list, stake_pool_address, @@ -1468,7 +1481,7 @@ fn command_update( ) } else { spl_stake_pool::instruction::update_stake_pool( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &stake_pool, &validator_list, stake_pool_address, @@ -1542,19 +1555,21 @@ where } fn prepare_withdraw_accounts( - rpc_client: &RpcClient, + config: &Config, stake_pool: &StakePool, pool_amount: u64, stake_pool_address: &Pubkey, skip_fee: bool, ) -> Result, Error> { - let stake_minimum_delegation = rpc_client.get_stake_minimum_delegation()?; + let stake_minimum_delegation = config.rpc_client.get_stake_minimum_delegation()?; let stake_pool_minimum_delegation = minimum_delegation(stake_minimum_delegation); - let min_balance = rpc_client + let min_balance = config + .rpc_client .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? .saturating_add(stake_pool_minimum_delegation); - let pool_mint = get_token_mint(rpc_client, &stake_pool.pool_mint)?; - let validator_list: ValidatorList = get_validator_list(rpc_client, &stake_pool.validator_list)?; + let pool_mint = get_token_mint(&config.rpc_client, &stake_pool.pool_mint)?; + let validator_list: ValidatorList = + get_validator_list(&config.rpc_client, &stake_pool.validator_list)?; let mut accounts: Vec<(Pubkey, u64, Option)> = Vec::new(); @@ -1564,7 +1579,7 @@ fn prepare_withdraw_accounts( |validator| { let validator_seed = NonZeroU32::new(validator.validator_seed_suffix.into()); let (stake_account_address, _) = find_stake_program_address( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &validator.vote_account_address, stake_pool_address, validator_seed, @@ -1583,7 +1598,7 @@ fn prepare_withdraw_accounts( stake_pool, |validator| { let (transient_stake_account_address, _) = find_transient_stake_program_address( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &validator.vote_account_address, stake_pool_address, validator.transient_seed_suffix.into(), @@ -1597,12 +1612,14 @@ fn prepare_withdraw_accounts( }, )); - let reserve_stake = rpc_client.get_account(&stake_pool.reserve_stake)?; + let reserve_stake = config.rpc_client.get_account(&stake_pool.reserve_stake)?; accounts.push(( stake_pool.reserve_stake, reserve_stake.lamports - - rpc_client.get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? + - config + .rpc_client + .get_minimum_balance_for_rent_exemption(STAKE_STATE_LEN)? - MINIMUM_RESERVE_LAMPORTS, None, )); @@ -1677,7 +1694,8 @@ fn command_withdraw_stake( let pool_amount = spl_token::ui_amount_to_amount(pool_amount, pool_mint.decimals); let pool_withdraw_authority = - find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + find_withdraw_authority_program_address(&config.stake_pool_program_id, stake_pool_address) + .0; let pool_token_account = pool_token_account.unwrap_or(get_associated_token_address( &config.token_owner.pubkey(), @@ -1748,7 +1766,7 @@ fn command_withdraw_stake( .ok_or(format!("Provided stake account is delegated to a vote account {} which does not exist in the stake pool", vote_account))?; let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()); let (stake_account_address, _) = find_stake_program_address( - &spl_stake_pool::id(), + &config.stake_pool_program_id, &vote_account, stake_pool_address, validator_seed, @@ -1784,7 +1802,7 @@ fn command_withdraw_stake( ))?; let validator_seed = NonZeroU32::new(validator_stake_info.validator_seed_suffix.into()); let (stake_account_address, _) = find_stake_program_address( - &spl_stake_pool::id(), + &config.stake_pool_program_id, vote_account_address, stake_pool_address, validator_seed, @@ -1815,7 +1833,7 @@ fn command_withdraw_stake( } else { // Get the list of accounts to withdraw from prepare_withdraw_accounts( - &config.rpc_client, + config, &stake_pool, pool_amount, stake_pool_address, @@ -1886,7 +1904,7 @@ fn command_withdraw_stake( }; instructions.push(spl_stake_pool::instruction::withdraw_stake( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &stake_pool.validator_list, &pool_withdraw_authority, @@ -1983,7 +2001,8 @@ fn command_withdraw_sol( ]; let pool_withdraw_authority = - find_withdraw_authority_program_address(&spl_stake_pool::id(), stake_pool_address).0; + find_withdraw_authority_program_address(&config.stake_pool_program_id, stake_pool_address) + .0; let withdraw_instruction = if let Some(withdraw_authority) = config.funding_authority.as_ref() { let expected_sol_withdraw_authority = @@ -2001,7 +2020,7 @@ fn command_withdraw_sol( } spl_stake_pool::instruction::withdraw_sol_with_authority( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &withdraw_authority.pubkey(), &pool_withdraw_authority, @@ -2016,7 +2035,7 @@ fn command_withdraw_sol( ) } else { spl_stake_pool::instruction::withdraw_sol( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &pool_withdraw_authority, &user_transfer_authority.pubkey(), @@ -2079,7 +2098,7 @@ fn command_set_manager( let transaction = checked_transaction_with_signers( config, &[spl_stake_pool::instruction::set_manager( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &config.manager.pubkey(), &new_manager_pubkey, @@ -2104,7 +2123,7 @@ fn command_set_staker( let transaction = checked_transaction_with_signers( config, &[spl_stake_pool::instruction::set_staker( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &config.manager.pubkey(), new_staker, @@ -2129,7 +2148,7 @@ fn command_set_funding_authority( let transaction = checked_transaction_with_signers( config, &[spl_stake_pool::instruction::set_funding_authority( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &config.manager.pubkey(), new_authority.as_ref(), @@ -2154,7 +2173,7 @@ fn command_set_fee( let transaction = checked_transaction_with_signers( config, &[spl_stake_pool::instruction::set_fee( - &spl_stake_pool::id(), + &config.stake_pool_program_id, stake_pool_address, &config.manager.pubkey(), new_fee, @@ -2166,7 +2185,7 @@ fn command_set_fee( } fn command_list_all_pools(config: &Config) -> CommandResult { - let all_pools = get_stake_pools(&config.rpc_client)?; + let all_pools = get_stake_pools(&config.rpc_client, &config.stake_pool_program_id)?; let cli_stake_pool_vec: Vec = all_pools.into_iter().map(CliStakePool::from).collect(); let cli_stake_pools = CliStakePools { @@ -2295,6 +2314,15 @@ fn main() { .validator(is_compute_unit_limit_or_simulated) .global(true) ) + .arg( + Arg::with_name("program_id") + .long("program-id") + .validator(is_pubkey) + .value_name("PROGRAM-ID") + .takes_value(true) + .help("Stake pool program id. [default: spl_stake_pool::id() or spl_stake_pool::devnet::id(), depending on target network]") + .global(true) + ) .subcommand(SubCommand::with_name("create-pool") .about("Create a new stake pool") .arg( @@ -3133,6 +3161,8 @@ fn main() { }, ); let verbose = matches.is_present("verbose"); + let stake_pool_program_id = pubkey_of(&matches, "program_id") + .unwrap_or_else(|| default_stake_pool_id(&json_rpc_url)); let output_format = matches .value_of("output_format") .map(|value| match value { @@ -3160,7 +3190,11 @@ fn main() { }); Config { - rpc_client: RpcClient::new_with_commitment(json_rpc_url, CommitmentConfig::confirmed()), + rpc_client: RpcClient::new_with_commitment( + &json_rpc_url, + CommitmentConfig::confirmed(), + ), + stake_pool_program_id, verbose, output_format, manager, diff --git a/program/src/lib.rs b/program/src/lib.rs index 557cf032..2c03b6f6 100644 --- a/program/src/lib.rs +++ b/program/src/lib.rs @@ -158,6 +158,10 @@ pub fn find_ephemeral_stake_program_address( } solana_program::declare_id!("SPoo1Ku8WFXoNDMHPsrGSTSG1Y47rzgn41SLUNakuHy"); +/// Program id for devnet +pub mod devnet { + solana_program::declare_id!("DPoo15wWDqpPJJtS2MUZ49aRxqz5ZaaJCJP4z8bLuib"); +} #[cfg(test)] mod test { diff --git a/scripts/solana.dic b/scripts/solana.dic index 61570060..ad15e4ef 100644 --- a/scripts/solana.dic +++ b/scripts/solana.dic @@ -58,3 +58,4 @@ mpl destake/D bpf sbf +devnet