From 907fc4e44cec7c941a33a199cdea7ccec8aa817f Mon Sep 17 00:00:00 2001 From: ZiminDmitriy Date: Wed, 19 Jan 2022 22:02:50 +0300 Subject: [PATCH] reallocate-half --- stake-pool/cli/src/main.rs | 105 ++++++++++++++++++++++++++ stake-pool/program/src/instruction.rs | 41 ++++++++++ stake-pool/program/src/lib.rs | 2 +- stake-pool/program/src/processor.rs | 82 ++++++++++++++++++++ 4 files changed, 229 insertions(+), 1 deletion(-) diff --git a/stake-pool/cli/src/main.rs b/stake-pool/cli/src/main.rs index 7610d01a745..88a4d1aaba3 100755 --- a/stake-pool/cli/src/main.rs +++ b/stake-pool/cli/src/main.rs @@ -1869,6 +1869,82 @@ fn command_deposit_liquidity_sol( Ok(()) } +fn command_reallocate_stake_pool_account_space( + config: &Config, + stake_pool_address: &Pubkey, + from: &Option, +) -> CommandResult { + + // Check withdraw_from balance + let from_pubkey = from + .as_ref() + .map_or_else(|| config.fee_payer.pubkey(), |keypair| keypair.pubkey()); + let from_balance = config.rpc_client.get_balance(&from_pubkey)?; + + let amount: u64 = 10000000; // TODO + + if from_balance < amount { + return Err(format!( + "Not enough SOL to deposit into pool: {}.\nMaximum deposit amount is {} SOL.", + Sol(amount), + Sol(from_balance) + ) + .into()); + } + + // let new_space_size = get_packed_len::(); // TODO подсчитать Солы для рентексемпт + let new_space_size = 856; + + + + + + + + + let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?; + + let mut instructions: Vec = vec![]; + + // ephemeral SOL account just to do the transfer + let user_sol_transfer = Keypair::new(); + let mut signers = vec![config.fee_payer.as_ref(), config.manager.as_ref()]; //solana program deploy /solana-program-library/source/target/deploy/spl_stake_pool.so + if let Some(keypair) = from.as_ref() { + signers.push(keypair) + } + + // // Create the ephemeral SOL account + // instructions.push(system_instruction::transfer( + // &from_pubkey, + // &user_sol_transfer.pubkey(), + // amount, + // )); + + let reallocate_stake_pool_account_space_instruction = spl_stake_pool::instruction::reallocate_stake_pool_account_space( + &spl_stake_pool::id(), + &stake_pool_address, + &config.manager.pubkey(), + &from_pubkey, // &user_sol_transfer.pubkey(), + amount, + new_space_size as u64 + ); + + instructions.push(reallocate_stake_pool_account_space_instruction); + + let mut transaction = + Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey())); + + let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?; + check_fee_payer_balance( + config, + fee_calculator.calculate_fee(transaction.message()), + )?; + unique_signers!(signers); + transaction.sign(&signers, recent_blockhash); + send_transaction(config, transaction)?; + Ok(()) +} + fn main() { solana_logger::setup_with_default("solana=info"); @@ -2754,6 +2830,26 @@ fn main() { .help("Source account of funds. [default: cli config keypair]"), ) ) + .subcommand(SubCommand::with_name("reallocate-stake-pool-account-space") + .about("Reallocate space for stake pool account") + .arg( + Arg::with_name("pool") + .index(1) + .validator(is_pubkey) + .value_name("POOL_ADDRESS") + .takes_value(true) + .required(true) + .help("Stake pool address"), + ) + .arg( + Arg::with_name("from") + .long("from") + .validator(is_valid_signer) + .value_name("KEYPAIR") + .takes_value(true) + .help("Source account of funds. [default: cli config keypair]"), + ) + ) .get_matches(); let mut wallet_manager = None; @@ -3148,6 +3244,15 @@ fn main() { amount, ) } + ("reallocate-stake-pool-account-space", Some(arg_matches)) => { + let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap(); + let from = keypair_of(arg_matches, "from"); + command_reallocate_stake_pool_account_space( + &config, + &stake_pool_address, + &from, + ) + } _ => unreachable!(), } .map_err(|err| { diff --git a/stake-pool/program/src/instruction.rs b/stake-pool/program/src/instruction.rs index 6bd406806b4..a9836a21239 100755 --- a/stake-pool/program/src/instruction.rs +++ b/stake-pool/program/src/instruction.rs @@ -395,6 +395,20 @@ pub enum StakePoolInstruction { /// 5. `[]` System program account /// 6. `[s]` (Optional) Stake pool sol deposit authority. DepositLiquiditySol(u64), + + /// Reallocate space in stake pool account + /// + /// 0. `[w]` Stake pool + /// 1. `[s]` Manager + /// 2. `[s]` Account providing the lamports to be deposited into the pool + /// 3. `[]` System program account + /// 4. `[]` System program account + ReallocateStakePoolAccountSpace { + /// Number of lamports to transfer to the new account + lamports: u64, + /// Number of bytes of memory to allocate + space: u64, + } } /// Creates an 'initialize' instruction. @@ -1363,4 +1377,31 @@ pub fn deposit_liquidity_sol_with_authority( .try_to_vec() .unwrap(), } +} + +/// Creates instruction required to reallocate space in stake pool account +pub fn reallocate_stake_pool_account_space( + program_id: &Pubkey, + stake_pool: &Pubkey, + manager: &Pubkey, + lamports_from: &Pubkey, + lamports: u64, + space: u64 +) -> Instruction { + let accounts = vec![ + AccountMeta::new(*stake_pool, false), + AccountMeta::new_readonly(*manager, true), + AccountMeta::new(*lamports_from, true), + AccountMeta::new_readonly(*program_id, false), + ]; + Instruction { + program_id: *program_id, + accounts, + data: StakePoolInstruction::ReallocateStakePoolAccountSpace { + lamports, + space, + } + .try_to_vec() + .unwrap(), + } } \ No newline at end of file diff --git a/stake-pool/program/src/lib.rs b/stake-pool/program/src/lib.rs index e458582de8e..62e0d6f9122 100755 --- a/stake-pool/program/src/lib.rs +++ b/stake-pool/program/src/lib.rs @@ -122,4 +122,4 @@ pub fn find_transient_stake_program_address( ) } -solana_program::declare_id!("EverSFw9uN5t1V8kS3ficHUcKffSjwpGzUSGd7mgmSks"); \ No newline at end of file +solana_program::declare_id!("CrtX5qVvqQu6x33fBqMLRdr7wotbtjjWTrXM45rLZRsf"); // TODODOD \ No newline at end of file diff --git a/stake-pool/program/src/processor.rs b/stake-pool/program/src/processor.rs index c09ab583ee4..c2054f669f2 100755 --- a/stake-pool/program/src/processor.rs +++ b/stake-pool/program/src/processor.rs @@ -2852,6 +2852,81 @@ impl Processor { Ok(()) } + /// Processes [ReallocateStakePoolAccountSpace](enum.Instruction.html). + #[inline(never)] // needed to avoid stack size violation + fn process_reallocate_stake_pool_account_space( + program_id: &Pubkey, + accounts: &[AccountInfo], + lamports: u64, + new_space: u64, + ) -> ProgramResult { // TODO Проверка, что новы спейс точно больше предыдущег и на максимальное значение + let account_info_iter = &mut accounts.iter(); + let stake_pool_info = next_account_info(account_info_iter)?; + let manager_info = next_account_info(account_info_iter)?; + let from_user_lamports_info = next_account_info(account_info_iter)?; + let system_program_info = next_account_info(account_info_iter)?; + + + msg!("QQQQQQQQQQQQQQQQQQQQQ"); + msg!("{:?}", system_program_info.key); + msg!("{:?}", stake_pool_info.owner); + msg!("QQQQQQQQQQQQQQQQQQQQQ"); + + + msg!("{:?}", stake_pool_info.data_len()); + stake_pool_info.realloc(new_space as usize, false)?; + msg!("{:?}", stake_pool_info.data_len()); + + + + + // check_account_owner(stake_pool_info, program_id)?; + // let mut stake_pool = try_from_slice_unchecked::(&stake_pool_info.data.borrow())?; + // if !stake_pool.is_valid() { + // return Err(StakePoolError::InvalidState.into()); + // } + + // if stake_pool.last_update_epoch < Clock::get()?.epoch { + // return Err(StakePoolError::StakeListAndPoolOutOfDate.into()); + // } + + // stake_pool.check_authority_withdraw( + // withdraw_authority_info.key, + // program_id, + // stake_pool_info.key, + // )?; + // stake_pool.check_sol_deposit_authority(sol_deposit_authority_info)?; + // stake_pool.check_reserve_stake(reserve_stake_account_info)?; + + // stake_pool.check_manager(manager_info)?; + + // check_system_program(system_program_info.key)?; + + // if deposit_lamports < MINIMUM_DEPOSIT { + // return Err(StakePoolError::DepositTooSmall.into()); + // } + + // Self::sol_transfer( + // from_user_lamports_info.clone(), + // stake_pool_info.clone(), + // system_program_info.clone(), + // lamports, + // )?; + + // stake_pool.total_lamports = stake_pool + // .total_lamports + // .checked_add(deposit_lamports) + // .ok_or(StakePoolError::CalculationFailure)?; + // stake_pool.total_lamports_liquidity = stake_pool + // .total_lamports_liquidity + // .checked_add(deposit_lamports) + // .ok_or(StakePoolError::CalculationFailure)?; + + // stake_pool.serialize(&mut *stake_pool_info.data.borrow_mut())?; + + Ok(()) + } + /// Processes [Instruction](enum.Instruction.html). pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult { let instruction = StakePoolInstruction::try_from_slice(input)?; @@ -2978,6 +3053,13 @@ impl Processor { msg!("Instruction: DepositLiquiditySol"); Self::process_deposit_liquidity_sol(program_id, accounts, lamports) } + StakePoolInstruction::ReallocateStakePoolAccountSpace { + lamports, + space, + } => { + msg!("Instruction: ReallocateStakePoolAccountSpace"); + Self::process_reallocate_stake_pool_account_space(program_id, accounts, lamports, space) + } } } }