Line data Source code
1 : #include "fd_native_cpi.h" 2 : #include "../fd_borrowed_account.h" 3 : #include "../fd_executor.h" 4 : #include "../../vm/syscall/fd_vm_syscall.h" 5 : #include "../../../util/bits/fd_uwide.h" 6 : 7 : int 8 : fd_native_cpi_execute_system_program_instruction( fd_exec_instr_ctx_t * ctx, 9 : fd_system_program_instruction_t const * instr, 10 : fd_vm_rust_account_meta_t const * acct_metas, 11 : ulong acct_metas_len, 12 : fd_pubkey_t const * signers, 13 0 : ulong signers_cnt ) { 14 0 : fd_instr_info_t instr_info[ 1 ]; 15 0 : fd_instruction_account_t instruction_accounts[256]; 16 0 : ulong instruction_accounts_cnt; 17 : 18 : /* fd_vm_prepare_instruction will handle missing/invalid account case */ 19 0 : instr_info->program_id_pubkey = fd_solana_system_program_id; 20 0 : instr_info->program_id = UCHAR_MAX; 21 : 22 0 : for( ulong i = 0UL; i < ctx->txn_ctx->accounts_cnt; i++ ) { 23 0 : if( !memcmp( fd_solana_system_program_id.key, ctx->txn_ctx->account_keys[i].key, sizeof(fd_pubkey_t) ) ) { 24 0 : instr_info->program_id = (uchar)i; 25 0 : break; 26 0 : } 27 0 : } 28 : 29 0 : uchar acc_idx_seen[256]; 30 0 : memset( acc_idx_seen, 0, 256 ); 31 : 32 0 : instr_info->acct_cnt = (ushort)acct_metas_len; 33 0 : for ( ulong j = 0; j < acct_metas_len; j++ ) { 34 0 : fd_vm_rust_account_meta_t const * acct_meta = &acct_metas[j]; 35 : 36 0 : for ( ulong k = 0; k < ctx->instr->acct_cnt; k++ ) { 37 0 : if ( memcmp( acct_meta->pubkey, ctx->instr->acct_pubkeys[k].uc, sizeof(fd_pubkey_t) ) == 0 ) { 38 0 : instr_info->acct_pubkeys[j] = ctx->instr->acct_pubkeys[k]; 39 0 : instr_info->acct_txn_idxs[j] = ctx->instr->acct_txn_idxs[k]; 40 0 : instr_info->acct_flags[j] = 0; 41 0 : instr_info->accounts[j] = ctx->instr->accounts[k]; 42 : 43 0 : instr_info->is_duplicate[j] = acc_idx_seen[k]; 44 0 : if( FD_LIKELY( !acc_idx_seen[k] ) ) { 45 : /* This is the first time seeing this account */ 46 0 : acc_idx_seen[k] = 1; 47 0 : } 48 : 49 0 : if( acct_meta->is_writable ) { 50 0 : instr_info->acct_flags[j] |= FD_INSTR_ACCT_FLAGS_IS_WRITABLE; 51 0 : } 52 0 : if( acct_meta->is_signer ) { 53 0 : instr_info->acct_flags[j] |= FD_INSTR_ACCT_FLAGS_IS_SIGNER; 54 0 : } 55 0 : break; 56 0 : } 57 0 : } 58 0 : } 59 : 60 0 : fd_bincode_encode_ctx_t ctx2; 61 0 : uchar buf[4096UL]; // Size that is large enough for the instruction 62 0 : ctx2.data = buf; 63 0 : ctx2.dataend = (uchar*)ctx2.data + sizeof(buf); 64 0 : int err = fd_system_program_instruction_encode( instr, &ctx2 ); 65 0 : if( err ) { 66 0 : return FD_EXECUTOR_INSTR_ERR_FATAL; 67 0 : } 68 : 69 0 : instr_info->data = buf; 70 0 : instr_info->data_sz = sizeof(buf); 71 0 : int exec_err = fd_vm_prepare_instruction( ctx->instr, instr_info, ctx, instruction_accounts, 72 0 : &instruction_accounts_cnt, signers, signers_cnt ); 73 0 : if( exec_err != FD_EXECUTOR_INSTR_SUCCESS ) { 74 0 : return exec_err; 75 0 : } 76 : 77 0 : return fd_execute_instr( ctx->txn_ctx, instr_info ); 78 0 : } 79 : 80 : void 81 : fd_native_cpi_create_account_meta( fd_pubkey_t const * key, uchar is_signer, 82 0 : uchar is_writable, fd_vm_rust_account_meta_t * meta ) { 83 0 : meta->is_signer = is_signer; 84 0 : meta->is_writable = is_writable; 85 0 : fd_memcpy( meta->pubkey, key->key, sizeof(fd_pubkey_t) ); 86 0 : }