LCOV - code coverage report
Current view: top level - flamenco/accdb - fd_accdb_ref.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 19 72 26.4 %
Date: 2025-12-06 04:45:29 Functions: 6 1984 0.3 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_accdb_fd_accdb_ref_h
       2             : #define HEADER_fd_src_flamenco_accdb_fd_accdb_ref_h
       3             : 
       4             : /* fd_accdb_ref.h provides account database handle classes.
       5             : 
       6             :    - accdb_ref is an opaque handle to an account database cache entry.
       7             :    - accdb_ro (extends accdb_ref) represents a read-only handle.
       8             :    - accdb_rw (extends accdb_ro) represents a read-write handle.
       9             : 
      10             :    - accdb_guardr is a read-only account lock guard
      11             :    - accdb_guardw is an exclusive account lock guard
      12             :    - accdb_spec is an account speculative read guard
      13             : 
      14             :    These APIs sit between the database layer (abstracts away backing
      15             :    stores and DB specifics) and the runtime layer (offer no runtime
      16             :    protections). */
      17             : 
      18             : #include "../fd_flamenco_base.h"
      19             : #include "../../funk/fd_funk_rec.h"
      20             : #include "../../funk/fd_funk_val.h"
      21             : 
      22             : /* fd_accdb_ref_t is an opaque account database handle. */
      23             : 
      24             : struct fd_accdb_ref {
      25             :   ulong rec_laddr;
      26             :   ulong meta_laddr;
      27             :   uchar address[32];  /* only for vinyl requests */
      28             : };
      29             : typedef struct fd_accdb_ref fd_accdb_ref_t;
      30             : 
      31             : /* fd_accdb_ro_t is a readonly account database handle. */
      32             : 
      33             : union fd_accdb_ro {
      34             :   fd_accdb_ref_t ref[1];
      35             :   struct {
      36             :     fd_funk_rec_t const *     rec;
      37             :     fd_account_meta_t const * meta;
      38             :   };
      39             : };
      40             : typedef union fd_accdb_ro fd_accdb_ro_t;
      41             : 
      42             : FD_PROTOTYPES_BEGIN
      43             : 
      44             : static inline void const *
      45           3 : fd_accdb_ref_data_const( fd_accdb_ro_t const * ro ) {
      46           3 :   return (void *)( ro->meta+1 );
      47           3 : }
      48             : 
      49             : static inline ulong
      50         459 : fd_accdb_ref_data_sz( fd_accdb_ro_t const * ro ) {
      51         459 :   return ro->meta->dlen;
      52         459 : }
      53             : 
      54             : static inline ulong
      55           3 : fd_accdb_ref_lamports( fd_accdb_ro_t const * ro ) {
      56           3 :   return ro->meta->lamports;
      57           3 : }
      58             : 
      59             : static inline void const *
      60           3 : fd_accdb_ref_owner( fd_accdb_ro_t const * ro ) {
      61           3 :   return ro->meta->owner;
      62           3 : }
      63             : 
      64             : static inline uint
      65           3 : fd_accdb_ref_exec_bit( fd_accdb_ro_t const * ro ) {
      66           3 :   return !!ro->meta->executable;
      67           3 : }
      68             : 
      69             : static inline ulong
      70           0 : fd_accdb_ref_slot( fd_accdb_ro_t const * ro ) {
      71           0 :   return ro->meta->slot;
      72           0 : }
      73             : 
      74             : // void
      75             : // fd_accdb_ref_lthash( fd_accdb_ro_t const * ro,
      76             : //                      void *                lthash );
      77             : 
      78             : FD_PROTOTYPES_END
      79             : 
      80             : /* fd_accdb_rw_t is a writable database handle.  Typically, writable
      81             :    handles are only available for invisible/in-prepartion records.
      82             :    In rare cases (e.g. when booting up), components may directly write
      83             :    to globally visible writable records. */
      84             : 
      85             : union fd_accdb_rw {
      86             :   fd_accdb_ref_t ref[1];
      87             :   fd_accdb_ro_t  ro [1];
      88             :   struct {
      89             :     fd_funk_rec_t *     rec;
      90             :     fd_account_meta_t * meta;
      91             :     uint                published : 1;
      92             :   };
      93             : };
      94             : typedef union fd_accdb_rw fd_accdb_rw_t;
      95             : 
      96             : FD_PROTOTYPES_BEGIN
      97             : 
      98             : // void
      99             : // fd_accdb_ref_clear( fd_accdb_rw_t * rw );
     100             : 
     101             : static inline ulong
     102           0 : fd_accdb_ref_data_max( fd_accdb_rw_t * rw ) {
     103           0 :   ulong data_max;
     104           0 :   if( FD_UNLIKELY( __builtin_usubl_overflow( rw->rec->val_max, sizeof(fd_account_meta_t), &data_max ) ) ) {
     105           0 :     FD_LOG_CRIT(( "invalid rec->val_max %lu for account at rec %p", (ulong)rw->rec->val_max, (void *)rw->rec ));
     106           0 :   }
     107           0 :   return data_max;
     108           0 : }
     109             : 
     110             : static inline void *
     111           0 : fd_accdb_ref_data( fd_accdb_rw_t * rw ) {
     112           0 :   return (void *)( rw->meta+1 );
     113           0 : }
     114             : 
     115             : static inline void
     116             : fd_accdb_ref_data_set( fd_accdb_rw_t * rw,
     117             :                        void const *    data,
     118           0 :                        ulong           data_sz ) {
     119           0 :   ulong data_max = fd_accdb_ref_data_max( rw );
     120           0 :   if( FD_UNLIKELY( data_sz>data_max ) ) {
     121           0 :     FD_LOG_CRIT(( "attempted to write %lu bytes into a rec %p with only %lu bytes of data space",
     122           0 :                   data_sz, (void *)rw->rec, data_max ));
     123           0 :   }
     124           0 :   fd_memcpy( fd_accdb_ref_data( rw ), data, data_sz );
     125           0 :   rw->meta->dlen  = (uint)data_sz;
     126           0 :   rw->rec->val_sz = (uint)( sizeof(fd_account_meta_t)+data_sz ) & (FD_FUNK_REC_VAL_MAX-1);
     127           0 : }
     128             : 
     129             : FD_FN_UNUSED static void
     130             : fd_accdb_ref_data_sz_set( fd_accdb_rw_t * rw,
     131           0 :                           ulong           data_sz ) {
     132           0 :   ulong prev_sz = rw->meta->dlen;
     133           0 :   if( data_sz>prev_sz ) {
     134           0 :     /* Increasing size, zero out tail */
     135           0 :     ulong data_max = fd_accdb_ref_data_max( rw );
     136           0 :     if( FD_UNLIKELY( data_sz>data_max ) ) {
     137           0 :       FD_LOG_CRIT(( "attempted to write %lu bytes into a rec %p with only %lu bytes of data space",
     138           0 :                     data_sz, (void *)rw->rec, data_max ));
     139           0 :     }
     140           0 :     void * tail = (uchar *)fd_accdb_ref_data( rw ) + prev_sz;
     141           0 :     fd_memset( tail, 0, data_sz-prev_sz );
     142           0 :   }
     143           0 :   rw->meta->dlen  = (uint)data_sz;
     144           0 :   rw->rec->val_sz = (uint)( sizeof(fd_account_meta_t)+data_sz ) & (FD_FUNK_REC_VAL_MAX-1);
     145           0 : }
     146             : 
     147             : static inline void
     148             : fd_accdb_ref_lamports_set( fd_accdb_rw_t * rw,
     149           0 :                            ulong           lamports ) {
     150           0 :   rw->meta->lamports = lamports;
     151           0 : }
     152             : 
     153             : static inline void
     154             : fd_accdb_ref_owner_set( fd_accdb_rw_t * rw,
     155           0 :                         void const *    owner ) {
     156           0 :   memcpy( rw->meta->owner, owner, 32UL );
     157           0 : }
     158             : 
     159             : static inline void
     160             : fd_accdb_ref_exec_bit_set( fd_accdb_rw_t * rw,
     161           0 :                            uint            exec_bit ) {
     162           0 :   rw->meta->executable = !!exec_bit;
     163           0 : }
     164             : 
     165             : static inline void
     166             : fd_accdb_ref_slot_set( fd_accdb_rw_t * rw,
     167           0 :                        ulong           slot ) {
     168           0 :   rw->meta->slot = slot;
     169           0 : }
     170             : 
     171             : FD_PROTOTYPES_END
     172             : 
     173             : /* fd_accdb_guardr_t tracks a rwlock being held as read-only.
     174             :    Destroying this guard object detaches the caller's thread from the
     175             :    rwlock. */
     176             : 
     177             : struct fd_accbd_guardr {
     178             :   fd_rwlock_t * rwlock;
     179             : };
     180             : 
     181             : typedef struct fd_accdb_guardr fd_accdb_guardr_t;
     182             : 
     183             : /* fd_accdb_guardw_t tracks an rwlock being held exclusively.
     184             :    Destroying this guard object detaches the caller's thread from the
     185             :    lock. */
     186             : 
     187             : struct fd_accdb_guardw {
     188             :   fd_rwlock_t * rwlock;
     189             : };
     190             : 
     191             : typedef struct fd_accdb_guardw fd_accdb_guardw_t;
     192             : 
     193             : /* fd_accdb_spec_t tracks a speculative access to a shared resource.
     194             :    Destroying this guard object marks the end of a speculative access. */
     195             : 
     196             : struct fd_accdb_spec {
     197             :   fd_funk_rec_key_t * keyp;       /* shared key */
     198             :   fd_funk_rec_key_t   key;        /* expected key */
     199             : };
     200             : 
     201             : typedef struct fd_accdb_spec fd_accdb_spec_t;
     202             : 
     203             : /* fd_accdb_spec_test returns 1 if the shared resources has not been
     204             :    invalidated up until now.  Returns 0 if the speculative access may
     205             :    have possibly seen a conflict (e.g. a torn read, a use-after-free,
     206             :    etc). */
     207             : 
     208             : static inline int
     209           3 : fd_accdb_spec_test( fd_accdb_spec_t const * spec ) {
     210           3 :   fd_funk_rec_key_t key_found = FD_VOLATILE_CONST( *spec->keyp );
     211           3 :   return !!fd_funk_rec_key_eq( &key_found, &spec->key );
     212           3 : }
     213             : 
     214             : /* fd_accdb_spec_drop marks the end of a speculative access. */
     215             : 
     216             : static inline void
     217           0 : fd_accdb_spec_drop( fd_accdb_spec_t * spec ) {
     218             :   /* Speculative accesses do not need central synchronization, so no
     219             :      need to inform the holder of the resource of this drop. */
     220           0 :   (void)spec;
     221           0 : }
     222             : 
     223             : /* fd_accdb_peek_t is an ephemeral lock-free read-only pointer to an
     224             :    account in database cache. */
     225             : 
     226             : struct fd_accdb_peek {
     227             :   fd_accdb_ro_t   acc[1];
     228             :   fd_accdb_spec_t spec[1];
     229             : };
     230             : 
     231             : typedef struct fd_accdb_peek fd_accdb_peek_t;
     232             : 
     233             : #endif /* HEADER_fd_src_flamenco_accdb_fd_accdb_ref_h */

Generated by: LCOV version 1.14