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: 2025-01-08 12:08:44 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         273 :                                                   ulong signers_cnt ) {
      14         273 :   fd_instr_info_t * instr_info = &ctx->txn_ctx->instr_infos[ ctx->txn_ctx->instr_info_cnt ];
      15         273 :   ctx->txn_ctx->instr_info_cnt++;
      16         273 :   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         273 :   fd_instruction_account_t instruction_accounts[256];
      21         273 :   ulong instruction_accounts_cnt;
      22             : 
      23             :   /* fd_vm_prepare_instruction will handle missing/invalid account case */
      24         273 :   instr_info->program_id_pubkey = fd_solana_system_program_id;
      25         273 :   instr_info->program_id = UCHAR_MAX;
      26             : 
      27        2013 :   for( ulong i = 0UL; i < ctx->txn_ctx->accounts_cnt; i++ ) {
      28        2013 :     if( !memcmp( fd_solana_system_program_id.key, ctx->txn_ctx->accounts[i].key, sizeof(fd_pubkey_t) ) ) {
      29         273 :       instr_info->program_id = (uchar)i;
      30         273 :       break;
      31         273 :     }
      32        2013 :   }
      33             : 
      34             :   /* TODO: Lamport check may be redundant */
      35         273 :   ulong starting_lamports_h = 0;
      36         273 :   ulong starting_lamports_l = 0;
      37         273 :   uchar acc_idx_seen[256];
      38         273 :   memset( acc_idx_seen, 0, 256 );
      39             : 
      40         273 :   instr_info->acct_cnt = (ushort)acct_metas_len;
      41         981 :   for ( ulong j = 0; j < acct_metas_len; j++ ) {
      42         708 :     fd_vm_rust_account_meta_t const * acct_meta = &acct_metas[j];
      43             : 
      44        1689 :     for ( ulong k = 0; k < ctx->instr->acct_cnt; k++ ) {
      45        1689 :       if ( memcmp( acct_meta->pubkey, ctx->instr->acct_pubkeys[k].uc, sizeof(fd_pubkey_t) ) == 0 ) {
      46         708 :         instr_info->acct_pubkeys[j] = ctx->instr->acct_pubkeys[k];
      47         708 :         instr_info->acct_txn_idxs[j] = ctx->instr->acct_txn_idxs[k];
      48         708 :         instr_info->acct_flags[j] = 0;
      49         708 :         instr_info->borrowed_accounts[j] = ctx->instr->borrowed_accounts[k];
      50             : 
      51         708 :         instr_info->is_duplicate[j] = acc_idx_seen[k];
      52         708 :         if( FD_LIKELY( !acc_idx_seen[k] ) ) {
      53             :           /* This is the first time seeing this account */
      54         708 :           acc_idx_seen[k] = 1;
      55         708 :           if( instr_info->borrowed_accounts[j]->const_meta != NULL ) {
      56         708 :             fd_uwide_inc( &starting_lamports_h, &starting_lamports_l, 
      57         708 :                           starting_lamports_h, starting_lamports_l,
      58         708 :                           instr_info->borrowed_accounts[j]->const_meta->info.lamports );
      59         708 :           }
      60         708 :         }
      61             : 
      62         708 :         if( acct_meta->is_writable ) {
      63         708 :           instr_info->acct_flags[j] |= FD_INSTR_ACCT_FLAGS_IS_WRITABLE;
      64         708 :         }
      65         708 :         if( acct_meta->is_signer ) {
      66         435 :           instr_info->acct_flags[j] |= FD_INSTR_ACCT_FLAGS_IS_SIGNER;
      67         435 :         }
      68         708 :         break;
      69         708 :       }
      70        1689 :     }
      71             : 
      72         708 :     instr_info->starting_lamports_h = starting_lamports_h;
      73         708 :     instr_info->starting_lamports_l = starting_lamports_l;
      74         708 :   }
      75             : 
      76         273 :   fd_bincode_encode_ctx_t ctx2;
      77         273 :   uchar buf[4096UL]; // Size that is large enough for the instruction
      78         273 :   ctx2.data = buf;
      79         273 :   ctx2.dataend = (uchar*)ctx2.data + sizeof(buf);
      80         273 :   int err = fd_system_program_instruction_encode( instr, &ctx2 );
      81         273 :   if( err ) {
      82           0 :     FD_LOG_WARNING(( "Encode failed" ));
      83           0 :     return FD_EXECUTOR_INSTR_ERR_FATAL;
      84           0 :   }
      85             : 
      86         273 :   instr_info->data = buf;
      87         273 :   instr_info->data_sz = sizeof(buf);
      88         273 :   int exec_err = fd_vm_prepare_instruction( ctx->instr, instr_info, ctx, instruction_accounts,
      89         273 :                                             &instruction_accounts_cnt, signers, signers_cnt );
      90         273 :   if( exec_err != FD_EXECUTOR_INSTR_SUCCESS ) {
      91           3 :     FD_LOG_WARNING(("Preparing instruction failed"));
      92           3 :     return exec_err;
      93           3 :   }
      94             : 
      95         270 :   return fd_execute_instr( ctx->txn_ctx, instr_info );
      96         273 : }
      97             : 
      98             : void 
      99             : fd_native_cpi_create_account_meta( fd_pubkey_t const * key, uchar is_signer, 
     100         708 :                                    uchar is_writable, fd_vm_rust_account_meta_t * meta ) {
     101         708 :   meta->is_signer = is_signer;
     102         708 :   meta->is_writable = is_writable;
     103         708 :   fd_memcpy( meta->pubkey, key->key, sizeof(fd_pubkey_t) );
     104         708 : }

Generated by: LCOV version 1.14