Line data Source code
1 : #include "fd_instr_info.h" 2 : #include "../fd_runtime.h" 3 : #include "../fd_runtime_helpers.h" 4 : #include "../../../disco/fd_txn_p.h" 5 : #include "../../../util/bits/fd_uwide.h" 6 : 7 : void 8 : fd_instr_info_init_from_txn_instr( fd_instr_info_t * instr, 9 : fd_txn_in_t const * txn_in, 10 : fd_txn_out_t * txn_out, 11 6574 : fd_txn_instr_t const * txn_instr ) { 12 : 13 6574 : fd_txn_t const * txn_descriptor = TXN( txn_in->txn ); 14 6574 : uchar * instr_acc_idxs = (uchar *)txn_in->txn->payload + txn_instr->acct_off; 15 : 16 : /* Set the stack height to 1 (since this is a top-level instruction) */ 17 6574 : instr->stack_height = 1; 18 : 19 : /* Set the program id */ 20 6574 : instr->program_id = txn_instr->program_id; 21 6574 : instr->acct_cnt = txn_instr->acct_cnt; 22 6574 : if( FD_UNLIKELY( instr->acct_cnt > FD_TXN_INSTR_ACCT_MAX ) ) { 23 0 : FD_LOG_CRIT(( "invariant violation: Instruction has too many accounts: %d > %lu", instr->acct_cnt, FD_TXN_INSTR_ACCT_MAX )); 24 0 : } 25 6574 : instr->data_sz = txn_instr->data_sz; 26 6574 : memcpy( instr->data, txn_in->txn->payload+txn_instr->data_off, instr->data_sz ); 27 : 28 6574 : uchar acc_idx_seen[ FD_TXN_ACCT_ADDR_MAX ] = {0}; 29 : 30 25598 : for( ushort i=0; i<instr->acct_cnt; i++ ) { 31 19024 : ushort acc_idx = instr_acc_idxs[i]; 32 : 33 19024 : fd_instr_info_setup_instr_account( instr, 34 19024 : acc_idx_seen, 35 19024 : acc_idx, 36 19024 : acc_idx, 37 19024 : i, 38 19024 : (uchar)fd_runtime_account_is_writable_idx( txn_in, txn_out, instr_acc_idxs[i] ), 39 19024 : (uchar)fd_txn_is_signer( txn_descriptor, instr_acc_idxs[i] ) ); 40 : 41 19024 : } 42 6574 : } 43 : 44 : int 45 : fd_instr_info_sum_account_lamports( fd_instr_info_t const * instr, 46 : fd_txn_out_t * txn_out, 47 : ulong * total_lamports_h, 48 127517 : ulong * total_lamports_l ) { 49 127517 : *total_lamports_h = 0UL; 50 127517 : *total_lamports_l = 0UL; 51 918130 : for( ulong i=0UL; i<instr->acct_cnt; ++i ) { 52 790613 : ushort idx_in_txn = instr->accounts[i].index_in_transaction; 53 790613 : fd_acc_t const * ref = txn_out->accounts.account[ idx_in_txn ]; 54 : 55 790613 : if( instr->is_duplicate[i] ) { 56 235142 : continue; 57 235142 : } 58 : 59 : /* Perform a checked add on a fd_uwide */ 60 555471 : ulong tmp_total_lamports_h = 0UL; 61 555471 : ulong tmp_total_lamports_l = 0UL; 62 : 63 555471 : fd_uwide_inc( &tmp_total_lamports_h, &tmp_total_lamports_l, 64 555471 : *total_lamports_h, *total_lamports_l, 65 555471 : ref->lamports ); 66 : 67 555471 : if( tmp_total_lamports_h < *total_lamports_h ) { 68 0 : return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW; 69 0 : } 70 : 71 555471 : *total_lamports_h = tmp_total_lamports_h; 72 555471 : *total_lamports_l = tmp_total_lamports_l; 73 555471 : } 74 : 75 127517 : return FD_EXECUTOR_INSTR_SUCCESS; 76 127517 : }