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-03-31 06:22:16 Functions: 15 424 3.5 %

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

Generated by: LCOV version 1.14