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 9 0.0 %
Date: 2025-03-20 12:08:36 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               ) \
      40           0 :   X( fd_epoch_schedule,               epoch_schedule      ) \
      41           0 :   X( fd_sysvar_epoch_rewards,         epoch_rewards       ) \
      42           0 :   X( fd_sysvar_fees,                  fees                ) \
      43           0 :   X( fd_rent,                         rent                ) \
      44           0 :   X( fd_slot_hashes,                  slot_hashes         ) \
      45           0 :   X( fd_recent_block_hashes,          recent_block_hashes ) \
      46           0 :   X( fd_stake_history,                stake_history       ) \
      47           0 :   X( fd_sol_sysvar_last_restart_slot, last_restart_slot   )
      48             : 
      49             : /* The memory of fd_sysvar_cache_t fits as much sysvar information into
      50             :    the struct as possible.  Unfortunately some parts of the sysvar
      51             :    spill out onto the heap due to how the type generator works.
      52             : 
      53             :    The has_{...} bits specify whether a sysvar logically exists.
      54             :    The val_{...} structs contain the top-level struct of each sysvar.
      55             :    If has_{...}==0 then any heap pointers in val_{...} are NULL,
      56             :    allowing for safe idempotent calls to fd_sol_sysvar_{...}_destroy() */
      57             : 
      58             : struct __attribute__((aligned(16UL))) fd_sysvar_cache_private {
      59             :   ulong       magic;  /* ==FD_SYSVAR_CACHE_MAGIC */
      60             : 
      61             :   /* Declare the val_{...} values */
      62             : # define X( type, name ) \
      63             :   type##_global_t val_##name[1];
      64             :   FD_SYSVAR_CACHE_ITER(X)
      65             : # undef X
      66             : 
      67             :   /* Declare the has_{...} bits */
      68             : # define X( _type, name ) \
      69             :   ulong has_##name : 1;
      70             :   FD_SYSVAR_CACHE_ITER(X)
      71             : # undef X
      72             : };
      73             : 
      74             : struct fd_sysvar_cache_private;
      75             : typedef struct fd_sysvar_cache_private fd_sysvar_cache_t;
      76             : 
      77             : FD_PROTOTYPES_BEGIN
      78             : 
      79             : /* fd_sysvar_cache_{align,footprint} return the memory region params of
      80             :    an fd_sysvar_cache_t. */
      81             : 
      82             : ulong
      83             : fd_sysvar_cache_align( void );
      84             : 
      85             : ulong
      86             : fd_sysvar_cache_footprint( void );
      87             : 
      88             : /* fd_sysvar_cache_new creates a new sysvar cache object.  mem is the
      89             :    memory region that will back the fd_sysvar_cache_t.  Attaches to the
      90             :    given valloc for use as a heap allocator for sysvar data.  Returns
      91             :    object (in mem) on success and NULL on failure.  Logs reasons for
      92             :    failure. */
      93             : 
      94             : fd_sysvar_cache_t *
      95             : fd_sysvar_cache_new( void * mem );
      96             : 
      97             : /* fd_sysvar_cache_delete destroys a given sysvar cache object and any
      98             :    heap allocations made.  Detaches from the valloc provided in
      99             :    fd_sysvar_cache_new.  Returns the memory region that previously
     100             :    backed cache back to the caller. */
     101             : 
     102             : void *
     103             : fd_sysvar_cache_delete( fd_sysvar_cache_t * cache );
     104             : 
     105             : /* fd_sysvar_cache_restore restores all sysvars from the given slot
     106             :    context.
     107             : 
     108             :    Roughly compatible with Agave's
     109             :    solana_program_runtime::sysvar_cache::SysvarCache::fill_missing_entries
     110             :    https://github.com/solana-labs/solana/blob/v1.17.23/program-runtime/src/sysvar_cache.rs#L137-L208 */
     111             : 
     112             : void
     113             : fd_sysvar_cache_restore( fd_sysvar_cache_t * cache,
     114             :                          fd_acc_mgr_t *      acc_mgr,
     115             :                          fd_funk_txn_t *     funk_txn,
     116             :                          fd_spad_t *         runtime_spad,
     117             :                          fd_wksp_t *         wksp );
     118             : 
     119             : /* fd_sysvar_cache_restore_{name} restores only the given sysvar object from the given slot context */
     120             : 
     121             : # define X( type, name )                                               \
     122             : void                                                                   \
     123             : fd_sysvar_cache_restore_##name( fd_sysvar_cache_t * cache,             \
     124             :                                 fd_acc_mgr_t *      acc_mgr,           \
     125             :                                 fd_funk_txn_t *     funk_txn,          \
     126             :                                 fd_spad_t *         runtime_spad,      \
     127             :                                 fd_wksp_t *         wksp );
     128             :   FD_SYSVAR_CACHE_ITER(X)
     129             : # undef X
     130             : 
     131             : /* Accessors for sysvars.  May return NULL. */
     132             : 
     133             : FD_FN_PURE fd_sol_sysvar_clock_global_t             const * fd_sysvar_cache_clock              ( fd_sysvar_cache_t const * cache );
     134             : FD_FN_PURE fd_epoch_schedule_global_t               const * fd_sysvar_cache_epoch_schedule     ( fd_sysvar_cache_t const * cache );
     135             : FD_FN_PURE fd_sysvar_epoch_rewards_global_t         const * fd_sysvar_cache_epoch_rewards      ( fd_sysvar_cache_t const * cache );
     136             : FD_FN_PURE fd_sysvar_fees_global_t                  const * fd_sysvar_cache_fees               ( fd_sysvar_cache_t const * cache );
     137             : FD_FN_PURE fd_rent_global_t                         const * fd_sysvar_cache_rent               ( fd_sysvar_cache_t const * cache );
     138             : FD_FN_PURE fd_slot_hashes_global_t                  const * fd_sysvar_cache_slot_hashes        ( fd_sysvar_cache_t const * cache );
     139             : FD_FN_PURE fd_recent_block_hashes_global_t          const * fd_sysvar_cache_recent_block_hashes( fd_sysvar_cache_t const * cache );
     140             : FD_FN_PURE fd_stake_history_global_t                const * fd_sysvar_cache_stake_history      ( fd_sysvar_cache_t const * cache );
     141             : FD_FN_PURE fd_sol_sysvar_last_restart_slot_global_t const * fd_sysvar_cache_last_restart_slot  ( fd_sysvar_cache_t const * cache );
     142             : 
     143             : /* fd_sysvar_from_instr_acct_{...} pretends to read a sysvar from an
     144             :    instruction account.  Checks that a given instruction account has
     145             :    an address matching the sysvar.  Returns the sysvar from the sysvar
     146             :    cache.  On return, *err is in FD_EXECUTOR_INSTR_{SUCCESS,ERR_{...}}.
     147             : 
     148             :    Matches Agave's
     149             :    solana_program_runtime::sysvar_cache::get_sysvar_with_account_check
     150             :    https://github.com/solana-labs/solana/blob/v1.18.8/program-runtime/src/sysvar_cache.rs#L215-L314
     151             : 
     152             :    Equivalent to:
     153             : 
     154             :      fd_sysvar_FOO_t const *
     155             :      fd_sysvar_from_instr_acct_FOO( fd_exec_instr_ctx_t const * ctx,
     156             :                                     ulong                       acct_idx ) {
     157             :        if( FD_UNLIKELY( idx >= ctx->instr->acct_cnt ) ) {
     158             :           *err = FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
     159             :           return NULL;
     160             :        }
     161             :        if( ctx->instr->acct_pubkeys[ acct_idx ] != FOO_addr ) {
     162             :          *err = FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
     163             :          return NULL;
     164             :        }
     165             :        FOO_t const * value = fd_sysvar_cache_FOO( ctx->slot_ctx->sysvar_cache );
     166             :        *err = value ? 0 : FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;
     167             :        return value;
     168             :      } */
     169             : 
     170             : fd_sol_sysvar_clock_global_t             const * fd_sysvar_from_instr_acct_clock              ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     171             : fd_epoch_schedule_global_t               const * fd_sysvar_from_instr_acct_epoch_schedule     ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     172             : fd_sysvar_epoch_rewards_global_t         const * fd_sysvar_from_instr_acct_epoch_rewards      ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     173             : fd_sysvar_fees_global_t                  const * fd_sysvar_from_instr_acct_fees               ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     174             : fd_rent_global_t                         const * fd_sysvar_from_instr_acct_rent               ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     175             : 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 );
     176             : 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 );
     177             : fd_stake_history_global_t                const * fd_sysvar_from_instr_acct_stake_history      ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     178             : fd_sol_sysvar_last_restart_slot_global_t const * fd_sysvar_from_instr_acct_last_restart_slot  ( fd_exec_instr_ctx_t const * ctx, ulong acct_idx, int * err );
     179             : 
     180             : /* fd_check_sysvar_account does a check on if an instruction account index
     181             :    matches the expected pubkey of a specific sysvar. */
     182             : 
     183             : int
     184             : fd_check_sysvar_account( fd_exec_instr_ctx_t const * ctx,
     185             :                          ulong                       insn_acc_idx,
     186             :                          fd_pubkey_t const *         expected_id );
     187             : 
     188             : FD_PROTOTYPES_END
     189             : 
     190             : #endif /* HEADER_fd_src_flamenco_runtime_sysvar_fd_sysvar_cache_h */

Generated by: LCOV version 1.14