LCOV - code coverage report
Current view: top level - flamenco/runtime/info - fd_instr_info.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 47 0.0 %
Date: 2025-07-01 05:00:49 Functions: 0 490 0.0 %

          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_flamenco_base.h"
       5             : #include "../../types/fd_types.h"
       6             : #include "../fd_txn_account.h"
       7             : 
       8             : /* While the maximum number of instruction accounts allowed for instruction
       9             :    execution is 256, it is entirely possible to have a transaction with more
      10             :    than 256 instruction accounts that passes transaction loading checks and enters
      11             :    `fd_execute_instr` (See mainnet transaction
      12             :    3eDdfZE6HswPxFKrtnQPsEmTkyL1iP57gRPEXwaqNGAqF1paGXCYYMwh7z4uQDUMgFor742sikVSQZW1gFRDhPNh
      13             :    for an example). An instruction that goes into the VM with more than 256 instruction accounts
      14             :    will fail, but you could also theoretically invoke a native program with over 256 random
      15             :    unreferenced instruction accounts that will execute successfully. The true bound for the
      16             :    maximum number of instruction accounts you can pass in is slighly lower than the maximum
      17             :    possible size for a serialized transaction (1232).
      18             : 
      19             :    HOWEVER... to keep our memory footprint low, we cap the `acct_cnt` at 256 during setup since
      20             :    any extra accounts should (ideally) have literally 0 impact on program execution, whether
      21             :    or not they are present in the instr info. This keeps the transaction context size from
      22             :    blowing up to around 3MB in size. */
      23           0 : #define FD_INSTR_ACCT_MAX               (256)
      24           0 : #define FD_INSTR_ACCT_FLAGS_IS_SIGNER   (0x01U)
      25           0 : #define FD_INSTR_ACCT_FLAGS_IS_WRITABLE (0x02U)
      26             : 
      27             : struct fd_instruction_account {
      28             :   ushort index_in_transaction;
      29             :   ushort index_in_caller;
      30             :   ushort index_in_callee;
      31             :   uchar is_writable;
      32             :   uchar is_signer;
      33             : };
      34             : 
      35             : typedef struct fd_instruction_account fd_instruction_account_t;
      36             : 
      37             : struct fd_instr_info {
      38             :   uchar                    program_id;
      39             :   ushort                   data_sz;
      40             :   ushort                   acct_cnt;
      41             : 
      42             :   uchar *                  data;
      43             : 
      44             :   fd_instruction_account_t accounts[ FD_INSTR_ACCT_MAX ];
      45             :   uchar                    is_duplicate[ FD_INSTR_ACCT_MAX ];
      46             : 
      47             :   /* TODO: convert to fd_uwide_t representation of uint_128 */
      48             :   ulong                    starting_lamports_h;
      49             :   ulong                    starting_lamports_l;
      50             : };
      51             : 
      52             : typedef struct fd_instr_info fd_instr_info_t;
      53             : 
      54             : FD_PROTOTYPES_BEGIN
      55             : 
      56             : static inline fd_instruction_account_t
      57             : fd_instruction_account_init( ushort idx_in_txn,
      58             :                              ushort idx_in_caller,
      59             :                              ushort idx_in_callee,
      60             :                              uchar  is_writable,
      61           0 :                              uchar  is_signer ) {
      62           0 :   fd_instruction_account_t acc = {
      63           0 :     .index_in_transaction = idx_in_txn,
      64           0 :     .index_in_caller      = idx_in_caller,
      65           0 :     .index_in_callee      = idx_in_callee,
      66           0 :     .is_writable          = is_writable,
      67           0 :     .is_signer            = is_signer,
      68           0 :   };
      69           0 :   return acc;
      70           0 : }
      71             : 
      72             : static inline void
      73             : fd_instr_info_setup_instr_account( fd_instr_info_t * instr,
      74             :                                    uchar             acc_idx_seen[ FD_INSTR_ACCT_MAX ],
      75             :                                    ushort            idx_in_txn,
      76             :                                    ushort            idx_in_caller,
      77             :                                    ushort            idx_in_callee,
      78             :                                    uchar             is_writable,
      79           0 :                                    uchar             is_signer ) {
      80           0 :   if( FD_LIKELY( idx_in_txn!=USHORT_MAX ) ) {
      81           0 :     instr->is_duplicate[ idx_in_callee ] = acc_idx_seen[ idx_in_txn ];
      82             : 
      83           0 :     if( FD_LIKELY( !acc_idx_seen[ idx_in_txn ] ) ) {
      84             :       /* This is the first time seeing this account */
      85           0 :       acc_idx_seen[ idx_in_txn ] = 1;
      86           0 :     }
      87           0 :   }
      88             : 
      89           0 :   instr->accounts[ idx_in_callee ] = fd_instruction_account_init( idx_in_txn,
      90           0 :                                                                   idx_in_caller,
      91           0 :                                                                   idx_in_callee,
      92           0 :                                                                   is_writable,
      93           0 :                                                                   is_signer );
      94           0 : }
      95             : 
      96             : /* fd_instr_info_accumulate_starting_lamports accumulates the starting lamports fields
      97             :    when setting up an fd_instr_info_t object.
      98             :    Note that the caller must zero out the starting lamports fields in fd_instr_info_t
      99             :    beforehand. */
     100             : 
     101             : void
     102             : fd_instr_info_accumulate_starting_lamports( fd_instr_info_t *         instr,
     103             :                                             fd_exec_txn_ctx_t const * txn_ctx,
     104             :                                             ushort                    idx_in_callee,
     105             :                                             ushort                    idx_in_txn );
     106             : 
     107             : void
     108             : fd_instr_info_init_from_txn_instr( fd_instr_info_t *      instr,
     109             :                                    fd_exec_txn_ctx_t *    txn_ctx,
     110             :                                    fd_txn_instr_t const * txn_instr );
     111             : 
     112             : FD_FN_PURE static inline int
     113             : fd_instr_acc_is_writable_idx( fd_instr_info_t const * instr,
     114           0 :                               ushort                  idx ) {
     115           0 :   if( FD_UNLIKELY( idx>=instr->acct_cnt ) ) {
     116           0 :     return FD_EXECUTOR_INSTR_ERR_MISSING_ACC;
     117           0 :   }
     118             : 
     119           0 :   return !!(instr->accounts[idx].is_writable);
     120           0 : }
     121             : 
     122             : FD_FN_PURE static inline int
     123             : fd_instr_acc_is_signer_idx( fd_instr_info_t const * instr,
     124           0 :                             ushort                  idx ) {
     125           0 :   if( FD_UNLIKELY( idx>=instr->acct_cnt ) ) {
     126           0 :     return FD_EXECUTOR_INSTR_ERR_MISSING_ACC;
     127           0 :   }
     128             : 
     129           0 :   return !!(instr->accounts[idx].is_signer);
     130           0 : }
     131             : 
     132             : /* fd_instr_info_sum_account_lamports returns the sum of lamport account
     133             :    balances of all instruction accounts in the context.
     134             : 
     135             :    Aborts on integer overflow. */
     136             : 
     137             : int
     138             : fd_instr_info_sum_account_lamports( fd_instr_info_t const * instr,
     139             :                                     fd_exec_txn_ctx_t *     txn_ctx,
     140             :                                     ulong *                 total_lamports_h,
     141             :                                     ulong *                 total_lamports_l );
     142             : 
     143             : static inline uchar
     144             : fd_instr_get_acc_flags( fd_instr_info_t const * instr,
     145           0 :                         ushort                  idx ) {
     146           0 :   if( FD_UNLIKELY( idx>=instr->acct_cnt ) ) {
     147           0 :     return 0;
     148           0 :   }
     149             : 
     150           0 :   uchar flags = 0;
     151           0 :   if( instr->accounts[idx].is_signer )   flags |= FD_INSTR_ACCT_FLAGS_IS_SIGNER;
     152           0 :   if( instr->accounts[idx].is_writable ) flags |= FD_INSTR_ACCT_FLAGS_IS_WRITABLE;
     153             : 
     154           0 :   return flags;
     155           0 : }
     156             : 
     157             : FD_PROTOTYPES_END
     158             : 
     159             : #endif /* HEADER_fd_src_flamenco_runtime_info_fd_instr_info_h */

Generated by: LCOV version 1.14