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 36 0.0 %
Date: 2025-03-20 12:08:36 Functions: 0 594 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             : // TODO: rename to _MASK
       8           0 : #define FD_INSTR_ACCT_FLAGS_IS_SIGNER   (0x01U)
       9           0 : #define FD_INSTR_ACCT_FLAGS_IS_WRITABLE (0x02U)
      10             : 
      11             : /* While the maximum number of instruction accounts allowed for instruction
      12             :    execution is 256, it is entirely possible to have a transaction with more
      13             :    than 256 instruction accounts that passes transaction loading checks and enters
      14             :    `fd_execute_instr` (See mainnet transaction
      15             :    3eDdfZE6HswPxFKrtnQPsEmTkyL1iP57gRPEXwaqNGAqF1paGXCYYMwh7z4uQDUMgFor742sikVSQZW1gFRDhPNh
      16             :    for an example). An instruction that goes into the VM with more than 256 instruction accounts
      17             :    will fail, but you could also theoretically invoke a native program with over 256 random
      18             :    unreferenced instruction accounts that will execute successfully. The true bound for the
      19             :    maximum number of instruction accounts you can pass in is slighly lower than the maximum
      20             :    possible size for a serialized transaction (1232).
      21             : 
      22             :    HOWEVER... to keep our memory footprint low, we cap the `acct_cnt` at 256 during setup since
      23             :    any extra accounts should (ideally) have literally 0 impact on program execution, whether
      24             :    or not they are present in the instr info. This keeps the transaction context size from
      25             :    blowing up to around 3MB in size. */
      26           0 : #define FD_INSTR_ACCT_MAX (256)
      27             : 
      28             : struct fd_instr_info {
      29             :   uchar               program_id;
      30             :   ushort              data_sz;
      31             :   ushort              acct_cnt;
      32             : 
      33             :   uchar *             data;
      34             :   fd_pubkey_t         program_id_pubkey;
      35             : 
      36             :   uchar               acct_txn_idxs[FD_INSTR_ACCT_MAX];
      37             :   uchar               acct_flags[FD_INSTR_ACCT_MAX];
      38             :   fd_pubkey_t         acct_pubkeys[FD_INSTR_ACCT_MAX];
      39             :   uchar               is_duplicate[FD_INSTR_ACCT_MAX];
      40             : 
      41             :   /* Indexed by index in instruction, not by index in transaction. */
      42             :   fd_txn_account_t *  accounts[FD_INSTR_ACCT_MAX];
      43             : 
      44             :   /* fd_uwide representation of uint_128 */
      45             :   ulong               starting_lamports_h;
      46             :   ulong               starting_lamports_l;
      47             : };
      48             : 
      49             : typedef struct fd_instr_info fd_instr_info_t;
      50             : 
      51             : FD_PROTOTYPES_BEGIN
      52             : 
      53             : void
      54             : fd_convert_txn_instr_to_instr( fd_exec_txn_ctx_t *     txn_ctx,
      55             :                                fd_txn_instr_t const *  txn_instr,
      56             :                                fd_txn_account_t *      accts,
      57             :                                fd_instr_info_t *       instr );
      58             : 
      59             : FD_FN_PURE static inline int
      60             : fd_instr_acc_is_writable_idx( fd_instr_info_t const * instr,
      61           0 :                               ulong                   idx ) {
      62           0 :   return !!(instr->acct_flags[idx] & FD_INSTR_ACCT_FLAGS_IS_WRITABLE);
      63           0 : }
      64             : 
      65             : static inline int
      66           0 : fd_instr_acc_is_writable(fd_instr_info_t const * instr, fd_pubkey_t const * acc) {
      67           0 :   for( uchar i = 0; i < instr->acct_cnt; i++ ) {
      68           0 :     if( memcmp( &instr->acct_pubkeys[i], acc, sizeof( fd_pubkey_t ) )==0 ) {
      69           0 :       return fd_instr_acc_is_writable_idx( instr, i );
      70           0 :     }
      71           0 :   }
      72             : 
      73           0 :   return 0;
      74           0 : }
      75             : 
      76             : FD_FN_PURE static inline int
      77             : fd_instr_acc_is_signer_idx( fd_instr_info_t const * instr,
      78           0 :                             ulong                   idx ) {
      79           0 :   return !!(instr->acct_flags[idx] & FD_INSTR_ACCT_FLAGS_IS_SIGNER);
      80           0 : }
      81             : 
      82             : static inline int
      83           0 : fd_instr_acc_is_signer(fd_instr_info_t const * instr, fd_pubkey_t const * acc) {
      84           0 :   for( uchar i = 0; i < instr->acct_cnt; i++ ) {
      85           0 :     if( memcmp( &instr->acct_pubkeys[i], acc, sizeof( fd_pubkey_t ) )==0 ) {
      86           0 :       return fd_instr_acc_is_signer_idx( instr, i );
      87           0 :     }
      88           0 :   }
      89             : 
      90           0 :   return 0;
      91           0 : }
      92             : 
      93             : /* https://github.com/solana-labs/solana/blob/v1.17.23/programs/system/src/system_processor.rs#L35-L41
      94             : 
      95             :    fd_instr_any_signed matches
      96             :    solana_system_program::system_processor::Address::is_signer
      97             :    Scans instruction accounts for matching signer.
      98             : 
      99             :    Returns 1 if *any* instruction account with the given pubkey is a
     100             :    signer and 0 otherwise.  Note that the same account/pubkey can be
     101             :    specified as multiple different instruction accounts that might not
     102             :    all have the signer bit. */
     103             : 
     104             : FD_FN_PURE int
     105             : fd_instr_any_signed( fd_instr_info_t const * info,
     106             :                      fd_pubkey_t const *     pubkey );
     107             : 
     108             : /* fd_instr_info_sum_account_lamports returns the sum of lamport account
     109             :    balances of all instruction accounts in the context.
     110             : 
     111             :    Aborts on integer overflow. */
     112             : 
     113             : int
     114             : fd_instr_info_sum_account_lamports( fd_instr_info_t const * instr,
     115             :                                     ulong *                 total_lamports_h,
     116             :                                     ulong *                 total_lamports_l );
     117             : 
     118             : static inline void
     119             : fd_instr_get_signers( fd_instr_info_t const * self,
     120           0 :                       fd_pubkey_t const *     signers[static FD_TXN_SIG_MAX] ) {
     121           0 :   ulong j = 0UL;
     122           0 :   for( uchar i = 0; i < self->acct_cnt && j < FD_TXN_SIG_MAX; i++ )
     123           0 :     if( fd_instr_acc_is_signer_idx( self, i ) )
     124           0 :       signers[j++] = &self->acct_pubkeys[i];
     125           0 : }
     126             : 
     127             : /* Loop conditions could be optimized to allow for unroll/vectorize */
     128             : 
     129             : static inline int
     130             : fd_instr_signers_contains( fd_pubkey_t const * signers[FD_TXN_SIG_MAX],
     131           0 :                            fd_pubkey_t const * pubkey ) {
     132           0 :   for( ulong i = 0; i < FD_TXN_SIG_MAX && signers[i]; i++ )
     133           0 :     if( 0==memcmp( signers[i], pubkey, sizeof( fd_pubkey_t ) ) ) return 1;
     134           0 :   return 0;
     135           0 : }
     136             : 
     137             : FD_PROTOTYPES_END
     138             : 
     139             : #endif /* HEADER_fd_src_flamenco_runtime_info_fd_instr_info_h */

Generated by: LCOV version 1.14