LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_acc_mgr.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 55 80 68.8 %
Date: 2025-10-13 04:42:14 Functions: 2 3 66.7 %

          Line data    Source code
       1             : #include "fd_acc_mgr.h"
       2             : #include "../../ballet/base58/fd_base58.h"
       3             : #include "../../funk/fd_funk.h"
       4             : 
       5             : fd_account_meta_t const *
       6             : fd_funk_get_acc_meta_readonly( fd_funk_t const *         funk,
       7             :                                fd_funk_txn_xid_t const * xid,
       8             :                                fd_pubkey_t const *       pubkey,
       9             :                                fd_funk_rec_t const **    orec,
      10             :                                int *                     opt_err,
      11        4209 :                                fd_funk_txn_xid_t *       out_xid ) {
      12        4209 :   fd_funk_rec_key_t id = fd_funk_acc_key( pubkey );
      13             : 
      14             :   /* When we access this pointer later on in the execution pipeline, we assume that
      15             :      nothing else will change that account. If the account is writable in the solana txn,
      16             :      then we copy the data. If the account is read-only, we do not. This is safe because of
      17             :      the read-write locks that the solana transaction holds on the account. */
      18        4209 :   for( ; ; ) {
      19             : 
      20        4209 :     fd_funk_rec_query_t   query[1];
      21        4209 :     fd_funk_rec_t const * rec = fd_funk_rec_query_try_global( funk, xid, &id, out_xid, query );
      22             : 
      23        4209 :     if( FD_UNLIKELY( !rec ) )  {
      24        3675 :       fd_int_store_if( !!opt_err, opt_err, FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT );
      25        3675 :       return NULL;
      26        3675 :     }
      27         534 :     if( NULL != orec )
      28           0 :       *orec = rec;
      29             : 
      30         534 :     void const * raw = fd_funk_val( rec, fd_funk_wksp(funk) );
      31             : 
      32         534 :     fd_account_meta_t const * metadata = fd_type_pun_const( raw );
      33         534 :     if( FD_LIKELY( fd_funk_rec_query_test( query ) == FD_FUNK_SUCCESS ) ) {
      34         534 :       return metadata;
      35         534 :     }
      36             : 
      37         534 :   }
      38             : 
      39             :   /* unreachable */
      40           0 :   return NULL;
      41        4209 : }
      42             : 
      43             : fd_account_meta_t *
      44             : fd_funk_get_acc_meta_mutable( fd_funk_t *               funk,
      45             :                               fd_funk_txn_xid_t const * xid,
      46             :                               fd_pubkey_t const *       pubkey,
      47             :                               int                       do_create,
      48             :                               ulong                     min_data_sz,
      49             :                               fd_funk_rec_t **          opt_out_rec,
      50             :                               fd_funk_rec_prepare_t *   out_prepare,
      51         510 :                               int *                     opt_err ) {
      52         510 :   fd_wksp_t *       wksp = fd_funk_wksp(funk);
      53         510 :   fd_funk_rec_key_t id   = fd_funk_acc_key( pubkey );
      54             : 
      55         510 :   fd_funk_rec_query_t query[1];
      56         510 :   fd_funk_rec_t * rec = (fd_funk_rec_t *)fd_funk_rec_query_try( funk, xid, &id, query );
      57             : 
      58         510 :   int funk_err = 0;
      59             : 
      60             :   /* the record does not exist in the current funk transaction */
      61         510 :   if( !rec ) {
      62             :     /* clones a record from an ancestor transaction */
      63          45 :     rec = fd_funk_rec_clone( funk, xid, &id, out_prepare, &funk_err );
      64             : 
      65          45 :     if( rec == NULL ) {
      66             :       /* the record does not exist at all */
      67          45 :       if( FD_LIKELY( funk_err==FD_FUNK_ERR_KEY ) ) {
      68             :         /* create a new record */
      69          45 :         if( do_create ) {
      70          45 :           rec = fd_funk_rec_prepare( funk, xid, &id, out_prepare, &funk_err );
      71          45 :           if( rec == NULL ) {
      72             :             /* Irrecoverable funky internal error [[noreturn]] */
      73           0 :             FD_LOG_ERR(( "fd_funk_rec_write_prepare(%s) failed (%i-%s)", FD_BASE58_ENC_32_ALLOCA( pubkey->key ), funk_err, fd_funk_strerror( funk_err ) ));
      74           0 :           }
      75          45 :         } else {
      76           0 :           fd_int_store_if( !!opt_err, opt_err, FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT );
      77           0 :           return NULL;
      78           0 :         }
      79          45 :       } else {
      80             :         /* Irrecoverable funky internal error [[noreturn]] */
      81           0 :         FD_LOG_ERR(( "fd_funk_rec_write_prepare(%s) failed (%i-%s)", FD_BASE58_ENC_32_ALLOCA( pubkey->key ), funk_err, fd_funk_strerror( funk_err ) ));
      82           0 :       }
      83          45 :     }
      84          45 :   }
      85             : 
      86         510 :   ulong sz = sizeof(fd_account_meta_t)+min_data_sz;
      87         510 :   void * val;
      88         510 :   if( fd_funk_val_sz( rec ) < sz ) {
      89          48 :     val = fd_funk_val_truncate(
      90          48 :         rec,
      91          48 :         fd_funk_alloc( funk ),
      92          48 :         wksp,
      93          48 :         0UL,
      94          48 :         sz,
      95          48 :         &funk_err );
      96          48 :     if( FD_UNLIKELY( !val ) ) FD_LOG_CRIT(( "fd_funk_val_truncate(sz=%lu) failed (%i-%s)", sz, funk_err, fd_funk_strerror( funk_err ) ));
      97         462 :   } else {
      98         462 :     val = fd_funk_val( rec, wksp );
      99         462 :   }
     100             : 
     101         510 :   if (NULL != opt_out_rec) {
     102           0 :     *opt_out_rec = rec;
     103           0 :   }
     104             : 
     105         510 :   fd_account_meta_t * meta = val;
     106         510 :   if( do_create && meta->lamports==0UL ) {
     107          54 :     fd_account_meta_init( meta );
     108          54 :   }
     109             : 
     110         510 :   return meta;
     111         510 : }
     112             : 
     113             : FD_FN_CONST char const *
     114           0 : fd_acc_mgr_strerror( int err ) {
     115           0 :   switch( err ) {
     116           0 :   case FD_ACC_MGR_SUCCESS:
     117           0 :     return "success";
     118           0 :   case FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT:
     119           0 :     return "unknown account";
     120           0 :   case FD_ACC_MGR_ERR_WRITE_FAILED:
     121           0 :     return "write failed";
     122           0 :   case FD_ACC_MGR_ERR_READ_FAILED:
     123           0 :     return "read failed";
     124           0 :   default:
     125           0 :     return "unknown";
     126           0 :   }
     127           0 : }

Generated by: LCOV version 1.14