LCOV - code coverage report
Current view: top level - flamenco/runtime/program - fd_native_cpi.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 69 74 93.2 %
Date: 2024-11-13 11:58:15 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #include "fd_native_cpi.h"
       2             : #include "../fd_account.h"
       3             : #include "../fd_executor.h"
       4             : #include "../../vm/syscall/fd_vm_syscall.h"
       5             : #include "../../../util/bits/fd_uwide.h"
       6             : 
       7             : int 
       8             : fd_native_cpi_execute_system_program_instruction( fd_exec_instr_ctx_t * ctx,
       9             :                                                   fd_system_program_instruction_t const * instr,
      10             :                                                   fd_vm_rust_account_meta_t const * acct_metas,
      11             :                                                   ulong acct_metas_len,
      12             :                                                   fd_pubkey_t const * signers,
      13         666 :                                                   ulong signers_cnt ) {
      14         666 :   fd_instr_info_t * instr_info = &ctx->txn_ctx->instr_infos[ ctx->txn_ctx->instr_info_cnt ];
      15         666 :   ctx->txn_ctx->instr_info_cnt++;
      16         666 :   if( FD_UNLIKELY( ctx->txn_ctx->instr_info_cnt>FD_MAX_INSTRUCTION_TRACE_LENGTH ) ) {
      17           0 :     return FD_EXECUTOR_INSTR_ERR_MAX_INSN_TRACE_LENS_EXCEEDED;
      18           0 :   }
      19             : 
      20         666 :   fd_instruction_account_t instruction_accounts[256];
      21         666 :   ulong instruction_accounts_cnt;
      22             : 
      23             :   /* fd_vm_prepare_instruction will handle missing/invalid account case */
      24         666 :   instr_info->program_id_pubkey = fd_solana_system_program_id;
      25         666 :   instr_info->program_id = UCHAR_MAX;
      26             : 
      27        4122 :   for( ulong i = 0UL; i < ctx->txn_ctx->accounts_cnt; i++ ) {
      28        3996 :     if( !memcmp( fd_solana_system_program_id.key, ctx->txn_ctx->accounts[i].key, sizeof(fd_pubkey_t) ) ) {
      29         540 :       instr_info->program_id = (uchar)i;
      30         540 :       break;
      31         540 :     }
      32        3996 :   }
      33             : 
      34             :   /* TODO: Lamport check may be redundant */
      35         666 :   ulong starting_lamports_h = 0;
      36         666 :   ulong starting_lamports_l = 0;
      37         666 :   uchar acc_idx_seen[256];
      38         666 :   memset( acc_idx_seen, 0, 256 );
      39             : 
      40         666 :   instr_info->acct_cnt = (ushort)acct_metas_len;
      41        2106 :   for ( ulong j = 0; j < acct_metas_len; j++ ) {
      42        1440 :     fd_vm_rust_account_meta_t const * acct_meta = &acct_metas[j];
      43             : 
      44        3039 :     for ( ulong k = 0; k < ctx->instr->acct_cnt; k++ ) {
      45        3039 :       if ( memcmp( acct_meta->pubkey, ctx->instr->acct_pubkeys[k].uc, sizeof(fd_pubkey_t) ) == 0 ) {
      46        1440 :         instr_info->acct_pubkeys[j] = ctx->instr->acct_pubkeys[k];
      47        1440 :         instr_info->acct_txn_idxs[j] = ctx->instr->acct_txn_idxs[k];
      48        1440 :         instr_info->acct_flags[j] = 0;
      49        1440 :         instr_info->borrowed_accounts[j] = ctx->instr->borrowed_accounts[k];
      50             : 
      51        1440 :         instr_info->is_duplicate[j] = acc_idx_seen[k];
      52        1440 :         if( FD_LIKELY( !acc_idx_seen[k] ) ) {
      53             :           /* This is the first time seeing this account */
      54        1419 :           acc_idx_seen[k] = 1;
      55        1419 :           if( instr_info->borrowed_accounts[j]->const_meta != NULL ) {
      56        1419 :             fd_uwide_inc( &starting_lamports_h, &starting_lamports_l, 
      57        1419 :                           starting_lamports_h, starting_lamports_l,
      58        1419 :                           instr_info->borrowed_accounts[j]->const_meta->info.lamports );
      59        1419 :           }
      60        1419 :         }
      61             : 
      62        1440 :         if( acct_meta->is_writable ) {
      63        1440 :           instr_info->acct_flags[j] |= FD_INSTR_ACCT_FLAGS_IS_WRITABLE;
      64        1440 :         }
      65        1440 :         if( acct_meta->is_signer ) {
      66         828 :           instr_info->acct_flags[j] |= FD_INSTR_ACCT_FLAGS_IS_SIGNER;
      67         828 :         }
      68        1440 :         break;
      69        1440 :       }
      70        3039 :     }
      71             : 
      72        1440 :     instr_info->starting_lamports_h = starting_lamports_h;
      73        1440 :     instr_info->starting_lamports_l = starting_lamports_l;
      74        1440 :   }
      75             : 
      76         666 :   fd_bincode_encode_ctx_t ctx2;
      77         666 :   uchar buf[4096UL]; // Size that is large enough for the instruction
      78         666 :   ctx2.data = buf;
      79         666 :   ctx2.dataend = (uchar*)ctx2.data + sizeof(buf);
      80         666 :   int err = fd_system_program_instruction_encode( instr, &ctx2 );
      81         666 :   if( err ) {
      82           0 :     FD_LOG_WARNING(( "Encode failed" ));
      83           0 :     return FD_EXECUTOR_INSTR_ERR_FATAL;
      84           0 :   }
      85             : 
      86         666 :   instr_info->data = buf;
      87         666 :   instr_info->data_sz = sizeof(buf);
      88         666 :   int exec_err = fd_vm_prepare_instruction( ctx->instr, instr_info, ctx, instruction_accounts,
      89         666 :                                             &instruction_accounts_cnt, signers, signers_cnt );
      90         666 :   if( exec_err != FD_EXECUTOR_INSTR_SUCCESS ) {
      91         180 :     FD_LOG_WARNING(("Preparing instruction failed"));
      92         180 :     return exec_err;
      93         180 :   }
      94             : 
      95         486 :   return fd_execute_instr( ctx->txn_ctx, instr_info );
      96         666 : }
      97             : 
      98             : void 
      99             : fd_native_cpi_create_account_meta( fd_pubkey_t const * key, uchar is_signer, 
     100        1416 :                                    uchar is_writable, fd_vm_rust_account_meta_t * meta ) {
     101        1416 :   meta->is_signer = is_signer;
     102        1416 :   meta->is_writable = is_writable;
     103        1416 :   fd_memcpy( meta->pubkey, key->key, sizeof(fd_pubkey_t) );
     104        1416 : }

Generated by: LCOV version 1.14