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-01-23 05:02:40 Functions: 11 480 2.3 %

          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        5106 :                              uchar  is_signer ) {
      54        5106 :   fd_instruction_account_t acc = {
      55        5106 :     .index_in_transaction = idx_in_txn,
      56        5106 :     .index_in_caller      = idx_in_caller,
      57        5106 :     .index_in_callee      = idx_in_callee,
      58        5106 :     .is_writable          = is_writable,
      59        5106 :     .is_signer            = is_signer,
      60        5106 :   };
      61        5106 :   return acc;
      62        5106 : }
      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        4854 :                                    uchar             is_signer ) {
      72        4854 :   if( FD_LIKELY( idx_in_txn!=USHORT_MAX ) ) {
      73        4854 :     instr->is_duplicate[ idx_in_callee ] = acc_idx_seen[ idx_in_txn ];
      74             : 
      75        4854 :     if( FD_LIKELY( !acc_idx_seen[ idx_in_txn ] ) ) {
      76             :       /* This is the first time seeing this account */
      77          78 :       acc_idx_seen[ idx_in_txn ] = 1;
      78          78 :     }
      79        4854 :   }
      80             : 
      81        4854 :   instr->accounts[ idx_in_callee ] = fd_instruction_account_init( idx_in_txn,
      82        4854 :                                                                   idx_in_caller,
      83        4854 :                                                                   idx_in_callee,
      84        4854 :                                                                   is_writable,
      85        4854 :                                                                   is_signer );
      86        4854 : }
      87             : 
      88             : /* fd_instr_info_accumulate_starting_lamports accumulates the starting lamports fields
      89             :    when setting up an fd_instr_info_t object.
      90             :    Note that the caller must zero out the starting lamports fields in fd_instr_info_t
      91             :    beforehand. */
      92             : 
      93             : void
      94             : fd_instr_info_accumulate_starting_lamports( fd_instr_info_t * instr,
      95             :                                             fd_txn_out_t *    txn_out,
      96             :                                             ushort            idx_in_callee,
      97             :                                             ushort            idx_in_txn );
      98             : 
      99             : void
     100             : fd_instr_info_init_from_txn_instr( fd_instr_info_t *      instr,
     101             :                                    fd_bank_t *            bank,
     102             :                                    fd_txn_in_t const *    txn_in,
     103             :                                    fd_txn_out_t *         txn_out,
     104             :                                    fd_txn_instr_t const * txn_instr );
     105             : 
     106             : /* https://github.com/anza-xyz/solana-sdk/blob/589e6237f203c2719c300dc044f4e00f48e66a8f/message/src/versions/v0/loaded.rs#L152-L157 */
     107             : FD_FN_PURE static inline int
     108             : fd_instr_acc_is_writable_idx( fd_instr_info_t const * instr,
     109         930 :                               ushort                  idx ) {
     110         930 :   if( FD_UNLIKELY( idx>=instr->acct_cnt ) ) {
     111           0 :     return 0;
     112           0 :   }
     113             : 
     114         930 :   return !!(instr->accounts[idx].is_writable);
     115         930 : }
     116             : 
     117             : /* fd_instr_acc_is_signer_idx returns:
     118             :     - 1 if account is signer
     119             :     - 0 (with *out_opt_err==0) if account is not signer
     120             :   If an error occurs during query, returns 0 and writes the
     121             :   error code to *out_opt_err. Possible values for out_opt_err:
     122             :     - FD_EXECUTOR_INSTR_ERR_MISSING_ACC occurs when the instr account
     123             :       index provided is invalid (out of bounds).
     124             :     - 0 if the query was successful. Check the return value to see
     125             :       if the account is a signer.
     126             : 
     127             :   https://github.com/anza-xyz/agave/blob/v3.0.3/transaction-context/src/lib.rs#L770-L779    */
     128             : FD_FN_PURE static inline int
     129             : fd_instr_acc_is_signer_idx( fd_instr_info_t const * instr,
     130             :                             ushort                  idx,
     131         474 :                             int *                   out_opt_err ) {
     132         474 :   if( FD_UNLIKELY( idx>=instr->acct_cnt ) ) {
     133           0 :     if( out_opt_err ) *out_opt_err = FD_EXECUTOR_INSTR_ERR_MISSING_ACC;
     134           0 :     return 0;
     135           0 :   }
     136             : 
     137         474 :   if( out_opt_err ) *out_opt_err = 0;
     138         474 :   return !!(instr->accounts[idx].is_signer);
     139         474 : }
     140             : 
     141             : /* fd_instr_info_sum_account_lamports returns the sum of lamport account
     142             :    balances of all instruction accounts in the context.
     143             : 
     144             :    Aborts on integer overflow. */
     145             : 
     146             : int
     147             : fd_instr_info_sum_account_lamports( fd_instr_info_t const * instr,
     148             :                                     fd_txn_out_t *          txn_out,
     149             :                                     ulong *                 total_lamports_h,
     150             :                                     ulong *                 total_lamports_l );
     151             : 
     152             : FD_PROTOTYPES_END
     153             : 
     154             : #endif /* HEADER_fd_src_flamenco_runtime_info_fd_instr_info_h */

Generated by: LCOV version 1.14