LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_acc_mgr.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 62 92 67.4 %
Date: 2025-07-01 05:00:49 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_t const *  txn,
       8             :                                fd_pubkey_t const *    pubkey,
       9             :                                fd_funk_rec_t const ** orec,
      10             :                                int *                  opt_err,
      11          57 :                                fd_funk_txn_t const ** txn_out  ) {
      12          57 :   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          57 :   for ( ; ; ) {
      19             : 
      20          57 :     fd_funk_rec_query_t   query[1];
      21          57 :     fd_funk_txn_t const * dummy_txn_out[1];
      22          57 :     if( !txn_out ) txn_out    = dummy_txn_out;
      23          57 :     fd_funk_rec_t const * rec = fd_funk_rec_query_try_global( funk, txn, &id, txn_out, query );
      24             : 
      25          57 :     if( FD_UNLIKELY( !rec || !!( rec->flags & FD_FUNK_REC_FLAG_ERASE ) ) )  {
      26          12 :       fd_int_store_if( !!opt_err, opt_err, FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT );
      27          12 :       return NULL;
      28          12 :     }
      29          45 :     if( NULL != orec )
      30          15 :       *orec = rec;
      31             : 
      32          45 :     void const * raw = fd_funk_val( rec, fd_funk_wksp(funk) );
      33             : 
      34          45 :     fd_account_meta_t const * metadata = fd_type_pun_const( raw );
      35          45 :     if( FD_UNLIKELY( metadata->magic != FD_ACCOUNT_META_MAGIC ) ) {
      36           0 :       fd_int_store_if( !!opt_err, opt_err, FD_ACC_MGR_ERR_WRONG_MAGIC );
      37           0 :       return NULL;
      38           0 :     }
      39             : 
      40          45 :     if( FD_LIKELY( fd_funk_rec_query_test( query ) == FD_FUNK_SUCCESS ) ) {
      41          45 :       return metadata;
      42          45 :     }
      43             : 
      44          45 :   }
      45             : 
      46             :   /* unreachable */
      47           0 :   return NULL;
      48          57 : }
      49             : 
      50             : fd_account_meta_t *
      51             : fd_funk_get_acc_meta_mutable( fd_funk_t *             funk,
      52             :                               fd_funk_txn_t *         txn,
      53             :                               fd_pubkey_t const *     pubkey,
      54             :                               int                     do_create,
      55             :                               ulong                   min_data_sz,
      56             :                               fd_funk_rec_t **        opt_out_rec,
      57             :                               fd_funk_rec_prepare_t * out_prepare,
      58          30 :                               int *                   opt_err ) {
      59          30 :   fd_wksp_t *       wksp = fd_funk_wksp(funk);
      60          30 :   fd_funk_rec_key_t id   = fd_funk_acc_key( pubkey );
      61             : 
      62          30 :   fd_funk_rec_query_t query[1];
      63          30 :   fd_funk_rec_t * rec = (fd_funk_rec_t *)fd_funk_rec_query_try( funk, txn, &id, query );
      64             : 
      65          30 :   int funk_err = 0;
      66             : 
      67             :   /* the record does not exist in the current funk transaction */
      68          30 :   if( !rec ) {
      69             :     /* clones a record from an ancestor transaction */
      70          24 :     rec = fd_funk_rec_clone( funk, txn, &id, out_prepare, &funk_err );
      71             : 
      72          24 :     if( rec == NULL ) {
      73             :       /* the record does not exist at all */
      74          21 :       if( FD_LIKELY( funk_err==FD_FUNK_ERR_KEY ) ) {
      75             :         /* create a new record */
      76          21 :         if( do_create ) {
      77          21 :           rec = fd_funk_rec_prepare( funk, txn, &id, out_prepare, &funk_err );
      78          21 :           if( rec == NULL ) {
      79             :             /* Irrecoverable funky internal error [[noreturn]] */
      80           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 ) ));
      81           0 :           }
      82          21 :         } else {
      83           0 :           fd_int_store_if( !!opt_err, opt_err, FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT );
      84           0 :           return NULL;
      85           0 :         }
      86          21 :       } else {
      87             :         /* Irrecoverable funky internal error [[noreturn]] */
      88           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 ) ));
      89           0 :       }
      90          21 :     }
      91          24 :   }
      92             : 
      93          30 :   ulong sz = sizeof(fd_account_meta_t)+min_data_sz;
      94          30 :   void * val;
      95          30 :   if( fd_funk_val_sz( rec ) < sz ) {
      96          21 :     val = fd_funk_val_truncate(
      97          21 :         rec,
      98          21 :         fd_funk_alloc( funk ),
      99          21 :         wksp,
     100          21 :         0UL,
     101          21 :         sz,
     102          21 :         &funk_err );
     103          21 :     if( FD_UNLIKELY( !val ) ) FD_LOG_CRIT(( "fd_funk_val_truncate(sz=%lu) failed (%i-%s)", sz, funk_err, fd_funk_strerror( funk_err ) ));
     104          21 :   } else {
     105           9 :     val = fd_funk_val( rec, wksp );
     106           9 :   }
     107             : 
     108          30 :   if (NULL != opt_out_rec) {
     109          30 :     *opt_out_rec = rec;
     110          30 :   }
     111             : 
     112          30 :   fd_account_meta_t * meta = val;
     113          30 :   if( do_create && meta->magic==0UL ) {
     114          21 :     fd_account_meta_init( meta );
     115          21 :   }
     116          30 :   if( meta->magic != FD_ACCOUNT_META_MAGIC ) {
     117           0 :     fd_int_store_if( !!opt_err, opt_err, FD_ACC_MGR_ERR_WRONG_MAGIC );
     118           0 :     return NULL;
     119           0 :   }
     120             : 
     121          30 :   return meta;
     122          30 : }
     123             : 
     124             : FD_FN_CONST char const *
     125           0 : fd_acc_mgr_strerror( int err ) {
     126           0 :   switch( err ) {
     127           0 :   case FD_ACC_MGR_SUCCESS:
     128           0 :     return "success";
     129           0 :   case FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT:
     130           0 :     return "unknown account";
     131           0 :   case FD_ACC_MGR_ERR_WRITE_FAILED:
     132           0 :     return "write failed";
     133           0 :   case FD_ACC_MGR_ERR_READ_FAILED:
     134           0 :     return "read failed";
     135           0 :   case FD_ACC_MGR_ERR_WRONG_MAGIC:
     136           0 :     return "wrong magic";
     137           0 :   default:
     138           0 :     return "unknown";
     139           0 :   }
     140           0 : }

Generated by: LCOV version 1.14