Line data Source code
1 : #include "fd_instr_info.h" 2 : #include "../context/fd_exec_txn_ctx.h" 3 : #include "../../../util/bits/fd_uwide.h" 4 : 5 : void 6 : fd_instr_info_accumulate_starting_lamports( fd_instr_info_t * instr, 7 : fd_exec_txn_ctx_t const * txn_ctx, 8 : ushort idx_in_callee, 9 0 : ushort idx_in_txn ) { 10 0 : if( FD_LIKELY( !instr->is_duplicate[ idx_in_callee ] ) ) { 11 0 : fd_txn_account_t const * account = &txn_ctx->accounts[ idx_in_txn ]; 12 0 : if( account->vt->get_meta( account ) ) { 13 0 : fd_uwide_inc( 14 0 : &instr->starting_lamports_h, &instr->starting_lamports_l, 15 0 : instr->starting_lamports_h, instr->starting_lamports_l, 16 0 : account->vt->get_lamports( account ) ); 17 0 : } 18 0 : } 19 0 : } 20 : 21 : void 22 : fd_instr_info_init_from_txn_instr( fd_instr_info_t * instr, 23 : fd_exec_txn_ctx_t * txn_ctx, 24 0 : fd_txn_instr_t const * txn_instr ) { 25 : 26 0 : fd_txn_t const * txn_descriptor = txn_ctx->txn_descriptor; 27 0 : fd_rawtxn_b_t const * txn_raw = txn_ctx->_txn_raw; 28 0 : uchar * instr_acc_idxs = (uchar *)txn_raw->raw + txn_instr->acct_off; 29 : 30 0 : instr->program_id = txn_instr->program_id; 31 : 32 : /* See note in fd_instr_info.h. TLDR capping this value at 256 should have 33 : literally 0 effect on program execution, down to the error codes. This 34 : is purely for the sake of not increasing the overall memory footprint of the 35 : transaction context. If this change causes issues, we may need to increase 36 : the array sizes in the instr info. */ 37 0 : instr->acct_cnt = fd_ushort_min( txn_instr->acct_cnt, FD_INSTR_ACCT_MAX ); 38 0 : instr->data_sz = txn_instr->data_sz; 39 0 : instr->data = (uchar *)txn_raw->raw + txn_instr->data_off; 40 : 41 0 : uchar acc_idx_seen[ FD_INSTR_ACCT_MAX ]; 42 0 : memset(acc_idx_seen, 0, FD_INSTR_ACCT_MAX); 43 : 44 0 : for( ushort i=0; i<instr->acct_cnt; i++ ) { 45 0 : ushort acc_idx = instr_acc_idxs[i]; 46 : 47 0 : fd_instr_info_setup_instr_account( instr, 48 0 : acc_idx_seen, 49 0 : acc_idx, 50 0 : acc_idx, 51 0 : i, 52 0 : (uchar)fd_exec_txn_ctx_account_is_writable_idx( txn_ctx, instr_acc_idxs[i] ), 53 0 : (uchar)fd_txn_is_signer( txn_descriptor, instr_acc_idxs[i] ) ); 54 : 55 0 : } 56 0 : } 57 : 58 : int 59 : fd_instr_info_sum_account_lamports( fd_instr_info_t const * instr, 60 : fd_exec_txn_ctx_t * txn_ctx, 61 : ulong * total_lamports_h, 62 0 : ulong * total_lamports_l ) { 63 0 : *total_lamports_h = 0UL; 64 0 : *total_lamports_l = 0UL; 65 0 : for( ulong i=0UL; i<instr->acct_cnt; ++i ) { 66 0 : ushort idx_in_txn = instr->accounts[i].index_in_transaction; 67 0 : fd_txn_account_t const * account = &txn_ctx->accounts[ idx_in_txn ]; 68 : 69 0 : if( account->vt->get_meta( account ) == NULL || 70 0 : instr->is_duplicate[i] ) { 71 0 : continue; 72 0 : } 73 : 74 : /* Perform a checked add on a fd_uwide */ 75 0 : ulong tmp_total_lamports_h = 0UL; 76 0 : ulong tmp_total_lamports_l = 0UL; 77 : 78 0 : fd_uwide_inc( &tmp_total_lamports_h, &tmp_total_lamports_l, *total_lamports_h, *total_lamports_l, 79 0 : account->vt->get_lamports( account ) ); 80 : 81 0 : if( tmp_total_lamports_h < *total_lamports_h ) { 82 0 : return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW; 83 0 : } 84 : 85 0 : *total_lamports_h = tmp_total_lamports_h; 86 0 : *total_lamports_l = tmp_total_lamports_l; 87 0 : } 88 : 89 0 : return FD_EXECUTOR_INSTR_SUCCESS; 90 0 : }