@@ -395,6 +395,95 @@ fn command_vsa_remove(
395
395
Ok ( ( ) )
396
396
}
397
397
398
+ fn command_increase_validator_stake (
399
+ config : & Config ,
400
+ stake_pool_address : & Pubkey ,
401
+ vote_account : & Pubkey ,
402
+ lamports : u64 ,
403
+ ) -> CommandResult {
404
+ if !config. no_update {
405
+ command_update ( config, stake_pool_address) ?;
406
+ }
407
+
408
+ let stake_pool = get_stake_pool ( & config. rpc_client , stake_pool_address) ?;
409
+ let pool_withdraw_authority =
410
+ find_withdraw_authority_program_address ( & spl_stake_pool:: id ( ) , stake_pool_address) . 0 ;
411
+ let ( transient_stake_address, _) = find_transient_stake_program_address (
412
+ & spl_stake_pool:: id ( ) ,
413
+ & vote_account,
414
+ stake_pool_address,
415
+ ) ;
416
+
417
+ let mut transaction = Transaction :: new_with_payer (
418
+ & [ spl_stake_pool:: instruction:: increase_validator_stake (
419
+ & spl_stake_pool:: id ( ) ,
420
+ & stake_pool_address,
421
+ & config. staker . pubkey ( ) ,
422
+ & pool_withdraw_authority,
423
+ & stake_pool. validator_list ,
424
+ & stake_pool. reserve_stake ,
425
+ & transient_stake_address,
426
+ & vote_account,
427
+ lamports,
428
+ ) ] ,
429
+ Some ( & config. fee_payer . pubkey ( ) ) ,
430
+ ) ;
431
+
432
+ let ( recent_blockhash, fee_calculator) = config. rpc_client . get_recent_blockhash ( ) ?;
433
+ check_fee_payer_balance ( config, fee_calculator. calculate_fee ( & transaction. message ( ) ) ) ?;
434
+ transaction. sign (
435
+ & [ config. fee_payer . as_ref ( ) , config. staker . as_ref ( ) ] ,
436
+ recent_blockhash,
437
+ ) ;
438
+ send_transaction ( & config, transaction) ?;
439
+ Ok ( ( ) )
440
+ }
441
+
442
+ fn command_decrease_validator_stake (
443
+ config : & Config ,
444
+ stake_pool_address : & Pubkey ,
445
+ vote_account : & Pubkey ,
446
+ lamports : u64 ,
447
+ ) -> CommandResult {
448
+ if !config. no_update {
449
+ command_update ( config, stake_pool_address) ?;
450
+ }
451
+
452
+ let stake_pool = get_stake_pool ( & config. rpc_client , stake_pool_address) ?;
453
+ let pool_withdraw_authority =
454
+ find_withdraw_authority_program_address ( & spl_stake_pool:: id ( ) , stake_pool_address) . 0 ;
455
+ let ( validator_stake_address, _) =
456
+ find_stake_program_address ( & spl_stake_pool:: id ( ) , & vote_account, stake_pool_address) ;
457
+ let ( transient_stake_address, _) = find_transient_stake_program_address (
458
+ & spl_stake_pool:: id ( ) ,
459
+ & vote_account,
460
+ stake_pool_address,
461
+ ) ;
462
+
463
+ let mut transaction = Transaction :: new_with_payer (
464
+ & [ spl_stake_pool:: instruction:: decrease_validator_stake (
465
+ & spl_stake_pool:: id ( ) ,
466
+ & stake_pool_address,
467
+ & config. staker . pubkey ( ) ,
468
+ & pool_withdraw_authority,
469
+ & stake_pool. validator_list ,
470
+ & validator_stake_address,
471
+ & transient_stake_address,
472
+ lamports,
473
+ ) ] ,
474
+ Some ( & config. fee_payer . pubkey ( ) ) ,
475
+ ) ;
476
+
477
+ let ( recent_blockhash, fee_calculator) = config. rpc_client . get_recent_blockhash ( ) ?;
478
+ check_fee_payer_balance ( config, fee_calculator. calculate_fee ( & transaction. message ( ) ) ) ?;
479
+ transaction. sign (
480
+ & [ config. fee_payer . as_ref ( ) , config. staker . as_ref ( ) ] ,
481
+ recent_blockhash,
482
+ ) ;
483
+ send_transaction ( & config, transaction) ?;
484
+ Ok ( ( ) )
485
+ }
486
+
398
487
fn unwrap_create_token_account < F > (
399
488
config : & Config ,
400
489
token_optional : & Option < Pubkey > ,
@@ -630,21 +719,10 @@ fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult
630
719
631
720
let validator_list = get_validator_list ( & config. rpc_client , & stake_pool. validator_list ) ?;
632
721
633
- let accounts_to_update : Vec < Pubkey > = validator_list
722
+ let vote_accounts : Vec < Pubkey > = validator_list
634
723
. validators
635
724
. iter ( )
636
- . filter_map ( |item| {
637
- if item. last_update_epoch >= epoch_info. epoch {
638
- None
639
- } else {
640
- let ( stake_account, _) = find_stake_program_address (
641
- & spl_stake_pool:: id ( ) ,
642
- & item. vote_account_address ,
643
- & stake_pool_address,
644
- ) ;
645
- Some ( stake_account)
646
- }
647
- } )
725
+ . map ( |item| item. vote_account_address )
648
726
. collect ( ) ;
649
727
650
728
println ! ( "Updating stake pool..." ) ;
@@ -653,7 +731,7 @@ fn command_update(config: &Config, stake_pool_address: &Pubkey) -> CommandResult
653
731
654
732
let mut instructions: Vec < Instruction > = vec ! [ ] ;
655
733
let mut start_index = 0 ;
656
- for accounts_chunk in accounts_to_update . chunks ( MAX_VALIDATORS_TO_UPDATE ) {
734
+ for accounts_chunk in vote_accounts . chunks ( MAX_VALIDATORS_TO_UPDATE ) {
657
735
instructions. push ( spl_stake_pool:: instruction:: update_validator_list_balance (
658
736
& spl_stake_pool:: id ( ) ,
659
737
stake_pool_address,
@@ -1181,6 +1259,64 @@ fn main() {
1181
1259
Defaults to the wallet owner pubkey." ) ,
1182
1260
)
1183
1261
)
1262
+ . subcommand ( SubCommand :: with_name ( "increase-validator-stake" )
1263
+ . about ( "Increase stake to a validator, drawing from the stake pool reserve. Must be signed by the pool staker." )
1264
+ . arg (
1265
+ Arg :: with_name ( "pool" )
1266
+ . index ( 1 )
1267
+ . validator ( is_pubkey)
1268
+ . value_name ( "POOL_ADDRESS" )
1269
+ . takes_value ( true )
1270
+ . required ( true )
1271
+ . help ( "Stake pool address" ) ,
1272
+ )
1273
+ . arg (
1274
+ Arg :: with_name ( "vote_account" )
1275
+ . index ( 2 )
1276
+ . validator ( is_pubkey)
1277
+ . value_name ( "VOTE_ACCOUNT_ADDRESS" )
1278
+ . takes_value ( true )
1279
+ . required ( true )
1280
+ . help ( "Vote account for the validator to increase stake to" ) ,
1281
+ )
1282
+ . arg (
1283
+ Arg :: with_name ( "lamports" )
1284
+ . index ( 3 )
1285
+ . validator ( is_pubkey)
1286
+ . value_name ( "LAMPORTS" )
1287
+ . takes_value ( true )
1288
+ . help ( "Amount in lamports to add to the validator stake account. Must be at least the rent-exempt amount for a stake plus 1 SOL for merging." ) ,
1289
+ )
1290
+ )
1291
+ . subcommand ( SubCommand :: with_name ( "decrease-validator-stake" )
1292
+ . about ( "Decrease stake to a validator, splitting from the active stake. Must be signed by the pool staker." )
1293
+ . arg (
1294
+ Arg :: with_name ( "pool" )
1295
+ . index ( 1 )
1296
+ . validator ( is_pubkey)
1297
+ . value_name ( "POOL_ADDRESS" )
1298
+ . takes_value ( true )
1299
+ . required ( true )
1300
+ . help ( "Stake pool address" ) ,
1301
+ )
1302
+ . arg (
1303
+ Arg :: with_name ( "vote_account" )
1304
+ . index ( 2 )
1305
+ . validator ( is_pubkey)
1306
+ . value_name ( "VOTE_ACCOUNT_ADDRESS" )
1307
+ . takes_value ( true )
1308
+ . required ( true )
1309
+ . help ( "Vote account for the validator to decrease stake from" ) ,
1310
+ )
1311
+ . arg (
1312
+ Arg :: with_name ( "lamports" )
1313
+ . index ( 3 )
1314
+ . validator ( is_pubkey)
1315
+ . value_name ( "LAMPORTS" )
1316
+ . takes_value ( true )
1317
+ . help ( "Amount in lamports to remove from the validator stake account. Must be at least the rent-exempt amount for a stake." ) ,
1318
+ )
1319
+ )
1184
1320
. subcommand ( SubCommand :: with_name ( "deposit" )
1185
1321
. about ( "Add stake account to the stake pool" )
1186
1322
. arg (
@@ -1455,6 +1591,18 @@ fn main() {
1455
1591
let new_authority: Option < Pubkey > = pubkey_of ( arg_matches, "new_authority" ) ;
1456
1592
command_vsa_remove ( & config, & stake_pool_address, & vote_account, & new_authority)
1457
1593
}
1594
+ ( "increase-validator-stake" , Some ( arg_matches) ) => {
1595
+ let stake_pool_address = pubkey_of ( arg_matches, "pool" ) . unwrap ( ) ;
1596
+ let vote_account = pubkey_of ( arg_matches, "vote_account" ) . unwrap ( ) ;
1597
+ let lamports = value_t_or_exit ! ( arg_matches, "lamports" , u64 ) ;
1598
+ command_increase_validator_stake ( & config, & stake_pool_address, & vote_account, lamports)
1599
+ }
1600
+ ( "decrease-validator-stake" , Some ( arg_matches) ) => {
1601
+ let stake_pool_address = pubkey_of ( arg_matches, "pool" ) . unwrap ( ) ;
1602
+ let vote_account = pubkey_of ( arg_matches, "vote_account" ) . unwrap ( ) ;
1603
+ let lamports = value_t_or_exit ! ( arg_matches, "lamports" , u64 ) ;
1604
+ command_decrease_validator_stake ( & config, & stake_pool_address, & vote_account, lamports)
1605
+ }
1458
1606
( "deposit" , Some ( arg_matches) ) => {
1459
1607
let stake_pool_address = pubkey_of ( arg_matches, "pool" ) . unwrap ( ) ;
1460
1608
let stake_account = pubkey_of ( arg_matches, "stake_account" ) . unwrap ( ) ;
0 commit comments