LCOV - code coverage report
Current view: top level - flamenco/runtime/program - fd_stake_program.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 1755 1918 91.5 %
Date: 2025-01-08 12:08:44 Functions: 47 55 85.5 %

          Line data    Source code
       1             : #define FD_SCRATCH_USE_HANDHOLDING 1
       2             : #include <limits.h>
       3             : 
       4             : #include "../../../util/bits/fd_sat.h"
       5             : #include "../../../util/bits/fd_uwide.h"
       6             : #include "../fd_account.h"
       7             : #include "../fd_executor.h"
       8             : #include "../fd_pubkey_utils.h"
       9             : #include "../fd_system_ids.h"
      10             : 
      11             : #include "fd_stake_program.h"
      12             : #include "fd_vote_program.h"
      13             : #include "../sysvar/fd_sysvar_epoch_schedule.h"
      14             : #include "../sysvar/fd_sysvar_rent.h"
      15             : 
      16             : /* A note on fd_borrowed_account_acquire_write:
      17             : 
      18             :    The stake program uses this function to prevent aliasing of accounts.
      19             :    (When the same account is passed via multiple instruction account
      20             :    indexes.)  Internally, it acquires a transaction-wide mutex on the
      21             :    account.  If called twice on the same account while the mutex is
      22             :    still locked, it returns an "AccountBorrowFailed" error.
      23             : 
      24             :    There is no exact equivalent to this in Agave/Rust.
      25             : 
      26             :      let handle = instruction_context.try_borrow_instruction_account(...)
      27             : 
      28             :    The above creates the lock on the account.  However, that lock is
      29             :    **implicitly** released when 'handle' goes out of scope.  Firedancer
      30             :    releases the handle **explicitly**. */
      31             : 
      32             : /**********************************************************************/
      33             : /* Errors                                                             */
      34             : /**********************************************************************/
      35             : 
      36             : // DO NOT REORDER: https://github.com/bincode-org/bincode/blob/trunk/docs/spec.md#enums
      37             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L28
      38             : #define FD_STAKE_ERR_NO_CREDITS_TO_REDEEM                                                   ( 0 )
      39          81 : #define FD_STAKE_ERR_LOCKUP_IN_FORCE                                                        ( 1 )
      40         219 : #define FD_STAKE_ERR_ALREADY_DEACTIVATED                                                    ( 2 )
      41          66 : #define FD_STAKE_ERR_TOO_SOON_TO_REDELEGATE                                                 ( 3 )
      42           0 : #define FD_STAKE_ERR_INSUFFICIENT_STAKE                                                     ( 4 )
      43         561 : #define FD_STAKE_ERR_MERGE_TRANSIENT_STAKE                                                  ( 5 )
      44         303 : #define FD_STAKE_ERR_MERGE_MISMATCH                                                         ( 6 )
      45          39 : #define FD_STAKE_ERR_CUSTODIAN_MISSING                                                      ( 7 )
      46          36 : #define FD_STAKE_ERR_CUSTODIAN_SIGNATURE_MISSING                                            ( 8 )
      47         189 : #define FD_STAKE_ERR_INSUFFICIENT_REFERENCE_VOTES                                           ( 9 )
      48          27 : #define FD_STAKE_ERR_VOTE_ADDRESS_MISMATCH                                                  ( 10 )
      49         204 : #define FD_STAKE_ERR_MINIMUM_DELIQUENT_EPOCHS_FOR_DEACTIVATION_NOT_MET                      ( 11 )
      50         213 : #define FD_STAKE_ERR_INSUFFICIENT_DELEGATION                                                ( 12 )
      51             : #define FD_STAKE_ERR_REDELEGATE_TRANSIENT_OR_INACTIVE_STAKE                                 ( 13 )
      52             : #define FD_STAKE_ERR_REDELEGATE_TO_SAME_VOTE_ACCOUNT                                        ( 14 )
      53             : #define FD_STAKE_ERR_REDELEGATED_STAKE_MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED ( 15 )
      54         234 : #define FD_STAKE_ERR_EPOCH_REWARDS_ACTIVE                                                   ( 16 )
      55             : 
      56             : /**********************************************************************/
      57             : /* Constants                                                          */
      58             : /**********************************************************************/
      59             : 
      60             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/lib.rs#L31
      61        3984 : #define MINIMUM_DELEGATION_SOL                     ( 1 )
      62             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/native_token.rs#L6
      63        3984 : #define LAMPORTS_PER_SOL                           ( 1000000000 )
      64             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/mod.rs#L18
      65        1119 : #define MINIMUM_DELINQUENT_EPOCHS_FOR_DEACTIVATION ( 5 )
      66             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L26-L28
      67        5361 : #define DEFAULT_WARMUP_COOLDOWN_RATE               ( 0.25 )
      68        5151 : #define NEW_WARMUP_COOLDOWN_RATE                   ( 0.09 )
      69           0 : #define DEFAULT_SLASH_PENALTY                      ( 12 )
      70             : 
      71             : #define STAKE_AUTHORIZE_STAKER                                                                     \
      72        4098 :   ( ( fd_stake_authorize_t ){ .discriminant = fd_stake_authorize_enum_staker, .inner = {0} } )
      73             : #define STAKE_AUTHORIZE_WITHDRAWER                                                                 \
      74         477 :   ( ( fd_stake_authorize_t ){ .discriminant = fd_stake_authorize_enum_withdrawer, .inner = {0} } )
      75             : 
      76             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L51
      77             : #define DEFAULT_COMPUTE_UNITS 750UL
      78             : 
      79             : /**********************************************************************/
      80             : /* MergeKind                                                          */
      81             : /**********************************************************************/
      82             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1074-L1079
      83             : struct merge_kind_inactive {
      84             :   fd_stake_meta_t  meta;
      85             :   ulong            active_stake;
      86             :   fd_stake_flags_t stake_flags;
      87             : };
      88             : typedef struct merge_kind_inactive merge_kind_inactive_t;
      89             : 
      90             : struct merge_kind_activation_epoch {
      91             :   fd_stake_meta_t  meta;
      92             :   fd_stake_t       stake;
      93             :   fd_stake_flags_t stake_flags;
      94             : };
      95             : typedef struct merge_kind_activation_epoch merge_kind_activation_epoch_t;
      96             : 
      97             : struct merge_kind_fully_active {
      98             :   fd_stake_meta_t meta;
      99             :   fd_stake_t      stake;
     100             : };
     101             : typedef struct merge_kind_fully_active merge_kind_fully_active_t;
     102             : 
     103             : union merge_kind_inner {
     104             :   merge_kind_inactive_t         inactive;
     105             :   merge_kind_activation_epoch_t activation_epoch;
     106             :   merge_kind_fully_active_t     fully_active;
     107             : };
     108             : typedef union merge_kind_inner merge_kind_inner_t;
     109             : 
     110             : struct merge_kind {
     111             :   uint               discriminant;
     112             :   merge_kind_inner_t inner;
     113             : };
     114             : typedef struct merge_kind merge_kind_t;
     115             : 
     116             : enum { merge_kind_inactive = 0, merge_kind_activation_epoch = 1, merge_kind_fully_active = 2 };
     117             : 
     118             : typedef fd_stake_history_entry_t stake_activation_status_t;
     119             : 
     120             : struct effective_activating {
     121             :   ulong effective;
     122             :   ulong activating;
     123             : };
     124             : typedef struct effective_activating effective_activating_t;
     125             : 
     126             : /**********************************************************************/
     127             : /* Bincode                                                            */
     128             : /**********************************************************************/
     129             : 
     130             : static int
     131             : get_state( fd_borrowed_account_t const * self,
     132             :            fd_valloc_t                   valloc,
     133       11616 :            fd_stake_state_v2_t *         out ) {
     134       11616 :   int rc;
     135             : 
     136       11616 :   fd_bincode_decode_ctx_t bincode_ctx;
     137       11616 :   bincode_ctx.data    = self->const_data;
     138       11616 :   bincode_ctx.dataend = self->const_data + self->const_meta->dlen;
     139       11616 :   bincode_ctx.valloc  = valloc; /* No real allocation from this valloc. */
     140             : 
     141       11616 :   rc = fd_stake_state_v2_decode( out, &bincode_ctx );
     142       11616 :   if( FD_UNLIKELY( rc!=FD_BINCODE_SUCCESS ) ) return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
     143             : 
     144       10848 :   return 0;
     145       11616 : }
     146             : 
     147             : static int
     148             : set_state( fd_exec_instr_ctx_t const * ctx,
     149             :            ulong                       acct_idx,
     150        3555 :            fd_stake_state_v2_t const * state ) {
     151             : 
     152        3555 :   uchar * data = NULL;
     153        3555 :   ulong   dlen = 0UL;
     154             : 
     155        3555 :   int err = fd_account_get_data_mut( ctx, acct_idx, &data, &dlen );
     156        3555 :   if( FD_UNLIKELY( err ) ) return err;
     157             : 
     158        3288 :   ulong serialized_size = fd_stake_state_v2_size( state );
     159        3288 :   if( FD_UNLIKELY( serialized_size>dlen ) )
     160           0 :     return FD_EXECUTOR_INSTR_ERR_ACC_DATA_TOO_SMALL;
     161             : 
     162        3288 :   fd_borrowed_account_t * account = NULL;
     163        3288 :   do {
     164        3288 :     int err = fd_instr_borrowed_account_modify_idx( ctx, acct_idx, serialized_size, &account );
     165        3288 :     if( FD_UNLIKELY( err ) ) FD_LOG_ERR(( "fd_instr_borrowed_account_modify_idx failed (%d-%s)", err, fd_acc_mgr_strerror( err ) ));
     166        3288 :   } while(0);
     167             : 
     168        3288 :   fd_bincode_encode_ctx_t encode = {
     169        3288 :     .data    = account->data,
     170        3288 :     .dataend = account->data + serialized_size,
     171        3288 :   };
     172        3288 :   do {
     173        3288 :     int err = fd_stake_state_v2_encode( state, &encode );
     174        3288 :     if( FD_UNLIKELY( err ) ) FD_LOG_ERR(( "fd_stake_state_v2_encode failed" ));
     175        3288 :   } while(0);
     176             : 
     177        3288 :   return 0;
     178        3288 : }
     179             : 
     180             : /**********************************************************************/
     181             : /* mod stake                                                          */
     182             : /**********************************************************************/
     183             : 
     184             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/lib.rs#L29
     185             : static inline ulong
     186        3984 : get_minimum_delegation( fd_exec_slot_ctx_t const * slot_ctx /* feature set */ ) {
     187        3984 :   return fd_ulong_if( FD_FEATURE_ACTIVE( slot_ctx, stake_raise_minimum_delegation_to_1_sol ),
     188        3984 :                       MINIMUM_DELEGATION_SOL * LAMPORTS_PER_SOL,
     189        3984 :                       1 );
     190        3984 : }
     191             : 
     192             : /**********************************************************************/
     193             : /* mod stake/state                                                    */
     194             : /**********************************************************************/
     195             : 
     196             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L30
     197             : static inline double
     198        5151 : warmup_cooldown_rate( ulong current_epoch, ulong * new_rate_activation_epoch ) {
     199        5151 :   return fd_double_if( current_epoch <
     200        5151 :                            ( new_rate_activation_epoch ? *new_rate_activation_epoch : ULONG_MAX ),
     201        5151 :                        DEFAULT_WARMUP_COOLDOWN_RATE,
     202        5151 :                        NEW_WARMUP_COOLDOWN_RATE );
     203        5151 : }
     204             : 
     205             : /**********************************************************************/
     206             : /* validated                                                          */
     207             : /**********************************************************************/
     208             : 
     209             : struct validated_delegated_info {
     210             :   ulong stake_amount;
     211             : };
     212             : typedef struct validated_delegated_info validated_delegated_info_t;
     213             : 
     214             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L963
     215             : static int
     216             : validate_delegated_amount( fd_borrowed_account_t *      account,
     217             :                            fd_stake_meta_t const *      meta,
     218             :                            fd_exec_slot_ctx_t const *   slot_ctx,
     219             :                            validated_delegated_info_t * out,
     220         630 :                            uint *                       custom_err ) {
     221         630 :   ulong stake_amount = fd_ulong_sat_sub( account->const_meta->info.lamports, meta->rent_exempt_reserve );
     222             : 
     223         630 :   if( FD_UNLIKELY( stake_amount<get_minimum_delegation( slot_ctx ) ) ) {
     224         150 :     *custom_err = FD_STAKE_ERR_INSUFFICIENT_DELEGATION;
     225         150 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     226         150 :   }
     227         480 :   out->stake_amount = stake_amount;
     228         480 :   return 0;
     229         630 : }
     230             : 
     231             : struct validated_split_info {
     232             :   ulong source_remaining_balance;
     233             :   ulong destination_rent_exempt_reserve;
     234             : };
     235             : typedef struct validated_split_info validated_split_info_t;
     236             : 
     237             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L992
     238             : static int
     239             : validate_split_amount( fd_exec_instr_ctx_t const * invoke_context,
     240             :                        uchar                       source_account_index,
     241             :                        uchar                       destination_account_index,
     242             :                        ulong                       lamports,
     243             :                        fd_stake_meta_t const *     source_meta,
     244             :                        ulong                       additional_required_lamports,
     245             :                        int                         source_is_active,
     246        1530 :                        validated_split_info_t *    out ) {
     247             : 
     248        1530 :   ulong source_lamports = 0;
     249             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1003-L1004
     250        6120 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( invoke_context, source_account_index, source_account ) {
     251             : 
     252             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1005
     253        1530 :   source_lamports = source_account->const_meta->info.lamports;
     254             : 
     255        1530 :   } FD_BORROWED_ACCOUNT_DROP( source_account );
     256             : 
     257        1530 :   ulong destination_lamports = 0;
     258        1530 :   ulong destination_data_len = 0;
     259             : 
     260             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1007-L1008
     261        6120 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( invoke_context, destination_account_index, destination_account ) {
     262             : 
     263             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1009-1010
     264        1530 :   destination_lamports = destination_account->const_meta->info.lamports;
     265        1530 :   destination_data_len = destination_account->const_meta->dlen;
     266             : 
     267        1530 :   } FD_BORROWED_ACCOUNT_DROP( destination_account );
     268             : 
     269             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1013-L1021
     270        1530 :   if( FD_UNLIKELY( lamports==0 ) ) return FD_EXECUTOR_INSTR_ERR_INSUFFICIENT_FUNDS;
     271        1467 :   if( FD_UNLIKELY( lamports>source_lamports ) ) return FD_EXECUTOR_INSTR_ERR_INSUFFICIENT_FUNDS;
     272             : 
     273             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1027-L1040
     274        1467 :   ulong source_minimum_balance =
     275        1467 :       fd_ulong_sat_add( source_meta->rent_exempt_reserve, additional_required_lamports );
     276        1467 :   ulong source_remaining_balance = fd_ulong_sat_sub( source_lamports, lamports );
     277             : 
     278        1467 :   if( FD_LIKELY( source_remaining_balance==0 ) ) {
     279        1038 :   } else if( source_remaining_balance<source_minimum_balance ) {
     280         117 :     return FD_EXECUTOR_INSTR_ERR_INSUFFICIENT_FUNDS;
     281         921 :   } else {
     282        1350 :   };
     283             : 
     284             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1042
     285        1350 :   fd_rent_t const * rent = fd_sysvar_cache_rent( invoke_context->slot_ctx->sysvar_cache );
     286        1350 :   if( FD_UNLIKELY( !rent ) )
     287           0 :     return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
     288             : 
     289             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1043
     290        1350 :   ulong destination_rent_exempt_reserve =
     291        1350 :       fd_rent_exempt_minimum_balance( rent, destination_data_len );
     292             : 
     293             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1048
     294        1350 :   if( FD_UNLIKELY(
     295        1350 :            FD_FEATURE_ACTIVE( invoke_context->slot_ctx, require_rent_exempt_split_destination ) &&
     296        1350 :            source_is_active && source_remaining_balance!=0 &&
     297        1350 :            destination_lamports<destination_rent_exempt_reserve ) ) {
     298         258 :     return FD_EXECUTOR_INSTR_ERR_INSUFFICIENT_FUNDS;
     299         258 :   }
     300             : 
     301             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1059-L1066
     302        1092 :   ulong destination_minimum_balance =
     303        1092 :       fd_ulong_sat_add( destination_rent_exempt_reserve, additional_required_lamports );
     304        1092 :   ulong destination_balance_deficit =
     305        1092 :       fd_ulong_sat_sub( destination_minimum_balance, destination_lamports );
     306        1092 :   if( FD_UNLIKELY( lamports<destination_balance_deficit ) ) {
     307         168 :     return FD_EXECUTOR_INSTR_ERR_INSUFFICIENT_FUNDS;
     308         168 :   }
     309             : 
     310             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1067-L1071
     311         924 :   out->source_remaining_balance        = source_remaining_balance;
     312         924 :   out->destination_rent_exempt_reserve = destination_rent_exempt_reserve;
     313         924 :   return 0;
     314        1092 : }
     315             : 
     316             : /**********************************************************************/
     317             : /* impl Lockup                                                        */
     318             : /**********************************************************************/
     319             : 
     320             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L270
     321             : static inline int
     322             : lockup_is_in_force( fd_stake_lockup_t const *     self,
     323             :                     fd_sol_sysvar_clock_t const * clock,
     324        1875 :                     fd_pubkey_t const *           custodian ) {
     325             :   // FIXME FD_LIKELY
     326        1875 :   if( custodian && !memcmp( custodian, &self->custodian, sizeof( fd_pubkey_t ) ) ) {
     327          45 :     return 0;
     328          45 :   }
     329        1830 :   return self->unix_timestamp>clock->unix_timestamp || self->epoch>clock->epoch;
     330        1875 : }
     331             : 
     332             : /**********************************************************************/
     333             : /* impl Authorized                                                    */
     334             : /**********************************************************************/
     335             : 
     336             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L359
     337             : static inline int
     338             : authorized_check( fd_stake_authorized_t const * self,
     339             :                   fd_pubkey_t const *           signers[static FD_TXN_SIG_MAX],
     340        4803 :                   fd_stake_authorize_t          stake_authorize ) {
     341             :   /* clang-format off */
     342        4803 :   switch( stake_authorize.discriminant ) {
     343             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L365
     344        4098 :   case fd_stake_authorize_enum_staker:
     345        4098 :     if( FD_LIKELY( fd_instr_signers_contains( signers, &self->staker ) ) ) {
     346        3165 :       return 0;
     347        3165 :     }
     348         933 :     return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     349             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L366
     350         705 :   case fd_stake_authorize_enum_withdrawer:
     351         705 :     if( FD_LIKELY( fd_instr_signers_contains( signers, &self->withdrawer ) ) ) {
     352         555 :       return 0;
     353         555 :     }
     354         150 :     return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     355           0 :   default:
     356           0 :     return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     357        4803 :   }
     358             :   /* clang-format on */
     359        4803 : }
     360             : 
     361             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L371
     362             : static int
     363             : authorized_authorize( fd_stake_authorized_t *                  self,
     364             :                       fd_pubkey_t const *                      signers[static FD_TXN_SIG_MAX],
     365             :                       fd_pubkey_t const *                      new_authorized,
     366             :                       fd_stake_authorize_t const *             stake_authorize,
     367             :                       fd_stake_lockup_custodian_args_t const * lockup_custodian_args,
     368         747 :                       /* out */ uint *                         custom_err ) {
     369         747 :   int rc;
     370         747 :   switch( stake_authorize->discriminant ) {
     371             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L379
     372         396 :   case fd_stake_authorize_enum_staker:
     373         396 :     if( FD_UNLIKELY( !fd_instr_signers_contains( signers, &self->staker ) &&
     374         396 :                       !fd_instr_signers_contains( signers, &self->withdrawer ) ) ) {
     375         216 :       return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     376         216 :     }
     377         180 :     self->staker = *new_authorized;
     378         180 :     break;
     379             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L386
     380         351 :   case fd_stake_authorize_enum_withdrawer:
     381         351 :     if( FD_LIKELY( lockup_custodian_args ) ) {
     382         351 :       fd_stake_lockup_t const *     lockup    = &lockup_custodian_args->lockup;
     383         351 :       fd_sol_sysvar_clock_t const * clock     = &lockup_custodian_args->clock;
     384         351 :       fd_pubkey_t const *           custodian = lockup_custodian_args->custodian;
     385             : 
     386             :       // FIXME FD_LIKELY
     387         351 :       if( lockup_is_in_force( lockup, clock, NULL ) ) {
     388             :         // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L389-L402
     389         129 :         if( !custodian ) { // FIXME FD_LIKELY
     390          39 :           *custom_err = FD_STAKE_ERR_CUSTODIAN_MISSING;
     391          39 :           return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     392          90 :         } else {
     393          90 :           if( FD_UNLIKELY( !fd_instr_signers_contains( signers, custodian ) ) ) {
     394          36 :             *custom_err = FD_STAKE_ERR_CUSTODIAN_SIGNATURE_MISSING;
     395          36 :             return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     396          36 :           }
     397             : 
     398          54 :           if( FD_UNLIKELY( lockup_is_in_force( lockup, clock, custodian ) ) ) {
     399          48 :             *custom_err = FD_STAKE_ERR_LOCKUP_IN_FORCE;
     400          48 :             return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     401          48 :           }
     402          54 :         }
     403         129 :       }
     404             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L405
     405         228 :       rc = authorized_check( self, signers, *stake_authorize );
     406         228 :       if( FD_UNLIKELY( rc ) ) return rc;
     407         144 :       self->withdrawer = *new_authorized;
     408         144 :     }
     409         747 :   }
     410         324 :   return 0;
     411         747 : }
     412             : 
     413             : /**********************************************************************/
     414             : /* impl Meta                                                          */
     415             : /**********************************************************************/
     416             : 
     417             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L482
     418             : static inline int
     419             : set_lockup_meta( fd_stake_meta_t *             self,
     420             :                  fd_lockup_args_t const *      lockup,
     421             :                  fd_pubkey_t const *           signers[static FD_TXN_SIG_MAX],
     422         525 :                  fd_sol_sysvar_clock_t const * clock ) {
     423             :   // FIXME FD_LIKELY
     424         525 :   if( lockup_is_in_force( &self->lockup, clock, NULL ) ) {
     425         333 :     if( !fd_instr_signers_contains( signers, &self->lockup.custodian ) ) {
     426         270 :       return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     427         270 :     }
     428         333 :   } else if( !fd_instr_signers_contains( signers, &self->authorized.withdrawer ) ) {
     429         138 :     return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     430         138 :   }
     431             : 
     432             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L498-L506
     433         117 :   if( lockup->unix_timestamp ) self->lockup.unix_timestamp = *lockup->unix_timestamp;
     434         117 :   if( lockup->epoch ) self->lockup.epoch = *lockup->epoch;
     435         117 :   if( lockup->custodian ) self->lockup.custodian = *lockup->custodian;
     436         117 :   return 0;
     437         525 : }
     438             : 
     439             : /**********************************************************************/
     440             : /* impl Delegation                                                    */
     441             : /**********************************************************************/
     442             : 
     443             : typedef fd_stake_history_entry_t fd_stake_activation_status_t;
     444             : 
     445             : fd_stake_history_entry_t const *
     446             : fd_stake_history_ele_query_const( fd_stake_history_t const * history,
     447        7233 :                                   ulong epoch ) {
     448        7233 :   if( 0 == history->fd_stake_history_len ) {
     449        1233 :     return NULL;
     450        1233 :   }
     451             : 
     452        6000 :   if( epoch > history->fd_stake_history[0].epoch ) {
     453          18 :     return NULL;
     454          18 :   }
     455             : 
     456        5982 :   ulong off = (history->fd_stake_history[0].epoch - epoch);
     457        5982 :   if( off >= history->fd_stake_history_len ) {
     458         705 :     return NULL;
     459         705 :   }
     460             : 
     461        5277 :   ulong e = (off + history->fd_stake_history_offset) & (history->fd_stake_history_size - 1);
     462             : 
     463        5277 :   if ( history->fd_stake_history[e].epoch != epoch ) {
     464           0 :     return NULL;
     465           0 :   }
     466             : 
     467        5277 :   return &history->fd_stake_history[e];
     468        5277 : }
     469             : 
     470             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L728
     471             : static effective_activating_t
     472             : stake_and_activating( fd_delegation_t const *    self,
     473             :                       ulong                      target_epoch,
     474             :                       fd_stake_history_t const * history,
     475        3336 :                       ulong *                    new_rate_activation_epoch ) {
     476        3336 :   ulong delegated_stake = self->stake;
     477             : 
     478        3336 :   fd_stake_history_entry_t const * cluster_stake_at_activation_epoch;
     479             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L736
     480        3336 :   if( self->activation_epoch==ULONG_MAX ) {
     481         312 :     return ( effective_activating_t ){ .effective = delegated_stake, .activating = 0 };
     482        3024 :   } else if( self->activation_epoch==self->deactivation_epoch ) {
     483         270 :     return ( effective_activating_t ){ .effective = 0, .activating = 0 };
     484        2754 :   } else if( target_epoch==self->activation_epoch ) {
     485         450 :     return ( effective_activating_t ){ .effective = 0, .activating = delegated_stake };
     486        2304 :   } else if( target_epoch<self->activation_epoch ) {
     487         252 :     return ( effective_activating_t ){ .effective = 0, .activating = 0 };
     488        2052 :   } else if( history &&
     489        2052 :               ( cluster_stake_at_activation_epoch = fd_stake_history_ele_query_const(
     490        2052 :                     history, self->activation_epoch ) ) ) {
     491         585 :     ulong                            prev_epoch         = self->activation_epoch;
     492         585 :     fd_stake_history_entry_t const * prev_cluster_stake = cluster_stake_at_activation_epoch;
     493             : 
     494             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L763
     495         585 :     ulong current_epoch;
     496         585 :     ulong current_effective_stake = 0;
     497        4077 :     for( ;; ) {
     498        4077 :       current_epoch = prev_epoch + 1;
     499        4077 :       if( FD_LIKELY( prev_cluster_stake->activating==0 ) ) { // FIXME always optimize loop break?
     500         120 :         break;
     501         120 :       }
     502             : 
     503             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L775-L780
     504        3957 :       ulong  remaining_activating_stake = delegated_stake - current_effective_stake;
     505        3957 :       double weight = (double)remaining_activating_stake / (double)prev_cluster_stake->activating;
     506        3957 :       double warmup_cooldown_rate_ =
     507        3957 :           warmup_cooldown_rate( current_epoch, new_rate_activation_epoch );
     508             : 
     509             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L782-L786
     510        3957 :       double newly_effective_cluster_stake =
     511        3957 :           (double)prev_cluster_stake->effective * warmup_cooldown_rate_;
     512        3957 :       ulong newly_effective_stake =
     513        3957 :           fd_ulong_max( fd_rust_cast_double_to_ulong( weight * newly_effective_cluster_stake ), 1 );
     514             : 
     515             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L787-L792
     516        3957 :       current_effective_stake += newly_effective_stake;
     517        3957 :       if( FD_LIKELY( current_effective_stake>=delegated_stake ) ) {
     518         198 :         current_effective_stake = delegated_stake;
     519         198 :         break;
     520         198 :       }
     521             : 
     522             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L793
     523        3759 :       if( FD_LIKELY( current_epoch>=target_epoch ||
     524        3759 :                      current_epoch>=self->deactivation_epoch ) ) { // FIXME always optimize loop break
     525         264 :         break;
     526         264 :       }
     527             : 
     528             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L796-L801
     529        3495 :       fd_stake_history_entry_t const * current_cluster_stake =
     530        3495 :           fd_stake_history_ele_query_const( history, current_epoch );
     531        3495 :       if( FD_UNLIKELY( NULL != current_cluster_stake ) ) {
     532        3492 :         prev_epoch         = current_epoch;
     533        3492 :         prev_cluster_stake = current_cluster_stake;
     534        3492 :       } else {
     535             :         // FIXME always optimize loop break
     536           3 :         break;
     537           3 :       }
     538        3495 :     }
     539             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L804-L807
     540         585 :     return ( effective_activating_t ){ .effective  = current_effective_stake,
     541         585 :                                        .activating = delegated_stake - current_effective_stake };
     542        1467 :   } else {
     543             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L810
     544        1467 :     return ( effective_activating_t ){ .effective = delegated_stake, .activating = 0 };
     545        1467 :   }
     546        3336 : }
     547             : 
     548             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L641
     549             : static fd_stake_activation_status_t
     550             : stake_activating_and_deactivating( fd_delegation_t const *    self,
     551             :                                    ulong                      target_epoch,
     552             :                                    fd_stake_history_t const * stake_history,
     553        3336 :                                    ulong *                    new_rate_activation_epoch ) {
     554             : 
     555             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L648
     556        3336 :   effective_activating_t effective_activating =
     557        3336 :       stake_and_activating( self, target_epoch, stake_history, new_rate_activation_epoch );
     558             : 
     559        3336 :   ulong effective_stake  = effective_activating.effective;
     560        3336 :   ulong activating_stake = effective_activating.activating;
     561             : 
     562        3336 :   fd_stake_history_entry_t const * cluster_stake_at_activation_epoch = NULL;
     563             : 
     564        3336 :   fd_stake_history_entry_t k;
     565        3336 :   k.epoch = self->deactivation_epoch;
     566             : 
     567             :   // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/stake/state.rs#L652
     568        3336 :   if( target_epoch<self->deactivation_epoch ) {
     569             :     // if is bootstrap
     570        2292 :     if( activating_stake==0 ) {
     571        1566 :       return ( fd_stake_history_entry_t ){
     572        1566 :           .effective = effective_stake, .deactivating = 0, .activating = 0 };
     573        1566 :     } else {
     574         726 :       return ( fd_stake_history_entry_t ){
     575         726 :           .effective = effective_stake, .deactivating = 0, .activating = activating_stake };
     576         726 :     }
     577        2292 :   } else if( target_epoch==self->deactivation_epoch ) {
     578             :     // https://github.com/anza-xyz/agave/blob/be16321eb0db3e12a57a32f59febbf54b92ebb7c/sdk/program/src/stake/state.rs#L662
     579         318 :     return ( fd_stake_history_entry_t ){
     580         318 :         .effective = effective_stake, .deactivating = effective_stake, .activating = 0 };
     581         726 :   } else if( stake_history!=NULL ) {
     582             :     // https://github.com/anza-xyz/agave/blob/be16321eb0db3e12a57a32f59febbf54b92ebb7c/sdk/program/src/stake/state.rs#L665
     583         726 :     fd_stake_history_entry_t const * n = fd_stake_history_ele_query_const( stake_history, k.epoch );
     584             : 
     585         726 :     if( NULL!=n ) { cluster_stake_at_activation_epoch = n; }
     586             : 
     587         726 :     if( cluster_stake_at_activation_epoch==NULL ) {
     588         486 :       fd_stake_history_entry_t entry = { .effective = 0, .activating = 0, .deactivating = 0 };
     589             : 
     590         486 :       return entry;
     591         486 :     }
     592         240 :     ulong                      prev_epoch         = self->deactivation_epoch;
     593         240 :     fd_stake_history_entry_t const * prev_cluster_stake = cluster_stake_at_activation_epoch;
     594             : 
     595         240 :     ulong current_epoch;
     596         240 :     ulong current_effective_stake = effective_stake;
     597        1200 :     for( ;; ) {
     598        1200 :       current_epoch = prev_epoch + 1;
     599        1200 :       if( prev_cluster_stake->deactivating==0 ) break;
     600             : 
     601        1194 :       double weight = (double)current_effective_stake / (double)prev_cluster_stake->deactivating;
     602        1194 :       double warmup_cooldown_rate_ =
     603        1194 :           warmup_cooldown_rate( current_epoch, new_rate_activation_epoch );
     604             : 
     605             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L697-L700
     606        1194 :       double newly_not_effective_cluster_stake =
     607        1194 :           (double)prev_cluster_stake->effective * warmup_cooldown_rate_;
     608        1194 :       ulong newly_not_effective_stake =
     609        1194 :           fd_ulong_max( fd_rust_cast_double_to_ulong( weight * newly_not_effective_cluster_stake ), 1 );
     610             : 
     611        1194 :       current_effective_stake =
     612        1194 :           fd_ulong_sat_sub( current_effective_stake, newly_not_effective_stake );
     613        1194 :       if( current_effective_stake==0 ) break;
     614             : 
     615        1170 :       if( current_epoch>=target_epoch ) break;
     616             : 
     617             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L711-L713
     618         960 :       fd_stake_history_entry_t const * current_cluster_stake = NULL;
     619         960 :       if( ( current_cluster_stake = fd_stake_history_ele_query_const(stake_history, current_epoch ) ) ) {
     620         960 :         prev_epoch         = current_epoch;
     621         960 :         prev_cluster_stake = current_cluster_stake;
     622         960 :       } else {
     623           0 :         break;
     624           0 :       }
     625         960 :     }
     626             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L720
     627         240 :     return ( fd_stake_history_entry_t ){ .effective    = current_effective_stake,
     628         240 :                                          .deactivating = current_effective_stake,
     629         240 :                                          .activating   = 0 };
     630         726 :   } else {
     631             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L723C16-L723C17
     632           0 :     return ( fd_stake_history_entry_t ){ .effective = 0, .activating = 0, .deactivating = 0 };
     633           0 :   }
     634        3336 : }
     635             : 
     636             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L630
     637             : static inline ulong
     638             : delegation_stake( fd_delegation_t const *    self,
     639             :                   ulong                      epoch,
     640             :                   fd_stake_history_t const * history,
     641         444 :                   ulong *                    new_rate_activation_epoch ) {
     642         444 :   return stake_activating_and_deactivating( self, epoch, history, new_rate_activation_epoch )
     643         444 :       .effective;
     644         444 : }
     645             : 
     646             : /**********************************************************************/
     647             : /* mod tools                                                          */
     648             : /**********************************************************************/
     649             : 
     650             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/tools.rs#L44
     651             : static inline int
     652             : acceptable_reference_epoch_credits( fd_vote_epoch_credits_t * epoch_credits,
     653         681 :                                     ulong                     current_epoch ) {
     654         681 :   ulong len            = deq_fd_vote_epoch_credits_t_cnt( epoch_credits );
     655         681 :   ulong epoch_index[1] = { ULONG_MAX };
     656             :   // FIXME FD_LIKELY
     657         681 :   if( !__builtin_usubl_overflow( len, MINIMUM_DELINQUENT_EPOCHS_FOR_DEACTIVATION, epoch_index ) ) {
     658         558 :     ulong epoch = current_epoch;
     659        3057 :     for( ulong i = len - 1; i>=*epoch_index; i-- ) {
     660        2574 :       ulong vote_epoch = deq_fd_vote_epoch_credits_t_peek_index( epoch_credits, i )->epoch;
     661        2574 :       if( vote_epoch!=epoch ) { return 0; }
     662        2508 :       epoch = fd_ulong_sat_sub( epoch, 1 );
     663        2508 :       if( i==0 ) break;
     664        2508 :     }
     665         492 :     return 1;
     666         558 :   } else {
     667         123 :     return 0;
     668         123 :   };
     669           0 : }
     670             : 
     671             : /* https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/tools.rs#L67-L83 */
     672             : static inline int
     673         468 : eligible_for_deactivate_delinquent( fd_vote_epoch_credits_t * epoch_credits, ulong current_epoch ) {
     674         468 :   if( FD_LIKELY( deq_fd_vote_epoch_credits_t_empty( epoch_credits ) ) ) {
     675          30 :     return 1;
     676          30 :   }
     677             : 
     678         438 :   fd_vote_epoch_credits_t * last = deq_fd_vote_epoch_credits_t_peek_tail( epoch_credits );
     679         438 :   if( FD_LIKELY( !last ) ) {
     680           0 :     return 1;
     681         438 :   } else {
     682         438 :     ulong epoch         = last->epoch;
     683         438 :     ulong minimum_epoch = ULONG_MAX;
     684         438 :     int res = fd_ulong_checked_sub( current_epoch, MINIMUM_DELINQUENT_EPOCHS_FOR_DEACTIVATION, &minimum_epoch );
     685         438 :     if( FD_LIKELY( res==0 ) ) {
     686         438 :       return epoch<=minimum_epoch;
     687         438 :     } else {
     688           0 :       return 0;
     689           0 :     }
     690         438 :   }
     691         438 : }
     692             : 
     693             : /**********************************************************************/
     694             : /* impl StakeFlags                                                    */
     695             : /**********************************************************************/
     696             : 
     697             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/stake_flags.rs#L72
     698             : #define STAKE_FLAGS_MUST_FULLY_ACTIVATE_BEFORE_DEACTIVATION_IS_PERMITTED                           \
     699             :   ( ( fd_stake_flags_t ){ .bits = 1 } )
     700             : 
     701             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/stake_flags.rs#L75
     702         837 : #define STAKE_FLAGS_EMPTY ( ( fd_stake_flags_t ){ .bits = 0 } )
     703             : 
     704             : /**********************************************************************/
     705             : /* impl Stake                                                         */
     706             : /**********************************************************************/
     707             : 
     708             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L915
     709             : static int
     710             : stake_split( fd_stake_t * self,
     711             :              ulong        remaining_stake_delta,
     712             :              ulong        split_stake_amount,
     713             :              uint *       custom_err,
     714         543 :              fd_stake_t * out ) {
     715         543 :   if( FD_UNLIKELY( remaining_stake_delta>self->delegation.stake ) ) {
     716           0 :     *custom_err = FD_STAKE_ERR_INSUFFICIENT_STAKE;
     717           0 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     718           0 :   }
     719         543 :   self->delegation.stake -= remaining_stake_delta;
     720         543 :   fd_stake_t new;
     721         543 :   new                  = *self;
     722         543 :   new.delegation.stake = split_stake_amount;
     723         543 :   *out                 = new;
     724         543 :   return 0;
     725         543 : }
     726             : 
     727             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L934
     728             : static int
     729         432 : stake_deactivate( fd_stake_t * stake, ulong epoch, uint * custom_err ) {
     730         432 :   if( FD_UNLIKELY( stake->delegation.deactivation_epoch!=ULONG_MAX ) ) {
     731         219 :     *custom_err = FD_STAKE_ERR_ALREADY_DEACTIVATED;
     732         219 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     733         219 :   } else {
     734         213 :     stake->delegation.deactivation_epoch = epoch;
     735         213 :     return 0;
     736         213 :   }
     737         432 : }
     738             : 
     739             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L62
     740             : int
     741             : fd_new_warmup_cooldown_rate_epoch( fd_exec_slot_ctx_t const * slot_ctx,
     742             :                                    /* out */ ulong *          epoch,
     743        3804 :                                    int *                      err ) {
     744        3804 :   *err = 0;
     745        3804 :   fd_epoch_schedule_t const * epoch_schedule = fd_sysvar_cache_epoch_schedule( slot_ctx->sysvar_cache );
     746        3804 :   if( FD_UNLIKELY( !epoch_schedule ) ) {
     747           0 :     *epoch = ULONG_MAX;
     748           0 :     *err   = FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
     749           0 :     return 1;
     750           0 :   }
     751             :   /* reduce_stake_warmup_cooldown is activated on all clusters, so we shouldn't have a `None` case. */
     752        3804 :   if( FD_LIKELY( FD_FEATURE_ACTIVE( slot_ctx, reduce_stake_warmup_cooldown ) ) ) {
     753        3804 :     ulong slot = slot_ctx->epoch_ctx->features.reduce_stake_warmup_cooldown;
     754        3804 :     *epoch     = fd_slot_to_epoch( epoch_schedule, slot, NULL );
     755        3804 :     return 1;
     756        3804 :   }
     757           0 :   return 0;
     758        3804 : }
     759             : 
     760             : /**********************************************************************/
     761             : /* util                                                               */
     762             : /**********************************************************************/
     763             : 
     764             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/state.rs#L205
     765             : FD_FN_CONST static inline ulong
     766           0 : stake_state_v2_size_of( void ) {
     767           0 :   return 200;
     768           0 : }
     769             : 
     770             : /**********************************************************************/
     771             : /* impl MergeKind                                                     */
     772             : /**********************************************************************/
     773             : 
     774             : static fd_stake_meta_t const *
     775        2475 : meta( merge_kind_t const * self ) {
     776        2475 :   switch( self->discriminant ) {
     777        1533 :   case merge_kind_inactive:
     778        1533 :     return &self->inner.inactive.meta;
     779         453 :   case merge_kind_activation_epoch:
     780         453 :     return &self->inner.activation_epoch.meta;
     781         489 :   case merge_kind_fully_active:
     782         489 :     return &self->inner.fully_active.meta;
     783           0 :   default:
     784           0 :     FD_LOG_ERR( ( "invalid merge_kind_t discriminant" ) );
     785        2475 :   }
     786        2475 : }
     787             : 
     788             : static fd_stake_t const *
     789         408 : active_stake( merge_kind_t const * self ) {
     790         408 :   switch( self->discriminant ) {
     791         216 :   case merge_kind_inactive:
     792         216 :     return NULL;
     793         117 :   case merge_kind_activation_epoch:
     794         117 :     return &self->inner.activation_epoch.stake;
     795          75 :   case merge_kind_fully_active:
     796          75 :     return &self->inner.fully_active.stake;
     797           0 :   default:
     798           0 :     FD_LOG_ERR( ( "invalid merge_kind_t discriminant" ) );
     799         408 :   }
     800         408 : }
     801             : 
     802             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1097
     803             : static int
     804             : get_if_mergeable( fd_exec_instr_ctx_t *         invoke_context, // not const to log
     805             :                   fd_stake_state_v2_t const *   stake_state,
     806             :                   ulong                         stake_lamports,
     807             :                   fd_sol_sysvar_clock_t const * clock,
     808             :                   fd_stake_history_t const *    stake_history,
     809             :                   merge_kind_t *                out,
     810        2529 :                   uint *                        custom_err ) {
     811             :   // stake_history must be non-NULL
     812             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1104
     813        2529 :   switch( stake_state->discriminant ) {
     814        1827 :   case fd_stake_state_v2_enum_stake: {
     815        1827 :     fd_stake_meta_t const *  meta        = &stake_state->inner.stake.meta;
     816        1827 :     fd_stake_t const *       stake       = &stake_state->inner.stake.stake;
     817        1827 :     fd_stake_flags_t const * stake_flags = &stake_state->inner.stake.stake_flags;
     818             : 
     819        1827 :     ulong new_rate_activation_epoch = ULONG_MAX;
     820        1827 :     int   err;
     821             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1111
     822        1827 :     int   is_some = fd_new_warmup_cooldown_rate_epoch( invoke_context->slot_ctx, &new_rate_activation_epoch, &err );
     823        1827 :     if( FD_UNLIKELY( err ) ) return err;
     824             : 
     825             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1108
     826        1827 :     fd_stake_history_entry_t status =
     827        1827 :         stake_activating_and_deactivating( &stake->delegation,
     828        1827 :                                            clock->epoch,
     829        1827 :                                            stake_history,
     830        1827 :                                            fd_ptr_if( is_some, &new_rate_activation_epoch, NULL ) );
     831             : 
     832             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1115
     833        1827 :     if( status.effective==0 && status.activating==0 && status.deactivating==0 ) {
     834             : 
     835         588 :       *out = ( merge_kind_t ){ .discriminant = merge_kind_inactive,
     836         588 :                                .inner        = { .inactive = { .meta         = *meta,
     837         588 :                                                                .active_stake = stake_lamports,
     838         588 :                                                                .stake_flags  = *stake_flags } } };
     839         588 :       return 0;
     840             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1116
     841        1239 :     } else if( status.effective==0 ) {
     842         342 :       *out = ( merge_kind_t ){ .discriminant = merge_kind_activation_epoch,
     843         342 :                                .inner        = { .activation_epoch = { .meta        = *meta,
     844         342 :                                                                        .stake       = *stake,
     845         342 :                                                                        .stake_flags = *stake_flags } } };
     846         342 :       return 0;
     847             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1117
     848         897 :     } else if( status.activating==0 && status.deactivating==0 ) {
     849         336 :       *out = ( merge_kind_t ){ .discriminant = merge_kind_fully_active,
     850         336 :                                .inner = { .fully_active = { .meta  = *meta,
     851         336 :                                                             .stake = *stake } } };
     852         336 :       return 0;
     853         561 :     } else {
     854         561 :       fd_log_collector_msg_literal( invoke_context, "stake account with transient stake cannot be merged" );
     855         561 :       *custom_err = FD_STAKE_ERR_MERGE_TRANSIENT_STAKE;
     856         561 :       return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     857         561 :     }
     858           0 :     break;
     859        1827 :   }
     860         552 :   case fd_stake_state_v2_enum_initialized: {
     861             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1126
     862         552 :     *out = ( merge_kind_t ){ .discriminant = merge_kind_inactive,
     863         552 :                              .inner        = { .inactive = { .meta         = stake_state->inner.initialized.meta,
     864         552 :                                                              .active_stake = stake_lamports,
     865         552 :                                                              .stake_flags  = STAKE_FLAGS_EMPTY} } };
     866         552 :     break;
     867        1827 :   }
     868         150 :   default:
     869             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1128
     870         150 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
     871        2529 :   }
     872         552 :   return 0;
     873        2529 : }
     874             : 
     875             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1132
     876             : static int
     877             : metas_can_merge( fd_exec_instr_ctx_t *         invoke_context, // not const to log
     878             :                  fd_stake_meta_t const *       stake,
     879             :                  fd_stake_meta_t const *       source,
     880             :                  fd_sol_sysvar_clock_t const * clock,
     881         657 :                  uint *                        custom_err ) {
     882             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1139
     883         657 :   int  can_merge_lockups =
     884         657 :       ( !memcmp( &stake->lockup, &source->lockup, sizeof( fd_stake_lockup_t ) ) ) ||
     885         657 :       ( !lockup_is_in_force( &stake->lockup, clock, NULL ) &&
     886         327 :         !lockup_is_in_force( &source->lockup, clock, NULL ) );
     887             : 
     888             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1146
     889         657 :   if( FD_LIKELY( !memcmp( &stake->authorized, &source->authorized, sizeof( fd_stake_authorized_t ) ) && can_merge_lockups ) ) {
     890         375 :     return 0;
     891         375 :   } else {
     892         282 :     fd_log_collector_msg_literal( invoke_context, "Unable to merge due to metadata mismatch" );
     893         282 :     *custom_err = FD_STAKE_ERR_MERGE_MISMATCH;
     894         282 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     895         282 :   }
     896         657 : }
     897             : 
     898             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1154
     899             : static int
     900             : active_delegations_can_merge( fd_exec_instr_ctx_t *   invoke_context, // not const to log
     901             :                               fd_delegation_t const * stake,
     902             :                               fd_delegation_t const * source,
     903          51 :                               uint *                  custom_err ) {
     904          51 :   if( memcmp( &stake->voter_pubkey, &source->voter_pubkey, sizeof(fd_pubkey_t) ) ) {
     905           3 :     fd_log_collector_msg_literal( invoke_context, "Unable to merge due to voter mismatch" );
     906           3 :     *custom_err = FD_STAKE_ERR_MERGE_MISMATCH;
     907           3 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     908          48 :   } else if( FD_LIKELY( stake->deactivation_epoch==ULONG_MAX && source->deactivation_epoch==ULONG_MAX ) ) {
     909             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1162
     910          39 :     return 0;
     911          39 :   } else {
     912             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1167
     913           9 :     fd_log_collector_msg_literal( invoke_context, "Unable to merge due to stake deactivation" );
     914           9 :     *custom_err = FD_STAKE_ERR_MERGE_MISMATCH;
     915           9 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     916           9 :   }
     917          51 : }
     918             : 
     919             : static int
     920             : stake_weighted_credits_observed( fd_stake_t const * stake,
     921             :                                  ulong              absorbed_lamports,
     922             :                                  ulong              absorbed_credits_observed,
     923          60 :                                  ulong *            out ) {
     924             :   /* https://github.com/anza-xyz/agave/blob/dc74c22960b4f2adfc672f6dc3bfaa74ec1d5d48/programs/stake/src/stake_state.rs#L1194 */
     925          60 :   if( FD_LIKELY( stake->credits_observed==absorbed_credits_observed ) ) {
     926          39 :     *out = stake->credits_observed;
     927          39 :     return 1;
     928          39 :   } else {
     929             :     /* https://github.com/anza-xyz/agave/blob/dc74c22960b4f2adfc672f6dc3bfaa74ec1d5d48/programs/stake/src/stake_state.rs#L1197 */
     930             :     /* let total_stake = u128::from(stake.delegation.stake.checked_add(absorbed_lamports)?); */
     931          21 :     ulong total_stake;
     932             :     /* If there is an overflow on the ulong addition then exit */
     933          21 :     if( FD_UNLIKELY( fd_ulong_checked_add( stake->delegation.stake, absorbed_lamports, &total_stake ) ) ) {
     934           6 :       return 0;
     935           6 :     }
     936             : 
     937             :     /* https://github.com/anza-xyz/agave/blob/9489096dc5b7f0a61a981f3d0fd393d264896c2a/programs/stake/src/stake_state.rs#L1198 */
     938             :     /* The multiplication of two 64 bit integers will never overflow the 128 bits */
     939          15 :     ulong stake_weighted_credits_h;
     940          15 :     ulong stake_weighted_credits_l;
     941             :     /* let stake_weighted_credits = */
     942             :     /*     u128::from(stake.credits_observed).checked_mul(u128::from(stake.delegation.stake))?; */
     943          15 :     fd_uwide_mul( &stake_weighted_credits_h, &stake_weighted_credits_l,
     944          15 :                   stake->credits_observed, stake->delegation.stake );
     945             : 
     946             :     /* https://github.com/anza-xyz/agave/blob/9489096dc5b7f0a61a981f3d0fd393d264896c2a/programs/stake/src/stake_state.rs#L1200 */
     947             :     /* The multiplication of two 64 bit integers will never overflow the 128 bits */
     948          15 :     ulong absorbed_weighted_credits_h;
     949          15 :     ulong absorbed_weighted_credits_l;
     950             :     /* let absorbed_weighted_credits = */
     951             :     /*     u128::from(absorbed_credits_observed).checked_mul(u128::from(absorbed_lamports))?; */
     952          15 :     fd_uwide_mul( &absorbed_weighted_credits_h, &absorbed_weighted_credits_l,
     953          15 :                   absorbed_credits_observed, absorbed_lamports );
     954             : 
     955             :     /* https://github.com/anza-xyz/agave/blob/9489096dc5b7f0a61a981f3d0fd393d264896c2a/programs/stake/src/stake_state.rs#L1204 */
     956             :     /* let total_weighted_credits = stake_weighted_credits */
     957             :     /*     .checked_add(absorbed_weighted_credits)? */
     958             :     /*     .checked_add(total_stake)? */
     959             :     /*     .checked_sub(1)?; */
     960          15 :     ulong total_weighted_credits_partial_one_h;
     961          15 :     ulong total_weighted_credits_partial_one_l;
     962          15 :     ulong carry_out = fd_uwide_add( &total_weighted_credits_partial_one_h, &total_weighted_credits_partial_one_l,
     963          15 :                                     stake_weighted_credits_h, stake_weighted_credits_l,
     964          15 :                                     absorbed_weighted_credits_h, absorbed_weighted_credits_l, 0UL );
     965             :     /* return on overflow */
     966          15 :     if( FD_UNLIKELY( carry_out ) ) {
     967           0 :       return 0;
     968           0 :     }
     969             : 
     970          15 :     ulong total_weighted_credits_partial_two_h;
     971          15 :     ulong total_weighted_credits_partial_two_l;
     972          15 :     carry_out = fd_uwide_add( &total_weighted_credits_partial_two_h, &total_weighted_credits_partial_two_l,
     973          15 :                               total_weighted_credits_partial_one_h, total_weighted_credits_partial_one_l,
     974          15 :                               0UL, total_stake, 0UL );
     975             :     /* return on overflow */
     976          15 :     if( FD_UNLIKELY( carry_out ) ) {
     977           0 :       return 0;
     978           0 :     }
     979             : 
     980             :     /* The only way we can underflow the subtraction of 1 is if the value of total_weighted_credits_partial_two is zero */
     981          15 :     if( FD_UNLIKELY( total_weighted_credits_partial_two_h==0 && total_weighted_credits_partial_two_l==0 ) ) {
     982           0 :       return 0;
     983           0 :     }
     984          15 :     ulong total_weighted_credits_h;
     985          15 :     ulong total_weighted_credits_l;
     986          15 :     fd_uwide_dec( &total_weighted_credits_h, &total_weighted_credits_l,
     987          15 :                   total_weighted_credits_partial_two_h, total_weighted_credits_partial_two_l, 1UL );
     988             : 
     989             :     /* https://github.com/anza-xyz/agave/blob/8a1b2dc3fa4b85e26fbce0db06a462d4853b0652/programs/stake/src/stake_state.rs#L1208 */
     990             :     /* u64::try_from(total_weighted_credits.checked_div(total_stake)?).ok() */
     991          15 :     ulong res_h;
     992          15 :     ulong res_l;
     993          15 :     if( FD_UNLIKELY( fd_uwide_div( &res_h, &res_l, total_weighted_credits_h, total_weighted_credits_l, total_stake ) ) ) {
     994           0 :       return 0;
     995           0 :     }
     996          15 :     *out = res_l;
     997          15 :     return 1;
     998          15 :   }
     999          60 : }
    1000             : 
    1001             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1239
    1002             : static int
    1003             : merge_delegation_stake_and_credits_observed( FD_FN_UNUSED fd_exec_instr_ctx_t const * invoke_context,
    1004             :                                              fd_stake_t *                stake,
    1005             :                                              ulong                       absorbed_lamports,
    1006          60 :                                              ulong absorbed_credits_observed ) {
    1007          60 :   int rc;
    1008          60 :   int  is_some = stake_weighted_credits_observed(
    1009          60 :       stake, absorbed_lamports, absorbed_credits_observed, &stake->credits_observed );
    1010          60 :   if( FD_UNLIKELY( !is_some ) ) return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW;
    1011          54 :   rc = fd_ulong_checked_add( stake->delegation.stake, absorbed_lamports, &stake->delegation.stake );
    1012          54 :   if( FD_UNLIKELY( rc ) ) return rc;
    1013          51 :   return 0;
    1014          54 : }
    1015             : 
    1016             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1171
    1017             : static int
    1018             : merge_kind_merge( merge_kind_t                  self,
    1019             :                   fd_exec_instr_ctx_t *         invoke_context, // not const to log
    1020             :                   merge_kind_t                  source,
    1021             :                   fd_sol_sysvar_clock_t const * clock,
    1022             :                   fd_stake_state_v2_t *         out,
    1023             :                   int  *                        is_some,
    1024         423 :                   uint *                        custom_err ) {
    1025         423 :   int rc;
    1026             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1177
    1027         423 :   rc = metas_can_merge( invoke_context, meta( &self ), meta( &source ), clock, custom_err );
    1028         423 :   if( FD_UNLIKELY( rc ) ) return rc;
    1029             : 
    1030             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1178-L1188
    1031         204 :   fd_stake_t const * stake   = active_stake( &self );
    1032         204 :   fd_stake_t const * source_ = active_stake( &source );
    1033             : 
    1034             :   // FIXME FD_LIKELY
    1035         204 :   if( stake && source_ ) {
    1036          51 :     rc = active_delegations_can_merge(
    1037          51 :         invoke_context, &stake->delegation, &source_->delegation, custom_err );
    1038          51 :     if( FD_UNLIKELY( rc ) ) return rc;
    1039          51 :   }
    1040             : 
    1041             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1188
    1042             :   // FIXME FD_LIKELY
    1043         192 :   fd_stake_state_v2_t   merged_state_ = {0};
    1044         192 :   fd_stake_state_v2_t * merged_state  = &merged_state_;
    1045         192 :   if( self.discriminant==merge_kind_inactive && source.discriminant==merge_kind_inactive ) {
    1046             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1189
    1047          63 :     merged_state = NULL;
    1048         129 :   } else if( self.discriminant==merge_kind_inactive && source.discriminant==merge_kind_activation_epoch ) {
    1049             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1190
    1050          39 :     merged_state = NULL;
    1051          90 :   } else if( self.discriminant==merge_kind_activation_epoch && source.discriminant==merge_kind_inactive ) {
    1052          42 :     fd_stake_meta_t  meta               = self.inner.activation_epoch.meta;
    1053          42 :     fd_stake_t       stake              = self.inner.activation_epoch.stake;
    1054          42 :     fd_stake_flags_t stake_flags        = self.inner.activation_epoch.stake_flags;
    1055          42 :     ulong            source_lamports    = source.inner.inactive.active_stake;
    1056          42 :     fd_stake_flags_t source_stake_flags = source.inner.inactive.stake_flags;
    1057             : 
    1058             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1195
    1059          42 :     rc = fd_ulong_checked_add( stake.delegation.stake, source_lamports, &stake.delegation.stake );
    1060          42 :     if( FD_UNLIKELY( rc ) ) return rc;
    1061             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1196
    1062          39 :     *merged_state = ( fd_stake_state_v2_t ){
    1063          39 :         .discriminant = fd_stake_state_v2_enum_stake,
    1064          39 :         .inner        = { .stake = { .meta        = meta,
    1065          39 :                                      .stake       = stake,
    1066          39 :                                      .stake_flags = { .bits = stake_flags.bits | source_stake_flags.bits } } } };
    1067          48 :   } else if( self.discriminant==merge_kind_activation_epoch && source.discriminant==merge_kind_activation_epoch ) {
    1068             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1203
    1069          18 :     fd_stake_meta_t  meta               = self.inner.activation_epoch.meta;
    1070          18 :     fd_stake_t       stake              = self.inner.activation_epoch.stake;
    1071          18 :     fd_stake_flags_t stake_flags        = self.inner.activation_epoch.stake_flags;
    1072          18 :     fd_stake_meta_t  source_meta        = source.inner.activation_epoch.meta;
    1073          18 :     fd_stake_t       source_stake       = source.inner.activation_epoch.stake;
    1074          18 :     fd_stake_flags_t source_stake_flags = source.inner.activation_epoch.stake_flags;
    1075             : 
    1076             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1206
    1077          18 :     ulong source_lamports = ULONG_MAX;
    1078          18 :     rc = fd_ulong_checked_add( source_meta.rent_exempt_reserve, source_stake.delegation.stake, &source_lamports );
    1079          18 :     if( FD_UNLIKELY( rc ) ) return rc;
    1080             : 
    1081             :     // // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1210
    1082          18 :     rc = merge_delegation_stake_and_credits_observed(invoke_context, &stake, source_lamports, source_stake.credits_observed );
    1083          18 :     if( FD_UNLIKELY( rc ) ) return rc;
    1084             : 
    1085             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1215
    1086          18 :     *merged_state = ( fd_stake_state_v2_t ){
    1087          18 :         .discriminant = fd_stake_state_v2_enum_stake,
    1088          18 :         .inner        = { .stake = { .meta        = meta,
    1089          18 :                                      .stake       = stake,
    1090          18 :                                      .stake_flags = { .bits = stake_flags.bits | source_stake_flags.bits } } } };
    1091          30 :   } else if( self.discriminant==merge_kind_fully_active && source.discriminant==merge_kind_fully_active ) {
    1092             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1221
    1093          21 :     fd_stake_meta_t meta         = self.inner.fully_active.meta;
    1094          21 :     fd_stake_t      stake        = self.inner.fully_active.stake;
    1095          21 :     fd_stake_t      source_stake = source.inner.fully_active.stake;
    1096          21 :     rc                           = merge_delegation_stake_and_credits_observed(
    1097          21 :         invoke_context, &stake, source_stake.delegation.stake, source_stake.credits_observed );
    1098          21 :     if( FD_UNLIKELY( rc ) ) return rc;
    1099             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L1231
    1100          12 :     *merged_state = ( fd_stake_state_v2_t ){
    1101          12 :         .discriminant = fd_stake_state_v2_enum_stake,
    1102          12 :         .inner = { .stake = { .meta = meta, .stake = stake, .stake_flags = STAKE_FLAGS_EMPTY } } };
    1103          12 :   } else {
    1104           9 :     *custom_err = FD_STAKE_ERR_MERGE_MISMATCH;
    1105           9 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
    1106           9 :   }
    1107         171 :   if( !merged_state ) {
    1108         102 :     *is_some = 0;
    1109         102 :     return 0;
    1110         102 :   }
    1111          69 :   *is_some = 1;
    1112          69 :   *out     = *merged_state;
    1113          69 :   return 0;
    1114         171 : }
    1115             : 
    1116             : /**********************************************************************/
    1117             : /* mod stake_state                                                    */
    1118             : /**********************************************************************/
    1119             : 
    1120             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L72
    1121             : static int
    1122             : get_stake_status( fd_exec_instr_ctx_t const *    invoke_context,
    1123             :                   fd_stake_t *                   stake,
    1124             :                   fd_sol_sysvar_clock_t const *  clock,
    1125        1071 :                   fd_stake_activation_status_t * out ) {
    1126        1071 :   fd_stake_history_t const * stake_history = fd_sysvar_cache_stake_history( invoke_context->slot_ctx->sysvar_cache );
    1127        1071 :   if( FD_UNLIKELY( !stake_history ) )
    1128           6 :     return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
    1129        1065 :   ulong new_rate_activation_epoch = ULONG_MAX;
    1130        1065 :   int   err;
    1131        1065 :   int   is_some = fd_new_warmup_cooldown_rate_epoch( invoke_context->slot_ctx, &new_rate_activation_epoch, &err );
    1132        1065 :   if( FD_UNLIKELY( err ) ) return err;
    1133             : 
    1134        1065 :   *out =
    1135        1065 :       stake_activating_and_deactivating( &stake->delegation,
    1136        1065 :                                          clock->epoch,
    1137        1065 :                                          stake_history,
    1138        1065 :                                          fd_ptr_if( is_some, &new_rate_activation_epoch, NULL ) );
    1139        1065 :   return 0;
    1140        1065 : }
    1141             : 
    1142             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/vote/state/mod.rs#L740
    1143             : static ulong
    1144         333 : get_credits( fd_vote_state_t       const * vote_state ) {
    1145             : 
    1146         333 :     return ( deq_fd_vote_epoch_credits_t_empty( vote_state->epoch_credits )
    1147         333 :               ? 0
    1148         333 :               : deq_fd_vote_epoch_credits_t_peek_index(
    1149         102 :                     vote_state->epoch_credits,
    1150         102 :                     deq_fd_vote_epoch_credits_t_cnt( vote_state->epoch_credits ) - 1 )
    1151         102 :                     ->credits );
    1152         333 : }
    1153             : 
    1154             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L85
    1155             : static int
    1156             : redelegate_stake( fd_exec_instr_ctx_t const *   ctx,
    1157             :                   fd_stake_t *                  stake,
    1158             :                   ulong                         stake_lamports,
    1159             :                   fd_pubkey_t const *           voter_pubkey,
    1160             :                   fd_vote_state_t const *       vote_state,
    1161             :                   fd_sol_sysvar_clock_t const * clock,
    1162             :                   fd_stake_history_t const *    stake_history,
    1163         261 :                   uint *                        custom_err ) {
    1164         261 :   ulong new_rate_activation_epoch = ULONG_MAX;
    1165         261 :   int   err;
    1166         261 :   int   is_some = fd_new_warmup_cooldown_rate_epoch( ctx->slot_ctx, &new_rate_activation_epoch, &err );
    1167         261 :   if( FD_UNLIKELY( err ) ) return err;
    1168             : 
    1169             :   // FIXME FD_LIKELY
    1170             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L96
    1171         261 :   if( delegation_stake( &stake->delegation, clock->epoch, stake_history, fd_ptr_if( is_some, &new_rate_activation_epoch, NULL ) )!=0 ) {
    1172             : 
    1173         138 :     if( FD_LIKELY( !memcmp( &stake->delegation.voter_pubkey, voter_pubkey, sizeof( fd_pubkey_t ) ) ) &&
    1174         138 :          clock->epoch==stake->delegation.deactivation_epoch ) {
    1175          72 :       stake->delegation.deactivation_epoch = ULONG_MAX;
    1176          72 :       return 0;
    1177          72 :     } else {
    1178          66 :       *custom_err = FD_STAKE_ERR_TOO_SOON_TO_REDELEGATE;
    1179          66 :       return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
    1180          66 :     }
    1181         138 :   }
    1182             : 
    1183             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L114-L118
    1184         123 :   stake->delegation.stake              = stake_lamports;
    1185         123 :   stake->delegation.activation_epoch   = clock->epoch;
    1186         123 :   stake->delegation.deactivation_epoch = ULONG_MAX;
    1187         123 :   stake->delegation.voter_pubkey       = *voter_pubkey;
    1188         123 :   stake->credits_observed              = get_credits( vote_state );
    1189         123 :   return 0;
    1190         261 : }
    1191             : 
    1192             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L202
    1193             : static fd_stake_t
    1194             : new_stake( ulong                   stake,
    1195             :            fd_pubkey_t const *     voter_pubkey,
    1196             :            fd_vote_state_t const * vote_state,
    1197         210 :            ulong                   activation_epoch ) {
    1198             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L208
    1199         210 :   return ( fd_stake_t ){
    1200         210 :       .delegation       = {.voter_pubkey         = *voter_pubkey,
    1201         210 :                            .stake                = stake,
    1202         210 :                            .activation_epoch     = activation_epoch,
    1203         210 :                            .deactivation_epoch   = ULONG_MAX,
    1204         210 :                            .warmup_cooldown_rate = DEFAULT_WARMUP_COOLDOWN_RATE},
    1205         210 :       .credits_observed = get_credits( vote_state ),
    1206         210 :   };
    1207         210 : }
    1208             : 
    1209             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L214
    1210             : static int
    1211             : initialize( fd_exec_instr_ctx_t const *   ctx,
    1212             :             fd_borrowed_account_t const * stake_account,
    1213             :             ulong                         stake_acc_idx,
    1214             :             fd_stake_authorized_t const * authorized,
    1215             :             fd_stake_lockup_t const *     lockup,
    1216         453 :             fd_rent_t const *             rent ) {
    1217             : 
    1218             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L220
    1219             : 
    1220         453 :   if( FD_UNLIKELY( stake_account->const_meta->dlen!=stake_state_v2_size_of() ) )
    1221         117 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    1222             : 
    1223             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L224
    1224         336 :   fd_stake_state_v2_t stake_state = {0};
    1225         336 :   do {
    1226         336 :     int rc = get_state( stake_account, fd_spad_virtual( ctx->txn_ctx->spad ), &stake_state );
    1227         336 :     if( FD_UNLIKELY( rc ) ) return rc;
    1228         336 :   } while(0);
    1229             : 
    1230         330 :   if( FD_LIKELY( stake_state.discriminant==fd_stake_state_v2_enum_uninitialized ) ) {
    1231             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L225
    1232         300 :     ulong rent_exempt_reserve = fd_rent_exempt_minimum_balance( rent, stake_account->const_meta->dlen );
    1233             : 
    1234             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L226
    1235         300 :     if( FD_LIKELY( stake_account->const_meta->info.lamports>=rent_exempt_reserve ) ) {
    1236         246 :       fd_stake_state_v2_t initialized = {
    1237         246 :         .discriminant = fd_stake_state_v2_enum_initialized,
    1238         246 :         .inner = { .initialized = { .meta = { .rent_exempt_reserve = rent_exempt_reserve,
    1239         246 :                                               .authorized          = *authorized,
    1240         246 :                                               .lockup              = *lockup } } } };
    1241         246 :       return set_state( ctx, stake_acc_idx, &initialized );
    1242         246 :     } else {
    1243             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L233
    1244          54 :       return FD_EXECUTOR_INSTR_ERR_INSUFFICIENT_FUNDS;
    1245          54 :     }
    1246             : 
    1247         300 :   } else {
    1248             : 
    1249             :     /// https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L236
    1250          30 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    1251             : 
    1252          30 :   }
    1253         330 : }
    1254             : 
    1255             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L243
    1256             : static int
    1257             : authorize( fd_exec_instr_ctx_t const *   ctx,
    1258             :            fd_borrowed_account_t *       stake_account,
    1259             :            ulong                         stake_acc_idx,
    1260             :            fd_pubkey_t const *           signers[static FD_TXN_SIG_MAX],
    1261             :            fd_pubkey_t const *           new_authority,
    1262             :            fd_stake_authorize_t const *  stake_authorize,
    1263             :            fd_sol_sysvar_clock_t const * clock,
    1264             :            fd_pubkey_t const *           custodian,
    1265         921 :            uint *                        custom_err ) {
    1266         921 :   int                 rc;
    1267         921 :   fd_stake_state_v2_t stake_state = {0};
    1268             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L251
    1269         921 :   rc = get_state( stake_account, fd_spad_virtual( ctx->txn_ctx->spad ), &stake_state );
    1270         921 :   if( FD_UNLIKELY( rc ) ) return rc;
    1271         774 :   switch( stake_state.discriminant ) {
    1272             :   /* FIXME check if the compiler can optimize away branching (given the layout of `meta` in both
    1273             :    * union members) and instead fallthrough */
    1274         207 :   case fd_stake_state_v2_enum_stake: {
    1275             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L252
    1276         207 :     fd_stake_meta_t * meta = &stake_state.inner.stake.meta;
    1277             : 
    1278         207 :     fd_stake_lockup_custodian_args_t lockup_custodian_args = {
    1279         207 :         .lockup = meta->lockup, .clock = *clock, .custodian = (fd_pubkey_t *)custodian };
    1280         207 :     rc = authorized_authorize(
    1281         207 :         &meta->authorized, /* &mut self */
    1282         207 :         signers,
    1283         207 :         new_authority,
    1284         207 :         stake_authorize,
    1285         207 :         &lockup_custodian_args,
    1286         207 :         custom_err );
    1287         207 :     if( FD_UNLIKELY( rc ) ) return rc;
    1288             : 
    1289          51 :     return set_state( ctx, stake_acc_idx, &stake_state );
    1290         207 :   }
    1291         540 :   case fd_stake_state_v2_enum_initialized: {
    1292             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L261
    1293         540 :     fd_stake_meta_t * meta = &stake_state.inner.initialized.meta;
    1294             : 
    1295         540 :     fd_stake_lockup_custodian_args_t lockup_custodian_args = {
    1296         540 :         .lockup = meta->lockup, .clock = *clock, .custodian = (fd_pubkey_t *)custodian };
    1297         540 :     rc = authorized_authorize(
    1298         540 :         &meta->authorized,
    1299         540 :         signers,
    1300         540 :         new_authority,
    1301         540 :         stake_authorize,
    1302         540 :         &lockup_custodian_args,
    1303         540 :         custom_err );
    1304         540 :     if( FD_UNLIKELY( rc ) ) return rc;
    1305             : 
    1306         273 :     return set_state( ctx, stake_acc_idx, &stake_state );
    1307         540 :   }
    1308          27 :   default:
    1309             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L270
    1310          27 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    1311         774 :   }
    1312           0 :   return rc;
    1313         774 : }
    1314             : 
    1315             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L275
    1316             : static int
    1317             : authorize_with_seed( fd_exec_instr_ctx_t const *   ctx,
    1318             :                      fd_borrowed_account_t *       stake_account,
    1319             :                      ulong                         stake_acc_idx,
    1320             :                      uchar                         authority_base_index,
    1321             :                      char const *                  authority_seed,
    1322             :                      ulong                         authority_seed_len,
    1323             :                      fd_pubkey_t const *           authority_owner,
    1324             :                      fd_pubkey_t const *           new_authority,
    1325             :                      fd_stake_authorize_t const *  stake_authorize,
    1326             :                      fd_sol_sysvar_clock_t const * clock,
    1327         429 :                      fd_pubkey_t const *           custodian ) {
    1328         429 :   int                 rc;
    1329         429 :   fd_pubkey_t const * signers[FD_TXN_SIG_MAX] = {0};
    1330         429 :   fd_pubkey_t         out                     = {0};
    1331         429 :   if( FD_LIKELY( fd_instr_acc_is_signer_idx( ctx->instr, authority_base_index ) ) ) {
    1332             : 
    1333             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L289
    1334         363 :     fd_pubkey_t const * base_pubkey = &ctx->instr->acct_pubkeys[authority_base_index];
    1335             : 
    1336             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L293
    1337         363 :     rc = fd_pubkey_create_with_seed( ctx,
    1338         363 :                                      base_pubkey->uc,
    1339         363 :                                      authority_seed,
    1340         363 :                                      authority_seed_len,
    1341         363 :                                      authority_owner->uc,
    1342         363 :                                      /* out */ out.uc );
    1343         363 :     if( FD_UNLIKELY( rc ) ) return rc;
    1344         216 :     signers[0] = &out;
    1345         216 :   }
    1346             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L299
    1347         282 :   return authorize( ctx,
    1348         282 :                     stake_account,
    1349         282 :                     stake_acc_idx,
    1350         282 :                     signers,
    1351         282 :                     new_authority,
    1352         282 :                     stake_authorize,
    1353         282 :                     clock,
    1354         282 :                     custodian,
    1355         282 :                     &ctx->txn_ctx->custom_err );
    1356         429 : }
    1357             : 
    1358             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L310
    1359             : static int
    1360             : delegate( fd_exec_instr_ctx_t const *   ctx,
    1361             :           uchar                         stake_account_index,
    1362             :           uchar                         vote_account_index,
    1363             :           fd_sol_sysvar_clock_t const * clock,
    1364             :           fd_stake_history_t const *    stake_history,
    1365        1272 :           fd_pubkey_t const *           signers[static FD_TXN_SIG_MAX] ) {
    1366        1272 :   int rc;
    1367             : 
    1368        1272 :   fd_valloc_t valloc = fd_spad_virtual( ctx->txn_ctx->spad );
    1369             : 
    1370        1272 :   fd_pubkey_t const * vote_pubkey;
    1371        1272 :   fd_vote_state_versioned_t vote_state = {0};
    1372        1272 :   int vote_get_state_rc;
    1373             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L321
    1374        5088 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, vote_account_index, vote_account ) {
    1375             : 
    1376             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L323
    1377        1272 :   if( FD_UNLIKELY( memcmp( &vote_account->const_meta->info.owner, fd_solana_vote_program_id.key, 32UL ) ) )
    1378          39 :     return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID;
    1379             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L3326
    1380        1233 :   vote_pubkey = vote_account->pubkey;
    1381             :   // https://github.com/anza-xyz/agave/blob/a60fbc2288d626a4f1846052c8fcb98d3f9ea58d/programs/stake/src/stake_state.rs#L327
    1382        1233 :   vote_get_state_rc = fd_vote_get_state( vote_account, valloc, &vote_state );
    1383             : 
    1384        1272 :   } FD_BORROWED_ACCOUNT_DROP( vote_account );
    1385             : 
    1386        1233 :   fd_stake_state_v2_t stake_state = {0};
    1387             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L330
    1388        4932 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, stake_account_index, stake_account ) {
    1389             :   
    1390        1233 :   rc = get_state( stake_account, fd_spad_virtual( ctx->txn_ctx->spad ), &stake_state );
    1391        1233 :   if( FD_UNLIKELY( rc ) ) return rc;
    1392             : 
    1393             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L332
    1394        1083 :   switch( stake_state.discriminant ) {
    1395         519 :   case fd_stake_state_v2_enum_initialized: {
    1396         519 :     fd_stake_meta_t meta = stake_state.inner.initialized.meta;
    1397             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L334
    1398         519 :     rc = authorized_check( &meta.authorized, signers, STAKE_AUTHORIZE_STAKER );
    1399         519 :     if( FD_UNLIKELY( rc ) ) return rc;
    1400             : 
    1401             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L335-L336
    1402         264 :     validated_delegated_info_t validated_delegated_info;
    1403         264 :     rc = validate_delegated_amount( stake_account,
    1404         264 :                                     &meta,
    1405         264 :                                     ctx->slot_ctx,
    1406         264 :                                     &validated_delegated_info,
    1407         264 :                                     &ctx->txn_ctx->custom_err );
    1408         264 :     if( FD_UNLIKELY( rc ) ) return rc;
    1409         213 :     ulong stake_amount = validated_delegated_info.stake_amount;
    1410             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L340
    1411         213 :     if( FD_UNLIKELY( vote_get_state_rc ) ) return vote_get_state_rc;
    1412         210 :     fd_vote_convert_to_current( &vote_state, valloc ); // FIXME
    1413         210 :     fd_stake_t stake =
    1414         210 :         new_stake( stake_amount, vote_pubkey, &vote_state.inner.current, clock->epoch );
    1415             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L343
    1416         210 :     fd_stake_state_v2_t new_stake_state = { .discriminant = fd_stake_state_v2_enum_stake,
    1417         210 :                                             .inner        = { .stake = {
    1418         210 :                                                                   .meta        = meta,
    1419         210 :                                                                   .stake       = stake,
    1420         210 :                                                                   .stake_flags = STAKE_FLAGS_EMPTY } } };
    1421         210 :     return set_state( ctx, stake_account_index, &new_stake_state );
    1422         213 :   }
    1423         540 :   case fd_stake_state_v2_enum_stake: {
    1424         540 :     fd_stake_meta_t  meta        = stake_state.inner.stake.meta;
    1425         540 :     fd_stake_t       stake       = stake_state.inner.stake.stake;
    1426         540 :     fd_stake_flags_t stake_flags = stake_state.inner.stake.stake_flags;
    1427             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L346
    1428         540 :     rc = authorized_check( &meta.authorized, signers, STAKE_AUTHORIZE_STAKER );
    1429         540 :     if( FD_UNLIKELY( rc ) ) return rc;
    1430             : 
    1431             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L347-L348
    1432         366 :     validated_delegated_info_t validated_delegated_info;
    1433         366 :     rc = validate_delegated_amount( stake_account,
    1434         366 :                                     &meta,
    1435         366 :                                     ctx->slot_ctx,
    1436         366 :                                     &validated_delegated_info,
    1437         366 :                                     &ctx->txn_ctx->custom_err );
    1438         366 :     if( FD_UNLIKELY( rc ) ) return rc;
    1439         267 :     ulong stake_amount = validated_delegated_info.stake_amount;
    1440             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L354
    1441         267 :     if( FD_UNLIKELY( vote_get_state_rc ) ) return vote_get_state_rc;
    1442         261 :     fd_vote_convert_to_current( &vote_state, valloc );
    1443             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L349
    1444         261 :     rc = redelegate_stake( ctx,
    1445         261 :                            &stake,
    1446         261 :                            stake_amount,
    1447         261 :                            vote_pubkey,
    1448         261 :                            &vote_state.inner.current,
    1449         261 :                            clock,
    1450         261 :                            stake_history,
    1451         261 :                            &ctx->txn_ctx->custom_err );
    1452         261 :     if( FD_UNLIKELY( rc ) ) return rc;
    1453             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L358
    1454         195 :     fd_stake_state_v2_t new_stake_state = { .discriminant = fd_stake_state_v2_enum_stake,
    1455         195 :                                             .inner        = { .stake = {
    1456         195 :                                                                   .meta        = meta,
    1457         195 :                                                                   .stake       = stake,
    1458         195 :                                                                   .stake_flags = stake_flags } } };
    1459             : 
    1460         195 :     return set_state( ctx, stake_account_index, &new_stake_state );
    1461         261 :   }
    1462          24 :   default:
    1463             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L360
    1464          24 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    1465        1083 :   }
    1466        1233 :   } FD_BORROWED_ACCOUNT_DROP( stake_account );
    1467        1233 : }
    1468             : 
    1469             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L364
    1470             : static int
    1471             : deactivate( fd_exec_instr_ctx_t const *   ctx,
    1472             :             fd_borrowed_account_t *       stake_account,
    1473             :             ulong                         stake_acc_idx,
    1474             :             fd_sol_sysvar_clock_t const * clock,
    1475             :             fd_pubkey_t const *           signers[static FD_TXN_SIG_MAX],
    1476         363 :             uint *                        custom_err ) {
    1477         363 :   int rc;
    1478             : 
    1479         363 :   fd_stake_state_v2_t state = {0};
    1480         363 :   rc                        = get_state( stake_account, fd_spad_virtual( ctx->txn_ctx->spad ), &state );
    1481         363 :   if( FD_UNLIKELY( rc ) ) return rc;
    1482             : 
    1483             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L370
    1484         279 :   if( state.discriminant==fd_stake_state_v2_enum_stake ) {
    1485         210 :     fd_stake_meta_t * meta  = &state.inner.stake.meta;
    1486         210 :     fd_stake_t *      stake = &state.inner.stake.stake;
    1487             : 
    1488             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L371
    1489         210 :     rc = authorized_check( &meta->authorized, signers, STAKE_AUTHORIZE_STAKER );
    1490         210 :     if( FD_UNLIKELY( rc ) ) return rc;
    1491             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L372
    1492         168 :     rc = stake_deactivate( stake, clock->epoch, custom_err );
    1493         168 :     if( FD_UNLIKELY( rc ) ) return rc;
    1494             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L373
    1495         141 :     return set_state( ctx, stake_acc_idx, &state );
    1496         168 :   } else {
    1497             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L375
    1498          69 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    1499          69 :   }
    1500         279 : }
    1501             : 
    1502             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L379
    1503             : static int
    1504             : set_lockup( fd_exec_instr_ctx_t const *   ctx,
    1505             :             fd_borrowed_account_t *       stake_account,
    1506             :             ulong                         stake_acc_idx,
    1507             :             fd_lockup_args_t const *      lockup,
    1508             :             fd_pubkey_t const *           signers[static FD_TXN_SIG_MAX],
    1509         723 :             fd_sol_sysvar_clock_t const * clock ) {
    1510         723 :   int rc;
    1511             : 
    1512             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L385
    1513         723 :   fd_stake_state_v2_t state = {0};
    1514         723 :   rc = get_state( stake_account, fd_spad_virtual( ctx->txn_ctx->spad ), &state );
    1515         723 :   if( FD_UNLIKELY( rc ) ) return rc;
    1516             : 
    1517         558 :   switch( state.discriminant ) {
    1518             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L386
    1519         222 :   case fd_stake_state_v2_enum_initialized: {
    1520         222 :     fd_stake_meta_t * meta = &state.inner.initialized.meta;
    1521         222 :     rc                     = set_lockup_meta( meta, lockup, signers, clock );
    1522         222 :     if( FD_UNLIKELY( rc ) ) return rc;
    1523          48 :     return set_state( ctx, stake_acc_idx, &state );
    1524         222 :   }
    1525             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L390
    1526         303 :   case fd_stake_state_v2_enum_stake: {
    1527         303 :     fd_stake_meta_t * meta = &state.inner.stake.meta;
    1528         303 :     rc                     = set_lockup_meta( meta, lockup, signers, clock );
    1529         303 :     if( FD_UNLIKELY( rc ) ) return rc;
    1530          69 :     return set_state( ctx, stake_acc_idx, &state );
    1531         303 :   }
    1532          33 :   default:
    1533             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L394
    1534          33 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    1535         558 :   }
    1536         558 : }
    1537             : 
    1538             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L398
    1539             : static int
    1540             : split( fd_exec_instr_ctx_t const * ctx,
    1541             :        uchar                       stake_account_index,
    1542             :        ulong                       lamports,
    1543             :        uchar                       split_index,
    1544        2778 :        fd_pubkey_t const *         signers[static FD_TXN_SIG_MAX] ) {
    1545        2778 :   int rc;
    1546             : 
    1547        2778 :   ulong split_lamport_balance = 0;
    1548             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L407
    1549       11112 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, split_index, split ) {
    1550             : 
    1551             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L409
    1552        2778 :   if( FD_UNLIKELY( memcmp( &split->const_meta->info.owner, fd_solana_stake_program_id.key, 32UL ) ) )
    1553          81 :     return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID;
    1554             : 
    1555             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L412
    1556        2697 :   if( FD_UNLIKELY( split->const_meta->dlen!=stake_state_v2_size_of() ) )
    1557         336 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    1558             : 
    1559             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L415
    1560        2361 :   fd_stake_state_v2_t split_get_state = {0};
    1561        2361 :   rc = get_state( split, fd_spad_virtual( ctx->txn_ctx->spad ), &split_get_state );
    1562        2361 :   if( FD_UNLIKELY( rc ) ) return rc;
    1563        2358 :   if( FD_UNLIKELY( split_get_state.discriminant!=fd_stake_state_v2_enum_uninitialized ) ) {
    1564          75 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    1565          75 :   }
    1566             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L418
    1567        2283 :   split_lamport_balance = split->const_meta->info.lamports;
    1568             : 
    1569        2778 :   } FD_BORROWED_ACCOUNT_DROP( split );
    1570             : 
    1571        2283 :   fd_stake_state_v2_t stake_state = {0};
    1572             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L420
    1573        9132 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, stake_account_index, stake_account) {
    1574             : 
    1575             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L422
    1576        2283 :   if( FD_UNLIKELY( lamports>stake_account->const_meta->info.lamports ) )
    1577         348 :     return FD_EXECUTOR_INSTR_ERR_INSUFFICIENT_FUNDS;
    1578             :     
    1579        1935 :   rc = get_state( stake_account, fd_spad_virtual( ctx->txn_ctx->spad ), &stake_state );
    1580        1935 :   if( FD_UNLIKELY( rc ) ) return rc;
    1581             : 
    1582        2283 :   } FD_BORROWED_ACCOUNT_DROP( stake_account );
    1583             : 
    1584             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L428
    1585        1893 :   switch( stake_state.discriminant ) {
    1586        1128 :   case fd_stake_state_v2_enum_stake: {
    1587        1128 :     fd_stake_meta_t *  meta        = &stake_state.inner.stake.meta;
    1588        1128 :     fd_stake_t *       stake       = &stake_state.inner.stake.stake;
    1589        1128 :     fd_stake_flags_t * stake_flags = &stake_state.inner.stake.stake_flags;
    1590             : 
    1591             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L430
    1592        1128 :     rc = authorized_check( &meta->authorized, signers, STAKE_AUTHORIZE_STAKER );
    1593        1128 :     if( FD_UNLIKELY( rc ) ) return rc;
    1594             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L431
    1595        1071 :     ulong minimum_delegation = get_minimum_delegation( ctx->slot_ctx );
    1596             : 
    1597        1071 :     int   is_active;
    1598        1071 :     if( FD_UNLIKELY( FD_FEATURE_ACTIVE( ctx->slot_ctx,
    1599        1071 :                                          require_rent_exempt_split_destination ) ) ) {
    1600             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L434
    1601        1071 :       fd_sol_sysvar_clock_t const * clock = fd_sysvar_cache_clock( ctx->slot_ctx->sysvar_cache );
    1602        1071 :       if( FD_UNLIKELY( !clock ) )
    1603           0 :         return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
    1604             : 
    1605             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L435
    1606        1071 :       fd_stake_activation_status_t status = {0};
    1607        1071 :       rc = get_stake_status( ctx, stake, clock, &status );
    1608        1071 :       if( FD_UNLIKELY( rc ) ) return rc;
    1609             : 
    1610        1065 :       is_active = status.effective>0;
    1611        1065 :     } else {
    1612           0 :       is_active = 0;
    1613           0 :     }
    1614             : 
    1615             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L438
    1616        1065 :     validated_split_info_t validated_split_info = {0};
    1617        1065 :     rc = validate_split_amount( ctx,
    1618        1065 :                                 stake_account_index,
    1619        1065 :                                 split_index,
    1620        1065 :                                 lamports,
    1621        1065 :                                 meta,
    1622        1065 :                                 minimum_delegation,
    1623        1065 :                                 is_active,
    1624        1065 :                                 &validated_split_info );
    1625        1065 :     if( FD_UNLIKELY( rc ) ) return rc;
    1626             : 
    1627         606 :     ulong remaining_stake_delta;
    1628         606 :     ulong split_stake_amount;
    1629             :     // FIXME FD_LIKELY
    1630             : 
    1631         606 :     if( validated_split_info.source_remaining_balance==0 ) {
    1632             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L456
    1633         249 :       remaining_stake_delta = fd_ulong_sat_sub( lamports, meta->rent_exempt_reserve );
    1634         249 :       split_stake_amount    = remaining_stake_delta;
    1635         357 :     } else {
    1636             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L469
    1637         357 :       if( FD_UNLIKELY( fd_ulong_sat_sub( stake->delegation.stake, lamports ) <
    1638         357 :                         minimum_delegation ) ) {
    1639          36 :         ctx->txn_ctx->custom_err = FD_STAKE_ERR_INSUFFICIENT_DELEGATION;
    1640          36 :         return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
    1641          36 :       }
    1642             : 
    1643         321 :       remaining_stake_delta = lamports;
    1644         321 :       split_stake_amount =
    1645         321 :           fd_ulong_sat_sub( lamports,
    1646         321 :                             fd_ulong_sat_sub( validated_split_info.destination_rent_exempt_reserve,
    1647         321 :                                               split_lamport_balance )
    1648             : 
    1649         321 :           );
    1650         321 :     }
    1651             : 
    1652             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L487
    1653         570 :     if( FD_UNLIKELY( split_stake_amount<minimum_delegation ) ) {
    1654          27 :       ctx->txn_ctx->custom_err = FD_STAKE_ERR_INSUFFICIENT_DELEGATION;
    1655          27 :       return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
    1656          27 :     }
    1657             : 
    1658             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L491-L493
    1659         543 :     fd_stake_t split_stake = {0};
    1660         543 :     rc = stake_split( stake,
    1661         543 :                       remaining_stake_delta,
    1662         543 :                       split_stake_amount,
    1663         543 :                       &ctx->txn_ctx->custom_err,
    1664         543 :                       &split_stake );
    1665         543 :     if( FD_UNLIKELY( rc ) ) return rc;
    1666         543 :     fd_stake_meta_t split_meta     = *meta;
    1667         543 :     split_meta.rent_exempt_reserve = validated_split_info.destination_rent_exempt_reserve;
    1668             : 
    1669             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L495
    1670        2172 :     FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, stake_account_index, stake_account ) {
    1671             : 
    1672             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L497
    1673         543 :     rc = set_state( ctx, stake_account_index, &stake_state );
    1674         543 :     if( FD_UNLIKELY( rc ) ) return rc;
    1675             : 
    1676         543 :     } FD_BORROWED_ACCOUNT_DROP( stake_account );
    1677             : 
    1678             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L499
    1679        2124 :     FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, split_index, split ) {
    1680             : 
    1681             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L501
    1682         531 :     fd_stake_state_v2_t temp = { .discriminant = fd_stake_state_v2_enum_stake,
    1683         531 :                                  .inner        = { .stake = { .meta        = split_meta,
    1684         531 :                                                               .stake       = split_stake,
    1685         531 :                                                               .stake_flags = *stake_flags } } };
    1686         531 :     rc = set_state( ctx, split_index, &temp );
    1687         531 :     if( FD_UNLIKELY( rc ) ) return rc;
    1688             : 
    1689         531 :     } FD_BORROWED_ACCOUNT_DROP( split );
    1690         522 :     break;
    1691         531 :   }
    1692         540 :   case fd_stake_state_v2_enum_initialized: {
    1693             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L504
    1694         540 :     fd_stake_meta_t * meta = &stake_state.inner.initialized.meta;
    1695         540 :     rc                     = authorized_check( &meta->authorized, signers, STAKE_AUTHORIZE_STAKER );
    1696         540 :     if( FD_UNLIKELY( rc ) ) return rc;
    1697             : 
    1698             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L505
    1699         465 :     validated_split_info_t validated_split_info = {0};
    1700         465 :     rc = validate_split_amount( ctx,
    1701         465 :                                 stake_account_index,
    1702         465 :                                 split_index,
    1703         465 :                                 lamports,
    1704         465 :                                 meta,
    1705         465 :                                 0,
    1706         465 :                                 0,
    1707         465 :                                 &validated_split_info );
    1708         465 :     if( FD_UNLIKELY( rc ) ) return rc;
    1709             : 
    1710             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L516
    1711         318 :     fd_stake_meta_t split_meta     = *meta;
    1712         318 :     split_meta.rent_exempt_reserve = validated_split_info.destination_rent_exempt_reserve;
    1713             : 
    1714             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L518
    1715        1272 :     FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, split_index, split ) {
    1716             : 
    1717             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L520
    1718         318 :     fd_stake_state_v2_t temp = { .discriminant = fd_stake_state_v2_enum_initialized,
    1719         318 :                                  .inner        = { .initialized = { .meta = split_meta } } };
    1720         318 :     rc = set_state( ctx, split_index, &temp );
    1721         318 :     if( FD_UNLIKELY( rc ) ) return rc;
    1722             : 
    1723         318 :     } FD_BORROWED_ACCOUNT_DROP( split );
    1724         315 :     break;
    1725         318 :   }
    1726         315 :   case fd_stake_state_v2_enum_uninitialized: {
    1727             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L523
    1728         222 :     fd_pubkey_t const * stake_pubkey = &ctx->instr->acct_pubkeys[stake_account_index];
    1729         222 :     if( FD_UNLIKELY( !fd_instr_signers_contains( signers, stake_pubkey ) ) ) {
    1730             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L527
    1731          69 :       return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
    1732          69 :     }
    1733         153 :     break;
    1734         222 :   }
    1735         153 :   default:
    1736             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L531
    1737           3 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    1738        1893 :   }
    1739             : 
    1740             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L535
    1741        3960 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, stake_account_index, stake_account ) {
    1742             : 
    1743             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L537
    1744         990 :   if( FD_UNLIKELY( lamports==stake_account->const_meta->info.lamports ) ) {
    1745         411 :     fd_stake_state_v2_t uninitialized = {0};
    1746         411 :     uninitialized.discriminant        = fd_stake_state_v2_enum_uninitialized;
    1747         411 :     rc                                = set_state( ctx, stake_account_index, &uninitialized );
    1748         411 :     if( FD_UNLIKELY( rc ) ) return rc;
    1749         987 :   };
    1750             : 
    1751         990 :   } FD_BORROWED_ACCOUNT_DROP( stake_account );
    1752             : 
    1753             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L542
    1754        3948 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, split_index, split ) {
    1755             : 
    1756             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L544
    1757         987 :   rc = fd_account_checked_add_lamports( ctx, split_index, lamports );
    1758         987 :   if( FD_UNLIKELY( rc ) ) return rc;
    1759             : 
    1760             : 
    1761         987 :   } FD_BORROWED_ACCOUNT_DROP( split );
    1762             : 
    1763             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L546
    1764        3804 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, stake_account_index, stake_account ) {
    1765             : 
    1766             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L548
    1767         951 :   rc = fd_account_checked_sub_lamports( ctx, stake_account_index, lamports );
    1768         951 :   if( FD_UNLIKELY( rc ) ) return rc;
    1769             : 
    1770         951 :   } FD_BORROWED_ACCOUNT_DROP( stake_account );
    1771         939 :   return 0;
    1772         951 : }
    1773             : 
    1774             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L552
    1775             : static int
    1776             : merge( fd_exec_instr_ctx_t *         ctx, // not const to log
    1777             :        uchar                         stake_account_index,
    1778             :        uchar                         source_account_index,
    1779             :        fd_sol_sysvar_clock_t const * clock,
    1780             :        fd_stake_history_t const *    stake_history,
    1781        1632 :        fd_pubkey_t const *           signers[static FD_TXN_SIG_MAX] ) {
    1782        1632 :   int rc;
    1783             : 
    1784             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L562
    1785        6528 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, source_account_index, source_account  ) {
    1786             : 
    1787             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L565
    1788        1632 :   if( FD_UNLIKELY( memcmp( &source_account->const_meta->info.owner, fd_solana_stake_program_id.key, 32UL ) ) )
    1789          42 :     return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID;
    1790             : 
    1791             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L569
    1792        1590 :   if( FD_UNLIKELY( !memcmp( &ctx->instr->acct_pubkeys[stake_account_index], &ctx->instr->acct_pubkeys[source_account_index], sizeof(fd_pubkey_t) ) ) )
    1793          24 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
    1794             : 
    1795             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L575
    1796        6264 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, stake_account_index, stake_account  ) {
    1797             : 
    1798        1566 :   fd_stake_state_v2_t stake_account_state = {0};
    1799        1566 :   rc = get_state( stake_account, fd_spad_virtual( ctx->txn_ctx->spad ), &stake_account_state );
    1800        1566 :   if( FD_UNLIKELY( rc ) ) return rc;
    1801             : 
    1802        1476 :   merge_kind_t stake_merge_kind = {0};
    1803        1476 :   fd_log_collector_msg_literal( ctx, "Checking if destination stake is mergeable" );
    1804             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L579
    1805        1476 :   rc = get_if_mergeable( ctx,
    1806        1476 :                          &stake_account_state,
    1807        1476 :                          stake_account->const_meta->info.lamports,
    1808        1476 :                          clock,
    1809        1476 :                          stake_history,
    1810        1476 :                          &stake_merge_kind,
    1811        1476 :                          &ctx->txn_ctx->custom_err );
    1812        1476 :   if( FD_UNLIKELY( rc ) )
    1813         579 :     return rc;
    1814             : 
    1815             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L588
    1816         897 :   rc = authorized_check( &meta( &stake_merge_kind )->authorized, signers, STAKE_AUTHORIZE_STAKER );
    1817         897 :   if( FD_UNLIKELY( rc ) )
    1818         327 :     return rc;
    1819             : 
    1820         570 :   fd_stake_state_v2_t source_account_state = {0};
    1821         570 :   rc = get_state( source_account, fd_spad_virtual( ctx->txn_ctx->spad ), &source_account_state );
    1822         570 :   if( FD_UNLIKELY( rc ) ) return rc;
    1823             : 
    1824         540 :   merge_kind_t source_merge_kind = {0};
    1825         540 :   fd_log_collector_msg_literal( ctx, "Checking if source stake is mergeable" );
    1826             :   //https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L594
    1827         540 :   rc = get_if_mergeable( ctx,
    1828         540 :                          &source_account_state,
    1829         540 :                          source_account->const_meta->info.lamports,
    1830         540 :                          clock,
    1831         540 :                          stake_history,
    1832         540 :                          &source_merge_kind,
    1833         540 :                          &ctx->txn_ctx->custom_err );
    1834         540 :   if( FD_UNLIKELY( rc ) ) return rc;
    1835             : 
    1836         423 :   fd_stake_state_v2_t merged_state = {0};
    1837         423 :   int                 is_some      = 0;
    1838         423 :   fd_log_collector_msg_literal( ctx, "Merging stake accounts" );
    1839             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L603
    1840         423 :   rc = merge_kind_merge( stake_merge_kind,
    1841         423 :                          ctx,
    1842         423 :                          source_merge_kind,
    1843         423 :                          clock,
    1844         423 :                          &merged_state,
    1845         423 :                          &is_some,
    1846         423 :                          &ctx->txn_ctx->custom_err );
    1847         423 :   if( FD_UNLIKELY( rc ) ) return rc;
    1848         171 :   if( is_some ) {
    1849             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L608
    1850          69 :     rc = set_state( ctx, stake_account_index, &merged_state );
    1851          69 :     if( FD_UNLIKELY( rc ) ) return rc;
    1852          69 :   }
    1853             : 
    1854             :   //  https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L608
    1855         168 :   fd_stake_state_v2_t uninitialized = {0};
    1856         168 :   uninitialized.discriminant        = fd_stake_state_v2_enum_uninitialized;
    1857         168 :   rc                                = set_state( ctx, source_account_index, &uninitialized );
    1858         168 :   if( FD_UNLIKELY( rc ) ) return rc;
    1859             : 
    1860             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L611-L613
    1861         141 :   ulong lamports = source_account->const_meta->info.lamports;
    1862         141 :   rc = fd_account_checked_sub_lamports( ctx, source_account_index, lamports );
    1863         141 :   if( FD_UNLIKELY( rc ) ) return rc;
    1864         141 :   rc = fd_account_checked_add_lamports( ctx, stake_account_index, lamports );
    1865         141 :   if( FD_UNLIKELY( rc ) ) return rc;
    1866             : 
    1867        1566 :   } FD_BORROWED_ACCOUNT_DROP( stake_account );
    1868        1632 :   } FD_BORROWED_ACCOUNT_DROP( source_account );
    1869             : 
    1870         135 :   return 0;
    1871        1632 : }
    1872             : 
    1873             : // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L136
    1874             : static int
    1875             : move_stake_or_lamports_shared_checks( fd_exec_instr_ctx_t *   invoke_context, // not const to log
    1876             :                                       fd_borrowed_account_t * source_account,
    1877             :                                       ulong                   lamports,
    1878             :                                       fd_borrowed_account_t * destination_account,
    1879             :                                       ulong                   stake_authority_index,
    1880             :                                       merge_kind_t *          source_merge_kind,
    1881             :                                       merge_kind_t *          destination_merge_kind,
    1882         768 :                                       uint *                  custom_err ) {
    1883         768 :     int rc;
    1884             : 
    1885             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L145-L153
    1886         768 :     if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( invoke_context->instr, stake_authority_index ) ) ) {
    1887         300 :       return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
    1888         300 :     }
    1889             : 
    1890         468 :     fd_pubkey_t const * stake_authority_pubkey = &invoke_context->instr->acct_pubkeys[stake_authority_index];
    1891         468 :     fd_pubkey_t const * signers[FD_TXN_SIG_MAX] = { stake_authority_pubkey };
    1892             : 
    1893             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L158
    1894         468 :     if( FD_UNLIKELY( memcmp( &source_account->const_meta->info.owner, fd_solana_stake_program_id.key, sizeof(fd_pubkey_t) ) ||
    1895         468 :                      memcmp( &destination_account->const_meta->info.owner, fd_solana_stake_program_id.key, sizeof(fd_pubkey_t) ) ) )
    1896           9 :       return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID;
    1897             : 
    1898             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L163
    1899         459 :     if( FD_UNLIKELY( !memcmp( &source_account->pubkey, &destination_account->pubkey, sizeof(fd_pubkey_t) ) ) )
    1900           0 :       return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
    1901             : 
    1902             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L168
    1903         459 :     if( FD_UNLIKELY( !fd_instr_acc_is_writable( invoke_context->instr, source_account->pubkey ) ||
    1904         459 :                      !fd_instr_acc_is_writable( invoke_context->instr, destination_account->pubkey ) ) )
    1905         174 :         return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
    1906             : 
    1907             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L173
    1908         285 :     if( lamports==0 )
    1909           3 :       return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
    1910             : 
    1911             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L177-L180
    1912         282 :     fd_sol_sysvar_clock_t const * clock = fd_sysvar_cache_clock( invoke_context->slot_ctx->sysvar_cache );
    1913         282 :     if( FD_UNLIKELY( !clock ) )
    1914           0 :       return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
    1915             : 
    1916         282 :     fd_stake_history_t const * stake_history = fd_sysvar_cache_stake_history( invoke_context->slot_ctx->sysvar_cache );
    1917         282 :     if( FD_UNLIKELY( !stake_history ) )
    1918           3 :       return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
    1919             : 
    1920             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L182
    1921         279 :     fd_stake_state_v2_t source_account_state = {0};
    1922         279 :     rc = get_state( source_account, fd_spad_virtual( invoke_context->txn_ctx->spad ), &source_account_state );
    1923         279 :     if( FD_UNLIKELY( rc ) ) return rc;
    1924             : 
    1925         267 :     rc = get_if_mergeable( invoke_context,
    1926         267 :                          &source_account_state,
    1927         267 :                          source_account->const_meta->info.lamports,
    1928         267 :                          clock,
    1929         267 :                          stake_history,
    1930         267 :                          source_merge_kind,
    1931         267 :                          &invoke_context->txn_ctx->custom_err );
    1932         267 :     if( FD_UNLIKELY( rc ) ) return rc;
    1933             : 
    1934             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L191
    1935         264 :     rc = authorized_check( &meta( source_merge_kind )->authorized, signers, STAKE_AUTHORIZE_STAKER );
    1936         264 :     if( FD_UNLIKELY( rc ) ) return rc;
    1937             : 
    1938             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L197
    1939         261 :     fd_stake_state_v2_t destination_account_state = {0};
    1940         261 :     rc = get_state( destination_account, fd_spad_virtual( invoke_context->txn_ctx->spad ), &destination_account_state );
    1941         261 :     if( FD_UNLIKELY( rc ) ) return rc;
    1942             : 
    1943         246 :     rc = get_if_mergeable( invoke_context,
    1944         246 :                          &destination_account_state,
    1945         246 :                          destination_account->const_meta->info.lamports,
    1946         246 :                          clock,
    1947         246 :                          stake_history,
    1948         246 :                          destination_merge_kind,
    1949         246 :                          &invoke_context->txn_ctx->custom_err );
    1950         246 :     if( FD_UNLIKELY( rc ) ) return rc;
    1951             : 
    1952             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L206
    1953         234 :     rc = metas_can_merge( invoke_context, meta( source_merge_kind ), meta( destination_merge_kind ), clock, custom_err );
    1954         234 :     if( FD_UNLIKELY( rc ) ) return rc;
    1955             : 
    1956         171 :   return 0;
    1957         234 : }
    1958             : 
    1959             : // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L789
    1960             : static int
    1961             : move_stake(fd_exec_instr_ctx_t * ctx, // not const to log
    1962             :            ulong                 source_account_index,
    1963             :            ulong                 lamports,
    1964             :            ulong                 destination_account_index,
    1965             :            ulong                 stake_authority_index,
    1966         477 :            uint *                custom_err ) {
    1967         477 :   int rc;
    1968             : 
    1969             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L798-L804
    1970        1908 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, source_account_index, source_account ) {
    1971        1908 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, destination_account_index, destination_account ) {
    1972             : 
    1973             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L804
    1974         477 :   merge_kind_t source_merge_kind = {0};
    1975         477 :   merge_kind_t destination_merge_kind = {0};
    1976         477 :   rc = move_stake_or_lamports_shared_checks( ctx,
    1977         477 :                                              source_account,
    1978         477 :                                              lamports,
    1979         477 :                                              destination_account,
    1980         477 :                                              stake_authority_index,
    1981         477 :                                              &source_merge_kind,
    1982         477 :                                              &destination_merge_kind,
    1983         477 :                                              &ctx->txn_ctx->custom_err );
    1984         477 :   if( FD_UNLIKELY( rc ) ) return rc;
    1985             : 
    1986             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L816
    1987          72 :   if( FD_UNLIKELY( source_account->const_meta->dlen!=stake_state_v2_size_of() ||
    1988          72 :                    destination_account->const_meta->dlen!=stake_state_v2_size_of() ) )
    1989           6 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    1990             : 
    1991             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L823
    1992          66 :   if( source_merge_kind.discriminant!=merge_kind_fully_active )
    1993           6 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    1994          60 :   fd_stake_meta_t * source_meta = &source_merge_kind.inner.fully_active.meta;
    1995          60 :   fd_stake_t * source_stake = &source_merge_kind.inner.fully_active.stake;
    1996             : 
    1997             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L827
    1998          60 :   ulong minimum_delegation = get_minimum_delegation( ctx->slot_ctx );
    1999             : 
    2000             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L831
    2001          60 :   if( FD_UNLIKELY( source_stake->delegation.stake<lamports ) )
    2002           3 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
    2003             : 
    2004          57 :   ulong source_final_stake = source_stake->delegation.stake - lamports;
    2005             : 
    2006             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L836
    2007          57 :   if( FD_UNLIKELY( source_final_stake!=0 && source_final_stake<minimum_delegation ) )
    2008           3 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
    2009             : 
    2010             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L841
    2011          54 :   fd_stake_meta_t * destination_meta = NULL;
    2012          54 :   switch( destination_merge_kind.discriminant ) {
    2013          27 :   case merge_kind_fully_active: {
    2014          27 :     fd_stake_t * destination_stake = &destination_merge_kind.inner.fully_active.stake;
    2015             : 
    2016             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L844
    2017          27 :     if( FD_UNLIKELY( memcmp( &source_stake->delegation.voter_pubkey, &destination_stake->delegation.voter_pubkey, sizeof(fd_pubkey_t) ) ) ) {
    2018           3 :       *custom_err = FD_STAKE_ERR_VOTE_ADDRESS_MISMATCH;
    2019           3 :       return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
    2020           3 :     }
    2021             : 
    2022             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L848
    2023          24 :     ulong destination_effective_stake = 0;
    2024          24 :     rc = fd_ulong_checked_add( destination_stake->delegation.stake, lamports, &destination_effective_stake );
    2025          24 :     if( FD_UNLIKELY( rc ) ) return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW;
    2026             : 
    2027             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L855
    2028          21 :     if( FD_UNLIKELY( destination_effective_stake<minimum_delegation ) ) {
    2029           0 :       return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
    2030           0 :     }
    2031             : 
    2032             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L859
    2033          21 :     rc = merge_delegation_stake_and_credits_observed(
    2034          21 :       ctx, destination_stake, lamports, source_stake->credits_observed );
    2035          21 :     if( FD_UNLIKELY( rc ) ) return rc;
    2036          21 :     destination_meta = &destination_merge_kind.inner.fully_active.meta;
    2037             : 
    2038             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L867
    2039          21 :     fd_stake_state_v2_t new_destination_state = {
    2040          21 :       .discriminant = fd_stake_state_v2_enum_stake,
    2041          21 :       .inner        = { .stake = {
    2042          21 :                             .meta        = *destination_meta,
    2043          21 :                             .stake       = *destination_stake,
    2044          21 :                             .stake_flags = STAKE_FLAGS_EMPTY} } };
    2045          21 :     rc = set_state( ctx, destination_account_index, &new_destination_state );
    2046          21 :     if( FD_UNLIKELY( rc ) ) return rc;
    2047             : 
    2048          18 :     break;
    2049          21 :   }
    2050          24 :   case merge_kind_inactive: {
    2051             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L877
    2052          24 :     if( lamports<minimum_delegation ) {
    2053           0 :       return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
    2054           0 :     }
    2055             : 
    2056             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L881
    2057          24 :     fd_stake_t * destination_stake = source_stake;
    2058          24 :     destination_stake->delegation.stake = lamports;
    2059             : 
    2060          24 :     destination_meta = &destination_merge_kind.inner.inactive.meta;
    2061             : 
    2062             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L886
    2063          24 :     fd_stake_state_v2_t new_destination_state = {
    2064          24 :       .discriminant = fd_stake_state_v2_enum_stake,
    2065          24 :       .inner        = { .stake = {
    2066          24 :                             .meta        = *destination_meta,
    2067          24 :                             .stake       = *destination_stake,
    2068          24 :                             .stake_flags = STAKE_FLAGS_EMPTY} } };
    2069          24 :     rc = set_state( ctx, destination_account_index, &new_destination_state );
    2070          24 :     if( FD_UNLIKELY( rc ) ) return rc;
    2071          21 :     break;
    2072          24 :   }
    2073          21 :   default:
    2074             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L894
    2075           3 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    2076          54 :   }
    2077             : 
    2078             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L897-L910
    2079          39 :   if( source_final_stake==0) {
    2080          21 :     fd_stake_state_v2_t new_source_state = { .discriminant = fd_stake_state_v2_enum_initialized,
    2081          21 :                                  .inner        = { .initialized = { .meta =  *source_meta} } };
    2082          21 :     rc = set_state( ctx, source_account_index, &new_source_state );
    2083          21 :     if( FD_UNLIKELY( rc ) ) return rc;
    2084             : 
    2085          21 :   } else {
    2086          18 :     source_stake->delegation.stake = source_final_stake;
    2087             : 
    2088          18 :     fd_stake_state_v2_t new_source_state = { .discriminant = fd_stake_state_v2_enum_stake,
    2089          18 :                                .inner        = { .stake = { .meta = *source_meta,
    2090          18 :                                                             .stake = *source_stake,
    2091          18 :                                                             .stake_flags = STAKE_FLAGS_EMPTY } } };
    2092          18 :     rc = set_state( ctx, source_account_index, &new_source_state );
    2093          18 :     if( FD_UNLIKELY( rc ) ) return rc;
    2094          18 :   }
    2095             : 
    2096             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L911-L914
    2097          33 :   rc = fd_account_checked_sub_lamports( ctx, source_account_index, lamports );
    2098          33 :   if( FD_UNLIKELY( rc ) ) return rc;
    2099          30 :   rc = fd_account_checked_add_lamports( ctx, destination_account_index, lamports );
    2100          30 :   if( FD_UNLIKELY( rc ) ) return rc;
    2101             : 
    2102             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L915-L923
    2103          18 :   if( FD_UNLIKELY( fd_account_get_lamports2( ctx, source_account_index )<source_meta->rent_exempt_reserve ) ||
    2104          18 :                    fd_account_get_lamports2( ctx, destination_account_index )<destination_meta->rent_exempt_reserve ) {
    2105          12 :     fd_log_collector_msg_literal( ctx, "Delegation calculations violated lamport balance assumptions" );
    2106          12 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
    2107          12 :   }
    2108             : 
    2109         477 :   } FD_BORROWED_ACCOUNT_DROP( destination_account );
    2110         477 :   } FD_BORROWED_ACCOUNT_DROP( source_account );
    2111             : 
    2112           6 :   return FD_EXECUTOR_INSTR_SUCCESS;
    2113         477 : }
    2114             : 
    2115             : // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L928
    2116             : static int
    2117             : move_lamports(fd_exec_instr_ctx_t * ctx, // not const to log
    2118             :               ulong                 source_account_index,
    2119             :               ulong                 lamports,
    2120             :               ulong                 destination_account_index,
    2121         291 :               ulong                 stake_authority_index ) {
    2122         291 :   int rc;
    2123             : 
    2124             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L937-L942
    2125        1164 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, source_account_index, source_account ) {
    2126        1164 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, destination_account_index, destination_account ) {
    2127             : 
    2128             : 
    2129             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L943
    2130         291 :   merge_kind_t source_merge_kind = {0};
    2131         291 :   merge_kind_t destination_merge_kind = {0};
    2132         291 :   rc = move_stake_or_lamports_shared_checks( ctx,
    2133         291 :                                              source_account,
    2134         291 :                                              lamports,
    2135         291 :                                              destination_account,
    2136         291 :                                              stake_authority_index,
    2137         291 :                                              &source_merge_kind,
    2138         291 :                                              &destination_merge_kind,
    2139         291 :                                              &ctx->txn_ctx->custom_err );
    2140         291 :   if( FD_UNLIKELY( rc ) ) return rc;
    2141             : 
    2142             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L953-L963
    2143          99 :   ulong source_free_lamports;
    2144          99 :   switch( source_merge_kind.discriminant ) {
    2145          21 :     case merge_kind_fully_active: {
    2146          21 :       source_free_lamports = fd_ulong_sat_sub( fd_ulong_sat_sub( source_account->const_meta->info.lamports,
    2147          21 :                                                                  source_merge_kind.inner.fully_active.stake.delegation.stake ),
    2148          21 :                                                 source_merge_kind.inner.fully_active.meta.rent_exempt_reserve );
    2149             : 
    2150          21 :       break;
    2151           0 :     }
    2152          72 :     case merge_kind_inactive: {
    2153          72 :       source_free_lamports = fd_ulong_sat_sub( source_merge_kind.inner.inactive.active_stake,
    2154          72 :                                                source_merge_kind.inner.inactive.meta.rent_exempt_reserve );
    2155          72 :       break;
    2156           0 :     }
    2157           6 :     default:
    2158           6 :       return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    2159          99 :   }
    2160             : 
    2161             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L964
    2162          93 :   if( FD_UNLIKELY( lamports>source_free_lamports ) ) {
    2163          51 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
    2164          51 :   }
    2165             : 
    2166             :   // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_state.rs#L968-L970
    2167          42 :   rc = fd_account_checked_sub_lamports( ctx, source_account_index, lamports );
    2168          42 :   if( FD_UNLIKELY( rc ) ) return rc;
    2169             : 
    2170          39 :   rc = fd_account_checked_add_lamports( ctx, destination_account_index, lamports );
    2171          39 :   if( FD_UNLIKELY( rc ) ) return rc;
    2172             : 
    2173         291 :   } FD_BORROWED_ACCOUNT_DROP( destination_account );
    2174         291 :   } FD_BORROWED_ACCOUNT_DROP( source_account );
    2175             : 
    2176          30 :   return FD_EXECUTOR_INSTR_SUCCESS;
    2177         291 : }
    2178             : 
    2179             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L797
    2180             : static int
    2181             : withdraw( fd_exec_instr_ctx_t const *   ctx,
    2182             :           uchar                         stake_account_index,
    2183             :           ulong                         lamports,
    2184             :           uchar                         to_index,
    2185             :           fd_sol_sysvar_clock_t const * clock,
    2186             :           fd_stake_history_t const *    stake_history,
    2187             :           uchar                         withdraw_authority_index,
    2188             :           uchar *                       custodian_index,
    2189         651 :           ulong *                       new_rate_activation_epoch ) {
    2190             : 
    2191         651 :   int rc;
    2192             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L809
    2193         651 :   fd_pubkey_t const * withdraw_authority_pubkey = &ctx->instr->acct_pubkeys[withdraw_authority_index];
    2194             : 
    2195             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L813
    2196         651 :   int is_signer = fd_instr_acc_is_signer_idx( ctx->instr, withdraw_authority_index );
    2197         651 :   if( FD_UNLIKELY( !is_signer ) ) return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
    2198             : 
    2199             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L817
    2200         576 :   fd_pubkey_t const * signers[FD_TXN_SIG_MAX] = { withdraw_authority_pubkey };
    2201             : 
    2202             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L819
    2203        2304 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, stake_account_index, stake_account ) {
    2204             : 
    2205             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L821
    2206         576 :   fd_stake_state_v2_t stake_state = {0};
    2207         576 :   rc = get_state( stake_account, fd_spad_virtual( ctx->txn_ctx->spad ), &stake_state );
    2208         576 :   if( FD_UNLIKELY( rc ) ) return rc;
    2209             : 
    2210         552 :   fd_stake_lockup_t lockup;
    2211         552 :   ulong             reserve;
    2212         552 :   int               is_staked;
    2213             : 
    2214         552 :   switch( stake_state.discriminant ) {
    2215         213 :   case fd_stake_state_v2_enum_stake: {
    2216             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L822
    2217         213 :     fd_stake_meta_t * meta  = &stake_state.inner.stake.meta;
    2218         213 :     fd_stake_t *      stake = &stake_state.inner.stake.stake;
    2219             : 
    2220             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L823
    2221         213 :     rc = authorized_check( &meta->authorized, signers, STAKE_AUTHORIZE_WITHDRAWER );
    2222         213 :     if( FD_UNLIKELY( rc ) ) return rc;
    2223             : 
    2224             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L826
    2225         183 :     ulong staked = fd_ulong_if(
    2226         183 :         clock->epoch>=stake->delegation.deactivation_epoch,
    2227         183 :         delegation_stake(
    2228         183 :             &stake->delegation, clock->epoch, stake_history, new_rate_activation_epoch ),
    2229         183 :         stake->delegation.stake );
    2230             : 
    2231             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L837
    2232         183 :     ulong staked_and_reserve = ULONG_MAX;
    2233         183 :     rc = fd_ulong_checked_add( staked, meta->rent_exempt_reserve, &staked_and_reserve );
    2234         183 :     if( FD_UNLIKELY( rc ) ) return rc;
    2235             : 
    2236             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L838
    2237         180 :     lockup    = meta->lockup;
    2238         180 :     reserve   = staked_and_reserve;
    2239         180 :     is_staked = staked!=0;
    2240         180 :     break;
    2241         183 :   }
    2242         264 :   case fd_stake_state_v2_enum_initialized: {
    2243             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L840
    2244         264 :     fd_stake_meta_t * meta = &stake_state.inner.initialized.meta;
    2245             : 
    2246             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L841
    2247         264 :     rc = authorized_check( &meta->authorized, signers, STAKE_AUTHORIZE_WITHDRAWER );
    2248         264 :     if( FD_UNLIKELY( rc ) ) return rc;
    2249             : 
    2250             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L844
    2251         228 :     lockup    = meta->lockup;
    2252         228 :     reserve   = meta->rent_exempt_reserve;
    2253         228 :     is_staked = 0;
    2254         228 :     break;
    2255         264 :   }
    2256          54 :   case fd_stake_state_v2_enum_uninitialized: {
    2257             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L846
    2258          54 :     if( FD_UNLIKELY( !fd_instr_signers_contains( signers, stake_account->pubkey ) ) ) {
    2259          36 :       return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
    2260          36 :     }
    2261             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L850
    2262          18 :     memset( &lockup, 0, sizeof( fd_stake_lockup_t ) ); /* Lockup::default(); */
    2263          18 :     reserve   = 0;
    2264          18 :     is_staked = 0;
    2265          18 :     break;
    2266          54 :   }
    2267          21 :   default:
    2268             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L852
    2269          21 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    2270         552 :   }
    2271             : 
    2272             :   // FIXME FD_LIKELY
    2273             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L857-L871
    2274         426 :   fd_pubkey_t custodian_pubkey_ = {0};
    2275         426 :   fd_pubkey_t const * custodian_pubkey  = &custodian_pubkey_;
    2276         426 :   if( custodian_index ) {
    2277          75 :     int is_signer = fd_instr_acc_is_signer_idx( ctx->instr, *custodian_index );
    2278          75 :     if( is_signer ) {
    2279          57 :       custodian_pubkey = &ctx->instr->acct_pubkeys[*custodian_index];
    2280          57 :     } else {
    2281          18 :       custodian_pubkey = NULL;
    2282          18 :     }
    2283         351 :   } else {
    2284         351 :     custodian_pubkey = NULL;
    2285         351 :   }
    2286             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L871
    2287         426 :   if( FD_UNLIKELY( lockup_is_in_force( &lockup, clock, custodian_pubkey ) ) ) {
    2288          33 :     ctx->txn_ctx->custom_err = FD_STAKE_ERR_LOCKUP_IN_FORCE;
    2289          33 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
    2290         393 :   };
    2291             : 
    2292             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L875
    2293         393 :   ulong lamports_and_reserve = ULONG_MAX;
    2294         393 :   rc                         = fd_ulong_checked_add( lamports, reserve, &lamports_and_reserve );
    2295         393 :   if( FD_UNLIKELY( rc ) ) return rc;
    2296             : 
    2297             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L877
    2298         369 :   if( FD_UNLIKELY( is_staked && lamports_and_reserve>stake_account->const_meta->info.lamports ) ) {
    2299          57 :     return FD_EXECUTOR_INSTR_ERR_INSUFFICIENT_FUNDS;
    2300          57 :   }
    2301             : 
    2302             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L883
    2303         312 :   if( FD_UNLIKELY( lamports!=stake_account->const_meta->info.lamports &&
    2304         312 :                     lamports_and_reserve>stake_account->const_meta->info.lamports ) ) {
    2305             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L886
    2306          75 :     FD_TEST( !is_staked );
    2307          75 :     return FD_EXECUTOR_INSTR_ERR_INSUFFICIENT_FUNDS;
    2308          75 :   }
    2309             : 
    2310             :   // FIXME FD_LIKELY
    2311             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L891
    2312         237 :   if( lamports==stake_account->const_meta->info.lamports ) {
    2313         126 :     fd_stake_state_v2_t uninitialized = {0};
    2314         126 :     uninitialized.discriminant        = fd_stake_state_v2_enum_uninitialized;
    2315         126 :     rc                                = set_state( ctx, stake_account_index, &uninitialized );
    2316         126 :     if( FD_UNLIKELY( rc ) ) return rc;
    2317         126 :   }
    2318             : 
    2319             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L895
    2320         237 :   rc = fd_account_checked_sub_lamports( ctx, stake_account_index, lamports );
    2321         237 :   if( FD_UNLIKELY( rc ) ) return rc;
    2322             : 
    2323         576 :   } FD_BORROWED_ACCOUNT_DROP( stake_account );
    2324             : 
    2325             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L897
    2326         924 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, to_index, to ) {
    2327             : 
    2328             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L899
    2329         231 :   rc = fd_account_checked_add_lamports( ctx, to_index, lamports );
    2330         231 :   if( FD_UNLIKELY( rc ) ) return rc;
    2331             : 
    2332         231 :   } FD_BORROWED_ACCOUNT_DROP( to );
    2333             : 
    2334         207 :   return 0;
    2335         231 : }
    2336             : 
    2337             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L903
    2338             : static int
    2339             : deactivate_delinquent( fd_exec_instr_ctx_t *   ctx,
    2340             :                        fd_borrowed_account_t * stake_account,
    2341             :                        ulong                   stake_acc_index,
    2342             :                        ulong                   delinquent_vote_account_index,
    2343             :                        ulong                   reference_vote_account_index,
    2344             :                        ulong                   current_epoch,
    2345        1326 :                        uint *                  custom_err ) {
    2346        1326 :   int rc;
    2347             : 
    2348        1326 :   fd_valloc_t valloc = fd_spad_virtual( ctx->txn_ctx->spad );
    2349             : 
    2350             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L911
    2351        1326 :   fd_pubkey_t const * delinquent_vote_account_pubkey =
    2352        1326 :       &ctx->instr->acct_pubkeys[delinquent_vote_account_index];
    2353             : 
    2354             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L915
    2355        5067 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, delinquent_vote_account_index, delinquent_vote_account ) {
    2356             : 
    2357             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L917
    2358        1089 :   if( FD_UNLIKELY( memcmp( &delinquent_vote_account->const_meta->info.owner, fd_solana_vote_program_id.key, 32UL ) ) )
    2359          48 :     return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID;
    2360             : 
    2361             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L920-L922
    2362        1041 :   fd_vote_state_versioned_t delinquent_vote_state_versioned = {0};
    2363        1041 :   rc = fd_vote_get_state( delinquent_vote_account, valloc, &delinquent_vote_state_versioned );
    2364        1041 :   if( FD_UNLIKELY( rc ) ) return rc;
    2365         696 :   fd_vote_convert_to_current( &delinquent_vote_state_versioned, valloc );
    2366         696 :   fd_vote_state_t delinquent_vote_state = delinquent_vote_state_versioned.inner.current;
    2367             : 
    2368             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L924
    2369        2784 :   FD_BORROWED_ACCOUNT_TRY_BORROW_IDX( ctx, reference_vote_account_index, reference_vote_account ) {
    2370             : 
    2371             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L926
    2372         696 :   if( FD_UNLIKELY( memcmp( &reference_vote_account->const_meta->info.owner, fd_solana_vote_program_id.key, 32UL ) ) )
    2373           9 :     return FD_EXECUTOR_INSTR_ERR_INCORRECT_PROGRAM_ID;
    2374             : 
    2375             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L929-L932
    2376         687 :   fd_vote_state_versioned_t reference_vote_state_versioned = {0};
    2377         687 :   rc = fd_vote_get_state( reference_vote_account, valloc, &reference_vote_state_versioned );
    2378         687 :   if( FD_UNLIKELY( rc ) ) return rc;
    2379         681 :   fd_vote_convert_to_current( &reference_vote_state_versioned, valloc );
    2380         681 :   fd_vote_state_t reference_vote_state = reference_vote_state_versioned.inner.current;
    2381             : 
    2382             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L933
    2383         681 :   if( !acceptable_reference_epoch_credits( reference_vote_state.epoch_credits, current_epoch ) ) {
    2384         189 :     ctx->txn_ctx->custom_err = FD_STAKE_ERR_INSUFFICIENT_REFERENCE_VOTES;
    2385         189 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
    2386         189 :   }
    2387             : 
    2388         492 :   fd_stake_state_v2_t stake_state = {0};
    2389         492 :   rc = get_state( stake_account, fd_spad_virtual( ctx->txn_ctx->spad ), &stake_state );
    2390         492 :   if( FD_UNLIKELY( rc ) ) return rc;
    2391             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L937
    2392         492 :   if( FD_LIKELY( stake_state.discriminant==fd_stake_state_v2_enum_stake ) ) {
    2393         492 :     fd_stake_t * stake = &stake_state.inner.stake.stake;
    2394             : 
    2395         492 :     if( FD_UNLIKELY( memcmp( &stake->delegation.voter_pubkey, delinquent_vote_account_pubkey, sizeof(fd_pubkey_t) ) ) ) {
    2396             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L939
    2397          24 :       *custom_err = FD_STAKE_ERR_VOTE_ADDRESS_MISMATCH;
    2398          24 :       return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
    2399          24 :     }
    2400             : 
    2401             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L944
    2402         468 :     if( FD_LIKELY( eligible_for_deactivate_delinquent( delinquent_vote_state.epoch_credits,
    2403         468 :                                                         current_epoch ) ) ) {
    2404         264 :       rc = stake_deactivate( stake, current_epoch, custom_err );
    2405         264 :       if( FD_UNLIKELY( rc ) ) return rc;
    2406          72 :       rc = set_state( ctx, stake_acc_index, &stake_state );
    2407         204 :     } else {
    2408             :       // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L948
    2409         204 :       *custom_err = FD_STAKE_ERR_MINIMUM_DELIQUENT_EPOCHS_FOR_DEACTIVATION_NOT_MET;
    2410         204 :       return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
    2411         204 :     }
    2412         468 :   } else {
    2413             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_state.rs#L951
    2414           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
    2415           0 :   }
    2416             : 
    2417         696 :   } FD_BORROWED_ACCOUNT_DROP( reference_vote_account );
    2418        1089 :   } FD_BORROWED_ACCOUNT_DROP( delinquent_vote_account );
    2419             : 
    2420          72 :   return rc;
    2421        1326 : }
    2422             : 
    2423             : /**********************************************************************/
    2424             : /* mod stake_instruction                                              */
    2425             : /**********************************************************************/
    2426             : 
    2427             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L25
    2428             : static int
    2429             : get_optional_pubkey( fd_exec_instr_ctx_t *          ctx,
    2430             :                      ulong                          acc_idx,
    2431             :                      int                            should_be_signer,
    2432        1311 :                      /* out */ fd_pubkey_t const ** pubkey ) {
    2433             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L32
    2434        1311 :   if( FD_LIKELY( acc_idx<ctx->instr->acct_cnt ) ) {
    2435             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L33
    2436         648 :     if( FD_UNLIKELY( should_be_signer && !fd_instr_acc_is_signer_idx( ctx->instr, acc_idx ) ) ) {
    2437          63 :       return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
    2438          63 :     }
    2439             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L39
    2440         585 :     *pubkey = &ctx->instr->acct_pubkeys[acc_idx];
    2441         663 :   } else {
    2442         663 :     *pubkey = NULL;
    2443         663 :   }
    2444        1248 :   return 0;
    2445        1311 : }
    2446             : 
    2447             : // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L60
    2448             : static int
    2449             : get_stake_account( fd_exec_instr_ctx_t const * ctx,
    2450       12876 :                    fd_borrowed_account_t **    out ) {
    2451             : 
    2452       12876 :   if( FD_UNLIKELY( ctx->instr->acct_cnt<1 ) )
    2453          96 :     return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    2454             : 
    2455             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L61
    2456       12780 :   do {
    2457       12780 :     int err = fd_instr_borrowed_account_view_idx( ctx, 0, out );
    2458       12780 :     if( FD_UNLIKELY( err ) ) FD_LOG_ERR(( "fd_instr_borrowed_account_view_idx failed (%d-%s)", err, fd_acc_mgr_strerror( err ) ));
    2459       12780 :   } while(0);
    2460             : 
    2461       12780 :   fd_borrowed_account_t * account = *out;
    2462       12780 :   if( FD_UNLIKELY( !fd_borrowed_account_acquire_write( account ) ) )
    2463           0 :     return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_FAILED;
    2464             : 
    2465             :   // https://github.com/https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L62-L65
    2466       12780 :   if( FD_UNLIKELY( memcmp( account->const_meta->info.owner, fd_solana_stake_program_id.key, 32UL ) ) )
    2467         663 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_OWNER;
    2468             : 
    2469       12117 :   return FD_EXECUTOR_INSTR_SUCCESS;
    2470       12780 : }
    2471             : 
    2472             : /**********************************************************************/
    2473             : /* Public API                                                         */
    2474             : /**********************************************************************/
    2475             : 
    2476             : int
    2477       21237 : fd_stake_program_execute( fd_exec_instr_ctx_t * ctx ) {
    2478       21237 :   FD_EXEC_CU_UPDATE( ctx, DEFAULT_COMPUTE_UNITS );
    2479             : 
    2480             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L77
    2481       17367 :   fd_pubkey_t const * signers[FD_TXN_SIG_MAX] = {0};
    2482       17367 :   fd_instr_get_signers( ctx->instr, signers );
    2483             : 
    2484       17367 :   if( FD_UNLIKELY( ctx->instr->data==NULL ) ) {
    2485          69 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
    2486          69 :   }
    2487             : 
    2488             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L79
    2489       17298 :   fd_spad_t * spad = ctx->txn_ctx->spad;
    2490       17298 :   fd_valloc_t valloc = fd_spad_virtual( spad );
    2491       17298 :   fd_bincode_decode_ctx_t decode =
    2492       17298 :     { .valloc  = valloc,
    2493       17298 :       .data    = ctx->instr->data,
    2494       17298 :       .dataend = ctx->instr->data + ctx->instr->data_sz };
    2495             : 
    2496       17298 :   fd_stake_instruction_t instruction[1];
    2497       17298 :   int decode_result = fd_stake_instruction_decode( instruction, &decode );
    2498             :   /* Fail if the number of bytes consumed by deserialize exceeds 1232
    2499             :      (hardcoded constant by Agave limited_deserialize) */
    2500       17298 :   if( decode_result!=FD_BINCODE_SUCCESS ||
    2501       17298 :       (ulong)ctx->instr->data + 1232UL<(ulong)decode.data )
    2502         984 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
    2503             : 
    2504             :   /* The EpochRewards sysvar only exists after partitioned epoch rewards is activated.
    2505             :      If the sysvar exists, check the `active` field */
    2506       16314 :   fd_sysvar_epoch_rewards_t const * rewards = fd_sysvar_cache_epoch_rewards( ctx->slot_ctx->sysvar_cache );
    2507       16314 :   int epoch_rewards_active = (NULL != rewards) ? rewards->active : false;
    2508             : 
    2509       16314 :   if (epoch_rewards_active && instruction->discriminant!=fd_stake_instruction_enum_get_minimum_delegation) {
    2510         234 :     ctx->txn_ctx->custom_err = FD_STAKE_ERR_EPOCH_REWARDS_ACTIVE;
    2511         234 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
    2512         234 :   }
    2513             : 
    2514             :   /* Replicate stake account changes to bank caches after processing the
    2515             :      transaction's instructions. */
    2516       16080 :   ctx->txn_ctx->dirty_stake_acc = 1;
    2517             : 
    2518       16080 :   int rc;
    2519             :   // PLEASE PRESERVE SWITCH-CASE ORDERING TO MIRROR AGAVE IMPL:
    2520             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L84
    2521       16080 :   switch( instruction->discriminant ) {
    2522             : 
    2523             :   /* Initialize
    2524             :    *
    2525             :    * Instruction:
    2526             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L110
    2527             :    *
    2528             :    * Processor:
    2529             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L85
    2530             :    */
    2531         510 :   case fd_stake_instruction_enum_initialize: {
    2532         510 :     fd_stake_authorized_t const * authorized = &instruction->inner.initialize.authorized;
    2533         510 :     fd_stake_lockup_t const *     lockup     = &instruction->inner.initialize.lockup;
    2534             : 
    2535             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L86
    2536         510 :     fd_borrowed_account_t * me = NULL;
    2537         510 :     rc = get_stake_account( ctx, &me );  /* acquire_write */
    2538         510 :     if( FD_UNLIKELY( rc ) ) return rc;
    2539             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L87
    2540         399 :     fd_rent_t const * rent = fd_sysvar_from_instr_acct_rent( ctx, 1, &rc );
    2541         399 :     if( FD_UNLIKELY( !rent ) ) return rc;
    2542             : 
    2543             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L88
    2544         357 :     rc = initialize( ctx, me, 0, authorized, lockup, rent );
    2545             : 
    2546         357 :     fd_borrowed_account_release_write( me );  /* implicit drop */
    2547         357 :     break;
    2548         399 :   }
    2549             : 
    2550             :   /* Authorize
    2551             :    *
    2552             :    * Instruction:
    2553             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L120
    2554             :    *
    2555             :    * Processor:
    2556             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L90
    2557             :    */
    2558         567 :   case fd_stake_instruction_enum_authorize: {
    2559         567 :     fd_pubkey_t const *          authorized_pubkey = &instruction->inner.authorize.pubkey;
    2560         567 :     fd_stake_authorize_t const * stake_authorize   = &instruction->inner.authorize.stake_authorize;
    2561             : 
    2562             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L91
    2563         567 :     fd_borrowed_account_t * me = NULL;
    2564         567 :     rc = get_stake_account( ctx, &me );
    2565         567 :     if( FD_UNLIKELY( rc ) ) return rc;
    2566             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L92
    2567         516 :     fd_sol_sysvar_clock_t const * clock = fd_sysvar_from_instr_acct_clock( ctx, 1, &rc );
    2568         516 :     if( FD_UNLIKELY( !clock ) ) return rc;
    2569             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L94
    2570         438 :     if( FD_UNLIKELY( ctx->instr->acct_cnt<3 ) )
    2571           0 :       return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    2572             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L95
    2573         438 :     fd_pubkey_t const * custodian_pubkey = NULL;
    2574         438 :     rc = get_optional_pubkey( ctx, 3, 0, &custodian_pubkey );
    2575         438 :     if( FD_UNLIKELY( rc ) ) return rc;
    2576             : 
    2577             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L98
    2578         438 :     rc = authorize( ctx,
    2579         438 :                     me,
    2580         438 :                     0,
    2581         438 :                     signers,
    2582         438 :                     authorized_pubkey,
    2583         438 :                     stake_authorize,
    2584         438 :                     clock,
    2585         438 :                     custodian_pubkey,
    2586         438 :                     &ctx->txn_ctx->custom_err );
    2587             : 
    2588         438 :     fd_borrowed_account_release_write( me );  /* implicit drop */
    2589         438 :     break;
    2590         438 :   }
    2591             : 
    2592             :   /* AuthorizeWithSeed
    2593             :    *
    2594             :    * Instruction:
    2595             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L211
    2596             :    *
    2597             :    * Processor:
    2598             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L107
    2599             :    */
    2600         378 :   case fd_stake_instruction_enum_authorize_with_seed: {
    2601         378 :     fd_authorize_with_seed_args_t args = instruction->inner.authorize_with_seed;
    2602             : 
    2603             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L108
    2604         378 :     fd_borrowed_account_t * me = NULL;
    2605         378 :     rc                         = get_stake_account( ctx, &me );
    2606         378 :     if( FD_UNLIKELY( rc ) ) return rc;
    2607             : 
    2608             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L109
    2609         363 :     if( ctx->instr->acct_cnt<2 )
    2610           0 :       return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    2611             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L110
    2612         363 :     fd_sol_sysvar_clock_t const * clock = fd_sysvar_from_instr_acct_clock( ctx, 2, &rc );
    2613         363 :     if( FD_UNLIKELY( !clock ) ) return rc;
    2614             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L112
    2615         351 :     fd_pubkey_t const * custodian_pubkey = NULL;
    2616         351 :     rc = get_optional_pubkey( ctx, 3, 0, &custodian_pubkey );
    2617         351 :     if( FD_UNLIKELY( rc ) ) return rc;
    2618             : 
    2619             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L115
    2620         351 :     rc = authorize_with_seed( ctx,
    2621         351 :                               me,
    2622         351 :                               0,
    2623         351 :                               1,
    2624         351 :                               (char const *)args.authority_seed,
    2625         351 :                               args.authority_seed_len,
    2626         351 :                               &args.authority_owner,
    2627         351 :                               &args.new_authorized_pubkey,
    2628         351 :                               &args.stake_authorize,
    2629         351 :                               clock,
    2630         351 :                               custodian_pubkey );
    2631             : 
    2632         351 :     fd_borrowed_account_release_write( me );  /* implicit drop */
    2633         351 :     break;
    2634         351 :   }
    2635             : 
    2636             :   /* DelegateStake
    2637             :    *
    2638             :    * Instruction:
    2639             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L135
    2640             :    *
    2641             :    * Processor:
    2642             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L128
    2643             :    */
    2644        1479 :   case fd_stake_instruction_enum_delegate_stake: {
    2645             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L129
    2646        1479 :     fd_borrowed_account_t * me = NULL;
    2647        1479 :     rc                         = get_stake_account( ctx, &me );
    2648        1479 :     if( FD_UNLIKELY( rc ) ) return rc;
    2649             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L130
    2650        1449 :     if( FD_UNLIKELY( ctx->instr->acct_cnt<2 ) )
    2651          42 :       return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    2652             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L131
    2653        1407 :     fd_sol_sysvar_clock_t const * clock =
    2654        1407 :       fd_sysvar_from_instr_acct_clock( ctx, 2, &rc );
    2655        1407 :     if( FD_UNLIKELY( !clock ) ) return rc;
    2656             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L133
    2657        1284 :     fd_stake_history_t const * stake_history =
    2658        1284 :       fd_sysvar_from_instr_acct_stake_history( ctx, 3, &rc );
    2659        1284 :     if( FD_UNLIKELY( !stake_history ) ) return rc;
    2660             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L138
    2661        1275 :     if( FD_UNLIKELY( ctx->instr->acct_cnt<5 ) )
    2662           3 :       return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    2663        1272 :     fd_borrowed_account_release_write( me );  /* implicit drop */
    2664             : 
    2665             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L140
    2666        1272 :     rc = delegate( ctx,
    2667        1272 :                    0,
    2668        1272 :                    1,
    2669        1272 :                    clock,
    2670        1272 :                    stake_history,
    2671        1272 :                    signers );
    2672             : 
    2673        1272 :     break;
    2674        1275 :   }
    2675             : 
    2676             :   /* Split
    2677             :    *
    2678             :    * Instruction:
    2679             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L143
    2680             :    *
    2681             :    * Processor:
    2682             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L152
    2683             :    */
    2684        2844 :   case fd_stake_instruction_enum_split: {
    2685        2844 :     ulong lamports = instruction->inner.split;
    2686             : 
    2687             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L153
    2688        2844 :     fd_borrowed_account_t * me = NULL;
    2689        2844 :     rc                         = get_stake_account( ctx, &me );
    2690        2844 :     if( FD_UNLIKELY( rc ) ) return rc;
    2691             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L154
    2692        2778 :     if( FD_UNLIKELY( ctx->instr->acct_cnt<2 ) )
    2693           0 :       return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    2694        2778 :     fd_borrowed_account_release_write( me );  /* implicit drop */
    2695             : 
    2696             :     //https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L156
    2697        2778 :     rc = split( ctx, 0, lamports, 1, signers );
    2698        2778 :     break;
    2699        2778 :   }
    2700             : 
    2701             :   /* Merge
    2702             :    *
    2703             :    * Instruction:
    2704             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L201
    2705             :    *
    2706             :    * Processor:
    2707             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L166
    2708             :    */
    2709        2001 :   case fd_stake_instruction_enum_merge: {
    2710             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L167
    2711        2001 :     fd_borrowed_account_t * me = NULL;
    2712        2001 :     rc                         = get_stake_account( ctx, &me );
    2713        2001 :     if( FD_UNLIKELY( rc ) ) return rc;
    2714             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L168
    2715        1953 :     if( FD_UNLIKELY( ctx->instr->acct_cnt<2 ) )
    2716           0 :       return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    2717             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L169
    2718        1953 :     fd_sol_sysvar_clock_t const * clock = fd_sysvar_from_instr_acct_clock( ctx, 2, &rc );
    2719        1953 :     if( FD_UNLIKELY( rc ) ) return rc;
    2720             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L171
    2721        1644 :     fd_stake_history_t const * stake_history = fd_sysvar_from_instr_acct_stake_history( ctx, 3, &rc );
    2722        1644 :     if( FD_UNLIKELY( rc ) ) return rc;
    2723             : 
    2724        1632 :     fd_borrowed_account_release_write( me );  /* implicit drop */
    2725             : 
    2726             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L177
    2727        1632 :     rc = merge( ctx, 0, 1, clock, stake_history, signers );
    2728        1632 :     break;
    2729        1644 :   }
    2730             : 
    2731             :   /* Withdraw
    2732             :    *
    2733             :    * Instruction:
    2734             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L157
    2735             :    *
    2736             :    * Processor:
    2737             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L188
    2738             :    */
    2739         894 :   case fd_stake_instruction_enum_withdraw: FD_SPAD_FRAME_BEGIN( spad ) {
    2740         894 :     ulong lamports = instruction->inner.withdraw;
    2741             : 
    2742             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L189
    2743         894 :     fd_borrowed_account_t * me = NULL;
    2744         894 :     rc = get_stake_account( ctx, &me );  /* calls acquire_write */
    2745         894 :     if( FD_UNLIKELY( rc ) ) return rc;
    2746             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L190
    2747         861 :     if( FD_UNLIKELY( ctx->instr->acct_cnt<2 ) )
    2748          24 :       return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    2749             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L191
    2750         837 :     fd_sol_sysvar_clock_t const * clock = fd_sysvar_from_instr_acct_clock( ctx, 2, &rc );
    2751         837 :     if( FD_UNLIKELY( !clock ) ) return rc;
    2752             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L193
    2753         687 :     fd_stake_history_t const * stake_history = fd_sysvar_from_instr_acct_stake_history( ctx, 3, &rc );
    2754         687 :     if( FD_UNLIKELY( !stake_history ) ) return rc;
    2755             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L198
    2756         654 :     if( FD_UNLIKELY( ctx->instr->acct_cnt<5 ) )
    2757           3 :       return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    2758             : 
    2759         651 :     fd_borrowed_account_release_write( me );  /* implicit drop */
    2760             : 
    2761         651 :     uchar custodian_index           = 5;
    2762         651 :     ulong new_rate_activation_epoch = ULONG_MAX;
    2763         651 :     int   err;
    2764         651 :     int   is_some = fd_new_warmup_cooldown_rate_epoch( ctx->slot_ctx, &new_rate_activation_epoch, &err );
    2765         651 :     if( FD_UNLIKELY( err ) ) return err;
    2766             : 
    2767             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L200
    2768         651 :     rc = withdraw(
    2769         651 :         ctx,
    2770         651 :         0,
    2771         651 :         lamports,
    2772         651 :         1,
    2773         651 :         clock,
    2774         651 :         stake_history,
    2775         651 :         4,
    2776             :         // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L209-L215
    2777         651 :         fd_ptr_if( ctx->instr->acct_cnt>=6, &custodian_index, NULL ),
    2778         651 :         fd_ptr_if( is_some, &new_rate_activation_epoch, NULL ) );
    2779             : 
    2780         894 :     } FD_SPAD_FRAME_END; /* No real allocations. Just logically whatever alloc there is, this is where their life ends. */
    2781         651 :     break;
    2782             : 
    2783             :   /* Deactivate
    2784             :    *
    2785             :    * Instruction:
    2786             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L165
    2787             :    *
    2788             :    * Processor:
    2789             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L217
    2790             :    */
    2791         651 :   case fd_stake_instruction_enum_deactivate: {
    2792             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L218
    2793         576 :     fd_borrowed_account_t * me = NULL;
    2794         576 :     rc                         = get_stake_account( ctx, &me );
    2795         576 :     if( FD_UNLIKELY( rc ) ) return rc;
    2796             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L219
    2797         459 :     fd_sol_sysvar_clock_t const * clock = fd_sysvar_from_instr_acct_clock( ctx, 1, &rc );
    2798         459 :     if( FD_UNLIKELY( !clock ) ) return rc;
    2799             : 
    2800             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L221
    2801         363 :     rc = deactivate( ctx, me, 0, clock, signers, &ctx->txn_ctx->custom_err );
    2802             : 
    2803         363 :     fd_borrowed_account_release_write( me );  /* implicit drop */
    2804         363 :     break;
    2805         459 :   }
    2806             : 
    2807             :   /* SetLockup
    2808             :    *
    2809             :    * Instruction:
    2810             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L175
    2811             :    *
    2812             :    * Processor:
    2813             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L223
    2814             :    */
    2815         606 :   case fd_stake_instruction_enum_set_lockup: {
    2816         606 :     fd_lockup_args_t * lockup = &instruction->inner.set_lockup;
    2817             : 
    2818             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L224
    2819         606 :     fd_borrowed_account_t * me = NULL;
    2820         606 :     rc = get_stake_account( ctx, &me );
    2821         606 :     if( FD_UNLIKELY( rc ) ) return rc;
    2822             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L225
    2823         543 :     fd_sol_sysvar_clock_t const * clock = fd_sysvar_cache_clock( ctx->slot_ctx->sysvar_cache );
    2824         543 :     if( FD_UNLIKELY( !clock ) )
    2825           0 :       return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
    2826             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L226
    2827         543 :     rc = set_lockup( ctx, me, 0, lockup, signers, clock );
    2828             : 
    2829         543 :     fd_borrowed_account_release_write( me );  /* implicit drop */
    2830         543 :     break;
    2831         543 :   }
    2832             : 
    2833             :   /* InitializeChecked
    2834             :    *
    2835             :    * Instruction:
    2836             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L224
    2837             :    *
    2838             :    * Processor:
    2839             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L228
    2840             :    */
    2841         186 :   case fd_stake_instruction_enum_initialize_checked: {
    2842             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L229
    2843         186 :     fd_borrowed_account_t * me = NULL;
    2844         186 :     rc = get_stake_account( ctx, &me );
    2845         186 :     if( FD_UNLIKELY( rc ) ) return rc;
    2846             : 
    2847             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L230
    2848         150 :     if( FD_UNLIKELY( ctx->instr->acct_cnt<4 ) )
    2849           6 :       return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    2850             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L231-L236
    2851         144 :     fd_pubkey_t const * staker_pubkey     = &ctx->instr->acct_pubkeys[2];
    2852         144 :     fd_pubkey_t const * withdrawer_pubkey = &ctx->instr->acct_pubkeys[3];
    2853             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L237
    2854         144 :     if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, 3 ) ) )
    2855          45 :       return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
    2856             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L241
    2857          99 :     fd_stake_authorized_t authorized = { .staker     = *staker_pubkey,
    2858          99 :                                           .withdrawer = *withdrawer_pubkey };
    2859             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L246
    2860          99 :     fd_rent_t const * rent = fd_sysvar_from_instr_acct_rent( ctx, 1, &rc );
    2861          99 :     if( FD_UNLIKELY( !rent ) ) return rc;
    2862             : 
    2863          96 :     fd_stake_lockup_t lockup_default = {0};
    2864             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L247
    2865          96 :     rc = initialize( ctx, me, 0, &authorized, &lockup_default, rent );
    2866             : 
    2867          96 :     fd_borrowed_account_release_write( me );  /* implicit drop */
    2868          96 :     break;
    2869          99 :   }
    2870             : 
    2871             :   /* AuthorizeChecked
    2872             :    *
    2873             :    * Instruction:
    2874             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L238
    2875             :    *
    2876             :    * Processor:
    2877             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L249
    2878             :    */
    2879         381 :   case fd_stake_instruction_enum_authorize_checked: {
    2880         381 :     fd_stake_authorize_t const * stake_authorize = &instruction->inner.authorize_checked;
    2881             : 
    2882             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L250
    2883         381 :     fd_borrowed_account_t * me = NULL;
    2884         381 :     rc                         = get_stake_account( ctx, &me );
    2885         381 :     if( FD_UNLIKELY( rc ) ) return rc;
    2886             : 
    2887             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L251
    2888         348 :     fd_sol_sysvar_clock_t const * clock = fd_sysvar_from_instr_acct_clock( ctx, 1, &rc );
    2889         348 :     if( FD_UNLIKELY( !clock ) ) return rc;
    2890             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L253
    2891         330 :     if( FD_UNLIKELY( ctx->instr->acct_cnt<4 ) )
    2892           6 :       return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    2893             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L254
    2894         324 :     fd_pubkey_t const * authorized_pubkey = &ctx->instr->acct_pubkeys[3];
    2895             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L257
    2896         324 :     int is_signer = fd_instr_acc_is_signer_idx( ctx->instr, 3 );
    2897         324 :     if( FD_UNLIKELY( !is_signer ) ) return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
    2898             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L260
    2899         201 :     fd_pubkey_t const * custodian_pubkey = NULL;
    2900         201 :     rc = get_optional_pubkey( ctx, 4, 0, &custodian_pubkey );
    2901         201 :     if( FD_UNLIKELY( rc ) ) return rc;
    2902             : 
    2903             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L263
    2904         201 :     rc = authorize( ctx,
    2905         201 :                     me,
    2906         201 :                     0,
    2907         201 :                     signers,
    2908         201 :                     authorized_pubkey,
    2909         201 :                     stake_authorize,
    2910         201 :                     clock,
    2911         201 :                     custodian_pubkey,
    2912         201 :                     &ctx->txn_ctx->custom_err );
    2913             : 
    2914         201 :     fd_borrowed_account_release_write( me );  /* implicit drop */
    2915         201 :     break;
    2916         201 :   }
    2917             : 
    2918             :   /* AuthorizeCheckedWithSeed
    2919             :    *
    2920             :    * Instruction:
    2921             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L252
    2922             :    *
    2923             :    * Processor:
    2924             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L272
    2925             :    */
    2926         171 :   case fd_stake_instruction_enum_authorize_checked_with_seed: {
    2927         171 :     fd_authorize_checked_with_seed_args_t const * args =
    2928         171 :         &instruction->inner.authorize_checked_with_seed;
    2929             : 
    2930             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L273
    2931         171 :     fd_borrowed_account_t * me = NULL;
    2932         171 :     rc                         = get_stake_account( ctx, &me );
    2933         171 :     if( FD_UNLIKELY( rc ) ) return rc;
    2934             : 
    2935             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L274
    2936         153 :     if( FD_UNLIKELY( ctx->instr->acct_cnt<2 ) )
    2937           0 :       return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    2938             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L276
    2939         153 :     fd_sol_sysvar_clock_t const * clock = fd_sysvar_from_instr_acct_clock( ctx, 2, &rc );
    2940         153 :     if( FD_UNLIKELY( !clock ) ) return rc;
    2941             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L277
    2942         141 :     if( FD_UNLIKELY( ctx->instr->acct_cnt<4 ) )
    2943           3 :       return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    2944             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L278
    2945         138 :     fd_pubkey_t const * authorized_pubkey = &ctx->instr->acct_pubkeys[3];
    2946             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L281
    2947         138 :     int is_signer = fd_instr_acc_is_signer_idx( ctx->instr, 3 );
    2948         138 :     if( FD_UNLIKELY( !is_signer ) ) return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
    2949             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L284
    2950          78 :     fd_pubkey_t const * custodian_pubkey = NULL;
    2951          78 :     rc = get_optional_pubkey( ctx, 4, 0, &custodian_pubkey );
    2952          78 :     if( FD_UNLIKELY( rc ) ) return rc;
    2953             : 
    2954             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L287
    2955          78 :     rc = authorize_with_seed( ctx,
    2956          78 :                               me,
    2957          78 :                               0,
    2958          78 :                               1,
    2959          78 :                               (char const *)args->authority_seed,
    2960          78 :                               args->authority_seed_len,
    2961          78 :                               &args->authority_owner,
    2962          78 :                               authorized_pubkey,
    2963          78 :                               &args->stake_authorize,
    2964          78 :                               clock,
    2965          78 :                               custodian_pubkey );
    2966             : 
    2967          78 :     fd_borrowed_account_release_write( me );  /* implicit drop */
    2968          78 :     break;
    2969          78 :   }
    2970             : 
    2971             :   /* SetLockupChecked
    2972             :    *
    2973             :    * Instruction:
    2974             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L266
    2975             :    *
    2976             :    * Processor:
    2977             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L300
    2978             :    */
    2979         300 :   case fd_stake_instruction_enum_set_lockup_checked: {
    2980         300 :     fd_lockup_checked_args_t * lockup_checked = &instruction->inner.set_lockup_checked;
    2981             : 
    2982             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L301
    2983         300 :     fd_borrowed_account_t * me = NULL;
    2984         300 :     rc = get_stake_account( ctx, &me );  /* acquire_write */
    2985         300 :     if( FD_UNLIKELY( rc ) ) return rc;
    2986             : 
    2987             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L302
    2988         243 :     fd_pubkey_t const * custodian_pubkey = NULL;
    2989         243 :     rc = get_optional_pubkey( ctx, 2, 1, &custodian_pubkey );
    2990         243 :     if( FD_UNLIKELY( rc ) ) return rc;
    2991             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L305
    2992         180 :     fd_lockup_args_t lockup = { .unix_timestamp = lockup_checked->unix_timestamp,
    2993         180 :                                 .epoch          = lockup_checked->epoch,
    2994         180 :                                 .custodian      = (fd_pubkey_t *)custodian_pubkey }; // FIXME
    2995             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L310
    2996         180 :     fd_sol_sysvar_clock_t const * clock = fd_sysvar_cache_clock( ctx->slot_ctx->sysvar_cache );
    2997         180 :     if( FD_UNLIKELY( !clock ) )
    2998           0 :       return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
    2999             : 
    3000             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L311
    3001         180 :     rc = set_lockup( ctx, me, 0, &lockup, signers, clock );
    3002             : 
    3003         180 :     fd_borrowed_account_release_write( me );  /* implicit drop */
    3004         180 :     break;
    3005         180 :   }
    3006             : 
    3007             :   /* GetMinimumDelegation
    3008             :    *
    3009             :    * Instruction:
    3010             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L278
    3011             :    *
    3012             :    * Processor:
    3013             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L313
    3014             :    */
    3015        2223 :   case fd_stake_instruction_enum_get_minimum_delegation: {
    3016        2223 :     ulong minimum_delegation = get_minimum_delegation( ctx->slot_ctx );
    3017        2223 :     fd_memcpy( &ctx->txn_ctx->return_data.program_id, fd_solana_stake_program_id.key, sizeof(fd_pubkey_t));
    3018        2223 :     fd_memcpy(ctx->txn_ctx->return_data.data, (uchar*)(&minimum_delegation), sizeof(ulong));
    3019        2223 :     ctx->txn_ctx->return_data.len = sizeof(ulong);
    3020        2223 :     rc = 0;
    3021        2223 :     goto done;
    3022         180 :   }
    3023             : 
    3024             :   /* DeactivateDelinquent
    3025             :    *
    3026             :    * Instruction:
    3027             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/instruction.rs#L291
    3028             :    *
    3029             :    * Processor:
    3030             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L321
    3031             :    */
    3032        1434 :   case fd_stake_instruction_enum_deactivate_delinquent: {
    3033             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L322
    3034        1434 :     fd_borrowed_account_t * me = NULL;
    3035        1434 :     rc                         = get_stake_account( ctx, &me );
    3036        1434 :     if( FD_UNLIKELY( rc ) ) return rc;
    3037             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L323
    3038        1377 :     if( FD_UNLIKELY( ctx->instr->acct_cnt<3 ) )
    3039          51 :       return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    3040             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L325
    3041        1326 :     fd_sol_sysvar_clock_t const * clock = fd_sysvar_cache_clock( ctx->slot_ctx->sysvar_cache );
    3042        1326 :     if( FD_UNLIKELY( !clock ) )
    3043           0 :       return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
    3044             : 
    3045             :     // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L326
    3046        1326 :     rc = deactivate_delinquent( ctx, me, 0, 1, 2, clock->epoch, &ctx->txn_ctx->custom_err );
    3047             : 
    3048        1326 :     fd_borrowed_account_release_write( me );  /* implicit drop */
    3049        1326 :     break;
    3050        1326 :   }
    3051             : 
    3052             :   /* Redelegate
    3053             :    *
    3054             :    * Deprecated:
    3055             :    * https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/programs/stake/src/stake_instruction.rs#L336
    3056             :    */
    3057         549 :   case fd_stake_instruction_enum_redelegate: {
    3058         549 :     fd_borrowed_account_t * me = NULL;
    3059         549 :     rc                         = get_stake_account( ctx, &me );
    3060         549 :     if( FD_UNLIKELY( rc ) ) return rc;
    3061             : 
    3062         525 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
    3063         549 :   }
    3064             :   /* MoveStake
    3065             :    *
    3066             :    * Instruction:
    3067             :    * https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/sdk/program/src/stake/instruction.rs#L330
    3068             :    *
    3069             :    * Processor:
    3070             :    * https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_instruction.rs#L356
    3071             :    */
    3072         600 :   case fd_stake_instruction_enum_move_stake: {
    3073             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_instruction.rs#L359
    3074         600 :     if( FD_LIKELY( FD_FEATURE_ACTIVE( ctx->slot_ctx, move_stake_and_move_lamports_ixs ) ) ) {
    3075             :       // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_instruction.rs#L361
    3076         480 :       if( FD_UNLIKELY( ctx->instr->acct_cnt<3 ) )
    3077           3 :         return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    3078             : 
    3079         477 :       ulong lamports = instruction->inner.move_stake;
    3080             :       // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_instruction.rs#L362
    3081         477 :       rc = move_stake( ctx,
    3082         477 :                        0UL,
    3083         477 :                        lamports,
    3084         477 :                        1UL,
    3085         477 :                        2UL,
    3086         477 :                        &ctx->txn_ctx->custom_err );
    3087         477 :     } else {
    3088             :       // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_instruction.rs#L372
    3089         120 :       return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
    3090         120 :     }
    3091         477 :     break;
    3092         600 :   }
    3093             :   /* MoveLamports
    3094             :    *
    3095             :    * Instruction:
    3096             :    * https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/sdk/program/src/stake/instruction.rs#L345
    3097             :    *
    3098             :    * Processor:
    3099             :    * https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_instruction.rs#L375
    3100             :    */
    3101         477 :   case fd_stake_instruction_enum_move_lamports: {
    3102             :     // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_instruction.rs#L378
    3103         381 :     if( FD_LIKELY( FD_FEATURE_ACTIVE( ctx->slot_ctx, move_stake_and_move_lamports_ixs ) ) ) {
    3104             :       // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_instruction.rs#L380
    3105         294 :       if( FD_UNLIKELY( ctx->instr->acct_cnt<3 ) )
    3106           3 :         return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
    3107             : 
    3108             :       // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_instruction.rs#L381
    3109         291 :       ulong lamports = instruction->inner.move_lamports;
    3110             : 
    3111             :       // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_instruction.rs#L381
    3112         291 :       rc = move_lamports( ctx,
    3113         291 :                        0UL,
    3114         291 :                        lamports,
    3115         291 :                        1UL,
    3116         291 :                        2UL );
    3117         291 :     } else {
    3118             :       // https://github.com/anza-xyz/agave/blob/cdff19c7807b006dd63429114fb1d9573bf74172/programs/stake/src/stake_instruction.rs#L391
    3119          87 :       return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
    3120          87 :     }
    3121         291 :     break;
    3122         381 :   }
    3123         291 :   default:
    3124           0 :     FD_LOG_ERR(( "unsupported stake instruction: %u", instruction->discriminant ));
    3125       16080 :   }
    3126             : 
    3127       13257 : done:
    3128       13257 :   return rc;
    3129       16080 : }
    3130             : 
    3131             : /* Public API *********************************************************/
    3132             : 
    3133             : static void
    3134           0 : write_stake_config( fd_exec_slot_ctx_t * slot_ctx, fd_stake_config_t const * stake_config ) {
    3135           0 :   ulong                   data_sz  = fd_stake_config_size( stake_config );
    3136           0 :   fd_pubkey_t const *     acc_key  = &fd_solana_stake_program_config_id;
    3137           0 :   fd_account_meta_t *     acc_meta = NULL;
    3138           0 :   uchar *                 acc_data = NULL;
    3139           0 :   FD_BORROWED_ACCOUNT_DECL(rec);
    3140           0 :   int err = fd_acc_mgr_modify( slot_ctx->acc_mgr, slot_ctx->funk_txn, acc_key, 1, data_sz, rec );
    3141           0 :   FD_TEST( !err );
    3142             : 
    3143           0 :   acc_meta                  = rec->meta;
    3144           0 :   acc_data                  = rec->data;
    3145           0 :   acc_meta->dlen            = data_sz;
    3146           0 :   acc_meta->info.lamports   = 960480UL;
    3147           0 :   acc_meta->info.rent_epoch = 0UL;
    3148           0 :   acc_meta->info.executable = 0;
    3149             : 
    3150           0 :   fd_bincode_encode_ctx_t ctx3;
    3151           0 :   ctx3.data    = acc_data;
    3152           0 :   ctx3.dataend = acc_data + data_sz;
    3153           0 :   if( fd_stake_config_encode( stake_config, &ctx3 ) )
    3154           0 :     FD_LOG_ERR( ( "fd_stake_config_encode failed" ) );
    3155             : 
    3156           0 :   fd_memset( acc_data, 0, data_sz );
    3157           0 :   fd_memcpy( acc_data, stake_config, sizeof( fd_stake_config_t ) );
    3158           0 : }
    3159             : 
    3160             : void
    3161           0 : fd_stake_program_config_init( fd_exec_slot_ctx_t * slot_ctx ) {
    3162             :   // https://github.com/anza-xyz/agave/blob/c8685ce0e1bb9b26014f1024de2cd2b8c308cbde/sdk/program/src/stake/config.rs#L26
    3163           0 :   fd_stake_config_t stake_config = {
    3164           0 :       .warmup_cooldown_rate = DEFAULT_WARMUP_COOLDOWN_RATE,
    3165           0 :       .slash_penalty        = DEFAULT_SLASH_PENALTY,
    3166           0 :   };
    3167           0 :   write_stake_config( slot_ctx, &stake_config );
    3168           0 : }
    3169             : 
    3170             : int
    3171             : fd_stake_get_state( fd_borrowed_account_t const * self,
    3172             :                     fd_valloc_t const *           valloc,
    3173           0 :                     fd_stake_state_v2_t *         out ) {
    3174           0 :   return get_state( self, *valloc, out );
    3175           0 : }
    3176             : 
    3177             : fd_stake_history_entry_t
    3178             : fd_stake_activating_and_deactivating( fd_delegation_t const *    self,
    3179             :                                       ulong                      target_epoch,
    3180             :                                       fd_stake_history_t const * stake_history,
    3181           0 :                                       ulong *                    new_rate_activation_epoch ) {
    3182           0 :   return stake_activating_and_deactivating(
    3183           0 :     self, target_epoch, stake_history, new_rate_activation_epoch );
    3184           0 : }
    3185             : 
    3186             : /* Removes stake delegation from epoch stakes and updates vote account */
    3187             : static void
    3188           0 : fd_stakes_remove_stake_delegation( fd_exec_slot_ctx_t * slot_ctx, fd_borrowed_account_t * stake_account ) {
    3189           0 :   fd_stake_accounts_pair_t_mapnode_t key;
    3190           0 :   fd_memcpy( key.elem.key.uc, stake_account->pubkey->uc, sizeof(fd_pubkey_t) );
    3191           0 :   if( slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool==NULL ) {
    3192           0 :     FD_LOG_DEBUG(("Stake accounts pool does not exist"));
    3193           0 :     return;
    3194           0 :   }
    3195           0 :   fd_stake_accounts_pair_t_mapnode_t * entry = fd_stake_accounts_pair_t_map_find( slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool, slot_ctx->slot_bank.stake_account_keys.stake_accounts_root, &key );
    3196           0 :   if (FD_UNLIKELY( entry )) {
    3197           0 :     fd_stake_accounts_pair_t_map_remove( slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool, &slot_ctx->slot_bank.stake_account_keys.stake_accounts_root, entry);
    3198             :     // TODO: do we need a release here?
    3199           0 :   }
    3200           0 : }
    3201             : 
    3202             : /* Updates stake delegation in epoch stakes */
    3203             : static void
    3204           0 : fd_stakes_upsert_stake_delegation( fd_exec_slot_ctx_t * slot_ctx, fd_borrowed_account_t * stake_account ) {
    3205           0 :   FD_TEST( stake_account->const_meta->info.lamports!=0 );
    3206           0 :   fd_epoch_bank_t * epoch_bank = fd_exec_epoch_ctx_epoch_bank( slot_ctx->epoch_ctx );
    3207           0 :   fd_stakes_t * stakes = &epoch_bank->stakes;
    3208             : 
    3209           0 :   fd_delegation_pair_t_mapnode_t key;
    3210           0 :   fd_memcpy(&key.elem.account, stake_account->pubkey->uc, sizeof(fd_pubkey_t));
    3211             : 
    3212           0 :   if( stakes->stake_delegations_pool==NULL) {
    3213           0 :     FD_LOG_DEBUG(("Stake delegations pool does not exist"));
    3214           0 :     return;
    3215           0 :   }
    3216             : 
    3217           0 :   fd_delegation_pair_t_mapnode_t * entry = fd_delegation_pair_t_map_find( stakes->stake_delegations_pool, stakes->stake_delegations_root, &key);
    3218           0 :   if( FD_UNLIKELY( !entry ) ) {
    3219           0 :     fd_stake_accounts_pair_t_mapnode_t key;
    3220           0 :     fd_memcpy( key.elem.key.uc, stake_account->pubkey->uc, sizeof(fd_pubkey_t) );
    3221           0 :     if( slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool==NULL) {
    3222           0 :       FD_LOG_DEBUG(("Stake accounts pool does not exist"));
    3223           0 :       return;
    3224           0 :     }
    3225           0 :     fd_stake_accounts_pair_t_mapnode_t * stake_entry = fd_stake_accounts_pair_t_map_find( slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool, slot_ctx->slot_bank.stake_account_keys.stake_accounts_root, &key );
    3226           0 :     if( stake_entry ) {
    3227           0 :       stake_entry->elem.exists = 1;
    3228           0 :     } else {
    3229           0 :       fd_stake_accounts_pair_t_mapnode_t * new_node = fd_stake_accounts_pair_t_map_acquire( slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool );
    3230           0 :       ulong size = fd_stake_accounts_pair_t_map_size( slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool, slot_ctx->slot_bank.stake_account_keys.stake_accounts_root );
    3231           0 :       FD_LOG_DEBUG(("Curr stake account size %lu %p", size, (void *)slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool));
    3232           0 :       if( new_node==NULL ) {
    3233           0 :         FD_LOG_ERR(("Stake accounts keys map full %lu", size));
    3234           0 :       }
    3235           0 :       new_node->elem.exists = 1;
    3236           0 :       fd_memcpy( new_node->elem.key.uc, stake_account->pubkey->uc, sizeof(fd_pubkey_t) );
    3237           0 :       fd_stake_accounts_pair_t_map_insert( slot_ctx->slot_bank.stake_account_keys.stake_accounts_pool, &slot_ctx->slot_bank.stake_account_keys.stake_accounts_root, new_node );
    3238           0 :     }
    3239           0 :   }
    3240           0 : }
    3241             : 
    3242           0 : void fd_store_stake_delegation( fd_exec_slot_ctx_t * slot_ctx, fd_borrowed_account_t * stake_account ) {
    3243           0 :   fd_pubkey_t const * owner = (fd_pubkey_t const *)stake_account->const_meta->info.owner;
    3244             : 
    3245           0 :   if( memcmp( owner->uc, fd_solana_stake_program_id.key, sizeof(fd_pubkey_t) ) ) {
    3246           0 :       return;
    3247           0 :   }
    3248             : 
    3249           0 :   int is_empty  = stake_account->const_meta->info.lamports==0;
    3250           0 :   int is_uninit = 1;
    3251           0 :   if( stake_account->const_meta->dlen>=4 ) {
    3252           0 :     uint prefix = FD_LOAD( uint, stake_account->const_data );
    3253           0 :     is_uninit = ( prefix==fd_stake_state_v2_enum_uninitialized );
    3254           0 :   }
    3255             : 
    3256           0 :   if( is_empty || is_uninit ) {
    3257           0 :     fd_stakes_remove_stake_delegation( slot_ctx, stake_account );
    3258           0 :   } else {
    3259           0 :     fd_stakes_upsert_stake_delegation( slot_ctx, stake_account );
    3260           0 :   }
    3261           0 : }

Generated by: LCOV version 1.14