Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 9f38a6f

Browse files
authored
Rework create validator stake account (#1539)
1 parent f2de73d commit 9f38a6f

File tree

10 files changed

+379
-572
lines changed

10 files changed

+379
-572
lines changed

stake-pool/cli/src/main.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -277,21 +277,21 @@ fn command_vsa_create(config: &Config, pool: &Pubkey, vote_account: &Pubkey) ->
277277
create_validator_stake_account(
278278
&spl_stake_pool::id(),
279279
&pool,
280+
&config.owner.pubkey(),
280281
&config.fee_payer.pubkey(),
281282
&stake_account,
282283
&vote_account,
283-
&config.owner.pubkey(),
284-
&config.owner.pubkey(),
285-
&solana_program::system_program::id(),
286-
&stake_program_id(),
287284
)?,
288285
],
289286
Some(&config.fee_payer.pubkey()),
290287
);
291288

292289
let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
293290
check_fee_payer_balance(config, fee_calculator.calculate_fee(&transaction.message()))?;
294-
transaction.sign(&[config.fee_payer.as_ref()], recent_blockhash);
291+
transaction.sign(
292+
&[config.fee_payer.as_ref(), config.owner.as_ref()],
293+
recent_blockhash,
294+
);
295295
send_transaction(&config, transaction)?;
296296
Ok(())
297297
}
@@ -377,7 +377,6 @@ fn command_vsa_add(
377377
&token_receiver,
378378
&pool_data.pool_mint,
379379
&spl_token::id(),
380-
&stake_program_id(),
381380
)?,
382381
]);
383382

@@ -468,7 +467,6 @@ fn command_vsa_remove(
468467
&withdraw_from,
469468
&pool_data.pool_mint,
470469
&spl_token::id(),
471-
&stake_program_id(),
472470
)?,
473471
],
474472
Some(&config.fee_payer.pubkey()),
@@ -645,7 +643,6 @@ fn command_deposit(
645643
&pool_data.owner_fee_account,
646644
&pool_data.pool_mint,
647645
&spl_token::id(),
648-
&stake_program_id(),
649646
)?,
650647
]);
651648

@@ -984,7 +981,6 @@ fn command_withdraw(
984981
&withdraw_from,
985982
&pool_data.pool_mint,
986983
&spl_token::id(),
987-
&stake_program_id(),
988984
withdraw_stake.pool_amount,
989985
)?);
990986
}
@@ -1163,7 +1159,7 @@ fn main() {
11631159
.help("Max number of validators included in the stake pool"),
11641160
)
11651161
)
1166-
.subcommand(SubCommand::with_name("create-validator-stake").about("Create a new stake account to use with the pool")
1162+
.subcommand(SubCommand::with_name("create-validator-stake").about("Create a new stake account to use with the pool. Must be signed by the pool owner.")
11671163
.arg(
11681164
Arg::with_name("pool")
11691165
.index(1)

stake-pool/program/src/instruction.rs

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
#![allow(clippy::too_many_arguments)]
44

55
use {
6+
crate::stake,
67
borsh::{BorshDeserialize, BorshSchema, BorshSerialize},
78
solana_program::{
89
instruction::{AccountMeta, Instruction},
910
program_error::ProgramError,
1011
pubkey::Pubkey,
11-
sysvar,
12+
system_program, sysvar,
1213
},
1314
};
1415

@@ -48,17 +49,17 @@ pub enum StakePoolInstruction {
4849
/// Creates new program account for accumulating stakes for a particular validator
4950
///
5051
/// 0. `[]` Stake pool account this stake will belong to
51-
/// 1. `[ws]` Funding account (must be a system account)
52-
/// 2. `[w]` Stake account to be created
53-
/// 3. `[]` Validator this stake account will vote for
54-
/// 4. `[]` Stake authority for the new stake account
55-
/// 5. `[]` Withdraw authority for the new stake account
56-
/// 6. `[]` Rent sysvar
57-
/// 7. `[]` System program
58-
/// 8. `[]` Stake program
52+
/// 1. `[s]` Owner
53+
/// 2. `[ws]` Funding account (must be a system account)
54+
/// 3. `[w]` Stake account to be created
55+
/// 4. `[]` Validator this stake account will vote for
56+
/// 5. `[]` Rent sysvar
57+
/// 6. `[]` System program
58+
/// 7. `[]` Stake program
5959
CreateValidatorStakeAccount,
6060

61-
/// Adds validator stake account to the pool
61+
/// Adds stake account delegated to validator to the pool's list of
62+
/// managed validators
6263
///
6364
/// 0. `[w]` Stake pool
6465
/// 1. `[s]` Owner
@@ -185,24 +186,23 @@ pub fn initialize(
185186
pub fn create_validator_stake_account(
186187
program_id: &Pubkey,
187188
stake_pool: &Pubkey,
189+
owner: &Pubkey,
188190
funder: &Pubkey,
189191
stake_account: &Pubkey,
190192
validator: &Pubkey,
191-
stake_authority: &Pubkey,
192-
withdraw_authority: &Pubkey,
193-
system_program_id: &Pubkey,
194-
stake_program_id: &Pubkey,
195193
) -> Result<Instruction, ProgramError> {
196194
let accounts = vec![
197195
AccountMeta::new_readonly(*stake_pool, false),
196+
AccountMeta::new_readonly(*owner, true),
198197
AccountMeta::new(*funder, true),
199198
AccountMeta::new(*stake_account, false),
200199
AccountMeta::new_readonly(*validator, false),
201-
AccountMeta::new_readonly(*stake_authority, false),
202-
AccountMeta::new_readonly(*withdraw_authority, false),
203200
AccountMeta::new_readonly(sysvar::rent::id(), false),
204-
AccountMeta::new_readonly(*system_program_id, false),
205-
AccountMeta::new_readonly(*stake_program_id, false),
201+
AccountMeta::new_readonly(sysvar::clock::id(), false),
202+
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
203+
AccountMeta::new_readonly(stake::config_id(), false),
204+
AccountMeta::new_readonly(system_program::id(), false),
205+
AccountMeta::new_readonly(stake::id(), false),
206206
];
207207
Ok(Instruction {
208208
program_id: *program_id,
@@ -220,10 +220,9 @@ pub fn add_validator_to_pool(
220220
stake_pool_withdraw: &Pubkey,
221221
validator_list: &Pubkey,
222222
stake_account: &Pubkey,
223-
pool_tokens_to: &Pubkey,
223+
pool_token_receiver: &Pubkey,
224224
pool_mint: &Pubkey,
225225
token_program_id: &Pubkey,
226-
stake_program_id: &Pubkey,
227226
) -> Result<Instruction, ProgramError> {
228227
let accounts = vec![
229228
AccountMeta::new(*stake_pool, false),
@@ -232,12 +231,12 @@ pub fn add_validator_to_pool(
232231
AccountMeta::new_readonly(*stake_pool_withdraw, false),
233232
AccountMeta::new(*validator_list, false),
234233
AccountMeta::new(*stake_account, false),
235-
AccountMeta::new(*pool_tokens_to, false),
234+
AccountMeta::new(*pool_token_receiver, false),
236235
AccountMeta::new(*pool_mint, false),
237236
AccountMeta::new_readonly(sysvar::clock::id(), false),
238237
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
239238
AccountMeta::new_readonly(*token_program_id, false),
240-
AccountMeta::new_readonly(*stake_program_id, false),
239+
AccountMeta::new_readonly(stake::id(), false),
241240
];
242241
Ok(Instruction {
243242
program_id: *program_id,
@@ -258,7 +257,6 @@ pub fn remove_validator_from_pool(
258257
burn_from: &Pubkey,
259258
pool_mint: &Pubkey,
260259
token_program_id: &Pubkey,
261-
stake_program_id: &Pubkey,
262260
) -> Result<Instruction, ProgramError> {
263261
let accounts = vec![
264262
AccountMeta::new(*stake_pool, false),
@@ -271,7 +269,7 @@ pub fn remove_validator_from_pool(
271269
AccountMeta::new(*pool_mint, false),
272270
AccountMeta::new_readonly(sysvar::clock::id(), false),
273271
AccountMeta::new_readonly(*token_program_id, false),
274-
AccountMeta::new_readonly(*stake_program_id, false),
272+
AccountMeta::new_readonly(stake::id(), false),
275273
];
276274
Ok(Instruction {
277275
program_id: *program_id,
@@ -330,7 +328,6 @@ pub fn deposit(
330328
pool_fee_to: &Pubkey,
331329
pool_mint: &Pubkey,
332330
token_program_id: &Pubkey,
333-
stake_program_id: &Pubkey,
334331
) -> Result<Instruction, ProgramError> {
335332
let accounts = vec![
336333
AccountMeta::new(*stake_pool, false),
@@ -345,7 +342,7 @@ pub fn deposit(
345342
AccountMeta::new_readonly(sysvar::clock::id(), false),
346343
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
347344
AccountMeta::new_readonly(*token_program_id, false),
348-
AccountMeta::new_readonly(*stake_program_id, false),
345+
AccountMeta::new_readonly(stake::id(), false),
349346
];
350347
Ok(Instruction {
351348
program_id: *program_id,
@@ -366,7 +363,6 @@ pub fn withdraw(
366363
burn_from: &Pubkey,
367364
pool_mint: &Pubkey,
368365
token_program_id: &Pubkey,
369-
stake_program_id: &Pubkey,
370366
amount: u64,
371367
) -> Result<Instruction, ProgramError> {
372368
let accounts = vec![
@@ -380,7 +376,7 @@ pub fn withdraw(
380376
AccountMeta::new(*pool_mint, false),
381377
AccountMeta::new_readonly(sysvar::clock::id(), false),
382378
AccountMeta::new_readonly(*token_program_id, false),
383-
AccountMeta::new_readonly(*stake_program_id, false),
379+
AccountMeta::new_readonly(stake::id(), false),
384380
];
385381
Ok(Instruction {
386382
program_id: *program_id,

stake-pool/program/src/processor.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -403,24 +403,38 @@ impl Processor {
403403
let account_info_iter = &mut accounts.iter();
404404
// Stake pool account
405405
let stake_pool_info = next_account_info(account_info_iter)?;
406+
// Owner account
407+
let owner_info = next_account_info(account_info_iter)?;
406408
// Account creation funder account
407409
let funder_info = next_account_info(account_info_iter)?;
408410
// Stake account to be created
409411
let stake_account_info = next_account_info(account_info_iter)?;
410412
// Validator this stake account will vote for
411413
let validator_info = next_account_info(account_info_iter)?;
412-
// Stake authority for the new stake account
413-
let stake_authority_info = next_account_info(account_info_iter)?;
414-
// Withdraw authority for the new stake account
415-
let withdraw_authority_info = next_account_info(account_info_iter)?;
416414
// Rent sysvar account
417415
let rent_info = next_account_info(account_info_iter)?;
418416
let rent = &Rent::from_account_info(rent_info)?;
417+
// Clock sysvar account
418+
let clock_info = next_account_info(account_info_iter)?;
419+
// Stake history sysvar account
420+
let stake_history_info = next_account_info(account_info_iter)?;
421+
// Stake config sysvar account
422+
let stake_config_info = next_account_info(account_info_iter)?;
419423
// System program id
420424
let system_program_info = next_account_info(account_info_iter)?;
421425
// Staking program id
422426
let stake_program_info = next_account_info(account_info_iter)?;
423427

428+
// Get stake pool stake (and check if it is initialized)
429+
if stake_pool_info.owner != program_id {
430+
return Err(ProgramError::IncorrectProgramId);
431+
}
432+
let stake_pool = StakePool::try_from_slice(&stake_pool_info.data.borrow())?;
433+
if !stake_pool.is_valid() {
434+
return Err(StakePoolError::InvalidState.into());
435+
}
436+
stake_pool.check_owner(owner_info)?;
437+
424438
// Check program ids
425439
if *system_program_info.key != solana_program::system_program::id() {
426440
return Err(ProgramError::IncorrectProgramId);
@@ -466,8 +480,8 @@ impl Processor {
466480
&stake::initialize(
467481
&stake_account_info.key,
468482
&stake::Authorized {
469-
staker: *stake_authority_info.key,
470-
withdrawer: *withdraw_authority_info.key,
483+
staker: *owner_info.key,
484+
withdrawer: *owner_info.key,
471485
},
472486
&stake::Lockup::default(),
473487
),
@@ -476,6 +490,22 @@ impl Processor {
476490
rent_info.clone(),
477491
stake_program_info.clone(),
478492
],
493+
)?;
494+
495+
invoke(
496+
&stake::delegate_stake(
497+
&stake_account_info.key,
498+
&owner_info.key,
499+
&validator_info.key,
500+
),
501+
&[
502+
stake_account_info.clone(),
503+
validator_info.clone(),
504+
clock_info.clone(),
505+
stake_history_info.clone(),
506+
stake_config_info.clone(),
507+
owner_info.clone(),
508+
],
479509
)
480510
}
481511

stake-pool/program/src/stake.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ use std::str::FromStr;
1313
solana_program::declare_id!("Stake11111111111111111111111111111111111111");
1414

1515
const STAKE_CONFIG: &str = "StakeConfig11111111111111111111111111111111";
16+
/// Id for stake config account
17+
pub fn config_id() -> Pubkey {
18+
Pubkey::from_str(STAKE_CONFIG).unwrap()
19+
}
1620

1721
/// FIXME copied from solana stake program
1822
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
@@ -489,8 +493,18 @@ pub fn delegate_stake(
489493
AccountMeta::new_readonly(*vote_pubkey, false),
490494
AccountMeta::new_readonly(sysvar::clock::id(), false),
491495
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
492-
AccountMeta::new_readonly(Pubkey::from_str(STAKE_CONFIG).unwrap(), false),
496+
AccountMeta::new_readonly(config_id(), false),
493497
AccountMeta::new_readonly(*authorized_pubkey, true),
494498
];
495499
Instruction::new_with_bincode(id(), &StakeInstruction::DelegateStake, account_metas)
496500
}
501+
502+
/// FIXME copied from stake program
503+
pub fn deactivate_stake(stake_pubkey: &Pubkey, authorized_pubkey: &Pubkey) -> Instruction {
504+
let account_metas = vec![
505+
AccountMeta::new(*stake_pubkey, false),
506+
AccountMeta::new_readonly(sysvar::clock::id(), false),
507+
AccountMeta::new_readonly(*authorized_pubkey, true),
508+
];
509+
Instruction::new_with_bincode(id(), &StakeInstruction::Deactivate, account_metas)
510+
}

0 commit comments

Comments
 (0)