1
- from typing import Tuple
1
+ from typing import Optional , Tuple
2
2
3
3
from solana .keypair import Keypair
4
4
from solana .publickey import PublicKey
22
22
find_stake_program_address , \
23
23
find_transient_stake_program_address , \
24
24
find_withdraw_authority_program_address , \
25
- find_metadata_account
25
+ find_metadata_account , \
26
+ find_ephemeral_stake_program_address
26
27
from stake_pool .state import STAKE_POOL_LAYOUT , ValidatorList , Fee , StakePool
27
28
import stake_pool .instructions as sp
28
29
@@ -480,8 +481,13 @@ async def update_stake_pool(client: AsyncClient, payer: Keypair, stake_pool_addr
480
481
481
482
482
483
async def increase_validator_stake (
483
- client : AsyncClient , payer : Keypair , staker : Keypair , stake_pool_address : PublicKey ,
484
- validator_vote : PublicKey , lamports : int
484
+ client : AsyncClient ,
485
+ payer : Keypair ,
486
+ staker : Keypair ,
487
+ stake_pool_address : PublicKey ,
488
+ validator_vote : PublicKey ,
489
+ lamports : int ,
490
+ ephemeral_stake_seed : Optional [int ] = None
485
491
):
486
492
resp = await client .get_account_info (stake_pool_address , commitment = Confirmed )
487
493
data = resp ['result' ]['value' ]['data' ]
@@ -493,7 +499,13 @@ async def increase_validator_stake(
493
499
(withdraw_authority , seed ) = find_withdraw_authority_program_address (STAKE_POOL_PROGRAM_ID , stake_pool_address )
494
500
495
501
validator_info = next (x for x in validator_list .validators if x .vote_account_address == validator_vote )
496
- transient_stake_seed = validator_info .transient_seed_suffix + 1 # bump up by one to avoid reuse
502
+
503
+ if ephemeral_stake_seed is None :
504
+ transient_stake_seed = validator_info .transient_seed_suffix + 1 # bump up by one to avoid reuse
505
+ else :
506
+ # we are updating an existing transient stake account, so we must use the same seed
507
+ transient_stake_seed = validator_info .transient_seed_suffix
508
+
497
509
validator_stake_seed = validator_info .validator_seed_suffix or None
498
510
(transient_stake , _ ) = find_transient_stake_program_address (
499
511
STAKE_POOL_PROGRAM_ID ,
@@ -509,38 +521,78 @@ async def increase_validator_stake(
509
521
)
510
522
511
523
txn = Transaction ()
512
- txn .add (
513
- sp .increase_validator_stake (
514
- sp .IncreaseValidatorStakeParams (
515
- program_id = STAKE_POOL_PROGRAM_ID ,
516
- stake_pool = stake_pool_address ,
517
- staker = staker .public_key ,
518
- withdraw_authority = withdraw_authority ,
519
- validator_list = stake_pool .validator_list ,
520
- reserve_stake = stake_pool .reserve_stake ,
521
- transient_stake = transient_stake ,
522
- validator_stake = validator_stake ,
523
- validator_vote = validator_vote ,
524
- clock_sysvar = SYSVAR_CLOCK_PUBKEY ,
525
- rent_sysvar = SYSVAR_RENT_PUBKEY ,
526
- stake_history_sysvar = SYSVAR_STAKE_HISTORY_PUBKEY ,
527
- stake_config_sysvar = SYSVAR_STAKE_CONFIG_ID ,
528
- system_program_id = sys .SYS_PROGRAM_ID ,
529
- stake_program_id = STAKE_PROGRAM_ID ,
530
- lamports = lamports ,
531
- transient_stake_seed = transient_stake_seed ,
524
+ if ephemeral_stake_seed is not None :
525
+
526
+ # We assume there is an existing transient account that we will update
527
+ (ephemeral_stake , _ ) = find_ephemeral_stake_program_address (
528
+ STAKE_POOL_PROGRAM_ID ,
529
+ stake_pool_address ,
530
+ ephemeral_stake_seed )
531
+
532
+ txn .add (
533
+ sp .increase_additional_validator_stake (
534
+ sp .IncreaseAdditionalValidatorStakeParams (
535
+ program_id = STAKE_POOL_PROGRAM_ID ,
536
+ stake_pool = stake_pool_address ,
537
+ staker = staker .public_key ,
538
+ withdraw_authority = withdraw_authority ,
539
+ validator_list = stake_pool .validator_list ,
540
+ reserve_stake = stake_pool .reserve_stake ,
541
+ transient_stake = transient_stake ,
542
+ validator_stake = validator_stake ,
543
+ validator_vote = validator_vote ,
544
+ clock_sysvar = SYSVAR_CLOCK_PUBKEY ,
545
+ rent_sysvar = SYSVAR_RENT_PUBKEY ,
546
+ stake_history_sysvar = SYSVAR_STAKE_HISTORY_PUBKEY ,
547
+ stake_config_sysvar = SYSVAR_STAKE_CONFIG_ID ,
548
+ system_program_id = sys .SYS_PROGRAM_ID ,
549
+ stake_program_id = STAKE_PROGRAM_ID ,
550
+ lamports = lamports ,
551
+ transient_stake_seed = transient_stake_seed ,
552
+ ephemeral_stake = ephemeral_stake ,
553
+ ephemeral_stake_seed = ephemeral_stake_seed
554
+ )
555
+ )
556
+ )
557
+
558
+ else :
559
+ txn .add (
560
+ sp .increase_validator_stake (
561
+ sp .IncreaseValidatorStakeParams (
562
+ program_id = STAKE_POOL_PROGRAM_ID ,
563
+ stake_pool = stake_pool_address ,
564
+ staker = staker .public_key ,
565
+ withdraw_authority = withdraw_authority ,
566
+ validator_list = stake_pool .validator_list ,
567
+ reserve_stake = stake_pool .reserve_stake ,
568
+ transient_stake = transient_stake ,
569
+ validator_stake = validator_stake ,
570
+ validator_vote = validator_vote ,
571
+ clock_sysvar = SYSVAR_CLOCK_PUBKEY ,
572
+ rent_sysvar = SYSVAR_RENT_PUBKEY ,
573
+ stake_history_sysvar = SYSVAR_STAKE_HISTORY_PUBKEY ,
574
+ stake_config_sysvar = SYSVAR_STAKE_CONFIG_ID ,
575
+ system_program_id = sys .SYS_PROGRAM_ID ,
576
+ stake_program_id = STAKE_PROGRAM_ID ,
577
+ lamports = lamports ,
578
+ transient_stake_seed = transient_stake_seed ,
579
+ )
532
580
)
533
581
)
534
- )
535
582
536
583
signers = [payer , staker ] if payer != staker else [payer ]
537
584
await client .send_transaction (
538
585
txn , * signers , opts = TxOpts (skip_confirmation = False , preflight_commitment = Confirmed ))
539
586
540
587
541
588
async def decrease_validator_stake (
542
- client : AsyncClient , payer : Keypair , staker : Keypair , stake_pool_address : PublicKey ,
543
- validator_vote : PublicKey , lamports : int
589
+ client : AsyncClient ,
590
+ payer : Keypair ,
591
+ staker : Keypair ,
592
+ stake_pool_address : PublicKey ,
593
+ validator_vote : PublicKey ,
594
+ lamports : int ,
595
+ ephemeral_stake_seed : Optional [int ] = None
544
596
):
545
597
resp = await client .get_account_info (stake_pool_address , commitment = Confirmed )
546
598
data = resp ['result' ]['value' ]['data' ]
@@ -559,7 +611,13 @@ async def decrease_validator_stake(
559
611
stake_pool_address ,
560
612
validator_stake_seed ,
561
613
)
562
- transient_stake_seed = validator_info .transient_seed_suffix + 1 # bump up by one to avoid reuse
614
+
615
+ if ephemeral_stake_seed is None :
616
+ transient_stake_seed = validator_info .transient_seed_suffix + 1 # bump up by one to avoid reuse
617
+ else :
618
+ # we are updating an existing transient stake account, so we must use the same seed
619
+ transient_stake_seed = validator_info .transient_seed_suffix
620
+
563
621
(transient_stake , _ ) = find_transient_stake_program_address (
564
622
STAKE_POOL_PROGRAM_ID ,
565
623
validator_info .vote_account_address ,
@@ -568,26 +626,61 @@ async def decrease_validator_stake(
568
626
)
569
627
570
628
txn = Transaction ()
571
- txn .add (
572
- sp .decrease_validator_stake_with_reserve (
573
- sp .DecreaseValidatorStakeWithReserveParams (
574
- program_id = STAKE_POOL_PROGRAM_ID ,
575
- stake_pool = stake_pool_address ,
576
- staker = staker .public_key ,
577
- withdraw_authority = withdraw_authority ,
578
- validator_list = stake_pool .validator_list ,
579
- reserve_stake = stake_pool .reserve_stake ,
580
- validator_stake = validator_stake ,
581
- transient_stake = transient_stake ,
582
- clock_sysvar = SYSVAR_CLOCK_PUBKEY ,
583
- stake_history_sysvar = SYSVAR_STAKE_HISTORY_PUBKEY ,
584
- system_program_id = sys .SYS_PROGRAM_ID ,
585
- stake_program_id = STAKE_PROGRAM_ID ,
586
- lamports = lamports ,
587
- transient_stake_seed = transient_stake_seed ,
629
+
630
+ if ephemeral_stake_seed is not None :
631
+
632
+ # We assume there is an existing transient account that we will update
633
+ (ephemeral_stake , _ ) = find_ephemeral_stake_program_address (
634
+ STAKE_POOL_PROGRAM_ID ,
635
+ stake_pool_address ,
636
+ ephemeral_stake_seed )
637
+
638
+ txn .add (
639
+ sp .decrease_additional_validator_stake (
640
+ sp .DecreaseAdditionalValidatorStakeParams (
641
+ program_id = STAKE_POOL_PROGRAM_ID ,
642
+ stake_pool = stake_pool_address ,
643
+ staker = staker .public_key ,
644
+ withdraw_authority = withdraw_authority ,
645
+ validator_list = stake_pool .validator_list ,
646
+ reserve_stake = stake_pool .reserve_stake ,
647
+ validator_stake = validator_stake ,
648
+ transient_stake = transient_stake ,
649
+ clock_sysvar = SYSVAR_CLOCK_PUBKEY ,
650
+ rent_sysvar = SYSVAR_RENT_PUBKEY ,
651
+ stake_history_sysvar = SYSVAR_STAKE_HISTORY_PUBKEY ,
652
+ system_program_id = sys .SYS_PROGRAM_ID ,
653
+ stake_program_id = STAKE_PROGRAM_ID ,
654
+ lamports = lamports ,
655
+ transient_stake_seed = transient_stake_seed ,
656
+ ephemeral_stake = ephemeral_stake ,
657
+ ephemeral_stake_seed = ephemeral_stake_seed
658
+ )
659
+ )
660
+ )
661
+
662
+ else :
663
+
664
+ txn .add (
665
+ sp .decrease_validator_stake_with_reserve (
666
+ sp .DecreaseValidatorStakeWithReserveParams (
667
+ program_id = STAKE_POOL_PROGRAM_ID ,
668
+ stake_pool = stake_pool_address ,
669
+ staker = staker .public_key ,
670
+ withdraw_authority = withdraw_authority ,
671
+ validator_list = stake_pool .validator_list ,
672
+ reserve_stake = stake_pool .reserve_stake ,
673
+ validator_stake = validator_stake ,
674
+ transient_stake = transient_stake ,
675
+ clock_sysvar = SYSVAR_CLOCK_PUBKEY ,
676
+ stake_history_sysvar = SYSVAR_STAKE_HISTORY_PUBKEY ,
677
+ system_program_id = sys .SYS_PROGRAM_ID ,
678
+ stake_program_id = STAKE_PROGRAM_ID ,
679
+ lamports = lamports ,
680
+ transient_stake_seed = transient_stake_seed ,
681
+ )
588
682
)
589
683
)
590
- )
591
684
592
685
signers = [payer , staker ] if payer != staker else [payer ]
593
686
await client .send_transaction (
0 commit comments