Line data Source code
1 : #include "fd_exec_instr_ctx.h" 2 : #include "../fd_borrowed_account.h" 3 : 4 : void * 5 7665 : fd_exec_instr_ctx_new( void * mem ) { 6 7665 : if( FD_UNLIKELY( !mem ) ) { 7 0 : FD_LOG_WARNING(( "NULL mem" )); 8 0 : return NULL; 9 0 : } 10 : 11 7665 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, FD_EXEC_INSTR_CTX_ALIGN ) ) ) { 12 0 : FD_LOG_WARNING(( "misaligned mem" )); 13 0 : return NULL; 14 0 : } 15 : 16 7665 : fd_memset(mem, 0, FD_EXEC_INSTR_CTX_FOOTPRINT); 17 : 18 7665 : fd_exec_instr_ctx_t * self = (fd_exec_instr_ctx_t *) mem; 19 : 20 7665 : FD_COMPILER_MFENCE(); 21 7665 : self->magic = FD_EXEC_INSTR_CTX_MAGIC; 22 7665 : FD_COMPILER_MFENCE(); 23 : 24 7665 : return mem; 25 7665 : } 26 : 27 : fd_exec_instr_ctx_t * 28 7665 : fd_exec_instr_ctx_join( void * mem ) { 29 7665 : if( FD_UNLIKELY( !mem ) ) { 30 0 : FD_LOG_WARNING(( "NULL block" )); 31 0 : return NULL; 32 0 : } 33 : 34 7665 : fd_exec_instr_ctx_t * ctx = (fd_exec_instr_ctx_t *) mem; 35 : 36 7665 : if( FD_UNLIKELY( ctx->magic!=FD_EXEC_INSTR_CTX_MAGIC ) ) { 37 0 : FD_LOG_WARNING(( "bad magic" )); 38 0 : return NULL; 39 0 : } 40 : 41 7665 : return ctx; 42 7665 : } 43 : 44 : void * 45 7665 : fd_exec_instr_ctx_leave( fd_exec_instr_ctx_t * ctx) { 46 7665 : if( FD_UNLIKELY( !ctx ) ) { 47 0 : FD_LOG_WARNING(( "NULL block" )); 48 0 : return NULL; 49 0 : } 50 : 51 7665 : if( FD_UNLIKELY( ctx->magic!=FD_EXEC_INSTR_CTX_MAGIC ) ) { 52 0 : FD_LOG_WARNING(( "bad magic" )); 53 0 : return NULL; 54 0 : } 55 : 56 7665 : return (void *) ctx; 57 7665 : } 58 : 59 : void * 60 7665 : fd_exec_instr_ctx_delete( void * mem ) { 61 7665 : if( FD_UNLIKELY( !mem ) ) { 62 0 : FD_LOG_WARNING(( "NULL mem" )); 63 0 : return NULL; 64 0 : } 65 : 66 7665 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, FD_EXEC_INSTR_CTX_ALIGN) ) ) { 67 0 : FD_LOG_WARNING(( "misaligned mem" )); 68 0 : return NULL; 69 0 : } 70 : 71 7665 : fd_exec_instr_ctx_t * hdr = (fd_exec_instr_ctx_t *)mem; 72 7665 : if( FD_UNLIKELY( hdr->magic!=FD_EXEC_INSTR_CTX_MAGIC ) ) { 73 0 : FD_LOG_WARNING(( "bad magic" )); 74 0 : return NULL; 75 0 : } 76 : 77 7665 : FD_COMPILER_MFENCE(); 78 7665 : FD_VOLATILE( hdr->magic ) = 0UL; 79 7665 : FD_COMPILER_MFENCE(); 80 : 81 7665 : return mem; 82 7665 : } 83 : 84 : int 85 : fd_exec_instr_ctx_try_borrow_account( fd_exec_instr_ctx_t const * ctx, 86 : ulong idx, 87 0 : fd_borrowed_account_t * account ) { 88 : /* TODO this is slightly wrong. Agave returns NotEnoughAccountKeys when the account index is 89 : out of bounds in the transaction context and MissingAccount when the account index is out of 90 : bounds in the instruction context. */ 91 : 92 : /* Return a NotEnoughAccountKeys error if the idx is out of bounds. 93 : https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L603 */ 94 0 : if( FD_UNLIKELY( idx >= ctx->instr->acct_cnt ) ) { 95 0 : return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS; 96 0 : } 97 : 98 0 : fd_txn_account_t * instr_account = ctx->instr->accounts[idx]; 99 : 100 : /* Return an AccountBorrowFailed error if the write is not acquirable. 101 : https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L605 */ 102 0 : int acquire_result = fd_txn_account_acquire_write( instr_account ); 103 0 : if( FD_UNLIKELY( !acquire_result ) ) { 104 0 : return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_FAILED; 105 0 : } 106 : 107 : /* Create a BorrowedAccount upon success. 108 : https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L606 */ 109 0 : fd_borrowed_account_init( account, instr_account, ctx, (int)idx ); 110 0 : return FD_EXECUTOR_INSTR_SUCCESS; 111 0 : } 112 : 113 : int 114 : fd_exec_instr_ctx_try_borrow_account_with_key( fd_exec_instr_ctx_t * ctx, 115 : fd_pubkey_t const * pubkey, 116 0 : fd_borrowed_account_t * account ) { 117 0 : for( ulong i = 0; i < ctx->instr->acct_cnt; i++ ) { 118 0 : if( memcmp( pubkey->uc, ctx->instr->acct_pubkeys[i].uc, sizeof(fd_pubkey_t) )==0 ) { 119 0 : return fd_exec_instr_ctx_try_borrow_account( ctx, i, account ); 120 0 : } 121 0 : } 122 0 : return FD_EXECUTOR_INSTR_ERR_MISSING_ACC; 123 0 : } 124 : 125 : int 126 : fd_exec_instr_ctx_find_idx_of_instr_account( fd_exec_instr_ctx_t const * ctx, 127 0 : fd_pubkey_t const * pubkey ) { 128 0 : for( int i = 0; i < ctx->instr->acct_cnt; i++ ) { 129 0 : if( memcmp( pubkey->uc, ctx->instr->acct_pubkeys[i].uc, sizeof(fd_pubkey_t) )==0 ) { 130 0 : return i; 131 0 : } 132 0 : } 133 0 : return -1; 134 0 : }