LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_acc_mgr.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 14 37 37.8 %
Date: 2025-09-18 04:41:32 Functions: 5 756 0.7 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_runtime_fd_acc_mgr_h
       2             : #define HEADER_fd_src_flamenco_runtime_fd_acc_mgr_h
       3             : 
       4             : /* fd_acc_mgr provides APIs for the Solana account database. */
       5             : 
       6             : #include "../fd_flamenco_base.h"
       7             : #include "../../ballet/txn/fd_txn.h"
       8             : #include "fd_txn_account.h"
       9             : 
      10             : #if FD_HAS_AVX
      11             : #include "../../util/simd/fd_avx.h"
      12             : #endif
      13             : 
      14             : /* FD_ACC_MGR_{SUCCESS,ERR{...}} are account management specific error codes.
      15             :    To be stored in an int. */
      16             : 
      17        6162 : #define FD_ACC_MGR_SUCCESS             (0)
      18        7806 : #define FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT (-1)
      19           0 : #define FD_ACC_MGR_ERR_WRITE_FAILED    (-2)
      20           0 : #define FD_ACC_MGR_ERR_READ_FAILED     (-3)
      21             : 
      22           0 : #define FD_ACC_NONCE_SZ_MAX (80UL)     /* 80 bytes */
      23             : 
      24             : /* FD_ACC_TOT_SZ_MAX is the size limit of a Solana account in the firedancer
      25             :    client. This means that it includes the max size of the account (10MiB)
      26             :    and the associated metadata. */
      27             : 
      28           0 : #define FD_ACC_TOT_SZ_MAX       (FD_RUNTIME_ACC_SZ_MAX + sizeof(fd_account_meta_t))
      29             : 
      30           0 : #define FD_ACC_NONCE_TOT_SZ_MAX (FD_ACC_NONCE_SZ_MAX + sizeof(fd_account_meta_t))
      31             : 
      32             : FD_PROTOTYPES_BEGIN
      33             : 
      34             : /* Account Management APIs **************************************************/
      35             : 
      36             : /* The following account management APIs are helpers for fd_account_meta_t creation,
      37             :    existence, and retrieval from funk */
      38             : 
      39             : static inline void
      40          42 : fd_account_meta_init( fd_account_meta_t * m ) {
      41          42 :   fd_memset( m, 0, sizeof(fd_account_meta_t) );
      42          42 : }
      43             : 
      44             : /* fd_account_meta_exists checks if the account in a funk record exists or was
      45             :    deleted.  Handles NULL input safely.  Returns 0 if the account was
      46             :    deleted (zero lamports, empty data, zero owner).  Otherwise, returns
      47             :    1. */
      48             : 
      49             : static inline int
      50           0 : fd_account_meta_exists( fd_account_meta_t const * m ) {
      51             : 
      52           0 :   if( !m ) return 0;
      53             : 
      54           0 : # if FD_HAS_AVX
      55           0 :   wl_t o = wl_ldu( m->owner );
      56           0 :   int has_owner = !_mm256_testz_si256( o, o );
      57             : # else
      58             :   int has_owner = 0;
      59             :   for( ulong i=0UL; i<32UL; i++ )
      60             :     has_owner |= m->owner[i];
      61             :   has_owner = !!has_owner;
      62             : # endif
      63             : 
      64           0 :   return ((m->lamports > 0UL) |
      65           0 :           (m->dlen     > 0UL) |
      66           0 :           (has_owner        ) );
      67             : 
      68           0 : }
      69             : 
      70             : /* Account meta helpers */
      71             : static inline void *
      72           3 : fd_account_meta_get_data( fd_account_meta_t * m ) {
      73           3 :   return ((uchar *) m) + sizeof(fd_account_meta_t);
      74           3 : }
      75             : 
      76             : static inline void const *
      77           0 : fd_account_meta_get_data_const( fd_account_meta_t const * m ) {
      78           0 :   return ((uchar const *) m) + sizeof(fd_account_meta_t);
      79           0 : }
      80             : 
      81             : static inline ulong
      82           0 : fd_account_meta_get_record_sz( fd_account_meta_t const * m ) {
      83           0 :   return sizeof(fd_account_meta_t) + m->dlen;
      84           0 : }
      85             : 
      86             : /* Funk key handling **************************************************/
      87             : 
      88             : /* fd_acc_funk_key returns a fd_funk database key given an account
      89             :    address. */
      90             : 
      91             : FD_FN_PURE static inline fd_funk_rec_key_t
      92        5184 : fd_funk_acc_key( fd_pubkey_t const * pubkey ) {
      93        5184 :   fd_funk_rec_key_t key = {0};
      94        5184 :   memcpy( key.uc, pubkey, sizeof(fd_pubkey_t) );
      95        5184 :   key.uc[ FD_FUNK_REC_KEY_FOOTPRINT - 1 ] = FD_FUNK_KEY_TYPE_ACC;
      96        5184 :   return key;
      97        5184 : }
      98             : 
      99             : /* fd_funk_key_is_acc returns 1 if given fd_funk key is an account
     100             :    and 0 otherwise. */
     101             : 
     102             : FD_FN_PURE static inline int
     103           0 : fd_funk_key_is_acc( fd_funk_rec_key_t const * id ) {
     104           0 :   return id->uc[ FD_FUNK_REC_KEY_FOOTPRINT - 1 ] == FD_FUNK_KEY_TYPE_ACC;
     105           0 : }
     106             : 
     107             : /* Account Access from Funk APIs *************************************************/
     108             : 
     109             : /* The following fd_funk_acc_mgr APIs translate between the runtime account DB abstraction
     110             :    and the actual funk database.
     111             : 
     112             :    ### Translation
     113             : 
     114             :    Each runtime account is backed by a funk record.  However, not all
     115             :    funk records contain an account.  Funk records may temporarily hold
     116             :    "deleted accounts".
     117             : 
     118             :    The memory layout of the account funk record data is
     119             :    (fd_account_meta_t, padding, account data). */
     120             : 
     121             : /* fd_funk_get_acc_meta_readonly requests a read-only handle to account data.
     122             :    funk is the database handle.  txn is the database
     123             :    transaction to query.  pubkey is the account key to query.
     124             : 
     125             :    On success:
     126             :    - loads the account data into in-memory cache
     127             :    - returns a pointer to it in the caller's local address space
     128             :    - if out_rec!=NULL, sets *out_rec to a pointer to the funk rec.
     129             :      This handle is suitable as opt_con_rec for fd_funk_get_acc_meta_readonly.
     130             :    - notably, leaves *opt_err untouched, even if opt_err!=NULL
     131             : 
     132             :    First byte of returned pointer is first byte of fd_account_meta_t.
     133             :    To find data region of account, add sizeof(fd_account_meta_t).
     134             : 
     135             :    Lifetime of returned fd_funk_rec_t and account record pointers ends
     136             :    when user calls modify_data for same account, or tranasction ends.
     137             : 
     138             :    On failure, returns NULL, and sets *opt_err if opt_err!=NULL.
     139             :    Reasons for error include
     140             :    - account not found
     141             :    - internal database or user error (out of memory, attempting to view
     142             :      record which has an active modify_data handle, etc.)
     143             : 
     144             :    It is always wrong to cast return value to a non-const pointer.
     145             :    Instead, use fd_funk_get_acc_meta_mutable to acquire a mutable handle.
     146             : 
     147             :    if txn_out is supplied (non-null), the txn the key was found in
     148             :    is returned. If *txn_out == NULL, the key was found in the root
     149             :    context.
     150             : 
     151             :    IMPORTANT: fd_funk_get_acc_meta_readonly is only safe if it
     152             :    is guaranteed there are no other modifying accesses to the account. */
     153             : 
     154             : fd_account_meta_t const *
     155             : fd_funk_get_acc_meta_readonly( fd_funk_t const *      funk,
     156             :                                fd_funk_txn_t const *  txn,
     157             :                                fd_pubkey_t const *    pubkey,
     158             :                                fd_funk_rec_t const ** opt_out_rec,
     159             :                                int *                  opt_err,
     160             :                                fd_funk_txn_t const ** txn_out );
     161             : 
     162             : /* fd_funk_get_acc_meta_mutable requests a writable handle to an account.
     163             :    Follows interface of fd_funk_get_account_meta_readonly with the following
     164             :    changes:
     165             : 
     166             :    - do_create controls behavior if account does not exist.  If set to
     167             :      0, returns error.  If set to 1, creates account with given size
     168             :      and zero-initializes metadata.  Caller must initialize metadata of
     169             :      returned handle in this case.
     170             :    - min_data_sz is the minimum writable data size that the caller will
     171             :      accept.  This parameter will never shrink an existing account.  If
     172             :      do_create, specifies the new account's size.  Otherwise, increases
     173             :      record size if necessary.
     174             :    - When resizing or creating an account, the caller should also always
     175             :      set the account meta's size field.  This is not done automatically.
     176             :    - If caller already has a read-only handle to the requested account,
     177             :      opt_con_rec can be used to skip query by pubkey.
     178             :    - In most cases, account is copied to "dirty cache".
     179             : 
     180             :    On success:
     181             :    - If opt_out_rec!=NULL, sets *opt_out_rec to a pointer to writable
     182             :      funk rec.
     183             :    - If a record was cloned from an ancestor funk txn or created,
     184             :      out_prepare is populated with the prepared record object.
     185             :    - Returns pointer to mutable account metadata and data analogous to
     186             :      fd_funk_get_acc_meta_readonly.
     187             :    - IMPORTANT:  Return value may point to the same memory region as a
     188             :      previous calls to fd_funk_get_acc_meta_readonly or fd_funk_get_acc_meta_mutable do,
     189             :      for the same funk rec (account/txn pair).  fd_funk_acc_mgr APIs only promises
     190             :      that account handles requested for different funk txns will not
     191             :      alias. Generally, for each funk txn, the user should only ever
     192             :      access the latest handle returned by view/modify.
     193             : 
     194             :    IMPORTANT: fd_funk_get_acc_meta_mutable can only be called if
     195             :    it is guaranteed that there are no other modifying accesses to
     196             :    that account. */
     197             : 
     198             : fd_account_meta_t *
     199             : fd_funk_get_acc_meta_mutable( fd_funk_t *             funk,
     200             :                               fd_funk_txn_t *         txn,
     201             :                               fd_pubkey_t const *     pubkey,
     202             :                               int                     do_create,
     203             :                               ulong                   min_data_sz,
     204             :                               fd_funk_rec_t **        opt_out_rec,
     205             :                               fd_funk_rec_prepare_t * out_prepare,
     206             :                               int *                   opt_err );
     207             : 
     208             : /* fd_acc_mgr_strerror converts an fd_acc_mgr error code into a human
     209             :    readable cstr.  The lifetime of the returned pointer is infinite and
     210             :    the call itself is thread safe.  The returned pointer is always to a
     211             :    non-NULL cstr. */
     212             : 
     213             : FD_FN_CONST char const *
     214             : fd_acc_mgr_strerror( int err );
     215             : 
     216             : FD_PROTOTYPES_END
     217             : 
     218             : #endif /* HEADER_fd_src_flamenco_runtime_fd_acc_mgr_h */

Generated by: LCOV version 1.14