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_borrowed_account.h" 7 : 8 : // TODO: rename to _MASK 9 444420 : #define FD_INSTR_ACCT_FLAGS_IS_SIGNER (0x01U) 10 300957 : #define FD_INSTR_ACCT_FLAGS_IS_WRITABLE (0x02U) 11 : 12 : #define FD_INSTR_ACCT_MAX (256) 13 : 14 : struct fd_instr_info { 15 : uchar program_id; 16 : ushort data_sz; 17 : ushort acct_cnt; 18 : 19 : uchar * data; 20 : fd_pubkey_t program_id_pubkey; 21 : 22 : uchar acct_txn_idxs[FD_INSTR_ACCT_MAX]; 23 : uchar acct_flags[FD_INSTR_ACCT_MAX]; 24 : fd_pubkey_t acct_pubkeys[FD_INSTR_ACCT_MAX]; 25 : uchar is_duplicate[FD_INSTR_ACCT_MAX]; 26 : 27 : /* Indexed by index in instruction, not by index in transaction. */ 28 : fd_borrowed_account_t * borrowed_accounts[FD_INSTR_ACCT_MAX]; 29 : 30 : /* fd_uwide representation of uint_128 */ 31 : ulong starting_lamports_h; 32 : ulong starting_lamports_l; 33 : }; 34 : 35 : typedef struct fd_instr_info fd_instr_info_t; 36 : 37 : FD_PROTOTYPES_BEGIN 38 : 39 : void 40 : fd_convert_txn_instr_to_instr( fd_exec_txn_ctx_t * txn_ctx, 41 : fd_txn_instr_t const * txn_instr, 42 : fd_borrowed_account_t * borrowed_accounts, 43 : fd_instr_info_t * instr ); 44 : 45 : FD_FN_PURE static inline int 46 : fd_instr_acc_is_writable_idx( fd_instr_info_t const * instr, 47 66057 : ulong idx ) { 48 66057 : return !!(instr->acct_flags[idx] & FD_INSTR_ACCT_FLAGS_IS_WRITABLE); 49 66057 : } 50 : 51 : static inline int 52 3261 : fd_instr_acc_is_writable(fd_instr_info_t const * instr, fd_pubkey_t const * acc) { 53 21504 : for( uchar i = 0; i < instr->acct_cnt; i++ ) { 54 21504 : if( memcmp( &instr->acct_pubkeys[i], acc, sizeof( fd_pubkey_t ) )==0 ) { 55 3261 : return fd_instr_acc_is_writable_idx( instr, i ); 56 3261 : } 57 21504 : } 58 : 59 0 : return 0; 60 3261 : } 61 : 62 : FD_FN_PURE static inline int 63 : fd_instr_acc_is_signer_idx( fd_instr_info_t const * instr, 64 206706 : ulong idx ) { 65 206706 : return !!(instr->acct_flags[idx] & FD_INSTR_ACCT_FLAGS_IS_SIGNER); 66 206706 : } 67 : 68 : static inline int 69 696 : fd_instr_acc_is_signer(fd_instr_info_t const * instr, fd_pubkey_t const * acc) { 70 1758 : for( uchar i = 0; i < instr->acct_cnt; i++ ) { 71 1758 : if( memcmp( &instr->acct_pubkeys[i], acc, sizeof( fd_pubkey_t ) )==0 ) { 72 696 : return fd_instr_acc_is_signer_idx( instr, i ); 73 696 : } 74 1758 : } 75 : 76 0 : return 0; 77 696 : } 78 : 79 : /* https://github.com/solana-labs/solana/blob/v1.17.23/programs/system/src/system_processor.rs#L35-L41 80 : 81 : fd_instr_any_signed matches 82 : solana_system_program::system_processor::Address::is_signer 83 : Scans instruction accounts for matching signer. 84 : 85 : Returns 1 if *any* instruction account with the given pubkey is a 86 : signer and 0 otherwise. Note that the same account/pubkey can be 87 : specified as multiple different instruction accounts that might not 88 : all have the signer bit. */ 89 : 90 : FD_FN_PURE int 91 : fd_instr_any_signed( fd_instr_info_t const * info, 92 : fd_pubkey_t const * pubkey ); 93 : 94 : /* fd_instr_info_sum_account_lamports returns the sum of lamport account 95 : balances of all instruction accounts in the context. 96 : 97 : Aborts on integer overflow. */ 98 : 99 : int 100 : fd_instr_info_sum_account_lamports( fd_instr_info_t const * instr, 101 : ulong * total_lamports_h, 102 : ulong * total_lamports_l ); 103 : 104 : static inline void 105 : fd_instr_get_signers( fd_instr_info_t const * self, 106 31044 : fd_pubkey_t const * signers[static FD_TXN_SIG_MAX] ) { 107 31044 : ulong j = 0UL; 108 199746 : for( uchar i = 0; i < self->acct_cnt && j < FD_TXN_SIG_MAX; i++ ) 109 168702 : if( fd_instr_acc_is_signer_idx( self, i ) ) 110 78765 : signers[j++] = &self->acct_pubkeys[i]; 111 31044 : } 112 : 113 : /* Loop conditions could be optimized to allow for unroll/vectorize */ 114 : 115 : static inline int 116 : fd_instr_signers_contains( fd_pubkey_t const * signers[FD_TXN_SIG_MAX], 117 12561 : fd_pubkey_t const * pubkey ) { 118 26208 : for( ulong i = 0; i < FD_TXN_SIG_MAX && signers[i]; i++ ) 119 20592 : if( 0==memcmp( signers[i], pubkey, sizeof( fd_pubkey_t ) ) ) return 1; 120 5616 : return 0; 121 12561 : } 122 : 123 : FD_PROTOTYPES_END 124 : 125 : #endif /* HEADER_fd_src_flamenco_runtime_info_fd_instr_info_h */