Line data Source code
1 : #include "fd_instr_info.h" 2 : 3 : #include "../fd_account.h" 4 : #include "../../../util/bits/fd_uwide.h" 5 : 6 : /* https://github.com/anza-xyz/agave/blob/1ca8cb866a8a1bcb33cea23613649b82d48ed62c/sdk/program/src/message/versions/v0/loaded.rs#L162 */ 7 : int 8 : fd_txn_account_is_demotion( fd_exec_txn_ctx_t const * txn_ctx, int idx ) 9 96579 : { 10 96579 : uint is_program = 0; 11 253986 : for ( ulong j = 0; j < txn_ctx->txn_descriptor->instr_cnt; j++ ) { 12 172473 : if ( txn_ctx->txn_descriptor->instr[j].program_id == idx ) { 13 15066 : is_program = 1; 14 15066 : break; 15 15066 : } 16 172473 : } 17 : 18 96579 : uint bpf_upgradeable_in_txn = 0; 19 1296183 : for( ulong j = 0; j < txn_ctx->accounts_cnt; j++ ) { 20 1214259 : const fd_pubkey_t * acc = &txn_ctx->accounts[j]; 21 1214259 : if ( memcmp( acc->uc, fd_solana_bpf_loader_upgradeable_program_id.key, sizeof(fd_pubkey_t) ) == 0 ) { 22 14655 : bpf_upgradeable_in_txn = 1; 23 14655 : break; 24 14655 : } 25 1214259 : } 26 96579 : return (is_program && !bpf_upgradeable_in_txn); 27 96579 : } 28 : 29 : void 30 : fd_convert_txn_instr_to_instr( fd_exec_txn_ctx_t * txn_ctx, 31 : fd_txn_instr_t const * txn_instr, 32 : fd_borrowed_account_t * borrowed_accounts, 33 8907 : fd_instr_info_t * instr ) { 34 : 35 8907 : fd_txn_t const * txn_descriptor = txn_ctx->txn_descriptor; 36 8907 : fd_rawtxn_b_t const * txn_raw = txn_ctx->_txn_raw; 37 8907 : const fd_pubkey_t * accounts = txn_ctx->accounts; 38 : 39 : /* TODO: Lamport check may be redundant */ 40 8907 : ulong starting_lamports_h = 0; 41 8907 : ulong starting_lamports_l = 0; 42 : 43 8907 : instr->program_id = txn_instr->program_id; 44 8907 : instr->program_id_pubkey = accounts[txn_instr->program_id]; 45 8907 : instr->acct_cnt = txn_instr->acct_cnt; 46 8907 : instr->data_sz = txn_instr->data_sz; 47 8907 : instr->data = (uchar *)txn_raw->raw + txn_instr->data_off; 48 : 49 8907 : uchar acc_idx_seen[256]; 50 8907 : memset(acc_idx_seen, 0, 256); 51 8907 : uchar * instr_acc_idxs = (uchar *)txn_raw->raw + txn_instr->acct_off; 52 40797 : for( ulong i = 0; i < instr->acct_cnt; i++ ) { 53 31890 : if( borrowed_accounts != NULL ) { 54 31890 : instr->borrowed_accounts[i] = &borrowed_accounts[instr_acc_idxs[i]]; 55 31890 : } else { 56 0 : instr->borrowed_accounts[i] = NULL; 57 0 : } 58 : 59 31890 : uchar acc_idx = instr_acc_idxs[i]; 60 : 61 31890 : instr->is_duplicate[i] = acc_idx_seen[acc_idx]; 62 31890 : if( FD_LIKELY( !acc_idx_seen[acc_idx] ) ) { 63 : /* This is the first time seeing this account */ 64 30477 : if( instr->borrowed_accounts[i] != NULL && instr->borrowed_accounts[i]->const_meta != NULL ) { 65 30477 : fd_uwide_inc( &starting_lamports_h, &starting_lamports_l, 66 30477 : starting_lamports_h, starting_lamports_l, 67 30477 : instr->borrowed_accounts[i]->const_meta->info.lamports ); 68 30477 : } 69 30477 : acc_idx_seen[acc_idx] = 1; 70 30477 : } 71 : 72 31890 : instr->acct_txn_idxs[i] = acc_idx; 73 31890 : instr->acct_pubkeys[i] = accounts[instr_acc_idxs[i]]; 74 31890 : instr->acct_flags[i] = 0; 75 31890 : if( fd_txn_account_is_writable_idx( txn_ctx, (int)instr_acc_idxs[i]) ) { 76 12504 : instr->acct_flags[i] |= FD_INSTR_ACCT_FLAGS_IS_WRITABLE; 77 12504 : } 78 31890 : if( fd_txn_is_signer( txn_descriptor, instr_acc_idxs[i] ) ) { 79 16542 : instr->acct_flags[i] |= FD_INSTR_ACCT_FLAGS_IS_SIGNER; 80 16542 : } 81 31890 : } 82 : 83 8907 : instr->starting_lamports_h = starting_lamports_h; 84 8907 : instr->starting_lamports_l = starting_lamports_l; 85 : 86 8907 : } 87 : 88 : int 89 : fd_instr_any_signed( fd_instr_info_t const * info, 90 7431 : fd_pubkey_t const * pubkey ) { 91 7431 : int is_signer = 0; 92 33846 : for( ulong j=0UL; j < info->acct_cnt; j++ ) 93 26415 : is_signer |= 94 26415 : ( ( !!fd_instr_acc_is_signer_idx( info, j ) ) & 95 26415 : ( 0==memcmp( pubkey->key, info->acct_pubkeys[j].key, sizeof(fd_pubkey_t) ) ) ); 96 7431 : return is_signer; 97 7431 : } 98 : 99 : /* https://github.com/anza-xyz/agave/blob/9706a6464665f7ebd6ead47f0d12f853ccacbab9/sdk/src/transaction_context.rs#L40 */ 100 : int 101 : fd_instr_info_sum_account_lamports( fd_instr_info_t const * instr, 102 : ulong * total_lamports_h, 103 306912 : ulong * total_lamports_l ) { 104 306912 : *total_lamports_h = 0UL; 105 306912 : *total_lamports_l = 0UL; 106 2924517 : for( ulong i=0UL; i<instr->acct_cnt; ++i ) { 107 2617605 : if( instr->borrowed_accounts[i] == NULL || 108 2617605 : instr->is_duplicate[i] || 109 2617605 : instr->borrowed_accounts[i]->const_meta == NULL ) { 110 86595 : continue; 111 86595 : } 112 : 113 : /* Perform a checked add on a fd_uwide */ 114 2531010 : ulong tmp_total_lamports_h = 0UL; 115 2531010 : ulong tmp_total_lamports_l = 0UL; 116 : 117 2531010 : fd_uwide_inc( &tmp_total_lamports_h, &tmp_total_lamports_l, *total_lamports_h, *total_lamports_l, 118 2531010 : instr->borrowed_accounts[i]->const_meta->info.lamports ); 119 : 120 2531010 : if( tmp_total_lamports_h < *total_lamports_h ) { 121 0 : return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW; 122 0 : } 123 : 124 2531010 : *total_lamports_h = tmp_total_lamports_h; 125 2531010 : *total_lamports_l = tmp_total_lamports_l; 126 2531010 : } 127 : 128 306912 : return FD_EXECUTOR_INSTR_SUCCESS; 129 306912 : }