LCOV - code coverage report
Current view: top level - flamenco/runtime/context - fd_exec_instr_ctx.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 31 155 20.0 %
Date: 2025-07-01 05:00:49 Functions: 4 13 30.8 %

          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_find_idx_of_instr_account( fd_exec_instr_ctx_t const * ctx,
      86           0 :                                              fd_pubkey_t const *         pubkey ) {
      87           0 :   for( int i=0; i<ctx->instr->acct_cnt; i++ ) {
      88           0 :     ushort idx_in_txn = ctx->instr->accounts[ i ].index_in_transaction;
      89           0 :     if( memcmp( pubkey->uc, ctx->txn_ctx->account_keys[ idx_in_txn ].uc, sizeof(fd_pubkey_t) )==0 ) {
      90           0 :       return i;
      91           0 :     }
      92           0 :   }
      93           0 :   return -1;
      94           0 : }
      95             : 
      96             : int
      97             : fd_exec_instr_ctx_get_key_of_account_at_index( fd_exec_instr_ctx_t const * ctx,
      98             :                                                ushort                      idx_in_instr,
      99           0 :                                                fd_pubkey_t const * *       key ) {
     100           0 :   ushort idx_in_txn;
     101           0 :   int err = fd_exec_instr_ctx_get_index_of_instr_account_in_transaction( ctx,
     102           0 :                                                                          idx_in_instr,
     103           0 :                                                                          &idx_in_txn );
     104           0 :   if( FD_UNLIKELY( err ) ) {
     105           0 :     return err;
     106           0 :   }
     107             : 
     108           0 :   return fd_exec_txn_ctx_get_key_of_account_at_index( ctx->txn_ctx,
     109           0 :                                                       idx_in_txn,
     110           0 :                                                       key );
     111           0 : }
     112             : 
     113             : int
     114             : fd_exec_instr_ctx_get_last_program_key( fd_exec_instr_ctx_t const * ctx,
     115           0 :                                         fd_pubkey_t const * *       key ) {
     116           0 :   return fd_exec_txn_ctx_get_key_of_account_at_index( ctx->txn_ctx,
     117           0 :                                                       ctx->instr->program_id,
     118           0 :                                                       key );
     119           0 : }
     120             : 
     121             : int
     122             : fd_exec_instr_ctx_try_borrow_account( fd_exec_instr_ctx_t const * ctx,
     123             :                                       ushort                      idx_in_instr,
     124             :                                       ushort                      idx_in_txn,
     125           0 :                                       fd_borrowed_account_t *     account ) {
     126             :   /* Get the account from the transaction context using idx_in_txn.
     127             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L600-L602 */
     128           0 :   fd_txn_account_t * txn_account = NULL;
     129           0 :   int err = fd_exec_txn_ctx_get_account_at_index( ctx->txn_ctx,
     130           0 :                                                   idx_in_txn,
     131           0 :                                                   &txn_account,
     132           0 :                                                   NULL );
     133           0 :   if( FD_UNLIKELY( err ) ) {
     134             :     /* Return a MissingAccount error if the account is not found.
     135             :        https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L603 */
     136           0 :     return FD_EXECUTOR_INSTR_ERR_MISSING_ACC;
     137           0 :   }
     138             : 
     139             :   /* Return an AccountBorrowFailed error if the write is not acquirable.
     140             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L605 */
     141           0 :   int borrow_res = txn_account->vt->try_borrow_mut( txn_account );
     142           0 :   if( FD_UNLIKELY( !borrow_res ) ) {
     143           0 :     return FD_EXECUTOR_INSTR_ERR_ACC_BORROW_FAILED;
     144           0 :   }
     145             : 
     146             :   /* Create a BorrowedAccount upon success.
     147             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L606 */
     148           0 :   fd_borrowed_account_init( account,
     149           0 :                             txn_account,
     150           0 :                             ctx,
     151           0 :                             idx_in_instr );
     152           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
     153           0 : }
     154             : 
     155             : int
     156             : fd_exec_instr_ctx_try_borrow_instr_account( fd_exec_instr_ctx_t const * ctx,
     157             :                                             ushort                      idx,
     158           0 :                                             fd_borrowed_account_t *     account ) {
     159             :   /* Find the index of the account in the transaction context.
     160             :      https://github.com/anza-xyz/agave/blob/v2.1.14/sdk/src/transaction_context.rs#L649-L650 */
     161           0 :   ushort idx_in_txn;
     162           0 :   int err = fd_exec_instr_ctx_get_index_of_instr_account_in_transaction( ctx,
     163           0 :                                                                          idx,
     164           0 :                                                                          &idx_in_txn );
     165           0 :   if( FD_UNLIKELY( err ) ) {
     166           0 :     return err;
     167           0 :   }
     168             : 
     169           0 :   return fd_exec_instr_ctx_try_borrow_account( ctx,
     170           0 :                                                idx,
     171           0 :                                                idx_in_txn,
     172           0 :                                                account );
     173           0 : }
     174             : 
     175             : int
     176             : fd_exec_instr_ctx_try_borrow_instr_account_with_key( fd_exec_instr_ctx_t const * ctx,
     177             :                                                      fd_pubkey_t const *         pubkey,
     178           0 :                                                      fd_borrowed_account_t *     account ) {
     179           0 :   for( ushort i=0; i<ctx->instr->acct_cnt; i++ ) {
     180           0 :     ushort idx_in_txn = ctx->instr->accounts[ i ].index_in_transaction;
     181           0 :     if( memcmp( pubkey->uc, ctx->txn_ctx->account_keys[ idx_in_txn ].uc, sizeof(fd_pubkey_t) )==0 ) {
     182           0 :       return fd_exec_instr_ctx_try_borrow_instr_account( ctx, i, account );
     183           0 :     }
     184           0 :   }
     185             : 
     186             :   /* Return a NotEnoughAccountKeys error if the account is not found
     187             :      in the instruction context to match the error code returned by
     188             :      fd_exec_instr_ctx_try_borrow_instr_account. */
     189           0 :   return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
     190           0 : }
     191             : 
     192             : int
     193             : fd_exec_instr_ctx_try_borrow_last_program_account( fd_exec_instr_ctx_t const * ctx,
     194           0 :                                                    fd_borrowed_account_t *     account ) {
     195             :   /* The index_in_instruction for a borrowed program account is invalid,
     196             :      so it is set to a sentinel value of USHORT_MAX. */
     197           0 :   return fd_exec_instr_ctx_try_borrow_account( ctx,
     198           0 :                                                USHORT_MAX,
     199           0 :                                                ctx->instr->program_id,
     200           0 :                                                account );
     201           0 : }
     202             : 
     203             : int
     204             : fd_exec_instr_ctx_get_signers( fd_exec_instr_ctx_t const * ctx,
     205           0 :                                fd_pubkey_t const *         signers[static FD_TXN_SIG_MAX] ) {
     206           0 :   ulong j = 0UL;
     207           0 :   for( ushort i=0; i<ctx->instr->acct_cnt && j<FD_TXN_SIG_MAX; i++ )
     208           0 :     if( fd_instr_acc_is_signer_idx( ctx->instr, i ) ) {
     209           0 :       ushort idx_in_txn = ctx->instr->accounts[i].index_in_transaction;
     210           0 :       int err = fd_exec_txn_ctx_get_key_of_account_at_index( ctx->txn_ctx,
     211           0 :                                                              idx_in_txn,
     212           0 :                                                              &signers[j++] );
     213           0 :       if( FD_UNLIKELY( err ) ) {
     214           0 :         return err;
     215           0 :       }
     216           0 :     }
     217           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
     218           0 : }
     219             : 
     220             : int
     221             : fd_exec_instr_ctx_any_signed( fd_exec_instr_ctx_t const * ctx,
     222           0 :                               fd_pubkey_t const *         pubkey ) {
     223           0 :   int is_signer = 0;
     224           0 :   for( ushort j=0; j<ctx->instr->acct_cnt; j++ ) {
     225           0 :     ushort idx_in_txn = ctx->instr->accounts[ j ].index_in_transaction;
     226           0 :     is_signer |=
     227           0 :       ( ( !!fd_instr_acc_is_signer_idx( ctx->instr, j ) ) &
     228           0 :         ( 0==memcmp( pubkey->key, ctx->txn_ctx->account_keys[ idx_in_txn ].key, sizeof(fd_pubkey_t) ) ) );
     229           0 :   }
     230           0 :   return is_signer;
     231           0 : }

Generated by: LCOV version 1.14