LCOV - code coverage report
Current view: top level - flamenco/progcache - fd_progcache_user.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 2 0.0 %
Date: 2026-06-29 05:51:35 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_progcache_fd_progcache_user_h
       2             : #define HEADER_fd_src_flamenco_progcache_fd_progcache_user_h
       3             : 
       4             : /* fd_progcache_user.h provides an API for managing a cache of loaded
       5             :    Solana on-chain program.
       6             : 
       7             :    ### Background
       8             : 
       9             :    Solana on-chain programs are rarely updated but frequently executed.
      10             :    Before a program can be executed, it must be loaded and verified,
      11             :    which is costly.
      12             : 
      13             :    ### Fork management
      14             : 
      15             :    The program cache is fork-aware (using transactions).  Txn-level
      16             :    operations take an exclusive lock over the cache (record ops are
      17             :    stalled indefinitely until the txn completes).
      18             : 
      19             :    ### Cache entry
      20             : 
      21             :    Each Solana program can have a number of program cache entries
      22             :    (typically only zero or one, in rare cases where the program content
      23             :    differs across forks multiple).
      24             : 
      25             :    A cache entry consists of a progcache_rec object (from a preallocated
      26             :    object pool), and a variable-sized fd_progcache_entry struct
      27             :    (from an fd_alloc heap).
      28             : 
      29             :    ### Cache fill policy
      30             : 
      31             :    fd_progcache is lazily filled on reads, and eagerly invalidated
      32             :    if underlying programs are written to.
      33             : 
      34             :    ### Cache evict policy
      35             : 
      36             :    Cache eviction (i.e. force removal of potentially useful records)
      37             :    happens on fill.  Specifically, cache eviction is triggered when a
      38             :    cache fill fails to allocate from the wksp (fd_alloc) heap.
      39             : 
      40             :    fd_progcache further has a concept of "generations" (gen).  Each
      41             :    cache fill operation specifies a 'gen' number.  Only entries with a
      42             :    lower 'gen' number may get evicted.
      43             : 
      44             :    ### Garbage collect policy
      45             : 
      46             :    fd_progcache cleans up unused entries eagerly when:
      47             : 
      48             :    1. a database fork is cancelled (e.g. slot is rooted and competing
      49             :       history dies, or consensus layer prunes a fork)
      50             :    2. a cache entry is orphaned (updated or invalidated by an epoch
      51             :       boundary) */
      52             : 
      53             : #include "fd_progcache.h"
      54             : #include "fd_prog_load.h"
      55             : #include "fd_progcache_lineage.h"
      56             : #include "../runtime/fd_runtime_const.h"
      57             : 
      58             : struct fd_progcache_metrics {
      59             :   ulong lookup_cnt;
      60             :   ulong hit_cnt;
      61             :   ulong miss_cnt;
      62             :   ulong oom_heap_cnt;
      63             :   ulong oom_desc_cnt;
      64             :   ulong fill_cnt;
      65             :   ulong fill_tot_sz;
      66             :   ulong spill_cnt;
      67             :   ulong spill_tot_sz;
      68             :   ulong evict_cnt;
      69             :   ulong evict_tot_sz;
      70             :   ulong cum_pull_ticks;
      71             :   ulong cum_load_ticks;
      72             : };
      73             : 
      74             : typedef struct fd_progcache_metrics fd_progcache_metrics_t;
      75             : 
      76             : /* fd_progcache_t is a thread-local client to a program cache instance.
      77             :    This struct is quite large and therefore not local/stack
      78             :    declaration-friendly. */
      79             : 
      80             : struct fd_progcache {
      81             :   fd_progcache_join_t join[1];
      82             :   fd_progcache_lineage_t lineage[1];
      83             : 
      84             :   fd_progcache_metrics_t * metrics;
      85             : 
      86             :   uchar * scratch;
      87             :   ulong   scratch_sz;
      88             : 
      89             :   uint spill_active;
      90             : };
      91             : 
      92             : FD_PROTOTYPES_BEGIN
      93             : 
      94             : extern FD_TL fd_progcache_metrics_t fd_progcache_metrics_default;
      95             : 
      96             : /* Constructor */
      97             : 
      98             : /* fd_progcache_join joins the caller to a program cache shmem instance.
      99             :    scratch points to a FD_PROGCACHE_SCRATCH_ALIGN aligned scratch buffer
     100             :    and scratch_sz is the size of the largest program/ELF binary that is
     101             :    going to be loaded (typically max account data sz). */
     102             : 
     103             : fd_progcache_t *
     104             : fd_progcache_join( fd_progcache_t *       ljoin,
     105             :                    fd_progcache_shmem_t * shmem,
     106             :                    uchar *                scratch,
     107             :                    ulong                  scratch_sz );
     108             : 
     109           0 : #define FD_PROGCACHE_SCRATCH_ALIGN     (64UL)
     110           0 : #define FD_PROGCACHE_SCRATCH_FOOTPRINT FD_RUNTIME_ACC_SZ_MAX
     111             : 
     112             : /* fd_progcache_leave detaches the caller from a program cache. */
     113             : 
     114             : void *
     115             : fd_progcache_leave( fd_progcache_t *        cache,
     116             :                     fd_progcache_shmem_t ** opt_shmem );
     117             : 
     118             : /* fd_progcache_peek queries the program cache for an existing cache
     119             :    entry.  Does not fill the cache.  Returns a pointer to the entry on
     120             :    cache hit.  Returns NULL on cache miss.  It is the caller's
     121             :    responsibility to release the returned record with
     122             :    fd_progcache_rec_close. */
     123             : 
     124             : fd_progcache_rec_t * /* read locked */
     125             : fd_progcache_peek( fd_progcache_t *       cache,
     126             :                    fd_progcache_fork_id_t fork_id,
     127             :                    fd_pubkey_t const *    prog_addr,
     128             :                    ulong                  feature_slot,
     129             :                    ulong                  deploy_slot );
     130             : 
     131             : /* fd_progcache_pull loads a program from cache, filling the cache if
     132             :    necessary.  The load operation can have a number of outcomes:
     133             :    - Returns a pointer to an existing cache entry (cache hit, state
     134             :      either "Loaded" or "FailedVerification")
     135             :    - Returns a pointer to a newly created cache entry (cache fill,
     136             :      state either "Loaded" or "FailedVerification")
     137             :    - Returns NULL if the requested program account is not deployed (i.e.
     138             :      account is missing, the program is under visibility delay, or user
     139             :      has not finished uploading the program)
     140             :    In other words, this method guarantees to return a cache entry if a
     141             :    deployed program was found in the account database, and the program
     142             :    either loaded successfully, or failed ELF/bytecode verification.
     143             :    It is the caller's responsibility to release the returned record with
     144             :    fd_progcache_rec_close. */
     145             : 
     146             : fd_progcache_rec_t * /* read locked */
     147             : fd_progcache_pull( fd_progcache_t *           cache,
     148             :                    fd_progcache_fork_id_t     fork_id,
     149             :                    fd_pubkey_t const *        prog_addr,
     150             :                    fd_prog_load_env_t const * env,
     151             :                    fd_acc_t const *           progdata_ro );
     152             : 
     153             : /* fd_progcache_rec_close releases a cache record handle returned by
     154             :    fd_progcache_{pull,peek}. */
     155             : 
     156             : void
     157             : fd_progcache_rec_close( fd_progcache_t *     cache,
     158             :                         fd_progcache_rec_t * rec );
     159             : 
     160             : FD_PROTOTYPES_END
     161             : 
     162             : #endif /* HEADER_fd_src_flamenco_progcache_fd_progcache_user_h */

Generated by: LCOV version 1.14