LCOV - code coverage report
Current view: top level - flamenco/runtime/info - fd_instr_info.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 32 39 82.1 %
Date: 2026-02-13 06:06:24 Functions: 15 440 3.4 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_runtime_info_fd_instr_info_h
       2             : #define HEADER_fd_src_flamenco_runtime_info_fd_instr_info_h
       3             : 
       4             : #include "../fd_executor_err.h"
       5             : #include "../fd_runtime_const.h"
       6             : #include "../../../ballet/txn/fd_txn.h"
       7             : 
       8           0 : #define FD_INSTR_ACCT_FLAGS_IS_SIGNER   (0x01U)
       9           0 : #define FD_INSTR_ACCT_FLAGS_IS_WRITABLE (0x02U)
      10             : 
      11             : /* The maximum possible size for the instruction data for any
      12             :    instruction, which is bounded by FD_RUNTIME_CPI_MAX_INSTR_DATA_LEN
      13             :    (which is 10KB). */
      14             : #define FD_INSTR_DATA_MAX FD_RUNTIME_CPI_MAX_INSTR_DATA_LEN
      15             : 
      16             : struct fd_instruction_account {
      17             :   ushort index_in_transaction;
      18             :   ushort index_in_caller;
      19             :   ushort index_in_callee;
      20             :   uchar is_writable;
      21             :   uchar is_signer;
      22             : };
      23             : 
      24             : typedef struct fd_instruction_account fd_instruction_account_t;
      25             : 
      26             : struct fd_instr_info {
      27             :   uchar                    program_id;
      28             :   ushort                   acct_cnt;
      29             : 
      30             :   uchar                    data[ FD_INSTR_DATA_MAX ];
      31             :   ushort                   data_sz;
      32             : 
      33             :   fd_instruction_account_t accounts[ FD_INSTR_ACCT_MAX ];
      34             :   uchar                    is_duplicate[ FD_INSTR_ACCT_MAX ];
      35             : 
      36             :   /* Stack height when this instruction was pushed onto the stack (including itself) */
      37             :   uchar stack_height;
      38             : 
      39             :   /* TODO: convert to fd_uwide_t representation of uint_128 */
      40             :   ulong                    starting_lamports_h;
      41             :   ulong                    starting_lamports_l;
      42             : };
      43             : 
      44             : typedef struct fd_instr_info fd_instr_info_t;
      45             : 
      46             : FD_PROTOTYPES_BEGIN
      47             : 
      48             : static inline fd_instruction_account_t
      49             : fd_instruction_account_init( ushort idx_in_txn,
      50             :                              ushort idx_in_caller,
      51             :                              ushort idx_in_callee,
      52             :                              uchar  is_writable,
      53        5262 :                              uchar  is_signer ) {
      54        5262 :   fd_instruction_account_t acc = {
      55        5262 :     .index_in_transaction = idx_in_txn,
      56        5262 :     .index_in_caller      = idx_in_caller,
      57        5262 :     .index_in_callee      = idx_in_callee,
      58        5262 :     .is_writable          = is_writable,
      59        5262 :     .is_signer            = is_signer,
      60        5262 :   };
      61        5262 :   return acc;
      62        5262 : }
      63             : 
      64             : static inline void
      65             : fd_instr_info_setup_instr_account( fd_instr_info_t * instr,
      66             :                                    uchar             acc_idx_seen[ FD_TXN_ACCT_ADDR_MAX ],
      67             :                                    ushort            idx_in_txn,
      68             :                                    ushort            idx_in_caller,
      69             :                                    ushort            idx_in_callee,
      70             :                                    uchar             is_writable,
      71        4968 :                                    uchar             is_signer ) {
      72        4968 :   if( FD_LIKELY( idx_in_txn!=USHORT_MAX ) ) {
      73        4968 :     instr->is_duplicate[ idx_in_callee ] = acc_idx_seen[ idx_in_txn ];
      74             : 
      75        4968 :     if( FD_LIKELY( !acc_idx_seen[ idx_in_txn ] ) ) {
      76             :       /* This is the first time seeing this account */
      77         192 :       acc_idx_seen[ idx_in_txn ] = 1;
      78         192 :     }
      79        4968 :   }
      80             : 
      81        4968 :   instr->accounts[ idx_in_callee ] = fd_instruction_account_init( idx_in_txn,
      82        4968 :                                                                   idx_in_caller,
      83        4968 :                                                                   idx_in_callee,
      84        4968 :                                                                   is_writable,
      85        4968 :                                                                   is_signer );
      86        4968 : }
      87             : 
      88             : void
      89             : fd_instr_info_init_from_txn_instr( fd_instr_info_t *      instr,
      90             :                                    fd_bank_t *            bank,
      91             :                                    fd_txn_in_t const *    txn_in,
      92             :                                    fd_txn_out_t *         txn_out,
      93             :                                    fd_txn_instr_t const * txn_instr );
      94             : 
      95             : /* https://github.com/anza-xyz/solana-sdk/blob/589e6237f203c2719c300dc044f4e00f48e66a8f/message/src/versions/v0/loaded.rs#L152-L157 */
      96             : FD_FN_PURE static inline int
      97             : fd_instr_acc_is_writable_idx( fd_instr_info_t const * instr,
      98        1065 :                               ushort                  idx ) {
      99        1065 :   if( FD_UNLIKELY( idx>=instr->acct_cnt ) ) {
     100           0 :     return 0;
     101           0 :   }
     102             : 
     103        1065 :   return !!(instr->accounts[idx].is_writable);
     104        1065 : }
     105             : 
     106             : /* fd_instr_acc_is_signer_idx returns:
     107             :     - 1 if account is signer
     108             :     - 0 (with *out_opt_err==0) if account is not signer
     109             :   If an error occurs during query, returns 0 and writes the
     110             :   error code to *out_opt_err. Possible values for out_opt_err:
     111             :     - FD_EXECUTOR_INSTR_ERR_MISSING_ACC occurs when the instr account
     112             :       index provided is invalid (out of bounds).
     113             :     - 0 if the query was successful. Check the return value to see
     114             :       if the account is a signer.
     115             : 
     116             :   https://github.com/anza-xyz/agave/blob/v3.0.3/transaction-context/src/lib.rs#L770-L779    */
     117             : static inline int
     118             : fd_instr_acc_is_signer_idx( fd_instr_info_t const * instr,
     119             :                             ushort                  idx,
     120         582 :                             int *                   out_opt_err ) {
     121         582 :   if( FD_UNLIKELY( idx>=instr->acct_cnt ) ) {
     122           0 :     if( out_opt_err ) *out_opt_err = FD_EXECUTOR_INSTR_ERR_MISSING_ACC;
     123           0 :     return 0;
     124           0 :   }
     125             : 
     126         582 :   if( out_opt_err ) *out_opt_err = 0;
     127         582 :   return !!(instr->accounts[idx].is_signer);
     128         582 : }
     129             : 
     130             : /* fd_instr_info_sum_account_lamports calculates the sum of lamports
     131             :    account balances of all instruction accounts in the context,
     132             :    outputting the result in total_lamports_h and total_lamports_l.
     133             : 
     134             :    Returns FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW on arithmetic
     135             :    overflow, otherwise FD_EXECUTOR_INSTR_SUCCESS */
     136             : 
     137             : int
     138             : fd_instr_info_sum_account_lamports( fd_instr_info_t const * instr,
     139             :                                     fd_txn_out_t *          txn_out,
     140             :                                     ulong *                 total_lamports_h,
     141             :                                     ulong *                 total_lamports_l );
     142             : 
     143             : FD_PROTOTYPES_END
     144             : 
     145             : #endif /* HEADER_fd_src_flamenco_runtime_info_fd_instr_info_h */

Generated by: LCOV version 1.14