LCOV - code coverage report
Current view: top level - flamenco/runtime/program - fd_system_program.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 340 0.0 %
Date: 2025-03-20 12:08:36 Functions: 0 16 0.0 %

          Line data    Source code
       1             : #include "../fd_executor.h"
       2             : #include "fd_system_program.h"
       3             : #include "../fd_acc_mgr.h"
       4             : #include "../fd_borrowed_account.h"
       5             : #include "../fd_system_ids.h"
       6             : #include "../fd_pubkey_utils.h"
       7             : #include "../sysvar/fd_sysvar_rent.h"
       8             : #include "../context/fd_exec_epoch_ctx.h"
       9             : #include "../context/fd_exec_slot_ctx.h"
      10             : #include "../context/fd_exec_txn_ctx.h"
      11             : 
      12             : /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L42-L68
      13             : 
      14             :    Partial port of system_processor::Address::create, only covering the
      15             :    case of the "seed" input actually existing.  Note that this doesn't
      16             :    "create" an address, but rather re-derives from PDA inputs and checks
      17             :    that the result matches some expected value. */
      18             : 
      19             : static int
      20             : verify_seed_address( fd_exec_instr_ctx_t * ctx,
      21             :                      fd_pubkey_t const *   expected,
      22             :                      fd_pubkey_t const *   base,
      23             :                      char const *          seed,
      24             :                      ulong                 seed_sz,
      25           0 :                      fd_pubkey_t const *   owner ) {
      26             : 
      27           0 :   fd_pubkey_t actual[1];
      28           0 :   do {
      29           0 :     int err = fd_pubkey_create_with_seed(
      30           0 :         ctx,
      31           0 :         base->uc,
      32           0 :         seed,
      33           0 :         seed_sz,
      34           0 :         owner->uc,
      35           0 :         actual->uc );
      36           0 :     if( FD_UNLIKELY( err ) ) return err;
      37           0 :   } while(0);
      38             : 
      39           0 :   if( FD_UNLIKELY( 0!=memcmp( actual->uc, expected->uc, sizeof(fd_pubkey_t) ) ) ) {
      40             :     /* Log msg_sz can be more or less than 127 bytes */
      41           0 :     fd_log_collector_printf_inefficient_max_512( ctx,
      42           0 :       "Create: address %s does not match derived address %s",
      43           0 :       FD_BASE58_ENC_32_ALLOCA( expected ),
      44           0 :       FD_BASE58_ENC_32_ALLOCA( actual ) );
      45           0 :     ctx->txn_ctx->custom_err = FD_SYSTEM_PROGRAM_ERR_ADDR_WITH_SEED_MISMATCH;
      46           0 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
      47           0 :   }
      48             : 
      49           0 :   return 0;
      50           0 : }
      51             : 
      52             : /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L183
      53             :    https://github.com/anza-xyz/agave/blob/v2.0.9/programs/system/src/system_processor.rs#L182
      54             : 
      55             :    Matches Solana Labs system_processor::transfer_verified */
      56             : 
      57             : static int
      58             : fd_system_program_transfer_verified( fd_exec_instr_ctx_t * ctx,
      59             :                                      ulong                 transfer_amount,
      60             :                                      ulong                 from_acct_idx,
      61           0 :                                      ulong                 to_acct_idx ) {
      62           0 :   int err;
      63             : 
      64             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L191-L192 */
      65             : 
      66           0 :   fd_guarded_borrowed_account_t from;
      67           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, from_acct_idx, &from );
      68             : 
      69             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L193-L196 */
      70             : 
      71           0 :   if( from.acct->const_meta->dlen != 0UL ) {
      72           0 :     fd_log_collector_msg_literal( ctx, "Transfer: `from` must not carry data" );
      73           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
      74           0 :   }
      75             : 
      76             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L197-L205 */
      77             : 
      78           0 :   if( transfer_amount > from.acct->const_meta->info.lamports ) {
      79             :     /* Max msg_sz: 45 - 6 + 20 + 20 = 79 < 127 => we can use printf */
      80           0 :     fd_log_collector_printf_dangerous_max_127( ctx, "Transfer: insufficient lamports %lu, need %lu", from.acct->const_meta->info.lamports, transfer_amount );
      81           0 :     ctx->txn_ctx->custom_err = FD_SYSTEM_PROGRAM_ERR_RESULT_WITH_NEGATIVE_LAMPORTS;
      82           0 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
      83           0 :   }
      84             : 
      85             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L207 */
      86             : 
      87           0 :   err = fd_borrowed_account_checked_sub_lamports( &from, transfer_amount );
      88             :   /* Note: this err can never happen because of the check above */
      89           0 :   if( FD_UNLIKELY( err ) ) return err;
      90             : 
      91             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L208 */
      92             : 
      93           0 :   fd_borrowed_account_drop( &from );
      94             : 
      95             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L209-L210 */
      96             : 
      97           0 :   fd_guarded_borrowed_account_t to;
      98           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, to_acct_idx, &to );
      99             : 
     100             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L211 */
     101             : 
     102           0 :   err = fd_borrowed_account_checked_add_lamports( &to, transfer_amount );
     103           0 :   if( FD_UNLIKELY( err ) ) return err;
     104             : 
     105           0 :   return 0;
     106           0 : }
     107             : 
     108             : /* https://github.com/anza-xyz/agave/blob/v2.0.9/programs/system/src/system_processor.rs#L214
     109             : 
     110             :    Matches system_processor::transfer */
     111             : 
     112             : static int
     113             : fd_system_program_transfer( fd_exec_instr_ctx_t * ctx,
     114             :                             ulong                 transfer_amount,
     115             :                             ulong                 from_acct_idx,
     116           0 :                             ulong                 to_acct_idx ) {
     117             : 
     118             :   /* https://github.com/anza-xyz/agave/blob/v2.0.9/programs/system/src/system_processor.rs#L222-L232 */
     119             : 
     120           0 :   if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, from_acct_idx ) ) ) {
     121             :     /* Max msg_sz: 37 - 2 + 45 = 80 < 127 => we can use printf */
     122           0 :     fd_log_collector_printf_dangerous_max_127( ctx,
     123           0 :       "Transfer: `from` account %s must sign", FD_BASE58_ENC_32_ALLOCA( &ctx->instr->acct_pubkeys[ from_acct_idx ] ) );
     124           0 :     return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     125           0 :   }
     126             : 
     127             :   /* https://github.com/anza-xyz/agave/blob/v2.0.9/programs/system/src/system_processor.rs#L234-L241 */
     128             : 
     129           0 :   return fd_system_program_transfer_verified( ctx, transfer_amount, from_acct_idx, to_acct_idx );
     130           0 : }
     131             : 
     132             : /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L71-L111
     133             :    https://github.com/anza-xyz/agave/blob/v2.0.9/programs/system/src/system_processor.rs#L70
     134             : 
     135             :    Based on Solana Labs system_processor::allocate() */
     136             : 
     137             : static int
     138             : fd_system_program_allocate( fd_exec_instr_ctx_t *   ctx,
     139             :                             fd_borrowed_account_t * account,
     140             :                             ulong                   space,
     141           0 :                             fd_pubkey_t const *     authority ) {
     142           0 :   int err;
     143             : 
     144             :   /* Assumes that acct_idx was bounds checked */
     145             : 
     146             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L78-L85 */
     147             : 
     148           0 :   if( FD_UNLIKELY( !fd_instr_any_signed( ctx->instr, authority ) ) ) {
     149             :     /* Max msg_sz: 35 - 2 + 45 = 78 < 127 => we can use printf */
     150           0 :     fd_log_collector_printf_dangerous_max_127( ctx,
     151           0 :       "Allocate: 'to' account %s must sign", FD_BASE58_ENC_32_ALLOCA( authority ) );
     152           0 :     return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     153           0 :   }
     154             : 
     155             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L87-L96 */
     156             : 
     157           0 :   if( FD_UNLIKELY( ( account->acct->const_meta->dlen != 0UL ) |
     158           0 :                    ( 0!=memcmp( account->acct->const_meta->info.owner, fd_solana_system_program_id.uc, 32UL ) ) ) ) {
     159             :     /* Max msg_sz: 35 - 2 + 45 = 78 < 127 => we can use printf */
     160           0 :     fd_log_collector_printf_dangerous_max_127( ctx,
     161           0 :       "Allocate: account %s already in use", FD_BASE58_ENC_32_ALLOCA( account->acct->pubkey ) );
     162           0 :     ctx->txn_ctx->custom_err = FD_SYSTEM_PROGRAM_ERR_ACCT_ALREADY_IN_USE;
     163           0 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     164           0 :   }
     165             : 
     166             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L98-L106 */
     167             : 
     168           0 :   if( FD_UNLIKELY( space > FD_ACC_SZ_MAX ) ) {
     169             :     /* Max msg_sz: 48 - 6 + 2*20 = 82 < 127 => we can use printf */
     170           0 :     fd_log_collector_printf_dangerous_max_127( ctx,
     171           0 :       "Allocate: requested %lu, max allowed %lu", space, FD_ACC_SZ_MAX );
     172           0 :     ctx->txn_ctx->custom_err = FD_SYSTEM_PROGRAM_ERR_INVALID_ACCT_DATA_LEN;
     173           0 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     174           0 :   }
     175             : 
     176             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L108 */
     177             : 
     178           0 :   err = fd_borrowed_account_set_data_length( account, space );
     179           0 :   if( FD_UNLIKELY( err ) ) {
     180           0 :     return err;
     181           0 :   }
     182             : 
     183           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
     184           0 : }
     185             : 
     186             : /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L113-L131
     187             :    https://github.com/anza-xyz/agave/blob/v2.0.9/programs/system/src/system_processor.rs#L112
     188             : 
     189             :    Based on Solana Labs system_processor::assign() */
     190             : 
     191             : static int
     192             : fd_system_program_assign( fd_exec_instr_ctx_t *   ctx,
     193             :                           fd_borrowed_account_t * account,
     194             :                           fd_pubkey_t const *     owner,
     195           0 :                           fd_pubkey_t const *     authority ) {
     196             :   /* Assumes addr_idx was bounds checked */
     197             : 
     198             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L121-L123 */
     199             : 
     200           0 :   if( 0==memcmp( account->acct->const_meta->info.owner, owner->uc, sizeof(fd_pubkey_t) ) )
     201           0 :     return 0;
     202             : 
     203             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L125-L128 */
     204             : 
     205           0 :   if( FD_UNLIKELY( !fd_instr_any_signed( ctx->instr, authority ) ) ) {
     206             :     /* Max msg_sz: 28 - 2 + 45 = 71 < 127 => we can use printf */
     207           0 :     fd_log_collector_printf_dangerous_max_127( ctx,
     208           0 :       "Assign: account %s must sign", FD_BASE58_ENC_32_ALLOCA( authority ) );
     209           0 :     return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     210           0 :   }
     211             : 
     212           0 :   return fd_borrowed_account_set_owner( account, owner );
     213           0 : }
     214             : 
     215             : /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L133-L143
     216             : 
     217             :    Based on Solana Labs system_processor::allocate_and_assign() */
     218             : 
     219             : static int
     220             : fd_system_program_allocate_and_assign( fd_exec_instr_ctx_t *   ctx,
     221             :                                        fd_borrowed_account_t * account,
     222             :                                        ulong                 space,
     223             :                                        fd_pubkey_t const *   owner,
     224           0 :                                        fd_pubkey_t const *   authority ) {
     225             : 
     226           0 :   do {
     227           0 :     int err = fd_system_program_allocate( ctx, account, space, authority );
     228           0 :     if( FD_UNLIKELY( err ) ) return err;
     229           0 :   } while(0);
     230           0 :   return fd_system_program_assign( ctx, account, owner, authority );
     231             : 
     232           0 : }
     233             : 
     234             : /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L146-L181
     235             :    https://github.com/anza-xyz/agave/blob/v2.0.9/programs/system/src/system_processor.rs#L145
     236             : 
     237             :    Matches Solana Labs system_processor::create_account() */
     238             : 
     239             : static int
     240             : fd_system_program_create_account( fd_exec_instr_ctx_t * ctx,
     241             :                                   ulong                 from_acct_idx,
     242             :                                   ulong                 to_acct_idx,
     243             :                                   ulong                 lamports,
     244             :                                   ulong                 space,
     245             :                                   fd_pubkey_t const *   owner,
     246           0 :                                   fd_pubkey_t const *   authority ) {
     247           0 :   int err;
     248             : 
     249             :   /* if it looks like the to account is already in use, bail
     250             :      https://github.com/anza-xyz/agave/blob/v2.1.14/programs/system/src/system_processor.rs#L159-L172 */
     251             : 
     252           0 :   do {
     253             :     /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L160-L161 */
     254             : 
     255           0 :     fd_guarded_borrowed_account_t to;
     256           0 :     FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, to_acct_idx, &to );
     257             : 
     258             :     /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L162-L169 */
     259             : 
     260           0 :     if( FD_UNLIKELY( to.acct->const_meta->info.lamports ) ) {
     261             :       /* Max msg_sz: 41 - 2 + 45 = 84 < 127 => we can use printf */
     262           0 :       fd_log_collector_printf_dangerous_max_127( ctx,
     263           0 :         "Create Account: account %s already in use", FD_BASE58_ENC_32_ALLOCA( to.acct->pubkey ) );
     264           0 :       ctx->txn_ctx->custom_err = FD_SYSTEM_PROGRAM_ERR_ACCT_ALREADY_IN_USE;
     265           0 :       return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     266           0 :     }
     267             : 
     268             :     /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L171 */
     269             : 
     270           0 :     err = fd_system_program_allocate_and_assign( ctx, &to, space, owner, authority );
     271           0 :     if( FD_UNLIKELY( err ) ) return err;
     272             : 
     273             :     /* Implicit drop
     274             :        https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L172 */
     275           0 :   } while (0);
     276             : 
     277             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L173-L180 */
     278             : 
     279           0 :   return fd_system_program_transfer( ctx, lamports, from_acct_idx, to_acct_idx );
     280           0 : }
     281             : 
     282             : /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L327-L352
     283             : 
     284             :    Matches Solana Labs system_processor SystemInstruction::CreateAccount { ... } => { ... } */
     285             : 
     286             : int
     287             : fd_system_program_exec_create_account( fd_exec_instr_ctx_t *                                  ctx,
     288           0 :                                        fd_system_program_instruction_create_account_t const * create_acc ) {
     289             : 
     290             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L332 */
     291             : 
     292           0 :   if( FD_UNLIKELY( ctx->instr->acct_cnt < 2 ) )
     293           0 :     return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
     294             : 
     295             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L333-L339
     296             :      Authorization check is lifted out from 'allocate' to here. */
     297             : 
     298           0 :   ulong const from_acct_idx    = 0UL;
     299           0 :   ulong const to_acct_idx      = 1UL;
     300           0 :   return fd_system_program_create_account(
     301           0 :       ctx,
     302           0 :       from_acct_idx,
     303           0 :       to_acct_idx,
     304           0 :       create_acc->lamports,
     305           0 :       create_acc->space,
     306           0 :       &create_acc->owner,
     307           0 :       &ctx->instr->acct_pubkeys[to_acct_idx] );
     308           0 : }
     309             : 
     310             : /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L381-L393
     311             : 
     312             :    Matches Solana Labs system_processor SystemInstruction::Assign { ... } => { ... } */
     313             : 
     314             : int
     315             : fd_system_program_exec_assign( fd_exec_instr_ctx_t * ctx,
     316           0 :                                fd_pubkey_t const *   owner ) {
     317           0 :   int err;
     318             : 
     319             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L382 */
     320             : 
     321           0 :   if( FD_UNLIKELY( ctx->instr->acct_cnt < 1 ) )
     322           0 :     return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
     323             : 
     324             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L383-L384 */
     325             : 
     326           0 :   fd_guarded_borrowed_account_t account;
     327           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, 0, &account );
     328             : 
     329             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L385-L391
     330             :      system_processor::Address::create eliminated (dead code) */
     331             : 
     332             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L392 */
     333             : 
     334           0 :   err = fd_system_program_assign( ctx, &account, owner, account.acct->pubkey );
     335           0 :   if( FD_UNLIKELY( err ) ) return err;
     336             : 
     337             :   /* Implicit drop */
     338             : 
     339           0 :   return 0;
     340           0 : }
     341             : 
     342             : /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L394-L404
     343             : 
     344             :    Matches Solana Labs system_processor SystemInstruction::Transfer { ... } => { ... } */
     345             : 
     346             : int
     347             : fd_system_program_exec_transfer( fd_exec_instr_ctx_t * ctx,
     348           0 :                                  ulong                 transfer_amount ) {
     349             : 
     350             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L395 */
     351             : 
     352           0 :   if( FD_UNLIKELY( ctx->instr->acct_cnt < 2 ) )
     353           0 :     return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
     354             : 
     355             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L396-L402 */
     356             : 
     357           0 :   return fd_system_program_transfer( ctx, transfer_amount, 0UL, 1UL );
     358           0 : }
     359             : 
     360             : /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L353
     361             : 
     362             :    Matches Solana Labs system_processor SystemInstruction::CreateAccountWithSeed { ... } => { ... } */
     363             : 
     364             : int
     365             : fd_system_program_exec_create_account_with_seed( fd_exec_instr_ctx_t *                                            ctx,
     366           0 :                                                  fd_system_program_instruction_create_account_with_seed_t const * args ) {
     367             : 
     368           0 :   fd_instr_info_t const * instr = ctx->instr;
     369             : 
     370             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L360 */
     371             : 
     372           0 :   if( FD_UNLIKELY( instr->acct_cnt < 2 ) )
     373           0 :     return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
     374             : 
     375             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L361-L367 */
     376             : 
     377           0 :   do {
     378           0 :     int err = verify_seed_address(
     379           0 :         ctx,
     380           0 :         &instr->acct_pubkeys[1],
     381           0 :         &args->base,
     382           0 :         (char const *)args->seed,
     383           0 :         args->seed_len,
     384           0 :         &args->owner );
     385           0 :     if( FD_UNLIKELY( err ) ) return err;
     386           0 :   } while(0);
     387             : 
     388             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L368-L379 */
     389             : 
     390           0 :   ulong const from_acct_idx    = 0UL;
     391           0 :   ulong const to_acct_idx      = 1UL;
     392           0 :   return fd_system_program_create_account(
     393           0 :       ctx,
     394           0 :       from_acct_idx,
     395           0 :       to_acct_idx,
     396           0 :       args->lamports,
     397           0 :       args->space,
     398           0 :       &args->owner,
     399           0 :       &args->base );
     400           0 : }
     401             : 
     402             : /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L504-L516
     403             : 
     404             :    Matches Solana Labs system_processor SystemInstruction::Allocate { ... } => { ... } */
     405             : 
     406             : int
     407             : fd_system_program_exec_allocate( fd_exec_instr_ctx_t * ctx,
     408           0 :                                  ulong                 space ) {
     409           0 :   int err;
     410             : 
     411             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L505 */
     412             : 
     413           0 :   if( FD_UNLIKELY( ctx->instr->acct_cnt < 1 ) )
     414           0 :     return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
     415             : 
     416             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L506-L507 */
     417           0 :   fd_guarded_borrowed_account_t account;
     418           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, 0, &account );
     419             : 
     420             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L508-L514
     421             :      system_processor::Address::create eliminated (dead code) */
     422             : 
     423             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L515
     424             :      Authorization check is lifted out from 'allocate' to here. */
     425             : 
     426           0 :   err = fd_system_program_allocate( ctx, &account, space, account.acct->pubkey );
     427           0 :   if( FD_UNLIKELY( err ) ) return err;
     428             : 
     429             :   /* Implicit drop */
     430             : 
     431           0 :   return 0;
     432           0 : }
     433             : 
     434             : /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L517-L541
     435             : 
     436             :    Matches Solana Labs system_processor SystemInstruction::AllocateWithSeed { ... } => { ... } */
     437             : 
     438             : int
     439             : fd_system_program_exec_allocate_with_seed( fd_exec_instr_ctx_t *                                      ctx,
     440           0 :                                            fd_system_program_instruction_allocate_with_seed_t const * args ) {
     441           0 :   int err;
     442             : 
     443             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L523 */
     444             : 
     445           0 :   if( FD_UNLIKELY( ctx->instr->acct_cnt < 1 ) )
     446           0 :     return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
     447             : 
     448             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#524-525 */
     449             : 
     450           0 :   fd_guarded_borrowed_account_t account;
     451           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, 0, &account );
     452             : 
     453             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L526-L532 */
     454             : 
     455           0 :   err = verify_seed_address(
     456           0 :     ctx,
     457           0 :     account.acct->pubkey,
     458           0 :     &args->base,
     459           0 :     (char const *)args->seed,
     460           0 :     args->seed_len,
     461           0 :     &args->owner );
     462           0 :   if( FD_UNLIKELY( err ) ) return err;
     463             : 
     464             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L533-L540
     465             :      Authorization check is lifted out from 'allocate' to here. */
     466             : 
     467           0 :   err = fd_system_program_allocate_and_assign(
     468           0 :     ctx,
     469           0 :     &account,
     470           0 :     args->space,
     471           0 :     &args->owner,
     472           0 :     &args->base );
     473           0 :   if( FD_UNLIKELY( err ) ) return err;
     474             : 
     475             :   /* Implicit drop */
     476             : 
     477           0 :   return 0;
     478           0 : }
     479             : 
     480             : /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L542-L554
     481             : 
     482             :    Matches Solana Labs system_processor SystemInstruction::AssignWithSeed { ... } => { ... } */
     483             : 
     484             : int
     485             : fd_system_program_exec_assign_with_seed( fd_exec_instr_ctx_t *                                    ctx,
     486           0 :                                          fd_system_program_instruction_assign_with_seed_t const * args ) {
     487           0 :   int err;
     488             : 
     489             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#543 */
     490             : 
     491           0 :   if( FD_UNLIKELY( ctx->instr->acct_cnt < 1 ) )
     492           0 :     return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
     493             : 
     494             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L544-L545 */
     495             : 
     496           0 :   fd_guarded_borrowed_account_t account;
     497           0 :   FD_TRY_BORROW_INSTR_ACCOUNT_DEFAULT_ERR_CHECK( ctx, 0, &account );
     498             : 
     499             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L546-L552 */
     500             : 
     501           0 :   err = verify_seed_address(
     502           0 :     ctx,
     503           0 :     account.acct->pubkey,
     504           0 :     &args->base,
     505           0 :     (char const *)args->seed,
     506           0 :     args->seed_len,
     507           0 :     &args->owner );
     508           0 :   if( FD_UNLIKELY( err ) ) return err;
     509             : 
     510             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L553
     511             :      Authorization check is lifted out from 'assign' to here. */
     512             : 
     513           0 :   err = fd_system_program_assign( ctx, &account, &args->owner, &args->base );
     514           0 :   if( FD_UNLIKELY( err ) ) return err;
     515             : 
     516             :   /* Implicit drop */
     517             : 
     518           0 :   return 0;
     519           0 : }
     520             : 
     521             : /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L405-L422
     522             : 
     523             :    Matches Solana Labs system_processor SystemInstruction::TransferWithSeed { ... } => { ... } */
     524             : 
     525             : int
     526             : fd_system_program_exec_transfer_with_seed( fd_exec_instr_ctx_t *                                      ctx,
     527           0 :                                            fd_system_program_instruction_transfer_with_seed_t const * args ) {
     528             : 
     529             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L410 */
     530             : 
     531           0 :   if( FD_UNLIKELY( ctx->instr->acct_cnt < 3 ) )
     532           0 :     return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
     533             : 
     534             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L411-L421
     535             :      Inlined call to system_processor::transfer_with_seed */
     536             : 
     537           0 :   ulong const from_idx      = 0UL;
     538           0 :   ulong const from_base_idx = 1UL;
     539           0 :   ulong const to_idx        = 2UL;
     540             : 
     541           0 :   if( FD_UNLIKELY( !fd_instr_acc_is_signer_idx( ctx->instr, from_base_idx ) ) ) {
     542             :     /* Max msg_sz: 37 - 2 + 45 = 80 < 127 => we can use printf */
     543           0 :     fd_log_collector_printf_dangerous_max_127( ctx,
     544           0 :       "Transfer: 'from' account %s must sign", FD_BASE58_ENC_32_ALLOCA( &ctx->instr->acct_pubkeys[ from_base_idx ] ) );
     545           0 :     return FD_EXECUTOR_INSTR_ERR_MISSING_REQUIRED_SIGNATURE;
     546           0 :   }
     547             : 
     548             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L283-L290 */
     549             : 
     550           0 :   fd_pubkey_t address_from_seed[1];
     551           0 :   do {
     552           0 :     int err = fd_pubkey_create_with_seed(
     553           0 :         ctx,
     554           0 :         ctx->instr->acct_pubkeys[ from_base_idx ].uc,
     555           0 :         (char const *)args->from_seed,
     556           0 :         args->from_seed_len,
     557           0 :         args->from_owner.uc,
     558           0 :         address_from_seed->uc );
     559           0 :     if( FD_UNLIKELY( err ) ) return err;
     560           0 :   } while(0);
     561             : 
     562             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L292-L303 */
     563             : 
     564           0 :   if( FD_UNLIKELY( 0!=memcmp( address_from_seed->uc,
     565           0 :                               ctx->instr->acct_pubkeys[ from_idx ].uc,
     566           0 :                               sizeof(fd_pubkey_t) ) ) ) {
     567             :     /* Log msg_sz can be more or less than 127 bytes */
     568           0 :     fd_log_collector_printf_inefficient_max_512( ctx,
     569           0 :       "Transfer: 'from' address %s does not match derived address %s",
     570           0 :       FD_BASE58_ENC_32_ALLOCA( &ctx->instr->acct_pubkeys[ from_idx ] ),
     571           0 :       FD_BASE58_ENC_32_ALLOCA( address_from_seed ) );
     572           0 :     ctx->txn_ctx->custom_err = FD_SYSTEM_PROGRAM_ERR_ADDR_WITH_SEED_MISMATCH;
     573           0 :     return FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR;
     574           0 :   }
     575             : 
     576             :   /* https://github.com/solana-labs/solana/blob/v1.17.22/programs/system/src/system_processor.rs#L305-L312 */
     577           0 :   return fd_system_program_transfer_verified( ctx, args->lamports, from_idx, to_idx );
     578           0 : }
     579             : 
     580             : int
     581           0 : fd_system_program_execute( fd_exec_instr_ctx_t * ctx ) {
     582           0 :   FD_EXEC_CU_UPDATE( ctx, 150UL );
     583             : 
     584             :   /* Deserialize the SystemInstruction enum */
     585           0 :   uchar * data = ctx->instr->data;
     586           0 :   if( FD_UNLIKELY( data==NULL ) ) {
     587           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
     588           0 :   }
     589             : 
     590           0 :   fd_bincode_decode_ctx_t decode = {
     591           0 :     .data    = data,
     592           0 :     .dataend = data + ctx->instr->data_sz
     593           0 :   };
     594             : 
     595           0 :   ulong total_sz   = 0UL;
     596           0 :   int   decode_err = fd_system_program_instruction_decode_footprint( &decode, &total_sz );
     597           0 :   if( FD_UNLIKELY( decode_err ) ) {
     598           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
     599           0 :   }
     600             : 
     601           0 :   uchar * mem = fd_spad_alloc( ctx->txn_ctx->spad, fd_system_program_instruction_align(), total_sz );
     602           0 :   if( FD_UNLIKELY( !mem ) ) {
     603           0 :     FD_LOG_ERR(( "Unable to allocate memory for system program instruction" ));
     604           0 :   }
     605             : 
     606           0 :   fd_system_program_instruction_t * instruction = fd_system_program_instruction_decode( mem, &decode );
     607             :   /* If the decoder consumes more than the TXN_MTU (1232) bytes, the transaction
     608             :      should fail. */
     609           0 :   if( FD_UNLIKELY( (ulong)data + FD_TXN_MTU < (ulong)decode.data ) ) {
     610           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_INSTR_DATA;
     611           0 :   }
     612             : 
     613           0 :   int result = FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
     614             : 
     615           0 :   switch( instruction->discriminant ) {
     616           0 :   case fd_system_program_instruction_enum_create_account: {
     617           0 :     result = fd_system_program_exec_create_account(
     618           0 :         ctx, &instruction->inner.create_account );
     619           0 :     break;
     620           0 :   }
     621           0 :   case fd_system_program_instruction_enum_assign: {
     622           0 :     result = fd_system_program_exec_assign(
     623           0 :         ctx, &instruction->inner.assign );
     624           0 :     break;
     625           0 :   }
     626           0 :   case fd_system_program_instruction_enum_transfer: {
     627           0 :     result = fd_system_program_exec_transfer(
     628           0 :         ctx, instruction->inner.transfer );
     629           0 :     break;
     630           0 :   }
     631           0 :   case fd_system_program_instruction_enum_create_account_with_seed: {
     632           0 :     result = fd_system_program_exec_create_account_with_seed(
     633           0 :         ctx, &instruction->inner.create_account_with_seed );
     634           0 :     break;
     635           0 :   }
     636           0 :   case fd_system_program_instruction_enum_advance_nonce_account: {
     637           0 :     result = fd_system_program_exec_advance_nonce_account( ctx );
     638           0 :     break;
     639           0 :   }
     640           0 :   case fd_system_program_instruction_enum_withdraw_nonce_account: {
     641           0 :     result = fd_system_program_exec_withdraw_nonce_account(
     642           0 :         ctx, instruction->inner.withdraw_nonce_account );
     643           0 :     break;
     644           0 :   }
     645           0 :   case fd_system_program_instruction_enum_initialize_nonce_account: {
     646           0 :     result = fd_system_program_exec_initialize_nonce_account(
     647           0 :         ctx, &instruction->inner.initialize_nonce_account );
     648           0 :     break;
     649           0 :   }
     650           0 :   case fd_system_program_instruction_enum_authorize_nonce_account: {
     651           0 :     result = fd_system_program_exec_authorize_nonce_account(
     652           0 :         ctx, &instruction->inner.authorize_nonce_account );
     653           0 :     break;
     654           0 :   }
     655           0 :   case fd_system_program_instruction_enum_allocate: {
     656           0 :     result = fd_system_program_exec_allocate( ctx, instruction->inner.allocate );
     657           0 :     break;
     658           0 :   }
     659           0 :   case fd_system_program_instruction_enum_allocate_with_seed: {
     660             :     // https://github.com/solana-labs/solana/blob/b00d18cec4011bb452e3fe87a3412a3f0146942e/runtime/src/system_instruction_processor.rs#L525
     661           0 :     result = fd_system_program_exec_allocate_with_seed(
     662           0 :         ctx, &instruction->inner.allocate_with_seed );
     663           0 :     break;
     664           0 :   }
     665           0 :   case fd_system_program_instruction_enum_assign_with_seed: {
     666             :     // https://github.com/solana-labs/solana/blob/b00d18cec4011bb452e3fe87a3412a3f0146942e/runtime/src/system_instruction_processor.rs#L545
     667           0 :     result = fd_system_program_exec_assign_with_seed(
     668           0 :         ctx, &instruction->inner.assign_with_seed );
     669           0 :     break;
     670           0 :   }
     671           0 :   case fd_system_program_instruction_enum_transfer_with_seed: {
     672             :     // https://github.com/solana-labs/solana/blob/b00d18cec4011bb452e3fe87a3412a3f0146942e/runtime/src/system_instruction_processor.rs#L412
     673           0 :     result = fd_system_program_exec_transfer_with_seed(
     674           0 :         ctx, &instruction->inner.transfer_with_seed );
     675           0 :     break;
     676           0 :   }
     677           0 :   case fd_system_program_instruction_enum_upgrade_nonce_account: {
     678             :     // https://github.com/solana-labs/solana/blob/b00d18cec4011bb452e3fe87a3412a3f0146942e/runtime/src/system_instruction_processor.rs#L491
     679           0 :     result = fd_system_program_exec_upgrade_nonce_account( ctx );
     680           0 :     break;
     681           0 :   }
     682           0 :   }
     683             : 
     684           0 :   return result;
     685           0 : }

Generated by: LCOV version 1.14