LCOV - code coverage report
Current view: top level - flamenco/runtime/sysvar - fd_sysvar_cache.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 109 142 76.8 %
Date: 2025-10-13 04:42:14 Functions: 16 21 76.2 %

          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         480 : fd_sysvar_cache_new( void * mem ) {
       7             : 
       8         480 :   if( FD_UNLIKELY( !mem ) ) {
       9           3 :     FD_LOG_WARNING(( "NULL mem" ));
      10           3 :     return NULL;
      11           3 :   }
      12         477 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, alignof(fd_sysvar_cache_t) ) ) ) {
      13           3 :     FD_LOG_WARNING(( "misaligned mem" ));
      14           3 :     return NULL;
      15           3 :   }
      16             : 
      17         474 :   fd_sysvar_cache_t * sysvar_cache = mem;
      18         474 :   sysvar_cache->magic = 0UL;
      19         474 :   memset( sysvar_cache->desc, 0, FD_SYSVAR_CACHE_ENTRY_CNT*sizeof(fd_sysvar_desc_t) );
      20             : 
      21         474 :   FD_COMPILER_MFENCE();
      22         474 :   sysvar_cache->magic = FD_SYSVAR_CACHE_MAGIC;
      23         474 :   FD_COMPILER_MFENCE();
      24             : 
      25         474 :   return sysvar_cache;
      26         477 : }
      27             : 
      28             : fd_sysvar_cache_t *
      29         486 : fd_sysvar_cache_join( void * mem ) {
      30             :   /* FIXME This is a good place to ref-count writable joins */
      31         486 :   return (fd_sysvar_cache_t *)fd_sysvar_cache_join_const( mem );
      32         486 : }
      33             : 
      34             : fd_sysvar_cache_t const *
      35         495 : fd_sysvar_cache_join_const( void const * mem ) {
      36             : 
      37         495 :   if( FD_UNLIKELY( !mem ) ) {
      38           6 :     FD_LOG_WARNING(( "NULL mem" ));
      39           6 :     return NULL;
      40           6 :   }
      41         489 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, alignof(fd_sysvar_cache_t) ) ) ) {
      42           6 :     FD_LOG_WARNING(( "misaligned mem" ));
      43           6 :     return NULL;
      44           6 :   }
      45         483 :   fd_sysvar_cache_t const * sysvar_cache = mem;
      46         483 :   if( FD_UNLIKELY( sysvar_cache->magic != FD_SYSVAR_CACHE_MAGIC ) ) {
      47           6 :     FD_LOG_WARNING(( "bad magic" ));
      48           6 :     return NULL;
      49           6 :   }
      50             : 
      51         477 :   return sysvar_cache;
      52         483 : }
      53             : 
      54             : void *
      55         474 : fd_sysvar_cache_leave( fd_sysvar_cache_t * sysvar_cache ) {
      56         474 :   return sysvar_cache;
      57         474 : }
      58             : 
      59             : void const *
      60           3 : fd_sysvar_cache_leave_const( fd_sysvar_cache_t const * sysvar_cache ) {
      61           3 :   return sysvar_cache;
      62           3 : }
      63             : 
      64             : void *
      65          21 : fd_sysvar_cache_delete( void * mem ) {
      66             : 
      67          21 :   if( FD_UNLIKELY( !mem ) ) {
      68           3 :     FD_LOG_WARNING(( "NULL mem" ));
      69           3 :     return NULL;
      70           3 :   }
      71          18 :   fd_sysvar_cache_t * sysvar_cache = mem;
      72          18 :   if( FD_UNLIKELY( sysvar_cache->magic != FD_SYSVAR_CACHE_MAGIC ) ) {
      73           3 :     FD_LOG_WARNING(( "bad magic" ));
      74           3 :     return NULL;
      75           3 :   }
      76             : 
      77          15 :   memset( sysvar_cache, 0, sizeof(fd_sysvar_cache_t) );
      78             : 
      79          15 :   return mem;
      80          18 : }
      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         492 : ) {
      88         492 :   *psz = 0UL;
      89         492 :   fd_pubkey_t const pubkey = FD_LOAD( fd_pubkey_t, address );
      90         492 :   sysvar_tbl_t const * entry = sysvar_map_query( &pubkey, NULL );
      91         492 :   if( FD_UNLIKELY( !entry ) ) return NULL; /* address is not a sysvar */
      92         489 :   fd_sysvar_desc_t const * desc = &sysvar_cache->desc[ entry->desc_idx ];
      93         489 :   fd_sysvar_pos_t const *  pos  = &fd_sysvar_pos_tbl [ entry->desc_idx ];
      94         489 :   if( !( desc->flags & FD_SYSVAR_FLAG_VALID ) ) return NULL; /* sysvar data invalid */
      95         462 :   *psz = desc->data_sz;
      96         462 :   return (uchar const *)sysvar_cache + pos->data_off;
      97         489 : }
      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          18 :                                  typet *                   out ) {     \
     105          18 :     ulong const idx = FD_SYSVAR_##name##_IDX;                          \
     106          18 :     fd_sysvar_desc_t const * desc = &cache->desc[ idx ];               \
     107          18 :     fd_sysvar_pos_t const *  pos  = &fd_sysvar_pos_tbl[ idx ];         \
     108          18 :     if( FD_UNLIKELY( !( desc->flags & FD_SYSVAR_FLAG_VALID ) ) ) return NULL; \
     109          18 :     memcpy( out, (uchar *)cache+pos->obj_off, pos->obj_max );          \
     110           3 :     return out;                                                        \
     111          18 :   }
     112             : 
     113             : #define SIMPLE_SYSVAR( name, name2, type ) \
     114             :   SIMPLE_SYSVAR_READ( name, name2, fd_##type##_t )
     115          15 : FD_SYSVAR_SIMPLE_ITER( SIMPLE_SYSVAR )
     116          15 : #undef SIMPLE_SYSVAR
     117          15 : #undef SIMPLE_SYSVAR_READ
     118          15 : 
     119          15 : fd_block_block_hash_entry_t const * /* deque */
     120          15 : fd_sysvar_cache_recent_hashes_join_const(
     121          15 :     fd_sysvar_cache_t const * cache
     122          15 : ) {
     123           0 :   if( FD_UNLIKELY( !fd_sysvar_cache_recent_hashes_is_valid( cache ) ) ) return NULL;
     124           0 :   fd_recent_block_hashes_global_t * var = (void *)cache->obj_recent_hashes;
     125           0 :   fd_block_block_hash_entry_t * deq = deq_fd_block_block_hash_entry_t_join( (uchar *)var+var->hashes_offset );
     126           0 :   if( FD_UNLIKELY( !deq ) ) FD_LOG_CRIT(( "recent blockhashes sysvar corruption detected" ));
     127           0 :   return deq; /* demote to const ptr */
     128           0 : }
     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           0 : ) {
     135           0 :   (void)sysvar_cache; (void)hashes_deque;
     136           0 : }
     137             : 
     138             : fd_slot_hash_t const *
     139             : fd_sysvar_cache_slot_hashes_join_const(
     140             :     fd_sysvar_cache_t const * cache
     141           3 : ) {
     142           3 :   if( FD_UNLIKELY( !fd_sysvar_cache_slot_hashes_is_valid( cache ) ) ) return NULL;
     143           0 :   fd_slot_hashes_global_t * var = (void *)cache->obj_slot_hashes;
     144           0 :   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           0 :   if( FD_UNLIKELY( !deq ) ) FD_LOG_CRIT(( "slot hashes sysvar corruption detected" ));
     147           0 :   return deq; /* demote to const ptr */
     148           0 : }
     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           0 : ) {
     155           0 :   (void)sysvar_cache; (void)slot_hashes;
     156           0 : }
     157             : 
     158             : fd_slot_history_global_t const *
     159             : fd_sysvar_cache_slot_history_join_const(
     160             :     fd_sysvar_cache_t const * cache
     161           3 : ) {
     162           3 :   if( FD_UNLIKELY( !fd_sysvar_cache_slot_history_is_valid( cache ) ) ) return NULL;
     163           0 :   return (void const *)( cache->obj_slot_history );
     164           3 : }
     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           3 : ) {
     178           3 :   if( FD_UNLIKELY( !fd_sysvar_cache_stake_history_is_valid( cache ) ) ) return NULL;
     179           0 :   return (void const *)cache->obj_stake_history;
     180           3 : }
     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         465 :                        fd_sysvar_pos_t const * pos ) {
     194         465 :   desc->flags &= ~FD_SYSVAR_FLAG_VALID;
     195             : 
     196         465 :   uchar const * data    = (uchar const *)cache + pos->data_off;
     197         465 :   ulong const   data_sz = desc->data_sz;
     198             : 
     199         465 :   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         465 :   fd_bincode_decode_ctx_t ctx = { .data=data, .dataend=data+data_sz };
     207         465 :   ulong obj_sz = 0UL;
     208         465 :   if( FD_UNLIKELY( pos->decode_footprint( &ctx, &obj_sz )!=FD_BINCODE_SUCCESS ) ) {
     209           3 :     FD_LOG_DEBUG(( "Failed to decode sysvar %s with data_sz=%lu: decode failed",
     210           3 :                    pos->name, data_sz ));
     211           3 :     return EINVAL;
     212           3 :   }
     213         462 :   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         462 :   pos->decode( (uchar *)cache+pos->obj_off, &ctx );
     219         462 :   desc->flags |= FD_SYSVAR_FLAG_VALID;
     220             : 
     221         462 :   FD_LOG_DEBUG(( "Restored sysvar %s (data_sz=%lu obj_sz=%lu)",
     222         462 :                  pos->name, data_sz, obj_sz ));
     223         462 :   return 0;
     224         462 : }

Generated by: LCOV version 1.14