LCOV - code coverage report
Current view: top level - flamenco/runtime/sysvar - fd_sysvar_cache.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 82 135 60.7 %
Date: 2026-03-19 18:19:27 Functions: 15 21 71.4 %

          Line data    Source code
       1             : #include "fd_sysvar_cache.h"
       2             : #include "fd_sysvar_cache_private.h"
       3             : #include <errno.h>
       4             : 
       5             : void *
       6        5838 : fd_sysvar_cache_new( void * mem ) {
       7             : 
       8        5838 :   if( FD_UNLIKELY( !mem ) ) {
       9           0 :     FD_LOG_WARNING(( "NULL mem" ));
      10           0 :     return NULL;
      11           0 :   }
      12        5838 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, alignof(fd_sysvar_cache_t) ) ) ) {
      13           0 :     FD_LOG_WARNING(( "misaligned mem" ));
      14           0 :     return NULL;
      15           0 :   }
      16             : 
      17        5838 :   fd_sysvar_cache_t * sysvar_cache = mem;
      18        5838 :   sysvar_cache->magic = 0UL;
      19        5838 :   memset( sysvar_cache->desc, 0, FD_SYSVAR_CACHE_ENTRY_CNT*sizeof(fd_sysvar_desc_t) );
      20             : 
      21        5838 :   FD_COMPILER_MFENCE();
      22        5838 :   sysvar_cache->magic = FD_SYSVAR_CACHE_MAGIC;
      23        5838 :   FD_COMPILER_MFENCE();
      24             : 
      25        5838 :   return sysvar_cache;
      26        5838 : }
      27             : 
      28             : fd_sysvar_cache_t *
      29        5838 : fd_sysvar_cache_join( void * mem ) {
      30             :   /* FIXME This is a good place to ref-count writable joins */
      31        5838 :   return (fd_sysvar_cache_t *)fd_sysvar_cache_join_const( mem );
      32        5838 : }
      33             : 
      34             : fd_sysvar_cache_t const *
      35        5838 : fd_sysvar_cache_join_const( void const * mem ) {
      36             : 
      37        5838 :   if( FD_UNLIKELY( !mem ) ) {
      38           0 :     FD_LOG_WARNING(( "NULL mem" ));
      39           0 :     return NULL;
      40           0 :   }
      41        5838 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, alignof(fd_sysvar_cache_t) ) ) ) {
      42           0 :     FD_LOG_WARNING(( "misaligned mem" ));
      43           0 :     return NULL;
      44           0 :   }
      45        5838 :   fd_sysvar_cache_t const * sysvar_cache = mem;
      46        5838 :   if( FD_UNLIKELY( sysvar_cache->magic != FD_SYSVAR_CACHE_MAGIC ) ) {
      47           0 :     FD_LOG_WARNING(( "bad magic" ));
      48           0 :     return NULL;
      49           0 :   }
      50             : 
      51        5838 :   return sysvar_cache;
      52        5838 : }
      53             : 
      54             : void *
      55        5841 : fd_sysvar_cache_leave( fd_sysvar_cache_t * sysvar_cache ) {
      56        5841 :   return sysvar_cache;
      57        5841 : }
      58             : 
      59             : void const *
      60           0 : fd_sysvar_cache_leave_const( fd_sysvar_cache_t const * sysvar_cache ) {
      61           0 :   return sysvar_cache;
      62           0 : }
      63             : 
      64             : void *
      65           0 : fd_sysvar_cache_delete( void * mem ) {
      66             : 
      67           0 :   if( FD_UNLIKELY( !mem ) ) {
      68           0 :     FD_LOG_WARNING(( "NULL mem" ));
      69           0 :     return NULL;
      70           0 :   }
      71           0 :   fd_sysvar_cache_t * sysvar_cache = mem;
      72           0 :   if( FD_UNLIKELY( sysvar_cache->magic != FD_SYSVAR_CACHE_MAGIC ) ) {
      73           0 :     FD_LOG_WARNING(( "bad magic" ));
      74           0 :     return NULL;
      75           0 :   }
      76             : 
      77           0 :   memset( sysvar_cache, 0, sizeof(fd_sysvar_cache_t) );
      78             : 
      79           0 :   return mem;
      80           0 : }
      81             : 
      82             : uchar const *
      83             : fd_sysvar_cache_data_query(
      84             :     fd_sysvar_cache_t const * sysvar_cache,
      85             :     void const *              address, /* 32 bytes */
      86             :     ulong *                   psz
      87          52 : ) {
      88          52 :   *psz = 0UL;
      89          52 :   fd_pubkey_t const pubkey = FD_LOAD( fd_pubkey_t, address );
      90          52 :   sysvar_tbl_t const * entry = sysvar_map_query( &pubkey, NULL );
      91          52 :   if( FD_UNLIKELY( !entry ) ) return NULL; /* address is not a sysvar */
      92          52 :   fd_sysvar_desc_t const * desc = &sysvar_cache->desc[ entry->desc_idx ];
      93          52 :   fd_sysvar_pos_t const *  pos  = &fd_sysvar_pos_tbl [ entry->desc_idx ];
      94          52 :   if( !( desc->flags & FD_SYSVAR_FLAG_VALID ) ) return NULL; /* sysvar data invalid */
      95          52 :   *psz = desc->data_sz;
      96          52 :   return (uchar const *)sysvar_cache + pos->data_off;
      97          52 : }
      98             : 
      99             : /* Generate accessors for sysvars that are backed by POD structs. */
     100             : 
     101             : #define SIMPLE_SYSVAR_READ( name, name2, typet )                       \
     102             :   typet *                                                              \
     103             :   fd_sysvar_cache_##name##_read( fd_sysvar_cache_t const * cache,      \
     104       80437 :                                  typet *                   out ) {     \
     105       80437 :     ulong const idx = FD_SYSVAR_##name##_IDX;                          \
     106       80437 :     fd_sysvar_desc_t const * desc = &cache->desc[ idx ];               \
     107       80437 :     fd_sysvar_pos_t const *  pos  = &fd_sysvar_pos_tbl[ idx ];         \
     108       80437 :     if( FD_UNLIKELY( !( desc->flags & FD_SYSVAR_FLAG_VALID ) ) ) return NULL; \
     109       80437 :     memcpy( out, (uchar *)cache+pos->obj_off, pos->obj_max );          \
     110       77170 :     return out;                                                        \
     111       80437 :   }
     112             : 
     113             : #define SIMPLE_SYSVAR( name, name2, type ) \
     114             :   SIMPLE_SYSVAR_READ( name, name2, fd_##type##_t )
     115             : FD_SYSVAR_SIMPLE_ITER( SIMPLE_SYSVAR )
     116             : #undef SIMPLE_SYSVAR
     117             : #undef SIMPLE_SYSVAR_READ
     118             : 
     119             : fd_block_block_hash_entry_t const * /* deque */
     120             : fd_sysvar_cache_recent_hashes_join_const(
     121             :     fd_sysvar_cache_t const * cache
     122       24984 : ) {
     123       24984 :   if( FD_UNLIKELY( !fd_sysvar_cache_recent_hashes_is_valid( cache ) ) ) return NULL;
     124       24984 :   fd_recent_block_hashes_global_t * var = (void *)cache->obj_recent_hashes;
     125       24984 :   fd_block_block_hash_entry_t * deq = deq_fd_block_block_hash_entry_t_join( (uchar *)var+var->hashes_offset );
     126       24984 :   if( FD_UNLIKELY( !deq ) ) FD_LOG_CRIT(( "recent blockhashes sysvar corruption detected" ));
     127       24984 :   return deq; /* demote to const ptr */
     128       24984 : }
     129             : 
     130             : void
     131             : fd_sysvar_cache_recent_hashes_leave_const(
     132             :     fd_sysvar_cache_t const *           sysvar_cache,
     133             :     fd_block_block_hash_entry_t const * hashes_deque
     134       24973 : ) {
     135       24973 :   (void)sysvar_cache; (void)hashes_deque;
     136       24973 : }
     137             : 
     138             : fd_slot_hash_t const *
     139             : fd_sysvar_cache_slot_hashes_join_const(
     140             :     fd_sysvar_cache_t const * cache
     141        5314 : ) {
     142        5314 :   if( FD_UNLIKELY( !fd_sysvar_cache_slot_hashes_is_valid( cache ) ) ) return NULL;
     143        5314 :   fd_slot_hashes_global_t * var = (void *)cache->obj_slot_hashes;
     144        5314 :   fd_slot_hash_t * deq = deq_fd_slot_hash_t_join( (uchar *)var+var->hashes_offset );
     145             :   /* If the above is_valid check is passed, then join is guaranteed to succeed */
     146        5314 :   if( FD_UNLIKELY( !deq ) ) FD_LOG_CRIT(( "slot hashes sysvar corruption detected" ));
     147        5314 :   return deq; /* demote to const ptr */
     148        5314 : }
     149             : 
     150             : void
     151             : fd_sysvar_cache_slot_hashes_leave_const(
     152             :     fd_sysvar_cache_t const * sysvar_cache,
     153             :     fd_slot_hash_t const *    slot_hashes
     154        5317 : ) {
     155        5317 :   (void)sysvar_cache; (void)slot_hashes;
     156        5317 : }
     157             : 
     158             : fd_slot_history_global_t const *
     159             : fd_sysvar_cache_slot_history_join_const(
     160             :     fd_sysvar_cache_t const * cache
     161           0 : ) {
     162           0 :   if( FD_UNLIKELY( !fd_sysvar_cache_slot_history_is_valid( cache ) ) ) return NULL;
     163           0 :   return (void const *)( cache->obj_slot_history );
     164           0 : }
     165             : 
     166             : void
     167             : fd_sysvar_cache_slot_history_leave_const(
     168             :     fd_sysvar_cache_t const *        sysvar_cache,
     169             :     fd_slot_history_global_t const * slot_history
     170           0 : ) {
     171           0 :   (void)sysvar_cache; (void)slot_history;
     172           0 : }
     173             : 
     174             : fd_stake_history_t const *
     175             : fd_sysvar_cache_stake_history_join_const(
     176             :     fd_sysvar_cache_t const * cache
     177           0 : ) {
     178           0 :   if( FD_UNLIKELY( !fd_sysvar_cache_stake_history_is_valid( cache ) ) ) return NULL;
     179           0 :   return (void const *)cache->obj_stake_history;
     180           0 : }
     181             : 
     182             : void
     183             : fd_sysvar_cache_stake_history_leave_const(
     184             :     fd_sysvar_cache_t const *  sysvar_cache,
     185             :     fd_stake_history_t const * stake_history
     186           0 : ) {
     187           0 :   (void)sysvar_cache; (void)stake_history;
     188           0 : }
     189             : 
     190             : int
     191             : fd_sysvar_obj_restore( fd_sysvar_cache_t *     cache,
     192             :                        fd_sysvar_desc_t *      desc,
     193      198912 :                        fd_sysvar_pos_t const * pos ) {
     194      198912 :   desc->flags &= ~FD_SYSVAR_FLAG_VALID;
     195             : 
     196      198912 :   uchar const * data    = (uchar const *)cache + pos->data_off;
     197      198912 :   ulong const   data_sz = desc->data_sz;
     198             : 
     199      198912 :   if( FD_UNLIKELY( !pos->obj_max ) ) {
     200             :     /* Sysvar is directly stored - does not need to be deserialized */
     201           0 :     desc->flags |= FD_SYSVAR_FLAG_VALID;
     202           0 :     FD_LOG_DEBUG(( "Restored sysvar %s (data_sz=%lu)", pos->name, data_sz ));
     203           0 :     return 0;
     204           0 :   }
     205             : 
     206      198912 :   fd_bincode_decode_ctx_t ctx = { .data=data, .dataend=data+data_sz };
     207      198912 :   ulong obj_sz = 0UL;
     208      198912 :   if( FD_UNLIKELY( pos->decode_footprint( &ctx, &obj_sz )!=FD_BINCODE_SUCCESS ) ) {
     209        3069 :     FD_LOG_DEBUG(( "Failed to decode sysvar %s with data_sz=%lu: decode failed",
     210        3069 :                    pos->name, data_sz ));
     211        3069 :     return EINVAL;
     212        3069 :   }
     213      195843 :   if( FD_UNLIKELY( obj_sz > pos->obj_max ) ) {
     214           0 :     FD_LOG_WARNING(( "Failed to restore sysvar %s: obj_sz=%lu exceeds max=%u",
     215           0 :                      pos->name, obj_sz, pos->obj_max ));
     216           0 :     return ENOMEM;
     217           0 :   }
     218      195843 :   pos->decode( (uchar *)cache+pos->obj_off, &ctx );
     219      195843 :   desc->flags |= FD_SYSVAR_FLAG_VALID;
     220             : 
     221      195843 :   FD_LOG_DEBUG(( "Restored sysvar %s (data_sz=%lu obj_sz=%lu)",
     222      195843 :                  pos->name, data_sz, obj_sz ));
     223      195843 :   return 0;
     224      195843 : }

Generated by: LCOV version 1.14