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-08-05 05:04: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        4188 :                                fd_funk_txn_t const ** txn_out  ) {
      12        4188 :   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        4188 :   for ( ; ; ) {
      19             : 
      20        4188 :     fd_funk_rec_query_t   query[1];
      21        4188 :     fd_funk_txn_t const * dummy_txn_out[1];
      22        4188 :     if( !txn_out ) txn_out    = dummy_txn_out;
      23        4188 :     fd_funk_rec_t const * rec = fd_funk_rec_query_try_global( funk, txn, &id, txn_out, query );
      24             : 
      25        4188 :     if( FD_UNLIKELY( !rec || !!( rec->flags & FD_FUNK_REC_FLAG_ERASE ) ) )  {
      26        3675 :       fd_int_store_if( !!opt_err, opt_err, FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT );
      27        3675 :       return NULL;
      28        3675 :     }
      29         513 :     if( NULL != orec )
      30         513 :       *orec = rec;
      31             : 
      32         513 :     void const * raw = fd_funk_val( rec, fd_funk_wksp(funk) );
      33             : 
      34         513 :     fd_account_meta_t const * metadata = fd_type_pun_const( raw );
      35         513 :     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         513 :     if( FD_LIKELY( fd_funk_rec_query_test( query ) == FD_FUNK_SUCCESS ) ) {
      41         513 :       return metadata;
      42         513 :     }
      43             : 
      44         513 :   }
      45             : 
      46             :   /* unreachable */
      47           0 :   return NULL;
      48        4188 : }
      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         489 :                               int *                   opt_err ) {
      59         489 :   fd_wksp_t *       wksp = fd_funk_wksp(funk);
      60         489 :   fd_funk_rec_key_t id   = fd_funk_acc_key( pubkey );
      61             : 
      62         489 :   fd_funk_rec_query_t query[1];
      63         489 :   fd_funk_rec_t * rec = (fd_funk_rec_t *)fd_funk_rec_query_try( funk, txn, &id, query );
      64             : 
      65         489 :   int funk_err = 0;
      66             : 
      67             :   /* the record does not exist in the current funk transaction */
      68         489 :   if( !rec ) {
      69             :     /* clones a record from an ancestor transaction */
      70          36 :     rec = fd_funk_rec_clone( funk, txn, &id, out_prepare, &funk_err );
      71             : 
      72          36 :     if( rec == NULL ) {
      73             :       /* the record does not exist at all */
      74          36 :       if( FD_LIKELY( funk_err==FD_FUNK_ERR_KEY ) ) {
      75             :         /* create a new record */
      76          36 :         if( do_create ) {
      77          36 :           rec = fd_funk_rec_prepare( funk, txn, &id, out_prepare, &funk_err );
      78          36 :           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          36 :         } else {
      83           0 :           fd_int_store_if( !!opt_err, opt_err, FD_ACC_MGR_ERR_UNKNOWN_ACCOUNT );
      84           0 :           return NULL;
      85           0 :         }
      86          36 :       } 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          36 :     }
      91          36 :   }
      92             : 
      93         489 :   ulong sz = sizeof(fd_account_meta_t)+min_data_sz;
      94         489 :   void * val;
      95         489 :   if( fd_funk_val_sz( rec ) < sz ) {
      96          36 :     val = fd_funk_val_truncate(
      97          36 :         rec,
      98          36 :         fd_funk_alloc( funk ),
      99          36 :         wksp,
     100          36 :         0UL,
     101          36 :         sz,
     102          36 :         &funk_err );
     103          36 :     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         453 :   } else {
     105         453 :     val = fd_funk_val( rec, wksp );
     106         453 :   }
     107             : 
     108         489 :   if (NULL != opt_out_rec) {
     109         489 :     *opt_out_rec = rec;
     110         489 :   }
     111             : 
     112         489 :   fd_account_meta_t * meta = val;
     113         489 :   if( do_create && meta->magic==0UL ) {
     114          36 :     fd_account_meta_init( meta );
     115          36 :   }
     116         489 :   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         489 :   return meta;
     122         489 : }
     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