LCOV - code coverage report
Current view: top level - flamenco/accdb - fd_accdb_sync.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 6 39 15.4 %
Date: 2025-12-06 04:45:29 Functions: 2 904 0.2 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_accdb_fd_accdb_sync_h
       2             : #define HEADER_fd_src_flamenco_accdb_fd_accdb_sync_h
       3             : 
       4             : /* fd_accdb_sync.h provides synchronous blocking APIs for the account
       5             :    database.  These are slow and should only be used for management ops. */
       6             : 
       7             : #include "fd_accdb_user.h"
       8             : 
       9             : /* Speculative zero-copy read API *************************************/
      10             : 
      11             : FD_PROTOTYPES_BEGIN
      12             : 
      13             : /* fd_accdb_peek_try starts a speculative read of an account.  Queries
      14             :    the account database cache for the given address.  On success,
      15             :    returns peek, which holds a speculative reference to an account.  Use
      16             :    fd_accdb_peek_test to confirm whether peek is still valid.
      17             : 
      18             :    Typical usage like:
      19             : 
      20             :      fd_accdb_peek_t peek[1];
      21             :      if( !fd_accdb_peek( accdb, ... ) ) {
      22             :        ... account not found ...
      23             :        return;
      24             :      }
      25             :      ... speculatively process account ...
      26             :      if( fd_accdb_peek_test( peek )!=FD_ACCDB_SUCCESS ) {
      27             :        ... data race detected ...
      28             :        return;
      29             :      }
      30             :      ... happy path ... */
      31             : 
      32             : static inline fd_accdb_peek_t *
      33             : fd_accdb_peek( fd_accdb_user_t *         accdb,
      34             :                fd_accdb_peek_t *         peek,
      35             :                fd_funk_txn_xid_t const * xid,
      36           0 :                void const *              address ) {
      37           0 :   return accdb->base.vt->peek( accdb, peek, xid, address );
      38           0 : }
      39             : 
      40             : /* fd_accdb_peek_test verifies whether a previously taken peek still
      41             :    refers to valid account data.  Returns 1 if still valid, 0 if peek
      42             :    may have seen a conflict. */
      43             : 
      44             : FD_FN_PURE static inline int
      45           3 : fd_accdb_peek_test( fd_accdb_peek_t const * peek ) {
      46           3 :   return fd_accdb_spec_test( peek->spec );
      47           3 : }
      48             : 
      49             : /* fd_accdb_peek_drop releases the caller's interest in the account. */
      50             : 
      51             : static inline void
      52           0 : fd_accdb_peek_drop( fd_accdb_peek_t * peek ) {
      53           0 :   fd_accdb_spec_drop( peek->spec );
      54           0 : }
      55             : 
      56             : FD_PROTOTYPES_END
      57             : 
      58             : /* In-place read APIs *************************************************/
      59             : 
      60             : static inline fd_accdb_ro_t *
      61             : fd_accdb_open_ro( fd_accdb_user_t *         accdb,
      62             :                   fd_accdb_ro_t *           ro,
      63             :                   fd_funk_txn_xid_t const * txn_id,
      64           0 :                   void const *              address ) {
      65           0 :   return accdb->base.vt->open_ro( accdb, ro, txn_id, address );
      66           0 : }
      67             : 
      68             : static inline void
      69             : fd_accdb_close_ro( fd_accdb_user_t * accdb,
      70           0 :                    fd_accdb_ro_t *   ro ) {
      71           0 :   accdb->base.vt->close_ro( accdb, ro );
      72           0 : }
      73             : 
      74             : /* FD_ACDB_RO_{BEGIN,END} provides RAII-style safe macros for
      75             :    fd_accdb_{open,close}_ro.
      76             : 
      77             :    Typical usage like:
      78             : 
      79             :      FD_ACCDB_RO_BEGIN( accdb, ro, xid, address ) {
      80             :        FD_LOG_NOTICE(( "Account has %lu lamports", fd_accdb_ref_lamports( ro ) ));
      81             :      }
      82             :      FD_ACCDB_RO_NOT_FOUND {
      83             :        FD_LOG_NOTICE(( "Account does not exist" ));
      84             :      }
      85             :      FD_ACCDB_RO_END; */
      86             : 
      87             : struct fd_accdb_ro_scope_guard {
      88             :   fd_accdb_user_t * accdb;
      89             :   fd_accdb_ro_t *   ro;
      90             : };
      91             : typedef struct fd_accdb_ro_scope_guard fd_accdb_ro_scope_guard_t;
      92             : 
      93             : FD_FN_UNUSED static inline void
      94           0 : fd_accdb_ro_scope_exit( fd_accdb_ro_scope_guard_t * guard ) {
      95           0 :   fd_accdb_close_ro( guard->accdb, guard->ro );
      96           0 : }
      97             : 
      98             : #define FD_ACCDB_RO_BEGIN( accdb__, handle, xid, address)              \
      99           0 :   {                                                                    \
     100           0 :     fd_accdb_ro_t     handle[1];                                       \
     101           0 :     fd_accdb_user_t * accdb_ = (accdb__);                              \
     102           0 :     void const *      addr_ = (address);                               \
     103           0 :     if( fd_accdb_open_ro( accdb, handle, (xid), addr_ ) ) {            \
     104           0 :       fd_accdb_ro_scope_guard_t __attribute__((cleanup(fd_accdb_ro_scope_exit))) guard_ = \
     105           0 :         { .accdb=accdb_, .ro=handle };                                 \
     106           0 :       (void)guard_;                                                    \
     107           0 :       {                                                                \
     108             :         /* User-provided account found snippet */
     109             : #define FD_ACCDB_RO_NOT_FOUND                                          \
     110           0 :       }                                                                \
     111           0 :     } else {                                                           \
     112           0 :       {                                                                \
     113             :         /* User-provided account not found snippet */
     114             : #define FD_ACCDB_RO_END                                                \
     115           0 :       }                                                                \
     116           0 :     }                                                                  \
     117           0 :   }
     118             : 
     119             : /* In-place transactional write APIs **********************************/
     120             : 
     121             : FD_PROTOTYPES_BEGIN
     122             : 
     123             : /* fd_accdb_open_rw starts an account modification op.  txn_xid names a
     124             :    non-rooted non-frozen fork graph node, and address identifies the
     125             :    account.  If the account data buffer is smaller than data_max, it is
     126             :    resized (does not affect the data size, just the buffer capacity).
     127             :    If do_create==0, returns NULL if the account does not exist.
     128             :    Otherwise, returns an existing or newly created account.
     129             : 
     130             :    For the entire lifetime of an rw handle, the (txn_xid,address) pair
     131             :    MUST NOT be accessed by any other ro or rw operation.  Violating this
     132             :    rule causes undefined behavior.  The lifetime of an rw handle starts
     133             :    as soon as open_rw is called.  It ends once all memory writes done
     134             :    after the close_rw call returns are visible to all other DB user
     135             :    threads.
     136             : 
     137             :    It is fine to do multiple open_rw/close_rw interactions with the same
     138             :    (txn_xid,address) pair assuming proper synchronization.  Only the
     139             :    final state for a (txn_xid,address) pair is retained. */
     140             : 
     141             : static inline fd_accdb_rw_t *
     142             : fd_accdb_open_rw( fd_accdb_user_t *         accdb,
     143             :                   fd_accdb_rw_t *           rw,
     144             :                   fd_funk_txn_xid_t const * txn_id,
     145             :                   void const *              address,
     146             :                   ulong                     data_max,
     147         498 :                   int                       do_create ) {
     148         498 :   return accdb->base.vt->open_rw( accdb, rw, txn_id, address, data_max, do_create );
     149         498 : }
     150             : 
     151             : /* fd_accdb_close_rw publishes a previously prepared account write.
     152             :    Note that this function returns before memory writes have propagated
     153             :    to other threads, thus requires external synchronization. */
     154             : 
     155             : static inline void
     156             : fd_accdb_close_rw( fd_accdb_user_t * accdb,
     157           0 :                    fd_accdb_rw_t *   write ) { /* destroyed */
     158           0 :   accdb->base.vt->close_rw( accdb, write );
     159           0 : }
     160             : 
     161             : FD_PROTOTYPES_END
     162             : 
     163             : #endif /* HEADER_fd_src_flamenco_accdb_fd_accdb_sync_h */

Generated by: LCOV version 1.14