LCOV - code coverage report
Current view: top level - flamenco/runtime/sysvar - fd_sysvar_cache.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 10 0.0 %
Date: 2025-06-04 05:03:10 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_runtime_sysvar_fd_sysvar_cache_h
       2             : #define HEADER_fd_src_flamenco_runtime_sysvar_fd_sysvar_cache_h
       3             : 
       4             : /* fd_sysvar_cache reproduces the behavior of
       5             :    solana_program_runtime::sysvar_cache::SysvarCache.
       6             : 
       7             :    Firedancer provides this sysvar cache to be compatible with the Agave
       8             :    validator.  Otherwise, it serves no purpose other than to make the
       9             :    runtime more complicated.  The sysvar cache keeps a copy of various
      10             :    sysvar accounts.  It is part of the implicit state of the runtime.
      11             : 
      12             :    Note that not all sysvars are in this cache.
      13             : 
      14             :    ### Cache state
      15             : 
      16             :    The sysvar cache is not a pure cache.  For every supported sysvar, it
      17             :    may store NULL or a parsed version of the sysvar account.  It is
      18             :    populated from the accounts DB.  After parsing, the contents of the
      19             :    cache are not identical to the original account content anymore.  If
      20             :    a sysvar account fails to parse, the corresponding cache entry will
      21             :    be NULL.
      22             : 
      23             :    ### Write back
      24             : 
      25             :    The sysvar cache can be modified directly by native programs.  There
      26             :    is no standard pattern to how these changes get written back to the
      27             :    accounts DB.  Currently, the write back happens at arbitrary stages
      28             :    in the slot boundary logic and is different for every sysvar.
      29             : 
      30             :    ### Memory Management
      31             : 
      32             :    fd_sysvar_cache_t is contained by a continuous memory region and
      33             :    embeds a heap allocator. */
      34             : 
      35             : #include "../fd_acc_mgr.h"
      36             : 
      37             : /* Reuse this table to avoid code duplication */
      38             : #define FD_SYSVAR_CACHE_ITER(X) \
      39           0 :   X( fd_sol_sysvar_clock,             clock,               0 ) \
      40           0 :   X( fd_epoch_schedule,               epoch_schedule,      0 ) \
      41           0 :   X( fd_sysvar_epoch_rewards,         epoch_rewards,       0 ) \
      42           0 :   X( fd_sysvar_fees,                  fees,                0 ) \
      43           0 :   X( fd_rent,                         rent,                0 ) \
      44           0 :   X( fd_slot_hashes,                  slot_hashes,         1 ) \
      45           0 :   X( fd_recent_block_hashes,          recent_block_hashes, 1 ) \
      46           0 :   X( fd_stake_history,                stake_history,       0 ) \
      47           0 :   X( fd_sol_sysvar_last_restart_slot, last_restart_slot,   0 ) \
      48           0 :   X( fd_slot_history,                 slot_history,        1 )
      49             : 
      50             : /* The memory of fd_sysvar_cache_t fits as much sysvar information into
      51             :    the struct as possible.  Unfortunately some parts of the sysvar
      52             :    spill out onto the heap due to how the type generator works.
      53             : 
      54             :    The has_{...} bits specify whether a sysvar logically exists.
      55             :    The gaddr_{...} ulong contains the address of the sysvar.
      56             :    If has_{...}==0 then any heap pointers in val_{...} are NULL,
      57             :    allowing for safe idempotent calls to fd_sol_sysvar_{...}_destroy() */
      58             : 
      59             : struct __attribute__((aligned(16UL))) fd_sysvar_cache_private {
      60             :   ulong magic; /* ==FD_SYSVAR_CACHE_MAGIC */
      61             : 
      62             :   /* Process for global types (is_global==1) */
      63             : 
      64             :   #define X(type, name, is_global) \
      65             :   ulong gaddr_##name;
      66             :   FD_SYSVAR_CACHE_ITER(X)
      67             :   #undef X
      68             : 
      69             :   # undef X
      70             : 
      71             :   /* Declare the has_{...} bits */
      72             :   #define X( _type, name, is_global ) \
      73             :   ulong has_##name : 1;
      74             :   FD_SYSVAR_CACHE_ITER(X)
      75             :   #undef X
      76             : 
      77             :   #undef HANDLE_GLOBAL_1
      78             :   #undef HANDLE_GLOBAL_0
      79             : };
      80             : struct fd_sysvar_cache_private;
      81             : typedef struct fd_sysvar_cache_private fd_sysvar_cache_t;
      82             : 
      83             : FD_PROTOTYPES_BEGIN
      84             : 
      85             : /* fd_sysvar_cache_{align,footprint} return the memory region params of
      86             :    an fd_sysvar_cache_t. */
      87             : 
      88             : ulong
      89             : fd_sysvar_cache_align( void );
      90             : 
      91             : ulong
      92             : fd_sysvar_cache_footprint( void );
      93             : 
      94             : /* fd_sysvar_cache_new creates a new sysvar cache object.  mem is the
      95             :    memory region that will back the fd_sysvar_cache_t.  Attaches to the
      96             :    given valloc for use as a heap allocator for sysvar data.  Returns
      97             :    object (in mem) on success and NULL on failure.  Logs reasons for
      98             :    failure. */
      99             : 
     100             : fd_sysvar_cache_t *
     101             : fd_sysvar_cache_new( void * mem );
     102             : 
     103             : /* fd_sysvar_cache_delete destroys a given sysvar cache object and any
     104             :    heap allocations made.  Detaches from the valloc provided in
     105             :    fd_sysvar_cache_new.  Returns the memory region that previously
     106             :    backed cache back to the caller. */
     107             : 
     108             : void *
     109             : fd_sysvar_cache_delete( fd_sysvar_cache_t * cache );
     110             : 
     111             : /* fd_sysvar_cache_restore restores all sysvars from the given slot
     112             :    context.
     113             : 
     114             :    Roughly compatible with Agave's
     115             :    solana_program_runtime::sysvar_cache::SysvarCache::fill_missing_entries
     116             :    https://github.com/solana-labs/solana/blob/v1.17.23/program-runtime/src/sysvar_cache.rs#L137-L208 */
     117             : 
     118             : void
     119             : fd_sysvar_cache_restore( fd_sysvar_cache_t * cache,
     120             :                          fd_funk_t *         funk,
     121             :                          fd_funk_txn_t *     funk_txn,
     122             :                          fd_spad_t *         runtime_spad,
     123             :                          fd_wksp_t *         wksp );
     124             : 
     125             : void
     126             : fd_sysvar_cache_invalidate( fd_sysvar_cache_t * cache );
     127             : 
     128             : /* fd_sysvar_cache_restore_{name} restores only the given sysvar object from the given slot context */
     129             : 
     130             : # define X( type, name, is_global )                                    \
     131             : void                                                                   \
     132             : fd_sysvar_cache_restore_##name( fd_sysvar_cache_t * cache,             \
     133             :                                 fd_funk_t *         funk,              \
     134             :                                 fd_funk_txn_t *     funk_txn,          \
     135             :                                 fd_spad_t *         runtime_spad,      \
     136             :                                 fd_wksp_t *         wksp );
     137             :   FD_SYSVAR_CACHE_ITER(X)
     138             : # undef X
     139             : 
     140             : /* Accessors for sysvars.  May return NULL. */
     141             : 
     142             : FD_FN_PURE fd_sol_sysvar_clock_t             * fd_sysvar_cache_clock              ( fd_sysvar_cache_t const * cache, fd_wksp_t * wksp );
     143             : FD_FN_PURE fd_epoch_schedule_t               * fd_sysvar_cache_epoch_schedule     ( fd_sysvar_cache_t const * cache, fd_wksp_t * wksp );
     144             : FD_FN_PURE fd_sysvar_epoch_rewards_t         * fd_sysvar_cache_epoch_rewards      ( fd_sysvar_cache_t const * cache, fd_wksp_t * wksp );
     145             : FD_FN_PURE fd_sysvar_fees_t                  * fd_sysvar_cache_fees               ( fd_sysvar_cache_t const * cache, fd_wksp_t * wksp );
     146             : FD_FN_PURE fd_rent_t                         * fd_sysvar_cache_rent               ( fd_sysvar_cache_t const * cache, fd_wksp_t * wksp );
     147             : FD_FN_PURE fd_slot_hashes_global_t           * fd_sysvar_cache_slot_hashes        ( fd_sysvar_cache_t const * cache, fd_wksp_t * wksp );
     148             : FD_FN_PURE fd_recent_block_hashes_global_t   * fd_sysvar_cache_recent_block_hashes( fd_sysvar_cache_t const * cache, fd_wksp_t * wksp );
     149             : FD_FN_PURE fd_stake_history_t                * fd_sysvar_cache_stake_history      ( fd_sysvar_cache_t const * cache, fd_wksp_t * wksp );
     150             : FD_FN_PURE fd_sol_sysvar_last_restart_slot_t * fd_sysvar_cache_last_restart_slot  ( fd_sysvar_cache_t const * cache, fd_wksp_t * wksp );
     151             : FD_FN_PURE fd_slot_history_global_t          * fd_sysvar_cache_slot_history       ( fd_sysvar_cache_t const * cache, fd_wksp_t * wksp );
     152             : 
     153             : /* fd_sysvar_from_instr_acct_{...} pretends to read a sysvar from an
     154             :    instruction account.  Checks that a given instruction account has
     155             :    an address matching the sysvar.  Returns the sysvar from the sysvar
     156             :    cache.  On return, *err is in FD_EXECUTOR_INSTR_{SUCCESS,ERR_{...}}.
     157             : 
     158             :    Matches Agave's
     159             :    solana_program_runtime::sysvar_cache::get_sysvar_with_account_check
     160             :    https://github.com/solana-labs/solana/blob/v1.18.8/program-runtime/src/sysvar_cache.rs#L215-L314
     161             : 
     162             :    Equivalent to:
     163             : 
     164             :      fd_sysvar_FOO_t const *
     165             :      fd_sysvar_from_instr_acct_FOO( fd_exec_instr_ctx_t const * ctx,
     166             :                                     ulong                       acct_idx ) {
     167             :        if( FD_UNLIKELY( idx >= ctx->instr->acct_cnt ) ) {
     168             :           *err = FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
     169             :           return NULL;
     170             :        }
     171             :        if( ctx->instr->acct_pubkeys[ acct_idx ] != FOO_addr ) {
     172             :          *err = FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
     173             :          return NULL;
     174             :        }
     175             :        FOO_t const * value = fd_sysvar_cache_FOO( ctx->slot_ctx->sysvar_cache );
     176             :        *err = value ? 0 : FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
     177             :        return value;
     178             :      } */
     179             : 
     180             : fd_sol_sysvar_clock_t             const * fd_sysvar_from_instr_acct_clock              ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     181             : fd_epoch_schedule_t               const * fd_sysvar_from_instr_acct_epoch_schedule     ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     182             : fd_sysvar_epoch_rewards_t         const * fd_sysvar_from_instr_acct_epoch_rewards      ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     183             : fd_sysvar_fees_t                  const * fd_sysvar_from_instr_acct_fees               ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     184             : fd_rent_t                         const * fd_sysvar_from_instr_acct_rent               ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     185             : fd_slot_hashes_global_t           const * fd_sysvar_from_instr_acct_slot_hashes        ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     186             : fd_recent_block_hashes_global_t   const * fd_sysvar_from_instr_acct_recent_block_hashes( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     187             : fd_stake_history_t                const * fd_sysvar_from_instr_acct_stake_history      ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     188             : fd_sol_sysvar_last_restart_slot_t const * fd_sysvar_from_instr_acct_last_restart_slot  ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     189             : 
     190             : /* fd_check_sysvar_account does a check on if an instruction account index
     191             :    matches the expected pubkey of a specific sysvar. */
     192             : 
     193             : int
     194             : fd_check_sysvar_account( fd_exec_instr_ctx_t const * ctx,
     195             :                          ulong                       insn_acc_idx,
     196             :                          fd_pubkey_t const *         expected_id );
     197             : 
     198             : FD_PROTOTYPES_END
     199             : 
     200             : #endif /* HEADER_fd_src_flamenco_runtime_sysvar_fd_sysvar_cache_h */

Generated by: LCOV version 1.14