Line data Source code
1 : #include "fd_instr_info.h" 2 : #include "../fd_runtime.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_txn_out_t * txn_out, 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_accdb_rw_t const * ref = &txn_out->accounts.account[ idx_in_txn ]; 12 0 : if( ref ) { 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 : fd_accdb_ref_lamports( ref->ro ) ); 17 0 : } 18 0 : } 19 0 : } 20 : 21 : void 22 : fd_instr_info_init_from_txn_instr( fd_instr_info_t * instr, 23 : fd_bank_t * bank, 24 : fd_txn_in_t const * txn_in, 25 : fd_txn_out_t * txn_out, 26 6 : fd_txn_instr_t const * txn_instr ) { 27 : 28 6 : fd_txn_t const * txn_descriptor = TXN( txn_in->txn ); 29 6 : uchar * instr_acc_idxs = (uchar *)txn_in->txn->payload + txn_instr->acct_off; 30 : 31 : /* Set the stack height to 1 (since this is a top-level instruction) */ 32 6 : instr->stack_height = 1; 33 : 34 : /* Set the program id */ 35 6 : instr->program_id = txn_instr->program_id; 36 6 : instr->acct_cnt = txn_instr->acct_cnt; 37 6 : if( FD_UNLIKELY( instr->acct_cnt > FD_INSTR_ACCT_MAX ) ) { 38 0 : FD_LOG_CRIT(( "invariant violation: Instruction has too many accounts: %d > %lu", instr->acct_cnt, FD_INSTR_ACCT_MAX )); 39 0 : } 40 6 : instr->data_sz = txn_instr->data_sz; 41 6 : memcpy( instr->data, txn_in->txn->payload+txn_instr->data_off, instr->data_sz ); 42 : 43 6 : uchar acc_idx_seen[ FD_TXN_ACCT_ADDR_MAX ] = {0}; 44 : 45 4788 : for( ushort i=0; i<instr->acct_cnt; i++ ) { 46 4782 : ushort acc_idx = instr_acc_idxs[i]; 47 : 48 4782 : fd_instr_info_setup_instr_account( instr, 49 4782 : acc_idx_seen, 50 4782 : acc_idx, 51 4782 : acc_idx, 52 4782 : i, 53 4782 : (uchar)fd_runtime_account_is_writable_idx( txn_in, txn_out, bank, instr_acc_idxs[i] ), 54 4782 : (uchar)fd_txn_is_signer( txn_descriptor, instr_acc_idxs[i] ) ); 55 : 56 4782 : } 57 6 : } 58 : 59 : int 60 : fd_instr_info_sum_account_lamports( fd_instr_info_t const * instr, 61 : fd_txn_out_t * txn_out, 62 : ulong * total_lamports_h, 63 60 : ulong * total_lamports_l ) { 64 60 : *total_lamports_h = 0UL; 65 60 : *total_lamports_l = 0UL; 66 9720 : for( ulong i=0UL; i<instr->acct_cnt; ++i ) { 67 9660 : ushort idx_in_txn = instr->accounts[i].index_in_transaction; 68 9660 : fd_accdb_rw_t const * ref = &txn_out->accounts.account[ idx_in_txn ]; 69 : 70 9660 : if( !ref || instr->is_duplicate[i] ) { 71 9552 : continue; 72 9552 : } 73 : 74 : /* Perform a checked add on a fd_uwide */ 75 108 : ulong tmp_total_lamports_h = 0UL; 76 108 : ulong tmp_total_lamports_l = 0UL; 77 : 78 108 : fd_uwide_inc( &tmp_total_lamports_h, &tmp_total_lamports_l, 79 108 : *total_lamports_h, *total_lamports_l, 80 108 : fd_accdb_ref_lamports( ref->ro ) ); 81 : 82 108 : if( tmp_total_lamports_h < *total_lamports_h ) { 83 0 : return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW; 84 0 : } 85 : 86 108 : *total_lamports_h = tmp_total_lamports_h; 87 108 : *total_lamports_l = tmp_total_lamports_l; 88 108 : } 89 : 90 60 : return FD_EXECUTOR_INSTR_SUCCESS; 91 60 : }