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

Generated by: LCOV version 1.14