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

Generated by: LCOV version 1.14