LCOV - code coverage report
Current view: top level - flamenco/runtime/program - fd_address_lookup_table_program.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 687 0.0 %
Date: 2025-08-05 05:04:49 Functions: 0 13 0.0 %

          Line data    Source code
       1             : #include "fd_address_lookup_table_program.h"
       2             : #include "../fd_executor.h"
       3             : #include "../fd_pubkey_utils.h"
       4             : #include "../fd_borrowed_account.h"
       5             : #include "../sysvar/fd_sysvar_slot_hashes.h"
       6             : #include "../../vm/syscall/fd_vm_syscall.h"
       7             : #include "fd_native_cpi.h"
       8             : #include "../fd_runtime_err.h"
       9             : 
      10             : #include <string.h>
      11             : 
      12             : struct fd_addrlut {
      13             :   fd_address_lookup_table_state_t state;
      14             : 
      15             :   fd_pubkey_t const * addr;  /* points into account data */
      16             :   ulong               addr_cnt;
      17             : };
      18             : 
      19             : typedef struct fd_addrlut fd_addrlut_t;
      20             : 
      21           0 : #define FD_ADDRLUT_META_SZ       (56UL)
      22           0 : #define FD_ADDRLUT_MAX_ADDR_CNT (256UL)
      23             : #define DEFAULT_COMPUTE_UNITS   (750UL)
      24           0 : #define MAX_ENTRIES             FD_SYSVAR_SLOT_HASHES_CAP
      25             : 
      26             : static fd_addrlut_t *
      27           0 : fd_addrlut_new( void * mem ) {
      28             : 
      29           0 :   if( FD_UNLIKELY( !mem ) ) {
      30           0 :     FD_LOG_WARNING(( "NULL mem" ));
      31           0 :     return NULL;
      32           0 :   }
      33             : 
      34           0 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, alignof(fd_addrlut_t) ) ) ) {
      35           0 :     FD_LOG_WARNING(( "misaligned mem" ));
      36           0 :     return NULL;
      37           0 :   }
      38             : 
      39           0 :   return fd_type_pun( mem );
      40           0 : }
      41             : 
      42             : static int
      43             : fd_addrlut_deserialize( fd_addrlut_t * lut,
      44             :                         uchar const *  data,
      45           0 :                         ulong          data_sz ) {
      46             : 
      47           0 :   lut = fd_addrlut_new( lut ); FD_TEST( lut );
      48             : 
      49             :   /* We anticipate that we require no allocations to decode the address lookup
      50             :      table state size and that the data is already preallocated. */
      51           0 :   fd_bincode_decode_ctx_t decode = {
      52           0 :     .data    = data,
      53           0 :     .dataend = data+data_sz
      54           0 :   };
      55             : 
      56           0 :   ulong total_sz = 0UL;
      57           0 :   if( FD_UNLIKELY( fd_address_lookup_table_state_decode_footprint( &decode, &total_sz )!=FD_BINCODE_SUCCESS ) ) {
      58           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
      59           0 :   }
      60             : 
      61             :   /* NOTE: We technically don't need this check if we assume that the caller
      62             :      is correctly handling the memory that is passed into this function. */
      63           0 :   if( FD_UNLIKELY( total_sz!=sizeof(fd_address_lookup_table_state_t) ) ) {
      64           0 :     FD_LOG_ERR(( "Unexpected total size of address lookup table state" ));
      65           0 :   }
      66             : 
      67           0 :   fd_address_lookup_table_state_decode( &lut->state, &decode );
      68             : 
      69           0 :   if( lut->state.discriminant==fd_address_lookup_table_state_enum_uninitialized )
      70           0 :     return FD_EXECUTOR_INSTR_ERR_UNINITIALIZED_ACCOUNT;
      71           0 :   FD_TEST( lut->state.discriminant == fd_address_lookup_table_state_enum_lookup_table );
      72             : 
      73           0 :   if( data_sz < FD_ADDRLUT_META_SZ )
      74           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
      75             : 
      76           0 :   uchar const * raw_addr_data    = data   +FD_ADDRLUT_META_SZ;
      77           0 :   ulong         raw_addr_data_sz = data_sz-FD_ADDRLUT_META_SZ;
      78             : 
      79           0 :   if( !fd_ulong_is_aligned( raw_addr_data_sz, 32UL ) )
      80           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
      81             : 
      82           0 :   lut->addr     = fd_type_pun_const( raw_addr_data );
      83           0 :   lut->addr_cnt = raw_addr_data_sz / 32UL;
      84             : 
      85           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
      86           0 : }
      87             : 
      88             : static int
      89             : fd_addrlut_serialize_meta( fd_address_lookup_table_state_t const * state,
      90             :                            uchar * data,
      91           0 :                            ulong   data_sz ) {
      92             : 
      93             :   /* TODO can this ever get hit?  All code paths to this function seem
      94             :      to check account data size during deserialization. */
      95           0 :   if( FD_UNLIKELY( data_sz<FD_ADDRLUT_META_SZ ) )
      96           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_DATA;
      97             : 
      98           0 :   fd_bincode_encode_ctx_t encode =
      99           0 :     { .data    = data,
     100           0 :       .dataend = data+FD_ADDRLUT_META_SZ };
     101           0 :   fd_memset( data, 0, (ulong)encode.dataend - (ulong)encode.data );
     102             : 
     103           0 :   int bin_err = fd_address_lookup_table_state_encode( state, &encode );
     104           0 :   FD_TEST( !bin_err );
     105             : 
     106           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
     107           0 : }
     108             : 
     109             : static ulong
     110             : slot_hashes_position( fd_slot_hash_t const * hashes, /* deque */
     111           0 :                       ulong                  slot ) {
     112             :   /* Logic is copied from slice::binary_search_by() in Rust. While not fully optimized,
     113             :      it aims to achieve fuzzing conformance for both sorted and unsorted inputs.
     114             :      Returns the slot hash position of the input slot. */
     115           0 :   ulong size = deq_fd_slot_hash_t_cnt( hashes );
     116           0 :   if( FD_UNLIKELY( size==0UL ) ) return ULONG_MAX;
     117             : 
     118           0 :   ulong base = 0UL;
     119           0 :   while( size>1UL ) {
     120           0 :     ulong half = size / 2UL;
     121           0 :     ulong mid = base + half;
     122           0 :     ulong mid_slot = deq_fd_slot_hash_t_peek_index_const( hashes, mid )->slot;
     123           0 :     base = (slot>mid_slot) ? base : mid;
     124           0 :     size -= half;
     125           0 :   }
     126             : 
     127           0 :   return deq_fd_slot_hash_t_peek_index_const( hashes, base )->slot==slot ? base : ULONG_MAX;
     128           0 : }
     129             : 
     130             : /* https://github.com/anza-xyz/agave/blob/368ea563c423b0a85cc317891187e15c9a321521/sdk/program/src/address_lookup_table/state.rs#L81-L104 */
     131             : static uchar
     132             : fd_addrlut_status( fd_lookup_table_meta_t const * state,
     133             :                    ulong                          current_slot,
     134             :                    fd_slot_hash_t const *         slot_hashes, /* deque */
     135           0 :                    ulong *                        remaining_blocks ) {
     136             :   /* https://github.com/anza-xyz/agave/blob/368ea563c423b0a85cc317891187e15c9a321521/sdk/program/src/address_lookup_table/state.rs#L82-L83 */
     137           0 :   if( state->deactivation_slot==ULONG_MAX ) {
     138           0 :     return FD_ADDRLUT_STATUS_ACTIVATED;
     139           0 :   }
     140             : 
     141             :   /* https://github.com/anza-xyz/agave/blob/368ea563c423b0a85cc317891187e15c9a321521/sdk/program/src/address_lookup_table/state.rs#L84-L87 */
     142           0 :   if( state->deactivation_slot==current_slot ) {
     143           0 :     *remaining_blocks = MAX_ENTRIES + 1UL;
     144           0 :     return FD_ADDRLUT_STATUS_DEACTIVATING;
     145           0 :   }
     146             : 
     147             :   /* https://github.com/anza-xyz/agave/blob/368ea563c423b0a85cc317891187e15c9a321521/sdk/program/src/address_lookup_table/state.rs#L88-L100 */
     148           0 :   ulong slot_hash_position = slot_hashes_position( slot_hashes, state->deactivation_slot );
     149           0 :   if( slot_hash_position!=ULONG_MAX ) {
     150           0 :     *remaining_blocks = MAX_ENTRIES - slot_hash_position;
     151           0 :     return FD_ADDRLUT_STATUS_DEACTIVATING;
     152           0 :   }
     153             : 
     154             :   /* https://github.com/anza-xyz/agave/blob/368ea563c423b0a85cc317891187e15c9a321521/sdk/program/src/address_lookup_table/state.rs#L102 */
     155           0 :   return FD_ADDRLUT_STATUS_DEACTIVATED;
     156           0 : }
     157             : 
     158             : /* Note on uses of fd_borrowed_account_acquire_write_is_safe:
     159             : 
     160             :    In some places of this program, the Agave implementation acquires a
     161             :    "mutable borrow" on the account that is immediately dropped before
     162             :    any borrow can occur.  In other words, this borrow attempt only
     163             :    introduces a "borrow failed" error case into the protocol but
     164             :    otherwise introduces no side effects.  i.e.
     165             : 
     166             :      if not fd_borrowed_account_acquire_write():
     167             :        return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_FAILED
     168             :      ... read only operations ...
     169             :      fd_borrowed_account_release_write()
     170             :      ... arbitrary logic ...
     171             : 
     172             :    Is equivalent to
     173             : 
     174             :      if not fd_borrowed_account_acquire_write_is_safe():
     175             :        return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_FAILED
     176             :      ... read only operations ...
     177             :      ... arbitrary logic ... */
     178             : 
     179             : static int
     180             : create_lookup_table( fd_exec_instr_ctx_t *       ctx,
     181           0 :                      fd_addrlut_create_t const * create ) {
     182             : 
     183           0 : # define ACC_IDX_LUT       (0UL)
     184           0 : # define ACC_IDX_AUTHORITY (1UL)
     185           0 : # define ACC_IDX_PAYER     (2UL)
     186             : 
     187           0 :   int err;
     188             : 
     189           0 :   ulong               lut_lamports  = 0UL;
     190           0 :   fd_pubkey_t const * lut_key       = NULL;
     191           0 :   fd_pubkey_t const * lut_owner     = NULL;
     192           0 :   fd_pubkey_t const * authority_key = NULL;
     193           0 :   fd_pubkey_t const * payer_key     = NULL;
     194             : 
     195             :   /* Prepare LUT account **********************************************/
     196             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L59-L60 */
     197             :   /* try_borrow_instruction_account => get_index_of_instruction_account_in_transaction */
     198           0 :   fd_guarded_borrowed_account_t lut_acct;
     199           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_LUT, &lut_acct );
     200             : 
     201             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L60-L62 */
     202           0 :   lut_lamports = fd_borrowed_account_get_lamports( &lut_acct );
     203           0 :   lut_key      = lut_acct.acct->pubkey;
     204           0 :   lut_owner    = fd_borrowed_account_get_owner( &lut_acct );
     205             : 
     206             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L63-L70 */
     207           0 :   if( !FD_FEATURE_ACTIVE_BANK( ctx->txn_ctx->bank, relax_authority_signer_check_for_lookup_table_creation )
     208           0 :       && fd_borrowed_account_get_data_len( &lut_acct ) != 0UL ) {
     209           0 :     fd_log_collector_msg_literal( ctx, "Table account must not be allocated" );
     210           0 :     return FD_EXECUTOR_INSTR_ERR_ACC_ALREADY_INITIALIZED;
     211           0 :   }
     212             : 
     213             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L72 */
     214           0 :   fd_borrowed_account_drop( &lut_acct );
     215             : 
     216             :   /* Prepare authority account ****************************************/
     217             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L74-L75 */
     218             :   /* try_borrow_instruction_account => get_index_of_instruction_account_in_transaction */
     219           0 :   fd_guarded_borrowed_account_t authority_acct;
     220           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_AUTHORITY, &authority_acct );
     221             : 
     222             : 
     223             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L75 */
     224           0 :   authority_key = authority_acct.acct->pubkey;
     225             : 
     226             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L76-L83 */
     227           0 :   if( !FD_FEATURE_ACTIVE_BANK( ctx->txn_ctx->bank, relax_authority_signer_check_for_lookup_table_creation )
     228           0 :       && !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_AUTHORITY ) ) {
     229           0 :     fd_log_collector_msg_literal( ctx, "Authority account must be a signer" );
     230           0 :     return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     231           0 :   }
     232             : 
     233             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L85 */
     234           0 :   fd_borrowed_account_drop( &authority_acct );
     235             : 
     236             :   /* Prepare payer account ********************************************/
     237             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L87-L88 */
     238             :     /* try_borrow_account => get_index_of_instruction_account_in_transaction */
     239           0 :   fd_guarded_borrowed_account_t payer_acct;
     240           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_PAYER, &payer_acct );
     241             : 
     242           0 :   payer_key = payer_acct.acct->pubkey;
     243             : 
     244             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L89-L92 */
     245           0 :   if( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_PAYER ) ) {
     246           0 :     fd_log_collector_msg_literal( ctx, "Payer account must be a signer" );
     247           0 :     return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     248           0 :   }
     249             : 
     250             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L94 */
     251           0 :   fd_borrowed_account_drop( &payer_acct );
     252             : 
     253           0 :   ulong derivation_slot = 1UL;
     254             : 
     255           0 :   do {
     256           0 :     fd_slot_hash_t const * slot_hash = fd_sysvar_cache_slot_hashes_join_const( ctx->sysvar_cache );
     257           0 :     if( FD_UNLIKELY( !slot_hash ) ) {
     258           0 :       return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
     259           0 :     }
     260             : 
     261             :     /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L97 */
     262           0 :     ulong is_recent_slot = slot_hashes_position( slot_hash, create->recent_slot )!=ULONG_MAX;
     263           0 :     fd_sysvar_cache_slot_hashes_leave_const( ctx->sysvar_cache, slot_hash );
     264           0 :     if( FD_UNLIKELY( !is_recent_slot ) ) {
     265             :       /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L100-L105 */
     266             :       /* Max msg_sz: 24 - 3 + 20 = 41 < 127 => we can use printf */
     267           0 :       fd_log_collector_printf_dangerous_max_127( ctx, "%lu is not a recent slot", create->recent_slot );
     268           0 :       return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
     269           0 :     } else {
     270           0 :       derivation_slot = create->recent_slot;
     271           0 :     }
     272           0 :   } while(0);
     273             : 
     274             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L109-L118 */
     275           0 :   fd_pubkey_t derived_tbl_key[1];
     276           0 :   uchar *     seeds[2];
     277           0 :   ulong       seed_szs[2] = { sizeof(fd_pubkey_t), sizeof(ulong) };
     278           0 :   seeds[0] = (uchar *)authority_key;
     279           0 :   seeds[1] = (uchar *)&derivation_slot;
     280           0 :   err = fd_pubkey_derive_pda( &fd_solana_address_lookup_table_program_id, 2UL, seeds,
     281           0 :                                   seed_szs, (uchar*)&create->bump_seed, derived_tbl_key, &ctx->txn_ctx->custom_err );
     282           0 :   if( FD_UNLIKELY( err ) ) {
     283           0 :     return err;
     284           0 :   }
     285             : 
     286             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L120-L127 */
     287           0 :   if( FD_UNLIKELY( 0!=memcmp( lut_key->key, derived_tbl_key->key, sizeof(fd_pubkey_t) ) ) ) {
     288             :     /* Max msg_sz: 44 - 2 + 45 = 87 < 127 => we can use printf */
     289           0 :     fd_log_collector_printf_dangerous_max_127( ctx,
     290           0 :       "Table address must match derived address: %s", FD_BASE58_ENC_32_ALLOCA( derived_tbl_key ) );
     291           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
     292           0 :   }
     293             : 
     294             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L129-L135 */
     295           0 :   if( FD_FEATURE_ACTIVE_BANK( ctx->txn_ctx->bank, relax_authority_signer_check_for_lookup_table_creation )
     296           0 :       && 0==memcmp( lut_owner, fd_solana_address_lookup_table_program_id.key, sizeof(fd_pubkey_t) ) ) {
     297           0 :     return FD_EXECUTOR_INSTR_SUCCESS;
     298           0 :   }
     299             : 
     300             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L137-L142 */
     301             : 
     302           0 :   fd_rent_t const rent = fd_sysvar_cache_rent_read_nofail( ctx->sysvar_cache );
     303           0 :   ulong tbl_acct_data_len = 0x38UL;
     304           0 :   ulong required_lamports = fd_rent_exempt_minimum_balance( &rent, tbl_acct_data_len );
     305           0 :   /* */ required_lamports = fd_ulong_max( required_lamports, 1UL );
     306           0 :   /* */ required_lamports = fd_ulong_sat_sub( required_lamports, lut_lamports );
     307             : 
     308             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L144-L149 */
     309           0 :   if( required_lamports>0UL ) {
     310             :     // Create account metas
     311           0 :     FD_SPAD_FRAME_BEGIN( ctx->txn_ctx->spad ) {
     312           0 :       fd_vm_rust_account_meta_t * acct_metas = (fd_vm_rust_account_meta_t *)
     313           0 :                                                 fd_spad_alloc( ctx->txn_ctx->spad, FD_VM_RUST_ACCOUNT_META_ALIGN, 2 * sizeof(fd_vm_rust_account_meta_t) );
     314           0 :       fd_native_cpi_create_account_meta( payer_key, 1, 1, &acct_metas[0] );
     315           0 :       fd_native_cpi_create_account_meta( lut_key,   0, 1, &acct_metas[1] );
     316             : 
     317             :       // Create signers list
     318           0 :       fd_pubkey_t signers[16];
     319           0 :       ulong signers_cnt = 1;
     320           0 :       signers[0] = *payer_key;
     321             : 
     322             :       // Create system program instruction
     323           0 :       uchar instr_data[FD_TXN_MTU];
     324           0 :       fd_system_program_instruction_t instr = {
     325           0 :         .discriminant = fd_system_program_instruction_enum_transfer,
     326           0 :         .inner = {
     327           0 :           .transfer = required_lamports,
     328           0 :         }
     329           0 :       };
     330             : 
     331           0 :       fd_bincode_encode_ctx_t encode_ctx = {
     332           0 :         .data    = instr_data,
     333           0 :         .dataend = instr_data + FD_TXN_MTU
     334           0 :       };
     335             : 
     336             :       // This should never fail.
     337           0 :       int err = fd_system_program_instruction_encode( &instr, &encode_ctx );
     338           0 :       if( FD_UNLIKELY( err ) ) {
     339           0 :         return FD_EXECUTOR_INSTR_ERR_FATAL;
     340           0 :       }
     341             : 
     342           0 :       err = fd_native_cpi_native_invoke( ctx,
     343           0 :                                          &fd_solana_system_program_id,
     344           0 :                                          instr_data,
     345           0 :                                          FD_TXN_MTU,
     346           0 :                                          acct_metas,
     347           0 :                                          2UL,
     348           0 :                                          signers,
     349           0 :                                          signers_cnt );
     350           0 :       if( FD_UNLIKELY( err ) ) {
     351           0 :         return err;
     352           0 :       }
     353           0 :     } FD_SPAD_FRAME_END;
     354           0 :   }
     355             : 
     356           0 :   FD_SPAD_FRAME_BEGIN( ctx->txn_ctx->spad ) {
     357           0 :     fd_vm_rust_account_meta_t * acct_metas = ( fd_vm_rust_account_meta_t * )
     358           0 :                                               fd_spad_alloc( ctx->txn_ctx->spad, FD_VM_RUST_ACCOUNT_META_ALIGN, sizeof(fd_vm_rust_account_meta_t) );
     359           0 :     fd_native_cpi_create_account_meta( lut_key, 1, 1, &acct_metas[0] );
     360             : 
     361             :     // Create signers list
     362           0 :     fd_pubkey_t signers[16];
     363           0 :     ulong signers_cnt = 1;
     364           0 :     signers[0] = *lut_key;
     365             : 
     366             :     // Create system program allocate instruction
     367           0 :     uchar instr_data[FD_TXN_MTU];
     368           0 :     fd_system_program_instruction_t instr = {
     369           0 :       .discriminant = fd_system_program_instruction_enum_allocate,
     370           0 :       .inner = {
     371           0 :         .allocate = FD_LOOKUP_TABLE_META_SIZE,
     372           0 :       }
     373           0 :     };
     374             : 
     375           0 :     fd_bincode_encode_ctx_t encode_ctx = {
     376           0 :       .data    = instr_data,
     377           0 :       .dataend = instr_data + FD_TXN_MTU
     378           0 :     };
     379             : 
     380             :     // This should never fail.
     381           0 :     int err = fd_system_program_instruction_encode( &instr, &encode_ctx );
     382           0 :     if( FD_UNLIKELY( err ) ) {
     383           0 :       return FD_EXECUTOR_INSTR_ERR_FATAL;
     384           0 :     }
     385             : 
     386             :     // Execute allocate instruction
     387           0 :     err = fd_native_cpi_native_invoke( ctx,
     388           0 :                                        &fd_solana_system_program_id,
     389           0 :                                        instr_data,
     390           0 :                                        FD_TXN_MTU,
     391           0 :                                        acct_metas,
     392           0 :                                        1UL,
     393           0 :                                        signers,
     394           0 :                                        signers_cnt );
     395           0 :     if( FD_UNLIKELY( err ) ) {
     396           0 :       return err;
     397           0 :     }
     398             : 
     399             :     // Prepare system program assign instruction
     400           0 :     instr = (fd_system_program_instruction_t) {
     401           0 :       .discriminant = fd_system_program_instruction_enum_assign,
     402           0 :       .inner = {
     403           0 :         .assign = fd_solana_address_lookup_table_program_id,
     404           0 :       }
     405           0 :     };
     406             : 
     407           0 :     encode_ctx = (fd_bincode_encode_ctx_t) {
     408           0 :       .data    = instr_data,
     409           0 :       .dataend = instr_data + FD_TXN_MTU
     410           0 :     };
     411             : 
     412             :     // This should never fail.
     413           0 :     err = fd_system_program_instruction_encode( &instr, &encode_ctx );
     414           0 :     if( FD_UNLIKELY( err ) ) {
     415           0 :       return FD_EXECUTOR_INSTR_ERR_FATAL;
     416           0 :     }
     417             : 
     418             :     // Execute assign instruction
     419           0 :     err = fd_native_cpi_native_invoke( ctx,
     420           0 :                                        &fd_solana_system_program_id,
     421           0 :                                        instr_data,
     422           0 :                                        FD_TXN_MTU,
     423           0 :                                        acct_metas,
     424           0 :                                        1UL,
     425           0 :                                        signers,
     426           0 :                                        signers_cnt );
     427           0 :     if( FD_UNLIKELY( err ) ) {
     428           0 :       return err;
     429           0 :     }
     430           0 :   } FD_SPAD_FRAME_END;
     431             : 
     432             : 
     433             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L164-L165 */
     434           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_LUT, &lut_acct );
     435             : 
     436           0 :   fd_address_lookup_table_state_t state[1];
     437           0 :   fd_address_lookup_table_state_new( state );
     438           0 :   state->discriminant = fd_address_lookup_table_state_enum_lookup_table;
     439           0 :   fd_address_lookup_table_new( &state->inner.lookup_table );
     440           0 :   fd_memcpy( state->inner.lookup_table.meta.authority.key, authority_key->key, 32UL );
     441           0 :   state->inner.lookup_table.meta.has_authority = 1;
     442           0 :   state->inner.lookup_table.meta.deactivation_slot = ULONG_MAX;
     443             : 
     444           0 :   uchar * data = NULL;
     445           0 :   ulong   dlen = 0UL;
     446           0 :   err = fd_borrowed_account_get_data_mut( &lut_acct, &data, &dlen );
     447           0 :   if( FD_UNLIKELY( err ) ) {
     448           0 :     return err;
     449           0 :   }
     450             : 
     451           0 :   int state_err = fd_addrlut_serialize_meta( state, data, sizeof(fd_address_lookup_table_state_t) );
     452           0 :   if( FD_UNLIKELY( state_err ) ) { return state_err; }
     453             : 
     454             :   /* implicit drop of lut_acct */
     455             : 
     456           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
     457             : 
     458           0 : # undef ACC_IDX_LUT
     459           0 : # undef ACC_IDX_AUTHORITY
     460           0 : # undef ACC_IDX_PAYER
     461           0 : }
     462             : 
     463             : static int
     464           0 : freeze_lookup_table( fd_exec_instr_ctx_t * ctx ) {
     465             : 
     466           0 : # define ACC_IDX_LUT       (0UL)
     467           0 : # define ACC_IDX_AUTHORITY (1UL)
     468           0 :   int err;
     469             : 
     470             :   /* Prepare LUT account **********************************************/
     471             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L177-L178 */
     472             :   /* try_borrow_account => get_index_of_instruction_account_in_transaction */
     473           0 :   fd_guarded_borrowed_account_t lut_acct;
     474           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_LUT, &lut_acct );
     475             : 
     476             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L178-L181 */
     477           0 :   if( FD_UNLIKELY( 0!=memcmp( fd_borrowed_account_get_owner( &lut_acct ), fd_solana_address_lookup_table_program_id.key, sizeof(fd_pubkey_t) ) ) ) {
     478           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_OWNER;
     479           0 :   }
     480             : 
     481             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L182 */
     482           0 :   fd_borrowed_account_drop( &lut_acct );
     483             : 
     484             :   /* Prepare authority account ****************************************/
     485             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L184-L185 */
     486           0 :   fd_pubkey_t const * authority_key = NULL;
     487             :   /* try_borrow_account => get_index_of_instruction_account_in_transaction */
     488           0 :   fd_guarded_borrowed_account_t authority_acct;
     489           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_AUTHORITY, &authority_acct );
     490             : 
     491           0 :   authority_key = authority_acct.acct->pubkey;
     492             : 
     493             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L186-L189 */
     494           0 :   if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_AUTHORITY ) ) ) {
     495           0 :     fd_log_collector_msg_literal( ctx, "Authority account must be a signer" );
     496           0 :     return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     497           0 :   }
     498             : 
     499             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L191 */
     500           0 :   fd_borrowed_account_drop( &authority_acct );
     501             : 
     502             :   /* Update lookup table account **************************************/
     503             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L193-L194 */
     504           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_LUT, &lut_acct );
     505             : 
     506             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L194 */
     507           0 :   uchar const * lut_data    = fd_borrowed_account_get_data( &lut_acct );
     508           0 :   ulong         lut_data_sz = fd_borrowed_account_get_data_len( &lut_acct );
     509             : 
     510             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L195 */
     511           0 :   fd_addrlut_t lut[1];
     512           0 :   err = fd_addrlut_deserialize( lut, lut_data, lut_data_sz );
     513           0 :   if( FD_UNLIKELY( err ) ) {
     514           0 :     return err;
     515           0 :   }
     516             : 
     517           0 :   fd_address_lookup_table_t * state = &lut->state.inner.lookup_table;
     518             : 
     519             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L197-L200 */
     520           0 :   if( FD_UNLIKELY( !state->meta.has_authority ) ) {
     521           0 :     fd_log_collector_msg_literal( ctx, "Lookup table is already frozen");
     522           0 :     return FD_EXECUTOR_INSTR_ERR_ACC_IMMUTABLE;
     523           0 :   }
     524             : 
     525             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L201-L203 */
     526           0 :   if( FD_UNLIKELY( 0!=memcmp( state->meta.authority.key, authority_key->key, sizeof(fd_pubkey_t) ) ) ) {
     527           0 :     return FD_EXECUTOR_INSTR_ERR_INCORRECT_AUTHORITY;
     528           0 :   }
     529             : 
     530             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L204-L207 */
     531           0 :   if( FD_UNLIKELY( state->meta.deactivation_slot!=ULONG_MAX ) ) {
     532           0 :     fd_log_collector_msg_literal( ctx, "Deactivated tables cannot be frozen" );
     533           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
     534           0 :   }
     535             : 
     536             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L208-L211 */
     537           0 :   if( FD_UNLIKELY( !lut->addr_cnt ) ) {
     538           0 :     fd_log_collector_msg_literal( ctx, "Empty lookup tables cannot be frozen" );
     539           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
     540           0 :   }
     541             : 
     542           0 :   uchar *data = NULL;
     543           0 :   ulong dlen  = 0UL;
     544           0 :   err = fd_borrowed_account_get_data_mut( &lut_acct, &data, &dlen );
     545           0 :   if( FD_UNLIKELY( err ) ) {
     546           0 :     return err;
     547           0 :   }
     548             : 
     549             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L213-L218 */
     550           0 :   state->meta.has_authority = 0;
     551             : 
     552           0 :   err = fd_addrlut_serialize_meta( &lut->state, data, dlen );
     553           0 :   if( FD_UNLIKELY( err ) ) {
     554           0 :     return err;
     555           0 :   }
     556             : 
     557             :   /* implicit drop of lut_acct */
     558             : 
     559           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
     560           0 : # undef ACC_IDX_LUT
     561           0 : # undef ACC_IDX_AUTHORITY
     562           0 : }
     563             : 
     564             : static int
     565             : extend_lookup_table( fd_exec_instr_ctx_t *       ctx,
     566           0 :                      fd_addrlut_extend_t const * extend ) {
     567             : 
     568           0 : # define ACC_IDX_LUT       (0UL)
     569           0 : # define ACC_IDX_AUTHORITY (1UL)
     570           0 : # define ACC_IDX_PAYER     (2UL)
     571           0 :   int err;
     572             : 
     573             :   /* Prepare LUT account **********************************************/
     574             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L230-L236 */
     575           0 :   fd_pubkey_t const * lut_key = NULL;
     576             :   /* try_borrow_account => get_index_of_instruction_account_in_transaction */
     577             : 
     578             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L231-L232 */
     579           0 :   fd_guarded_borrowed_account_t lut_acct;
     580           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_LUT, &lut_acct );
     581             : 
     582           0 :   lut_key = lut_acct.acct->pubkey;
     583             : 
     584             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L233-235 */
     585           0 :   if( FD_UNLIKELY( 0!=memcmp( fd_borrowed_account_get_owner( &lut_acct ), fd_solana_address_lookup_table_program_id.key, sizeof(fd_pubkey_t) ) ) )
     586           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_OWNER;
     587             : 
     588             :     /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L237 */
     589           0 :   fd_borrowed_account_drop( &lut_acct );
     590             : 
     591             :   /* Prepare authority account ****************************************/
     592             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L238-L245 */
     593           0 :   fd_pubkey_t const * authority_key = NULL;
     594             :   /* try_borrow_account => get_index_of_instruction_account_in_transaction */
     595             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L239-L240 */
     596           0 :   fd_guarded_borrowed_account_t authority_acct;
     597           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_AUTHORITY, &authority_acct );
     598             : 
     599           0 :   authority_key = authority_acct.acct->pubkey;
     600             : 
     601             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L241-L244 */
     602           0 :   if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_AUTHORITY ) ) ) {
     603           0 :     fd_log_collector_msg_literal( ctx, "Authority account must be a signer" );
     604           0 :     return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     605           0 :   }
     606             : 
     607             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L246 */
     608           0 :   fd_borrowed_account_drop( &authority_acct );
     609             : 
     610           0 :   uchar const * lut_data          = NULL;
     611           0 :   ulong         lut_data_sz       = 0UL;
     612           0 :   ulong         lut_lamports      = 0UL;
     613           0 :   ulong         new_table_data_sz = 0UL;
     614             : 
     615             :   /* Update lookup table account **************************************/
     616             : 
     617             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L248-L249 */
     618           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_LUT, &lut_acct );
     619             : 
     620           0 :   lut_data     = fd_borrowed_account_get_data( &lut_acct );
     621           0 :   lut_data_sz  = fd_borrowed_account_get_data_len( &lut_acct );
     622           0 :   lut_lamports = fd_borrowed_account_get_lamports( &lut_acct );
     623             : 
     624             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L251 */
     625           0 :   fd_addrlut_t lut[1];
     626           0 :   err = fd_addrlut_deserialize( lut, (uchar *)lut_data, lut_data_sz );
     627           0 :   if( FD_UNLIKELY( err ) ) {
     628           0 :     return err;
     629           0 :   }
     630             : 
     631           0 :   fd_address_lookup_table_t * state = &lut->state.inner.lookup_table;
     632             : 
     633             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L253-L255 */
     634           0 :   if( FD_UNLIKELY( !state->meta.has_authority ) ) {
     635           0 :     return FD_EXECUTOR_INSTR_ERR_ACC_IMMUTABLE;
     636           0 :   }
     637             : 
     638             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L256-L258 */
     639           0 :   if( FD_UNLIKELY( 0!=memcmp( state->meta.authority.key, authority_key->key, sizeof(fd_pubkey_t) ) ) ) {
     640           0 :     return FD_EXECUTOR_INSTR_ERR_INCORRECT_AUTHORITY;
     641           0 :   }
     642             : 
     643             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L259-L262 */
     644           0 :   if( FD_UNLIKELY( state->meta.deactivation_slot != ULONG_MAX ) ) {
     645           0 :     fd_log_collector_msg_literal( ctx, "Deactivated tables cannot be extended" );
     646           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
     647           0 :   }
     648             : 
     649             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L263-L269 */
     650           0 :   if( FD_UNLIKELY( lut->addr_cnt >= FD_ADDRLUT_MAX_ADDR_CNT ) ) {
     651           0 :     fd_log_collector_msg_literal( ctx, "Lookup table is full and cannot contain more addresses" );
     652           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
     653           0 :   }
     654             : 
     655             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L271-L274 */
     656           0 :   if( FD_UNLIKELY( !extend->new_addrs_len ) ) {
     657           0 :     fd_log_collector_msg_literal( ctx, "Must extend with at least one address" );
     658           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
     659           0 :   }
     660             : 
     661             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L276-L279 */
     662           0 :   ulong old_addr_cnt = lut->addr_cnt;
     663           0 :   ulong new_addr_cnt = lut->addr_cnt + extend->new_addrs_len;
     664           0 :   if( FD_UNLIKELY( new_addr_cnt > FD_ADDRLUT_MAX_ADDR_CNT ) ) {
     665             :     /* Max msg_sz: 65 - 6 + 20*2 = 99 < 127 => we can use printf */
     666           0 :     fd_log_collector_printf_dangerous_max_127( ctx,
     667           0 :       "Extended lookup table length %lu would exceed max capacity of %lu", new_addr_cnt, FD_ADDRLUT_MAX_ADDR_CNT );
     668           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
     669           0 :   }
     670             : 
     671             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L290 */
     672           0 :   fd_sol_sysvar_clock_t clock_;
     673           0 :   fd_sol_sysvar_clock_t const * clock = fd_sysvar_cache_clock_read( ctx->sysvar_cache, &clock_ );
     674           0 :   if( FD_UNLIKELY( !clock ) ) {
     675           0 :     return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
     676           0 :   }
     677             : 
     678             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L291-L299 */
     679           0 :   if( clock->slot!=state->meta.last_extended_slot ) {
     680           0 :     state->meta.last_extended_slot             = clock->slot;
     681           0 :     state->meta.last_extended_slot_start_index = (uchar)lut->addr_cnt;
     682           0 :   }
     683             : 
     684             :   // https://github.com/anza-xyz/agave/blob/v2.0.1/programs/address-lookup-table/src/processor.rs#L302
     685           0 :   new_table_data_sz = FD_ADDRLUT_META_SZ + new_addr_cnt * sizeof(fd_pubkey_t);
     686             : 
     687             :   /* https://github.com/anza-xyz/agave/blob/v2.2.0/programs/address-lookup-table/src/processor.rs#L286 */
     688           0 :   uchar * lut_data_mut = NULL;
     689           0 :   ulong   lut_data_mut_len = 0;
     690           0 :   err = fd_borrowed_account_get_data_mut( &lut_acct, &lut_data_mut, &lut_data_mut_len );
     691           0 :   if( FD_UNLIKELY( err ) ) {
     692           0 :     return err;
     693           0 :   }
     694           0 :   lut_acct.acct->vt->resize( lut_acct.acct, new_table_data_sz );
     695             : 
     696             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L307-L310 */
     697           0 :   err = fd_addrlut_serialize_meta( &lut->state, lut_data_mut, lut_data_mut_len );
     698           0 :   if( FD_UNLIKELY( err ) ) {
     699           0 :     return err;
     700           0 :   }
     701             : 
     702             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L311-L313 */
     703           0 :   do {
     704           0 :     uchar * new_keys = lut_data_mut + FD_ADDRLUT_META_SZ + old_addr_cnt * sizeof(fd_pubkey_t);
     705           0 :     fd_memcpy( new_keys, extend->new_addrs, extend->new_addrs_len * sizeof(fd_pubkey_t) );
     706           0 :   } while(0);
     707           0 :   fd_borrowed_account_set_data_length( &lut_acct, new_table_data_sz );
     708           0 :   lut->addr            = (fd_pubkey_t *)(lut_data_mut + FD_ADDRLUT_META_SZ);
     709           0 :   lut->addr_cnt        = new_addr_cnt;
     710             : 
     711             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L316 */
     712           0 :   fd_borrowed_account_drop( &lut_acct );
     713             : 
     714             : 
     715             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L317-L321 */
     716           0 :   fd_rent_t rent[1] = { fd_sysvar_cache_rent_read_nofail( ctx->sysvar_cache ) };
     717           0 :   ulong required_lamports = fd_rent_exempt_minimum_balance( rent, new_table_data_sz );
     718           0 :   /* */ required_lamports = fd_ulong_max    ( required_lamports, 1UL );
     719           0 :   /* */ required_lamports = fd_ulong_sat_sub( required_lamports, lut_lamports );
     720             : 
     721           0 :   if( required_lamports ) {
     722           0 :     fd_pubkey_t const * payer_key = NULL;
     723             : 
     724             :     /* try_borrow_account => get_index_of_instruction_account_in_transaction */
     725             :     /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L325-L326 */
     726           0 :     fd_guarded_borrowed_account_t payer_acct;
     727           0 :     FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_PAYER, &payer_acct );
     728             : 
     729           0 :     payer_key = payer_acct.acct->pubkey;
     730             :     /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L327-L330 */
     731           0 :     if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_PAYER ) ) ) {
     732           0 :       fd_log_collector_msg_literal( ctx, "Payer account must be a signer" );
     733           0 :       return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     734           0 :     }
     735             : 
     736             :     /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L332 */
     737           0 :     fd_borrowed_account_drop( &payer_acct );
     738             : 
     739             : 
     740           0 :     FD_SPAD_FRAME_BEGIN( ctx->txn_ctx->spad ) {
     741             :       // Create account metas
     742           0 :       fd_vm_rust_account_meta_t * acct_metas = (fd_vm_rust_account_meta_t *)
     743           0 :                                                 fd_spad_alloc( ctx->txn_ctx->spad, FD_VM_RUST_ACCOUNT_META_ALIGN, 2 * sizeof(fd_vm_rust_account_meta_t) );
     744           0 :       fd_native_cpi_create_account_meta( payer_key, 1, 1, &acct_metas[0] );
     745           0 :       fd_native_cpi_create_account_meta( lut_key,   0, 1, &acct_metas[1] );
     746             : 
     747             :       // Create signers list
     748           0 :       fd_pubkey_t signers[16];
     749           0 :       ulong signers_cnt = 1UL;
     750           0 :       signers[0]        = *payer_key;
     751             : 
     752             :       // Create system program instruction
     753           0 :       uchar instr_data[FD_TXN_MTU];
     754           0 :       fd_system_program_instruction_t instr = {
     755           0 :         .discriminant = fd_system_program_instruction_enum_transfer,
     756           0 :         .inner = {
     757           0 :           .transfer = required_lamports,
     758           0 :         }
     759           0 :       };
     760             : 
     761           0 :       fd_bincode_encode_ctx_t encode_ctx = {
     762           0 :         .data    = instr_data,
     763           0 :         .dataend = instr_data + FD_TXN_MTU
     764           0 :       };
     765             : 
     766             :       // This should never fail.
     767           0 :       int err = fd_system_program_instruction_encode( &instr, &encode_ctx );
     768           0 :       if( FD_UNLIKELY( err ) ) {
     769           0 :         return FD_EXECUTOR_INSTR_ERR_FATAL;
     770           0 :       }
     771             : 
     772           0 :       err = fd_native_cpi_native_invoke( ctx,
     773           0 :                                          &fd_solana_system_program_id,
     774           0 :                                          instr_data,
     775           0 :                                          FD_TXN_MTU,
     776           0 :                                          acct_metas,
     777           0 :                                          2UL,
     778           0 :                                          signers,
     779           0 :                                          signers_cnt );
     780           0 :       if( FD_UNLIKELY( err ) ) {
     781           0 :         return err;
     782           0 :       }
     783           0 :     } FD_SPAD_FRAME_END;
     784           0 :   }
     785             : 
     786           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
     787             : 
     788           0 : # undef ACC_IDX_LUT
     789           0 : # undef ACC_IDX_AUTHORITY
     790           0 : # undef ACC_IDX_PAYER
     791           0 : }
     792             : 
     793             : static int
     794           0 : deactivate_lookup_table( fd_exec_instr_ctx_t * ctx ) {
     795             : 
     796           0 : # define ACC_IDX_LUT       (0UL)
     797           0 : # define ACC_IDX_AUTHORITY (1UL)
     798           0 :   int err;
     799             : 
     800             :   /* Prepare LUT account **********************************************/
     801             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L346-L351 */
     802             :   /* try_borrow_instruction_account => get_index_of_instruction_account_in_transaction */
     803             : 
     804             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L347-L348 */
     805           0 :   fd_guarded_borrowed_account_t lut_acct;
     806           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_LUT, &lut_acct );
     807             : 
     808             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L348-L350 */
     809           0 :   if( FD_UNLIKELY( 0!=memcmp( fd_borrowed_account_get_owner( &lut_acct ), fd_solana_address_lookup_table_program_id.key, sizeof(fd_pubkey_t) ) ) )
     810           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_OWNER;
     811             : 
     812             :     /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L352 */
     813           0 :   fd_borrowed_account_drop( &lut_acct );
     814             : 
     815             :   /* Prepare authority account ****************************************/
     816             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L353-L360 */
     817           0 :   fd_pubkey_t const * authority_key = NULL;
     818             :   /* try_borrow_account => get_index_of_instruction_account_in_transaction */
     819             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L354-L355 */
     820           0 :   fd_guarded_borrowed_account_t authority_acct;
     821           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_AUTHORITY, &authority_acct );
     822             : 
     823           0 :   authority_key = authority_acct.acct->pubkey;
     824             : 
     825             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L356-L359 */
     826           0 :   if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_AUTHORITY ) ) ) {
     827           0 :     fd_log_collector_msg_literal( ctx, "Authority account must be a signer" );
     828           0 :     return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     829           0 :   }
     830             : 
     831             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L361 */
     832           0 :   fd_borrowed_account_drop( &authority_acct );
     833             : 
     834             :   /* Update lookup table account **************************************/
     835             : 
     836             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L363-L364 */
     837           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_LUT, &lut_acct );
     838             : 
     839             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L364 */
     840           0 :   uchar const * lut_data    = fd_borrowed_account_get_data( &lut_acct );
     841           0 :   ulong         lut_data_sz = fd_borrowed_account_get_data_len( &lut_acct );
     842             : 
     843             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L365 */
     844           0 :   fd_addrlut_t lut[1];
     845           0 :   err = fd_addrlut_deserialize( lut, (uchar *)lut_data, lut_data_sz );
     846           0 :   if( FD_UNLIKELY( err ) ) {
     847           0 :     return err;
     848           0 :   }
     849             : 
     850           0 :   fd_address_lookup_table_t * state = &lut->state.inner.lookup_table;
     851             : 
     852             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L367-L370 */
     853           0 :   if( FD_UNLIKELY( !state->meta.has_authority ) ) {
     854           0 :     fd_log_collector_msg_literal( ctx, "Lookup table is frozen" );
     855           0 :     return FD_EXECUTOR_INSTR_ERR_ACC_IMMUTABLE;
     856           0 :   }
     857             : 
     858             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L371-L373 */
     859           0 :   if( FD_UNLIKELY( 0!=memcmp( state->meta.authority.key, authority_key->key, sizeof(fd_pubkey_t) ) ) ) {
     860           0 :     return FD_EXECUTOR_INSTR_ERR_INCORRECT_AUTHORITY;
     861           0 :   }
     862             : 
     863             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L374-L377 */
     864           0 :   if( FD_UNLIKELY( state->meta.deactivation_slot != ULONG_MAX ) ) {
     865           0 :     fd_log_collector_msg_literal( ctx, "Lookup table is already deactivated" );
     866           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
     867           0 :   }
     868             : 
     869             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L380 */
     870           0 :   fd_sol_sysvar_clock_t clock_;
     871           0 :   fd_sol_sysvar_clock_t const * clock = fd_sysvar_cache_clock_read( ctx->sysvar_cache, &clock_ );
     872           0 :   if( FD_UNLIKELY( !clock ) ) {
     873           0 :     return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
     874           0 :   }
     875             : 
     876           0 :   uchar * data = NULL;
     877           0 :   ulong   dlen = 0UL;
     878           0 :   err = fd_borrowed_account_get_data_mut ( &lut_acct, &data, &dlen );
     879           0 :   if( FD_UNLIKELY( err ) ) {
     880           0 :     return err;
     881           0 :   }
     882             : 
     883             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L381 */
     884           0 :   state->meta.deactivation_slot = clock->slot;
     885             : 
     886             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L383-L386 */
     887           0 :   err = fd_addrlut_serialize_meta( &lut->state, data, dlen );
     888           0 :   if( FD_UNLIKELY( err ) ) {
     889           0 :     return err;
     890           0 :   }
     891             : 
     892             :   /* implicit drop of lut_acct */
     893             : 
     894           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
     895             : 
     896           0 : # undef ACC_IDX_LUT
     897           0 : # undef ACC_IDX_AUTHORITY
     898           0 : }
     899             : 
     900             : static int
     901           0 : close_lookup_table( fd_exec_instr_ctx_t * ctx ) {
     902             : 
     903           0 : # define ACC_IDX_LUT       (0UL)
     904           0 : # define ACC_IDX_AUTHORITY (1UL)
     905           0 : # define ACC_IDX_RECIPIENT (2UL)
     906           0 :   int err;
     907             : 
     908             :   /* Prepare LUT account **********************************************/
     909             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L395-L400 */
     910             :   /* try_borrow_instruction_account => get_index_of_instruction_account_in_transaction */
     911             : 
     912             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L396-L397 */
     913           0 :   fd_guarded_borrowed_account_t lut_acct;
     914           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_LUT, &lut_acct );
     915             : 
     916             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L397-L399 */
     917           0 :   if( FD_UNLIKELY( 0!=memcmp( fd_borrowed_account_get_owner( &lut_acct ), fd_solana_address_lookup_table_program_id.key, sizeof(fd_pubkey_t) ) ) )
     918           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ACC_OWNER;
     919             : 
     920             :     /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L401 */
     921           0 :   fd_borrowed_account_drop( &lut_acct );
     922             : 
     923             :   /* Prepare authority account ****************************************/
     924             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L402-L409 */
     925           0 :   fd_pubkey_t const * authority_key = NULL;
     926             :   /* try_borrow_account => get_index_of_instruction_account_in_transaction */
     927             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L403-L404 */
     928           0 :   fd_guarded_borrowed_account_t authority_acct;
     929           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_AUTHORITY, &authority_acct );
     930             : 
     931           0 :   authority_key = authority_acct.acct->pubkey;
     932             : 
     933             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L405-L408 */
     934           0 :   if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, ACC_IDX_AUTHORITY ) ) ) {
     935           0 :     fd_log_collector_msg_literal( ctx, "Authority account must be a signer" );
     936           0 :     return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     937           0 :   }
     938             : 
     939             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L410 */
     940           0 :   fd_borrowed_account_drop( &authority_acct );
     941             : 
     942             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L411 */
     943           0 :   err = fd_exec_instr_ctx_check_num_insn_accounts( ctx, 3 );
     944           0 :   if( FD_UNLIKELY( err ) ) {
     945           0 :     return err;
     946           0 :   }
     947             : 
     948             :   /* It's ok to directly access the instruction accounts because we already verified 3 expected instruction accounts.
     949             :      https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L412-L420 */
     950           0 :   if( FD_UNLIKELY( ctx->instr->accounts[0].index_in_transaction ==
     951           0 :                    ctx->instr->accounts[2].index_in_transaction ) ) {
     952           0 :     fd_log_collector_msg_literal( ctx, "Lookup table cannot be the recipient of reclaimed lamports" );
     953           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
     954           0 :   }
     955             : 
     956           0 :   ulong         withdrawn_lamports = 0UL;
     957           0 :   uchar const * lut_data           = NULL;
     958           0 :   ulong         lut_data_sz        = 0UL;
     959             : 
     960             :   /* Update lookup table account **************************************/
     961             : 
     962             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L423-L424 */
     963           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_LUT, &lut_acct );
     964             : 
     965           0 :   withdrawn_lamports = fd_borrowed_account_get_lamports( &lut_acct );
     966           0 :   lut_data           = fd_borrowed_account_get_data( &lut_acct );
     967           0 :   lut_data_sz        = fd_borrowed_account_get_data_len( &lut_acct );
     968             : 
     969             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L426 */
     970           0 :   fd_addrlut_t lut[1];
     971           0 :   err = fd_addrlut_deserialize( lut, (uchar *)lut_data, lut_data_sz );
     972           0 :   if( FD_UNLIKELY( err ) ) {
     973           0 :     return err;
     974           0 :   }
     975             : 
     976           0 :   fd_address_lookup_table_t * state = &lut->state.inner.lookup_table;
     977             : 
     978             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L428-L431 */
     979           0 :   if( FD_UNLIKELY( !state->meta.has_authority ) ) {
     980           0 :     fd_log_collector_msg_literal( ctx,  "Lookup table is frozen" );
     981           0 :     return FD_EXECUTOR_INSTR_ERR_ACC_IMMUTABLE;
     982           0 :   }
     983             : 
     984             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L432-L434 */
     985           0 :   if( FD_UNLIKELY( 0!=memcmp( state->meta.authority.key, authority_key->key, sizeof(fd_pubkey_t) ) ) ) {
     986           0 :     return FD_EXECUTOR_INSTR_ERR_INCORRECT_AUTHORITY;
     987           0 :   }
     988             : 
     989             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L437 */
     990           0 :   fd_sol_sysvar_clock_t clock_;
     991           0 :   fd_sol_sysvar_clock_t * clock = fd_sysvar_cache_clock_read( ctx->sysvar_cache, &clock_ );
     992           0 :   if( FD_UNLIKELY( !clock ) ) {
     993           0 :     return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
     994           0 :   }
     995             : 
     996             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L438 */
     997           0 :   fd_slot_hash_t const * slot_hash = fd_sysvar_cache_slot_hashes_join_const( ctx->sysvar_cache );
     998           0 :   if( FD_UNLIKELY( !slot_hash ) ) {
     999           0 :     return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
    1000           0 :   }
    1001             : 
    1002             :   /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L440 */
    1003           0 :   ulong remaining_blocks = 0UL;
    1004           0 :   int status = fd_addrlut_status( &state->meta, clock->slot, slot_hash, &remaining_blocks );
    1005           0 :   fd_sysvar_cache_slot_hashes_leave_const( ctx->sysvar_cache, slot_hash );
    1006             : 
    1007           0 :   switch( status ) {
    1008           0 :     case FD_ADDRLUT_STATUS_ACTIVATED:
    1009           0 :       fd_log_collector_msg_literal( ctx, "Lookup table is not deactivated" );
    1010           0 :       return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
    1011           0 :     case FD_ADDRLUT_STATUS_DEACTIVATING:
    1012             :       /* Max msg_sz: 65 - 3 + 20 = 82 < 127 => we can use printf */
    1013           0 :       fd_log_collector_printf_dangerous_max_127( ctx,
    1014           0 :         "Table cannot be closed until it's fully deactivated in %lu blocks", remaining_blocks );
    1015           0 :       return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
    1016           0 :     case FD_ADDRLUT_STATUS_DEACTIVATED:
    1017           0 :       break;
    1018           0 :     default:
    1019           0 :       __builtin_unreachable();
    1020           0 :   }
    1021             : 
    1022             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L456 */
    1023           0 :   fd_borrowed_account_drop( &lut_acct );
    1024             : 
    1025             :   /* Add lamports to recipient ****************************************/
    1026             :   /* try_borrow_instruction_account => get_index_of_instruction_account_in_transaction */
    1027             : 
    1028             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L458-L459 */
    1029           0 :   fd_guarded_borrowed_account_t recipient_acct;
    1030           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_RECIPIENT, &recipient_acct );
    1031             : 
    1032           0 :   err = fd_borrowed_account_checked_add_lamports( &recipient_acct, withdrawn_lamports );
    1033           0 :   if( FD_UNLIKELY( err ) ) {
    1034           0 :     return err;
    1035           0 :   }
    1036             : 
    1037             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L461 */
    1038           0 :   fd_borrowed_account_drop( &recipient_acct );
    1039             : 
    1040             :   /* Delete LUT account ***********************************************/
    1041             : 
    1042             :   /* https://github.com/anza-xyz/agave/blob/v2.1.4/programs/address-lookup-table/src/processor.rs#L463-L464 */
    1043           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, ACC_IDX_LUT, &lut_acct );
    1044             : 
    1045           0 :   err = fd_borrowed_account_set_data_length( &lut_acct, 0UL );
    1046           0 :   if( FD_UNLIKELY( err ) ) {
    1047           0 :     return err;
    1048           0 :   }
    1049             : 
    1050           0 :   err = fd_borrowed_account_set_lamports( &lut_acct, 0UL );
    1051           0 :   if( FD_UNLIKELY( err ) ) {
    1052           0 :     return err;
    1053           0 :   }
    1054             : 
    1055           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
    1056             : 
    1057           0 : # undef ACC_IDX_LUT
    1058           0 : # undef ACC_IDX_AUTHORITY
    1059           0 : # undef ACC_IDX_RECIPIENT
    1060           0 : }
    1061             : 
    1062             : int
    1063           0 : fd_address_lookup_table_program_execute( fd_exec_instr_ctx_t * ctx ) {
    1064             :   /* Prevent execution of migrated native programs */
    1065           0 :   if( FD_UNLIKELY( FD_FEATURE_ACTIVE_BANK( ctx->txn_ctx->bank, migrate_address_lookup_table_program_to_core_bpf ) ) ) {
    1066           0 :     return FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_PROGRAM_ID;
    1067           0 :   }
    1068             : 
    1069           0 :   FD_EXEC_CU_UPDATE( ctx, DEFAULT_COMPUTE_UNITS );
    1070             : 
    1071           0 :   uchar const * instr_data    = ctx->instr->data;
    1072           0 :   ulong         instr_data_sz = ctx->instr->data_sz;
    1073           0 :   if( FD_UNLIKELY( instr_data==NULL ) ) {
    1074           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
    1075           0 :   }
    1076             : 
    1077           0 :   FD_SPAD_FRAME_BEGIN( ctx->txn_ctx->spad ) {
    1078             :     /* https://github.com/solana-labs/solana/blob/v1.17.4/programs/address-lookup-table/src/processor.rs#L28 */
    1079           0 :     ulong decoded_sz;
    1080           0 :     fd_addrlut_instruction_t * instr = fd_bincode_decode1_spad(
    1081           0 :         addrlut_instruction, ctx->txn_ctx->spad,
    1082           0 :         instr_data, instr_data_sz,
    1083           0 :         NULL,
    1084           0 :         &decoded_sz );
    1085           0 :     if( FD_UNLIKELY( !instr || decoded_sz > FD_TXN_MTU ) ) {
    1086           0 :       return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
    1087           0 :     }
    1088             : 
    1089           0 :     switch( instr->discriminant ) {
    1090           0 :     case fd_addrlut_instruction_enum_create_lut:
    1091           0 :       return create_lookup_table( ctx, &instr->inner.create_lut );
    1092           0 :     case fd_addrlut_instruction_enum_freeze_lut:
    1093           0 :       return freeze_lookup_table( ctx );
    1094           0 :     case fd_addrlut_instruction_enum_extend_lut:
    1095           0 :       return extend_lookup_table( ctx, &instr->inner.extend_lut );
    1096           0 :     case fd_addrlut_instruction_enum_deactivate_lut:
    1097           0 :       return deactivate_lookup_table( ctx );
    1098           0 :     case fd_addrlut_instruction_enum_close_lut:
    1099           0 :       return close_lookup_table( ctx );
    1100           0 :     default:
    1101           0 :       break;
    1102           0 :     }
    1103           0 :   } FD_SPAD_FRAME_END;
    1104             : 
    1105           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
    1106           0 : }
    1107             : 
    1108             : /**********************************************************************/
    1109             : /* Public API                                                         */
    1110             : /**********************************************************************/
    1111             : 
    1112             : /* https://github.com/anza-xyz/agave/blob/368ea563c423b0a85cc317891187e15c9a321521/sdk/program/src/address_lookup_table/state.rs#L72-L78 */
    1113             : static uchar
    1114             : is_active( fd_address_lookup_table_t const * self,
    1115             :            ulong                             current_slot,
    1116           0 :            fd_slot_hash_t const *            slot_hashes ) { /* deque */
    1117             :   /* https://github.com/anza-xyz/agave/blob/368ea563c423b0a85cc317891187e15c9a321521/sdk/program/src/address_lookup_table/state.rs#L73-L77 */
    1118           0 :   ulong _dummy[1];
    1119           0 :   switch( fd_addrlut_status( &self->meta, current_slot, slot_hashes, _dummy ) ) {
    1120           0 :     case FD_ADDRLUT_STATUS_ACTIVATED:
    1121           0 :     case FD_ADDRLUT_STATUS_DEACTIVATING:
    1122           0 :       return 1;
    1123           0 :     case FD_ADDRLUT_STATUS_DEACTIVATED:
    1124           0 :       return 0;
    1125           0 :     default:
    1126           0 :       __builtin_unreachable();
    1127           0 :   }
    1128           0 : }
    1129             : 
    1130             : /* Sets active_addresses_len on success
    1131             :    https://github.com/anza-xyz/agave/blob/368ea563c423b0a85cc317891187e15c9a321521/sdk/program/src/address_lookup_table/state.rs#L142-L164 */
    1132             : int
    1133             : fd_get_active_addresses_len( fd_address_lookup_table_t * self,
    1134             :                              ulong                       current_slot,
    1135             :                              fd_slot_hash_t const *      slot_hashes, /* deque */
    1136             :                              ulong                       addresses_len,
    1137           0 :                              ulong *                     active_addresses_len ) {
    1138             :   /* https://github.com/anza-xyz/agave/blob/368ea563c423b0a85cc317891187e15c9a321521/sdk/program/src/address_lookup_table/state.rs#L147-L152 */
    1139           0 :   if( FD_UNLIKELY( !is_active( self, current_slot, slot_hashes ) ) ) {
    1140           0 :     return FD_RUNTIME_TXN_ERR_ADDRESS_LOOKUP_TABLE_NOT_FOUND;
    1141           0 :   }
    1142             : 
    1143             :   /* https://github.com/anza-xyz/agave/blob/368ea563c423b0a85cc317891187e15c9a321521/sdk/program/src/address_lookup_table/state.rs#L157-L161 */
    1144           0 :   *active_addresses_len = ( current_slot > self->meta.last_extended_slot )
    1145           0 :       ? addresses_len
    1146           0 :       : self->meta.last_extended_slot_start_index;
    1147             : 
    1148           0 :   return FD_RUNTIME_EXECUTE_SUCCESS;
    1149           0 : }

Generated by: LCOV version 1.14