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 49 65.3 %
Date: 2026-09-17 04:28:31 Functions: 22 530 4.2 %

          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_TXN_INSTR_ACCT_MAX ];
      34             :   uchar                    is_duplicate[ FD_TXN_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_instr_info_t *
      49           0 : fd_instr_info_new( fd_instr_info_t * instr ) {
      50           0 :   if( FD_UNLIKELY( !instr ) ) return NULL;
      51             : 
      52           0 :   instr->program_id          = UCHAR_MAX;
      53           0 :   instr->acct_cnt            = 0U;
      54           0 :   instr->data_sz             = 0U;
      55           0 :   instr->stack_height        = 0U;
      56           0 :   instr->starting_lamports_h = 0UL;
      57           0 :   instr->starting_lamports_l = 0UL;
      58             : 
      59           0 :   return instr;
      60           0 : }
      61             : 
      62             : static inline fd_instruction_account_t
      63             : fd_instruction_account_init( ushort idx_in_txn,
      64             :                              ushort idx_in_caller,
      65             :                              ushort idx_in_callee,
      66             :                              uchar  is_writable,
      67       23955 :                              uchar  is_signer ) {
      68       23955 :   fd_instruction_account_t acc = {
      69       23955 :     .index_in_transaction = idx_in_txn,
      70       23955 :     .index_in_caller      = idx_in_caller,
      71       23955 :     .index_in_callee      = idx_in_callee,
      72       23955 :     .is_writable          = is_writable,
      73       23955 :     .is_signer            = is_signer,
      74       23955 :   };
      75       23955 :   return acc;
      76       23955 : }
      77             : 
      78             : static inline void
      79             : fd_instr_info_setup_instr_account( fd_instr_info_t * instr,
      80             :                                    uchar             acc_idx_seen[ FD_TXN_ACCT_ADDR_MAX ],
      81             :                                    ushort            idx_in_txn,
      82             :                                    ushort            idx_in_caller,
      83             :                                    ushort            idx_in_callee,
      84             :                                    uchar             is_writable,
      85       15297 :                                    uchar             is_signer ) {
      86       15297 :   if( FD_LIKELY( idx_in_txn!=USHORT_MAX ) ) {
      87       15297 :     instr->is_duplicate[ idx_in_callee ] = acc_idx_seen[ idx_in_txn ];
      88             : 
      89       15297 :     if( FD_LIKELY( !acc_idx_seen[ idx_in_txn ] ) ) {
      90             :       /* This is the first time seeing this account */
      91       13131 :       acc_idx_seen[ idx_in_txn ] = 1;
      92       13131 :     }
      93       15297 :   }
      94             : 
      95       15297 :   instr->accounts[ idx_in_callee ] = fd_instruction_account_init( idx_in_txn,
      96       15297 :                                                                   idx_in_caller,
      97       15297 :                                                                   idx_in_callee,
      98       15297 :                                                                   is_writable,
      99       15297 :                                                                   is_signer );
     100       15297 : }
     101             : 
     102             : void
     103             : fd_instr_info_init_from_txn_instr( fd_instr_info_t *      instr,
     104             :                                    fd_txn_in_t const *    txn_in,
     105             :                                    fd_txn_out_t *         txn_out,
     106             :                                    fd_txn_instr_t const * txn_instr );
     107             : 
     108             : /* https://github.com/anza-xyz/solana-sdk/blob/589e6237f203c2719c300dc044f4e00f48e66a8f/message/src/versions/v0/loaded.rs#L152-L157 */
     109             : FD_FN_PURE static inline int
     110             : fd_instr_acc_is_writable_idx( fd_instr_info_t const * instr,
     111       22383 :                               ushort                  idx ) {
     112       22383 :   if( FD_UNLIKELY( idx>=instr->acct_cnt ) ) {
     113           0 :     return 0;
     114           0 :   }
     115             : 
     116       22383 :   return !!(instr->accounts[idx].is_writable);
     117       22383 : }
     118             : 
     119             : /* fd_instr_acc_is_signer_idx returns:
     120             :     - 1 if account is signer
     121             :     - 0 (with *out_opt_err==0) if account is not signer
     122             :   If an error occurs during query, returns 0 and writes the
     123             :   error code to *out_opt_err. Possible values for out_opt_err:
     124             :     - FD_EXECUTOR_INSTR_ERR_MISSING_ACC occurs when the instr account
     125             :       index provided is invalid (out of bounds).
     126             :     - 0 if the query was successful. Check the return value to see
     127             :       if the account is a signer.
     128             : 
     129             :   https://github.com/anza-xyz/agave/blob/v3.0.3/transaction-context/src/lib.rs#L770-L779    */
     130             : static inline int
     131             : fd_instr_acc_is_signer_idx( fd_instr_info_t const * instr,
     132             :                             ushort                  idx,
     133        5112 :                             int *                   out_opt_err ) {
     134        5112 :   if( FD_UNLIKELY( idx>=instr->acct_cnt ) ) {
     135           0 :     if( out_opt_err ) *out_opt_err = FD_EXECUTOR_INSTR_ERR_MISSING_ACC;
     136           0 :     return 0;
     137           0 :   }
     138             : 
     139        5112 :   if( out_opt_err ) *out_opt_err = 0;
     140        5112 :   return !!(instr->accounts[idx].is_signer);
     141        5112 : }
     142             : 
     143             : /* fd_instr_info_sum_account_lamports calculates the sum of lamports
     144             :    account balances of all instruction accounts in the context,
     145             :    outputting the result in total_lamports_h and total_lamports_l.
     146             : 
     147             :    Returns FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW on arithmetic
     148             :    overflow, otherwise FD_EXECUTOR_INSTR_SUCCESS */
     149             : 
     150             : int
     151             : fd_instr_info_sum_account_lamports( fd_instr_info_t const * instr,
     152             :                                     fd_txn_out_t *          txn_out,
     153             :                                     ulong *                 total_lamports_h,
     154             :                                     ulong *                 total_lamports_l );
     155             : 
     156             : FD_PROTOTYPES_END
     157             : 
     158             : #endif /* HEADER_fd_src_flamenco_runtime_info_fd_instr_info_h */

Generated by: LCOV version 1.14