LCOV - code coverage report
Current view: top level - flamenco/runtime/context - fd_exec_txn_ctx.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 8 8 100.0 %
Date: 2024-11-13 11:58:15 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_runtime_context_fd_exec_txn_ctx_h
       2             : #define HEADER_fd_src_flamenco_runtime_context_fd_exec_txn_ctx_h
       3             : 
       4             : #include "fd_exec_instr_ctx.h"
       5             : #include "../../../util/fd_util_base.h"
       6             : #include "../../log_collector/fd_log_collector_base.h"
       7             : 
       8             : #include "../fd_borrowed_account.h"
       9             : 
      10             : #include "../../../ballet/txn/fd_txn.h"
      11             : 
      12             : /* Return data for syscalls */
      13             : 
      14             : struct fd_txn_return_data {
      15             :   fd_pubkey_t program_id;
      16             :   ulong       len;
      17             :   uchar       data[1024];
      18             : };
      19             : 
      20             : typedef struct fd_txn_return_data fd_txn_return_data_t;
      21             : 
      22             : /* fd_exec_txn_ctx_t is the context needed to execute a transaction. */
      23             : 
      24             : /* Cache of deserialized vote accounts to support iteration after replaying a slot (required for fork choice) */
      25             : struct fd_vote_account_cache_entry {
      26             :   fd_pubkey_t pubkey;
      27             :   ulong next;
      28             :   fd_vote_state_t vote_account;
      29             : };
      30             : typedef struct fd_vote_account_cache_entry fd_vote_account_cache_entry_t;
      31             : 
      32             : #define POOL_NAME fd_vote_account_pool
      33             : #define POOL_T fd_vote_account_cache_entry_t
      34             : #include "../../../util/tmpl/fd_pool.c"
      35             : 
      36             : #define MAP_NAME          fd_vote_account_cache
      37             : #define MAP_ELE_T         fd_vote_account_cache_entry_t
      38             : #define MAP_KEY           pubkey
      39             : #define MAP_KEY_T         fd_pubkey_t
      40             : #define MAP_KEY_EQ(k0,k1) (!(memcmp((k0)->key,(k1)->key,sizeof(fd_hash_t))))
      41             : #define MAP_KEY_HASH(key,seed) ( ((key)->ui[0]) ^ (seed) )
      42             : #include "../../../util/tmpl/fd_map_chain.c"
      43             : 
      44             : /* An entry in the instruction trace */
      45             : struct fd_exec_instr_trace_entry {
      46             :   /* Metadata about the instruction */
      47             :   fd_instr_info_t * instr_info;
      48             :   /* Stack height when this instruction was pushed onto the stack (including itself)
      49             :      https://github.com/anza-xyz/agave/blob/d87e23d8d91c32d5f2be2bb3557c730bee1e9434/sdk/src/transaction_context.rs#L475-L480 */
      50             :   ulong stack_height;
      51             : };
      52             : typedef struct fd_exec_instr_trace_entry fd_exec_instr_trace_entry_t;
      53             : 
      54             : /* https://github.com/anza-xyz/agave/blob/0d34a1a160129c4293dac248e14231e9e773b4ce/program-runtime/src/compute_budget.rs#L139 */
      55             : #define FD_MAX_INSTRUCTION_TRACE_LENGTH (64UL)
      56             : /* https://github.com/anza-xyz/agave/blob/f70ab5598ccd86b216c3928e4397bf4a5b58d723/compute-budget/src/compute_budget.rs#L13 */
      57             : #define FD_MAX_INSTRUCTION_STACK_DEPTH  (5UL)
      58             : 
      59             : struct __attribute__((aligned(8UL))) fd_exec_txn_ctx {
      60             :   ulong magic; /* ==FD_EXEC_TXN_CTX_MAGIC */
      61             : 
      62             :   fd_exec_epoch_ctx_t const * epoch_ctx;
      63             :   fd_exec_slot_ctx_t const *  slot_ctx;
      64             : 
      65             :   fd_funk_txn_t *       funk_txn;
      66             :   fd_acc_mgr_t *        acc_mgr;
      67             :   fd_valloc_t           valloc;
      68             : 
      69             :   ulong                 paid_fees;
      70             :   ulong                 compute_unit_limit;                          /* Compute unit limit for this transaction. */
      71             :   ulong                 compute_unit_price;                          /* Compute unit price for this transaction. */
      72             :   ulong                 compute_meter;                               /* Remaining compute units */
      73             :   ulong                 heap_size;                                   /* Heap size for VMs for this transaction. */
      74             :   ulong                 loaded_accounts_data_size_limit;             /* Loaded accounts data size limit for this transaction. */
      75             :   uint                  prioritization_fee_type;                     /* The type of prioritization fee to use. */
      76             :   fd_txn_t const *      txn_descriptor;                              /* Descriptor of the transaction. */
      77             :   fd_rawtxn_b_t         _txn_raw[1];                                 /* Raw bytes of the transaction. */
      78             :   uint                  custom_err;                                  /* When a custom error is returned, this is where the numeric value gets stashed */
      79             :   uchar                 instr_stack_sz;                              /* Current depth of the instruction execution stack. */
      80             :   fd_exec_instr_ctx_t   instr_stack[FD_MAX_INSTRUCTION_STACK_DEPTH]; /* Instruction execution stack. */
      81             :   fd_exec_instr_ctx_t * failed_instr;
      82             :   int                   instr_err_idx;
      83             :   /* During sanitization, v0 transactions are allowed to have up to 256 accounts:
      84             :      https://github.com/anza-xyz/agave/blob/838c1952595809a31520ff1603a13f2c9123aa51/sdk/program/src/message/versions/v0/mod.rs#L139
      85             :      Nonetheless, when Agave prepares a sanitized batch for execution and tries to lock accounts, a lower limit is enforced:
      86             :      https://github.com/anza-xyz/agave/blob/838c1952595809a31520ff1603a13f2c9123aa51/accounts-db/src/account_locks.rs#L118
      87             :      That is the limit we are going to use here. */
      88             :   ulong                 accounts_cnt;                                /* Number of account pubkeys accessed by this transaction. */
      89             :   fd_pubkey_t           accounts[ MAX_TX_ACCOUNT_LOCKS ];            /* Array of account pubkeys accessed by this transaction. */
      90             :   ulong                 executable_cnt;                              /* Number of BPF upgradeable loader accounts. */
      91             :   fd_borrowed_account_t executable_accounts[ MAX_TX_ACCOUNT_LOCKS ]; /* Array of BPF upgradeable loader program data accounts */
      92             :   fd_borrowed_account_t borrowed_accounts[ MAX_TX_ACCOUNT_LOCKS ];   /* Array of borrowed accounts accessed by this transaction. */
      93             :   uchar                 nonce_accounts[ MAX_TX_ACCOUNT_LOCKS ];      /* Nonce accounts in the txn to be saved */
      94             :   uint                  num_instructions;                            /* Counter for number of instructions in txn */
      95             :   fd_txn_return_data_t  return_data;                                 /* Data returned from `return_data` syscalls */
      96             :   fd_vote_account_cache_t * vote_accounts_map;                       /* Cache of bank's deserialized vote accounts to support fork choice */
      97             :   fd_vote_account_cache_entry_t * vote_accounts_pool;                /* Memory pool for deserialized vote account cache */
      98             :   ulong                 accounts_resize_delta;                       /* Transaction level tracking for account resizing */
      99             :   fd_hash_t             blake_txn_msg_hash;                          /* Hash of raw transaction message used by the status cache */
     100             :   ulong                 execution_fee;                               /* Execution fee paid by the fee payer in the transaction */
     101             :   ulong                 priority_fee;                                /* Priority fee paid by the fee payer in the transaction */
     102             :   ulong                 collected_rent;                              /* Rent collected from accounts in this transaction */
     103             : 
     104             :   uchar dirty_vote_acc  : 1;                                         /* 1 if this transaction maybe modified a vote account */
     105             :   uchar dirty_stake_acc : 1;                                         /* 1 if this transaction maybe modified a stake account */
     106             : 
     107             :   fd_capture_ctx_t * capture_ctx;
     108             : 
     109             :   /* The instr_infos for the entire transaction are allocated at the start of
     110             :      the transaction. However, this must preserve a different counter because
     111             :      the top level instructions must get set up at once. The instruction 
     112             :      error check on a maximum instruction size can be done on the
     113             :      instr_info_cnt instead of the instr_trace_length because it is a proxy
     114             :      for the trace_length: the instr_info_cnt gets incremented faster than
     115             :      the instr_trace_length because it counts all of the top level instructions
     116             :      first. */
     117             :   fd_instr_info_t             instr_infos[FD_MAX_INSTRUCTION_TRACE_LENGTH];
     118             :   ulong                       instr_info_cnt;
     119             : 
     120             :   fd_exec_instr_trace_entry_t instr_trace[FD_MAX_INSTRUCTION_TRACE_LENGTH]; /* Instruction trace */
     121             :   ulong                       instr_trace_length;                           /* Number of instructions in the trace */
     122             : 
     123             :   fd_log_collector_t          log_collector;             /* Log collector instance */
     124             : 
     125             :   /* Execution error and type, to match Agave. */
     126             :   int exec_err;
     127             :   int exec_err_kind;
     128             : 
     129             :   fd_spad_t * spad;
     130             : };
     131             : 
     132      113193 : #define FD_EXEC_TXN_CTX_ALIGN     (alignof(fd_exec_txn_ctx_t))
     133      113193 : #define FD_EXEC_TXN_CTX_FOOTPRINT ( sizeof(fd_exec_txn_ctx_t))
     134      108786 : #define FD_EXEC_TXN_CTX_MAGIC     (0x9AD93EE71469F4D7UL      ) /* random */
     135             : 
     136             : FD_PROTOTYPES_BEGIN
     137             : 
     138       83610 : #define FD_TXN_ERR_FOR_LOG_INSTR( txn_ctx, err, idx ) (__extension__({ \
     139       83610 :     txn_ctx->exec_err = err;                                           \
     140       83610 :     txn_ctx->exec_err_kind = FD_EXECUTOR_ERR_KIND_INSTR;               \
     141       83610 :     txn_ctx->instr_err_idx = idx;                                      \
     142       83610 :   }))
     143             : 
     144             : void *
     145             : fd_exec_txn_ctx_new( void * mem );
     146             : 
     147             : fd_exec_txn_ctx_t *
     148             : fd_exec_txn_ctx_join( void * mem );
     149             : 
     150             : void *
     151             : fd_exec_txn_ctx_leave( fd_exec_txn_ctx_t * ctx );
     152             : 
     153             : void *
     154             : fd_exec_txn_ctx_delete( void * mem );
     155             : 
     156             : void
     157             : fd_exec_txn_ctx_setup( fd_exec_txn_ctx_t * txn_ctx,
     158             :                        fd_txn_t const * txn_descriptor,
     159             :                        fd_rawtxn_b_t const * txn_raw );
     160             : void
     161             : fd_exec_txn_ctx_from_exec_slot_ctx( fd_exec_slot_ctx_t * slot_ctx,
     162             :                                     fd_exec_txn_ctx_t * txn_ctx );
     163             : 
     164             : void
     165             : fd_exec_txn_ctx_teardown( fd_exec_txn_ctx_t * txn_ctx );
     166             : 
     167             : int
     168             : fd_txn_borrowed_account_view_idx( fd_exec_txn_ctx_t * ctx,
     169             :                                   uchar idx,
     170             :                                   fd_borrowed_account_t * * account );
     171             : 
     172             : /* Same as above, except that this function doesn't check if the account
     173             :    is dead (0 balance, 0 data, etc.) or not. When agave obtains a
     174             :    borrowed account, it doesn't always check if the account is dead or
     175             :    not. For example
     176             :    https://github.com/anza-xyz/agave/blob/838c1952595809a31520ff1603a13f2c9123aa51/program-runtime/src/invoke_context.rs#L453
     177             :    This function allows us to more closely emulate that behavior. */
     178             : int
     179             : fd_txn_borrowed_account_view_idx_allow_dead( fd_exec_txn_ctx_t * ctx,
     180             :                                              uchar idx,
     181             :                                              fd_borrowed_account_t * * account );
     182             : 
     183             : int
     184             : fd_txn_borrowed_account_view( fd_exec_txn_ctx_t * ctx,
     185             :                               fd_pubkey_t const *      pubkey,
     186             :                               fd_borrowed_account_t * * account );
     187             : 
     188             : int
     189             : fd_txn_borrowed_account_executable_view( fd_exec_txn_ctx_t * ctx,
     190             :                               fd_pubkey_t const *      pubkey,
     191             :                               fd_borrowed_account_t * * account );
     192             : 
     193             : int
     194             : fd_txn_borrowed_account_modify_idx( fd_exec_txn_ctx_t * ctx,
     195             :                                     uchar idx,
     196             :                                     ulong min_data_sz,
     197             :                                     fd_borrowed_account_t * * account );
     198             : int
     199             : fd_txn_borrowed_account_modify( fd_exec_txn_ctx_t * ctx,
     200             :                                 fd_pubkey_t const * pubkey,
     201             :                                 ulong min_data_sz,
     202             :                                 fd_borrowed_account_t * * account );
     203             : void
     204             : fd_exec_txn_ctx_reset_return_data( fd_exec_txn_ctx_t * txn_ctx );
     205             : 
     206             : FD_PROTOTYPES_END
     207             : 
     208             : #endif /* HEADER_fd_src_flamenco_runtime_context_fd_exec_txn_ctx_h */

Generated by: LCOV version 1.14