LCOV - code coverage report
Current view: top level - flamenco/runtime/sysvar - fd_sysvar_cache.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 121 0.0 %
Date: 2025-03-20 12:08:36 Functions: 0 33 0.0 %

          Line data    Source code
       1             : #include "fd_sysvar_cache.h"
       2             : #include "../fd_acc_mgr.h"
       3             : #include "../fd_executor.h"
       4             : #include "../fd_system_ids.h"
       5             : #include "../context/fd_exec_instr_ctx.h"
       6             : #include "../context/fd_exec_txn_ctx.h"
       7             : 
       8           0 : #define FD_SYSVAR_CACHE_MAGIC (0x195a0e78828cacd5UL)
       9             : 
      10             : ulong
      11           0 : fd_sysvar_cache_align( void ) {
      12           0 :   return alignof(fd_sysvar_cache_t);
      13           0 : }
      14             : 
      15             : ulong
      16           0 : fd_sysvar_cache_footprint( void ) {
      17           0 :   return sizeof(fd_sysvar_cache_t);
      18           0 : }
      19             : 
      20             : fd_sysvar_cache_t *
      21           0 : fd_sysvar_cache_new( void * mem ) {
      22             : 
      23           0 :   if( FD_UNLIKELY( !mem ) ) {
      24           0 :     FD_LOG_WARNING(( "NULL mem" ));
      25           0 :     return NULL;
      26           0 :   }
      27             : 
      28           0 :   fd_sysvar_cache_t * cache = (fd_sysvar_cache_t *)mem;
      29           0 :   fd_memset( cache, 0, sizeof(fd_sysvar_cache_t) );
      30             : 
      31           0 :   FD_COMPILER_MFENCE();
      32           0 :   cache->magic = FD_SYSVAR_CACHE_MAGIC;
      33           0 :   FD_COMPILER_MFENCE();
      34           0 :   return cache;
      35           0 : }
      36             : 
      37             : void *
      38           0 : fd_sysvar_cache_delete( fd_sysvar_cache_t * cache ) {
      39             : 
      40           0 :   if( FD_UNLIKELY( !cache ) ) {
      41           0 :     FD_LOG_WARNING(( "NULL cache" ));
      42           0 :     return NULL;
      43           0 :   }
      44             : 
      45           0 :   if( FD_UNLIKELY( cache->magic != FD_SYSVAR_CACHE_MAGIC ) ) {
      46           0 :     FD_LOG_WARNING(( "bad magic" ));
      47           0 :     return NULL;
      48           0 :   }
      49             : 
      50           0 :   FD_COMPILER_MFENCE();
      51           0 :   cache->magic = 0UL;
      52           0 :   FD_COMPILER_MFENCE();
      53             : 
      54             :   /* Call destroy on all objects.
      55             :      This is safe even if these objects logically don't exist
      56             :      (destroy is safe on zero-initialized values and is idempotent) */
      57           0 : # define X( type, name ) \
      58             :   //type##_destroy( cache->val_##name );
      59           0 :   FD_SYSVAR_CACHE_ITER(X)
      60           0 : # undef X
      61             : 
      62           0 :   return (void *)cache;
      63           0 : }
      64             : 
      65             : /* Provide accessor methods */
      66             : 
      67             : #define X( type, name )                                                \
      68             :   type##_global_t const *                                              \
      69           0 :   fd_sysvar_cache_##name( fd_sysvar_cache_t const * cache ) {          \
      70           0 :     type##_global_t const * val = cache->val_##name;                   \
      71           0 :     return (cache->has_##name) ? val : NULL;                           \
      72           0 :   }
      73             : FD_SYSVAR_CACHE_ITER(X)
      74             : #undef X
      75             : 
      76             : /* Restore sysvars */
      77             : 
      78             : # define X( type, name )                                                  \
      79             : void                                                                      \
      80             : fd_sysvar_cache_restore_##name(                                           \
      81             :   fd_sysvar_cache_t * cache,                                              \
      82             :   fd_acc_mgr_t *      acc_mgr,                                            \
      83             :   fd_funk_txn_t *     funk_txn,                                           \
      84             :   fd_spad_t *         runtime_spad,                                       \
      85           0 :   fd_wksp_t *         wksp ) {                                            \
      86           0 :   do {                                                                    \
      87           0 :     fd_pubkey_t const * pubkey = &fd_sysvar_##name##_id;                  \
      88           0 :     FD_TXN_ACCOUNT_DECL( account );                                       \
      89           0 :     int view_err = fd_acc_mgr_view( acc_mgr, funk_txn, pubkey, account ); \
      90           0 :     if( view_err==FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT ) break;                 \
      91           0 :                                                                           \
      92           0 :     if( view_err!=FD_ACC_MGR_SUCCESS ) {                                  \
      93           0 :       char pubkey_cstr[ FD_BASE58_ENCODED_32_SZ ];                        \
      94           0 :       FD_LOG_ERR(( "fd_acc_mgr_view(%s) failed (%d-%s)",                  \
      95           0 :                   fd_acct_addr_cstr( pubkey_cstr, pubkey->key ),          \
      96           0 :                   view_err, fd_acc_mgr_strerror( view_err ) ));           \
      97           0 :     }                                                                     \
      98           0 :                                                                           \
      99           0 :     if( account->const_meta->info.lamports == 0UL ) break;                \
     100           0 :                                                                           \
     101           0 :     /* Decode new value                                                   \
     102           0 :       type##_decode() does not do heap allocations on failure */          \
     103           0 :     fd_bincode_decode_ctx_t decode = {                                    \
     104           0 :       .data    = account->const_data,                                     \
     105           0 :       .dataend = account->const_data + account->const_meta->dlen,         \
     106           0 :       .wksp    = wksp                                                     \
     107           0 :     };                                                                    \
     108           0 :     ulong total_sz    = 0UL;                                              \
     109           0 :     int   err         = type##_decode_footprint( &decode, &total_sz );    \
     110           0 :     cache->has_##name = (err==FD_BINCODE_SUCCESS);                        \
     111           0 :     if( FD_UNLIKELY( err ) ) {                                            \
     112           0 :       break;                                                              \
     113           0 :     }                                                                     \
     114           0 :                                                                           \
     115           0 :     type##_global_t * mem = fd_spad_alloc( runtime_spad,                  \
     116           0 :                                            type##_align(),                \
     117           0 :                                            total_sz );                    \
     118           0 :     if( FD_UNLIKELY( !mem ) ) {                                           \
     119           0 :       FD_LOG_ERR(( "memory allocation failed" ));                         \
     120           0 :     }                                                                     \
     121           0 :     type##_decode_global( mem, &decode );                                 \
     122           0 :     fd_memcpy( cache->val_##name, mem, sizeof(type##_global_t) );         \
     123           0 :   } while(0);                                                             \
     124           0 : }
     125             :   FD_SYSVAR_CACHE_ITER(X)
     126             : # undef X
     127             : 
     128             : void
     129             : fd_sysvar_cache_restore( fd_sysvar_cache_t * cache,
     130             :                          fd_acc_mgr_t *      acc_mgr,
     131             :                          fd_funk_txn_t *     funk_txn,
     132             :                          fd_spad_t *         runtime_spad,
     133           0 :                          fd_wksp_t *         wksp ) {
     134           0 : # define X( type, name )                                               \
     135           0 : fd_sysvar_cache_restore_##name( cache, acc_mgr, funk_txn, runtime_spad, wksp );
     136           0 :   FD_SYSVAR_CACHE_ITER(X)
     137           0 : # undef X
     138           0 : }
     139             : 
     140             : # define X( type, name )                                               \
     141             :   type##_global_t const *                                              \
     142             :   fd_sysvar_from_instr_acct_##name( fd_exec_instr_ctx_t const * ctx,   \
     143             :                                     ulong                       idx,   \
     144           0 :                                     int *                       err ) {\
     145           0 :                                                                        \
     146           0 :     if( FD_UNLIKELY( idx >= ctx->instr->acct_cnt ) ) {                 \
     147           0 :       *err = FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;                \
     148           0 :       return NULL;                                                     \
     149           0 :     }                                                                  \
     150           0 :                                                                        \
     151           0 :     fd_sysvar_cache_t const * cache = ctx->txn_ctx->sysvar_cache;      \
     152           0 :     type##_global_t const * val = fd_sysvar_cache_##name ( cache );    \
     153           0 :                                                                        \
     154           0 :     fd_pubkey_t const * addr_have = &ctx->instr->acct_pubkeys[idx];    \
     155           0 :     fd_pubkey_t const * addr_want = &fd_sysvar_##name##_id;            \
     156           0 :     if( 0!=memcmp( addr_have, addr_want, sizeof(fd_pubkey_t) ) ) {     \
     157           0 :       *err = FD_EXECUTOR_INSTR_ERR_INVALID_ARG;                        \
     158           0 :       return NULL;                                                     \
     159           0 :     }                                                                  \
     160           0 :                                                                        \
     161           0 :     *err = val ?                                                       \
     162           0 :            FD_EXECUTOR_INSTR_SUCCESS :                                 \
     163           0 :            FD_EXECUTOR_INSTR_ERR_UNSUPPORTED_SYSVAR;                   \
     164           0 :     return val;                                                        \
     165           0 :                                                                        \
     166           0 :   }
     167             :   FD_SYSVAR_CACHE_ITER(X)
     168             : # undef X
     169             : 
     170             : /* https://github.com/anza-xyz/agave/blob/77daab497df191ef485a7ad36ed291c1874596e5/program-runtime/src/sysvar_cache.rs#L223-L234 */
     171             : int
     172             : fd_check_sysvar_account( fd_exec_instr_ctx_t const * ctx,
     173             :                          ulong                       insn_acc_idx,
     174           0 :                          fd_pubkey_t const *         expected_id ) {
     175           0 :   uchar const *       instr_acc_idxs = ctx->instr->acct_txn_idxs;
     176           0 :   fd_pubkey_t const * txn_accs       = ctx->txn_ctx->account_keys;
     177             : 
     178           0 :   if( insn_acc_idx>=ctx->instr->acct_cnt ) {
     179           0 :     return FD_EXECUTOR_INSTR_ERR_NOT_ENOUGH_ACC_KEYS;
     180           0 :   }
     181             : 
     182           0 :   fd_pubkey_t const * insn_acc_key = &txn_accs[ instr_acc_idxs[ insn_acc_idx ] ];
     183             : 
     184           0 :   if( memcmp( expected_id, insn_acc_key, sizeof(fd_pubkey_t) ) ) {
     185           0 :     return FD_EXECUTOR_INSTR_ERR_INVALID_ARG;
     186           0 :   }
     187           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
     188           0 : }

Generated by: LCOV version 1.14