LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_txn_account.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 179 339 52.8 %
Date: 2025-10-27 04:40:00 Functions: 22 38 57.9 %

          Line data    Source code
       1             : #include "fd_txn_account.h"
       2             : #include "fd_runtime.h"
       3             : #include "../accdb/fd_accdb_sync.h"
       4             : #include "program/fd_program_util.h"
       5             : 
       6             : void *
       7             : fd_txn_account_new( void *              mem,
       8             :                     fd_pubkey_t const * pubkey,
       9             :                     fd_account_meta_t * meta,
      10        1041 :                     int                 is_mutable ) {
      11        1041 :   if( FD_UNLIKELY( !mem ) ) {
      12           3 :     FD_LOG_WARNING(( "NULL mem" ));
      13           3 :     return NULL;
      14           3 :   }
      15             : 
      16        1038 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, alignof(fd_txn_account_t) ) ) ) {
      17           0 :     FD_LOG_WARNING(( "misaligned mem" ));
      18           0 :     return NULL;
      19           0 :   }
      20             : 
      21        1038 :   if( FD_UNLIKELY( !pubkey ) ) {
      22           3 :     FD_LOG_WARNING(( "NULL pubkey" ));
      23           3 :     return NULL;
      24           3 :   }
      25             : 
      26        1035 :   if( FD_UNLIKELY( !meta ) ) {
      27           3 :     FD_LOG_WARNING(( "NULL meta" ));
      28           3 :     return NULL;
      29           3 :   }
      30             : 
      31        1032 :   fd_txn_account_t * txn_account = (fd_txn_account_t *)mem;
      32             : 
      33        1032 :   fd_memcpy( txn_account->pubkey, pubkey, sizeof(fd_pubkey_t) );
      34             : 
      35        1032 :   txn_account->magic             = FD_TXN_ACCOUNT_MAGIC;
      36             : 
      37        1032 :   txn_account->starting_dlen     = meta->dlen;
      38        1032 :   txn_account->starting_lamports = meta->lamports;
      39             : 
      40        1032 :   uchar * data = (uchar *)meta + sizeof(fd_account_meta_t);
      41             : 
      42        1032 :   txn_account->meta_soff = (long)( (ulong)meta - (ulong)mem );
      43             : 
      44        1032 :   txn_account->meta       = meta;
      45        1032 :   txn_account->data       = data;
      46        1032 :   txn_account->is_mutable = is_mutable;
      47             : 
      48        1032 :   return mem;
      49        1035 : }
      50             : 
      51             : fd_txn_account_t *
      52        1047 : fd_txn_account_join( void * mem, fd_wksp_t * data_wksp ) {
      53        1047 :   if( FD_UNLIKELY( !mem ) ) {
      54           3 :     FD_LOG_WARNING(( "NULL mem" ));
      55           3 :     return NULL;
      56           3 :   }
      57             : 
      58        1044 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, alignof(fd_txn_account_t) ) ) ) {
      59           0 :     FD_LOG_WARNING(( "misaligned mem" ));
      60           0 :     return NULL;
      61           0 :   }
      62             : 
      63        1044 :   if( FD_UNLIKELY( !data_wksp ) ) {
      64           3 :     FD_LOG_WARNING(( "NULL data_wksp" ));
      65           3 :     return NULL;
      66           3 :   }
      67             : 
      68        1041 :   fd_txn_account_t * txn_account = (fd_txn_account_t *)mem;
      69             : 
      70        1041 :   if( FD_UNLIKELY( txn_account->magic != FD_TXN_ACCOUNT_MAGIC ) ) {
      71           6 :     FD_LOG_WARNING(( "wrong magic" ));
      72           6 :     return NULL;
      73           6 :   }
      74             : 
      75        1035 :   if( FD_UNLIKELY( txn_account->meta_soff==0UL ) ) {
      76           0 :     FD_LOG_CRIT(( "invalid meta_soff" ));
      77           0 :   }
      78             : 
      79        1035 :   txn_account->meta = (void *)( (ulong)mem + (ulong)txn_account->meta_soff );
      80        1035 :   txn_account->data = (void *)( (ulong)txn_account->meta + sizeof(fd_account_meta_t) );
      81             : 
      82        1035 :   return txn_account;
      83        1035 : }
      84             : 
      85             : void *
      86          15 : fd_txn_account_leave( fd_txn_account_t * acct ) {
      87             : 
      88          15 :   if( FD_UNLIKELY( !acct ) ) {
      89           3 :     FD_LOG_WARNING(( "NULL acct" ));
      90           3 :     return NULL;
      91           3 :   }
      92             : 
      93          12 :   if( FD_UNLIKELY( acct->magic != FD_TXN_ACCOUNT_MAGIC ) ) {
      94           0 :     FD_LOG_WARNING(( "wrong magic" ));
      95           0 :     return NULL;
      96           0 :   }
      97             : 
      98          12 :   acct->meta = NULL;
      99          12 :   acct->data = NULL;
     100             : 
     101          12 :   return acct;
     102          12 : }
     103             : 
     104             : void *
     105           9 : fd_txn_account_delete( void * mem ) {
     106           9 :   if( FD_UNLIKELY( !mem ) ) {
     107           3 :     FD_LOG_WARNING(( "NULL mem" ));
     108           3 :     return NULL;
     109           3 :   }
     110             : 
     111           6 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, alignof(fd_txn_account_t) ) ) ) {
     112           0 :     FD_LOG_WARNING(( "misaligned mem" ));
     113           0 :     return NULL;
     114           0 :   }
     115             : 
     116           6 :   fd_txn_account_t * txn_account = (fd_txn_account_t *)mem;
     117             : 
     118           6 :   if( FD_UNLIKELY( txn_account->magic != FD_TXN_ACCOUNT_MAGIC ) ) {
     119           0 :     FD_LOG_WARNING(( "wrong magic" ));
     120           0 :     return NULL;
     121           0 :   }
     122             : 
     123           6 :   txn_account->magic = 0UL;
     124             : 
     125           6 :   return mem;
     126           6 : }
     127             : 
     128             : /* Factory constructors from funk */
     129             : 
     130             : int
     131             : fd_txn_account_init_from_funk_readonly( fd_txn_account_t *        acct,
     132             :                                         fd_pubkey_t const *       pubkey,
     133             :                                         fd_funk_t const *         funk,
     134        4149 :                                         fd_funk_txn_xid_t const * xid ) {
     135             : 
     136        4149 :   int err = FD_ACC_MGR_SUCCESS;
     137        4149 :   fd_account_meta_t const * meta = fd_funk_get_acc_meta_readonly(
     138        4149 :       funk,
     139        4149 :       xid,
     140        4149 :       pubkey,
     141        4149 :       NULL,
     142        4149 :       &err,
     143        4149 :       NULL );
     144             : 
     145        4149 :   if( FD_UNLIKELY( err!=FD_ACC_MGR_SUCCESS ) ) {
     146        3672 :     return err;
     147        3672 :   }
     148             : 
     149         477 :   if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new(
     150         477 :         acct,
     151         477 :         pubkey,
     152         477 :         (fd_account_meta_t *)meta,
     153         477 :         0 ), fd_funk_wksp( funk ) ) ) ) {
     154           0 :     FD_LOG_CRIT(( "Failed to join txn account" ));
     155           0 :   }
     156             : 
     157         477 :   return FD_ACC_MGR_SUCCESS;
     158         477 : }
     159             : 
     160             : fd_account_meta_t *
     161             : fd_txn_account_init_from_funk_mutable( fd_txn_account_t *        acct,
     162             :                                        fd_pubkey_t const *       pubkey,
     163             :                                        fd_accdb_user_t *         accdb,
     164             :                                        fd_funk_txn_xid_t const * xid,
     165             :                                        int                       do_create,
     166             :                                        ulong                     min_data_sz,
     167         507 :                                        fd_funk_rec_prepare_t *   prepare_out ) {
     168         507 :   memset( prepare_out, 0, sizeof(fd_funk_rec_prepare_t) );
     169             : 
     170         507 :   fd_accdb_rw_t rw[1];
     171         507 :   if( FD_UNLIKELY( !fd_accdb_modify_prepare( accdb, rw, xid, pubkey->uc, min_data_sz, do_create ) ) ) {
     172           0 :     return NULL;
     173           0 :   }
     174             : 
     175         507 :   if( FD_UNLIKELY( !fd_txn_account_join( fd_txn_account_new(
     176         507 :         acct,
     177         507 :         pubkey,
     178         507 :         rw->meta,
     179         507 :         1 ), fd_funk_wksp( accdb->funk ) ) ) ) {
     180           0 :     FD_LOG_CRIT(( "Failed to join txn account" ));
     181           0 :   }
     182             : 
     183             :   /* HACKY: Convert accdb_rw writable reference into txn_account.
     184             :      In the future, use fd_accdb_modify_publish instead */
     185         507 :   accdb->rw_active--;
     186         507 :   fd_funk_txn_t * txn = accdb->funk->txn_pool->ele + accdb->tip_txn_idx;
     187         507 :   if( FD_UNLIKELY( !fd_funk_txn_xid_eq( &txn->xid, xid ) ) ) FD_LOG_CRIT(( "accdb_user corrupt: not joined to the expected transaction" ));
     188         507 :   if( !rw->published ) {
     189          45 :     *prepare_out = (fd_funk_rec_prepare_t) {
     190          45 :       .rec          = rw->rec,
     191          45 :       .rec_head_idx = &txn->rec_head_idx,
     192          45 :       .rec_tail_idx = &txn->rec_tail_idx
     193          45 :     };
     194         462 :   } else {
     195         462 :     memset( prepare_out, 0, sizeof(fd_funk_rec_prepare_t) );
     196         462 :   }
     197             : 
     198         507 :   return rw->meta;
     199         507 : }
     200             : 
     201             : void
     202             : fd_txn_account_mutable_fini( fd_txn_account_t *      acct,
     203             :                              fd_accdb_user_t *       accdb,
     204         507 :                              fd_funk_rec_prepare_t * prepare ) {
     205         507 :   fd_funk_rec_key_t key = fd_funk_acc_key( acct->pubkey );
     206             : 
     207             :   /* Check that the prepared record is still valid -
     208             :      if these invariants are broken something is very wrong. */
     209         507 :   if( prepare->rec ) {
     210             :     /* Check that the prepared record is not the Funk null value */
     211          45 :     if( !prepare->rec->val_gaddr ) {
     212           0 :       FD_LOG_CRIT(( "invalid prepared record for %s: unexpected NULL funk record value. the record might have been modified by another thread",
     213           0 :                    FD_BASE58_ENC_32_ALLOCA( acct->pubkey ) ));
     214           0 :     }
     215             : 
     216             :     /* Ensure that the prepared record key still matches our key. */
     217          45 :     if( FD_UNLIKELY( memcmp( prepare->rec->pair.key, &key, sizeof(fd_funk_rec_key_t) )!=0 ) ) {
     218           0 :       FD_LOG_CRIT(( "invalid prepared record for %s: the record might have been modified by another thread",
     219           0 :                   FD_BASE58_ENC_32_ALLOCA( acct->pubkey ) ));
     220           0 :     }
     221             : 
     222             :     /* Crashes the app if this key already exists in funk (conflicting
     223             :        write) */
     224          45 :     fd_funk_rec_publish( accdb->funk, prepare );
     225          45 :   }
     226         507 : }
     227             : 
     228             : /* read/write mutual exclusion */
     229             : 
     230             : FD_FN_PURE int
     231           0 : fd_txn_account_acquire_write_is_safe( fd_txn_account_t const * acct ) {
     232           0 :   return !acct->refcnt_excl;
     233           0 : }
     234             : 
     235             : /* fd_txn_account_acquire_write acquires write/exclusive access.
     236             :    Causes all other write or read acquire attempts will fail.  Returns 1
     237             :    on success, 0 on failure.
     238             : 
     239             :    Mirrors a try_borrow_mut() call in Agave. */
     240             : int
     241           0 : fd_txn_account_acquire_write( fd_txn_account_t * acct ) {
     242           0 :   if( FD_UNLIKELY( !fd_txn_account_acquire_write_is_safe( acct ) ) ) {
     243           0 :     return 0;
     244           0 :   }
     245           0 :   acct->refcnt_excl = (ushort)1;
     246           0 :   return 1;
     247           0 : }
     248             : 
     249             : /* fd_txn_account_release_write{_private} releases a write/exclusive
     250             :    access handle. The private version should only be used by fd_borrowed_account_drop
     251             :    and fd_borrowed_account_destroy. */
     252             : void
     253           0 : fd_txn_account_release_write( fd_txn_account_t * acct ) {
     254           0 :   if( FD_UNLIKELY( acct->refcnt_excl!=1 ) ) {
     255           0 :     FD_LOG_CRIT(( "refcnt_excl is %d, expected 1", acct->refcnt_excl ));
     256           0 :   }
     257           0 :   acct->refcnt_excl = (ushort)0;
     258           0 : }
     259             : 
     260             : void
     261           0 : fd_txn_account_release_write_private( fd_txn_account_t * acct ) {
     262             :   /* Only release if it is not yet released */
     263           0 :   if( !fd_txn_account_acquire_write_is_safe( acct ) ) {
     264           0 :     fd_txn_account_release_write( acct );
     265           0 :   }
     266           0 : }
     267             : 
     268             : fd_pubkey_t const *
     269          57 : fd_txn_account_get_owner( fd_txn_account_t const * acct ) {
     270          57 :   if( FD_UNLIKELY( !acct->meta ) ) {
     271           0 :     FD_LOG_CRIT(( "account is not setup" ));
     272           0 :   }
     273          57 :   return (fd_pubkey_t const *)acct->meta->owner;
     274          57 : }
     275             : 
     276             : fd_account_meta_t const *
     277         927 : fd_txn_account_get_meta( fd_txn_account_t const * acct ) {
     278         927 :   return acct->meta;
     279         927 : }
     280             : 
     281             : uchar const *
     282        1443 : fd_txn_account_get_data( fd_txn_account_t const * acct ) {
     283        1443 :   return acct->data;
     284        1443 : }
     285             : 
     286             : uchar *
     287          36 : fd_txn_account_get_data_mut( fd_txn_account_t const * acct ) {
     288          36 :   return acct->data;
     289          36 : }
     290             : 
     291             : ulong
     292         525 : fd_txn_account_get_data_len( fd_txn_account_t const * acct ) {
     293         525 :   if( FD_UNLIKELY( !acct->meta ) ) {
     294           0 :     FD_LOG_CRIT(( "account is not setup" ));
     295           0 :   }
     296         525 :   return acct->meta->dlen;
     297         525 : }
     298             : 
     299             : int
     300           0 : fd_txn_account_is_executable( fd_txn_account_t const * acct ) {
     301           0 :   if( FD_UNLIKELY( !acct->meta ) ) {
     302           0 :     FD_LOG_CRIT(( "account is not setup" ));
     303           0 :   }
     304           0 :   return !!acct->meta->executable;
     305           0 : }
     306             : 
     307             : ulong
     308         936 : fd_txn_account_get_lamports( fd_txn_account_t const * acct ) {
     309         936 :   if( FD_UNLIKELY( !acct->meta ) ) {
     310           0 :     FD_LOG_CRIT(( "account is not setup" ));
     311           0 :   }
     312         936 :   return acct->meta->lamports;
     313         936 : }
     314             : 
     315             : ulong
     316           6 : fd_txn_account_get_rent_epoch( fd_txn_account_t const * acct ) {
     317           6 :   (void)acct;
     318           6 :   return ULONG_MAX;
     319           6 : }
     320             : 
     321             : void
     322           0 : fd_txn_account_set_meta( fd_txn_account_t * acct, fd_account_meta_t * meta ) {
     323           0 :   if( FD_UNLIKELY( !acct->is_mutable ) ) {
     324           0 :     FD_LOG_CRIT(( "account is not mutable" ));
     325           0 :   }
     326           0 :   if( FD_UNLIKELY( !meta ) ) {
     327           0 :     FD_LOG_CRIT(( "account is not setup" ));
     328           0 :   }
     329           0 :   acct->meta = meta;
     330           0 : }
     331             : 
     332             : void
     333          33 : fd_txn_account_set_executable( fd_txn_account_t * acct, int is_executable ) {
     334          33 :   if( FD_UNLIKELY( !acct->is_mutable ) ) {
     335           0 :     FD_LOG_CRIT(( "account is not mutable" ));
     336           0 :   }
     337          33 :   if( FD_UNLIKELY( !acct->meta ) ) {
     338           0 :     FD_LOG_CRIT(( "account is not setup" ));
     339           0 :   }
     340          33 :   acct->meta->executable = !!is_executable;
     341          33 : }
     342             : 
     343             : void
     344         507 : fd_txn_account_set_owner( fd_txn_account_t * acct, fd_pubkey_t const * owner ) {
     345         507 :   if( FD_UNLIKELY( !acct->is_mutable ) ) {
     346           0 :     FD_LOG_CRIT(( "account is not mutable" ));
     347           0 :   }
     348         507 :   if( FD_UNLIKELY( !acct->meta ) ) {
     349           0 :     FD_LOG_CRIT(( "account is not setup" ));
     350           0 :   }
     351         507 :   fd_memcpy( acct->meta->owner, owner, sizeof(fd_pubkey_t) );
     352         507 : }
     353             : 
     354             : void
     355         498 : fd_txn_account_set_lamports( fd_txn_account_t * acct, ulong lamports ) {
     356         498 :   if( FD_UNLIKELY( !acct->is_mutable ) ) {
     357           0 :     FD_LOG_CRIT(( "account is not mutable" ));
     358           0 :   }
     359         498 :   if( FD_UNLIKELY( !acct->meta ) ) {
     360           0 :     FD_LOG_CRIT(( "account is not setup" ));
     361           0 :   }
     362         498 :   acct->meta->lamports = lamports;
     363         498 : }
     364             : 
     365             : int
     366           0 : fd_txn_account_checked_add_lamports( fd_txn_account_t * acct, ulong lamports ) {
     367           0 :   ulong balance_post = 0UL;
     368           0 :   int err = fd_ulong_checked_add( fd_txn_account_get_lamports( acct ), lamports, &balance_post );
     369           0 :   if( FD_UNLIKELY( err ) ) {
     370           0 :     return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW;
     371           0 :   }
     372             : 
     373           0 :   fd_txn_account_set_lamports( acct, balance_post );
     374           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
     375           0 : }
     376             : 
     377             : int
     378           0 : fd_txn_account_checked_sub_lamports( fd_txn_account_t * acct, ulong lamports ) {
     379           0 :   ulong balance_post = 0UL;
     380           0 :   int err = fd_ulong_checked_sub( fd_txn_account_get_lamports( acct ),
     381           0 :                                   lamports,
     382           0 :                                   &balance_post );
     383           0 :   if( FD_UNLIKELY( err ) ) {
     384           0 :     return FD_EXECUTOR_INSTR_ERR_ARITHMETIC_OVERFLOW;
     385           0 :   }
     386             : 
     387           0 :   fd_txn_account_set_lamports( acct, balance_post );
     388           0 :   return FD_EXECUTOR_INSTR_SUCCESS;
     389           0 : }
     390             : 
     391             : void
     392             : fd_txn_account_set_data( fd_txn_account_t * acct,
     393             :                          void const *       data,
     394         495 :                          ulong              data_sz ) {
     395         495 :   if( FD_UNLIKELY( !acct->is_mutable ) ) {
     396           0 :     FD_LOG_CRIT(( "account is not mutable" ));
     397           0 :   }
     398         495 :   if( FD_UNLIKELY( !acct->meta ) ) {
     399           0 :     FD_LOG_CRIT(( "account is not setup" ));
     400           0 :   }
     401         495 :   acct->meta->dlen = (uint)data_sz;
     402         495 :   fd_memcpy( acct->data, data, data_sz );
     403         495 : }
     404             : 
     405             : void
     406          15 : fd_txn_account_set_data_len( fd_txn_account_t * acct, ulong data_len ) {
     407          15 :   if( FD_UNLIKELY( !acct->is_mutable ) ) {
     408           0 :     FD_LOG_CRIT(( "account is not mutable" ));
     409           0 :   }
     410          15 :   if( FD_UNLIKELY( !acct->meta ) ) {
     411           0 :     FD_LOG_CRIT(( "account is not setup" ));
     412           0 :   }
     413          15 :   acct->meta->dlen = (uint)data_len;
     414          15 : }
     415             : 
     416             : void
     417         462 : fd_txn_account_set_slot( fd_txn_account_t * acct, ulong slot ) {
     418         462 :   if( FD_UNLIKELY( !acct->is_mutable ) ) {
     419           0 :     FD_LOG_CRIT(( "account is not mutable" ));
     420           0 :   }
     421         462 :   if( FD_UNLIKELY( !acct->meta ) ) {
     422           0 :     FD_LOG_CRIT(( "account is not setup" ));
     423           0 :   }
     424         462 :   acct->meta->slot = slot;
     425         462 : }
     426             : 
     427             : void
     428           0 : fd_txn_account_clear_owner( fd_txn_account_t * acct ) {
     429           0 :   if( FD_UNLIKELY( !acct->is_mutable ) ) {
     430           0 :     FD_LOG_CRIT(( "account is not mutable" ));
     431           0 :   }
     432           0 :   if( FD_UNLIKELY( !acct->meta ) ) {
     433           0 :     FD_LOG_CRIT(( "account is not setup" ));
     434           0 :   }
     435           0 :   fd_memset( acct->meta->owner, 0, sizeof(fd_pubkey_t) );
     436           0 : }
     437             : 
     438             : void
     439             : fd_txn_account_resize( fd_txn_account_t * acct,
     440           0 :                        ulong              dlen ) {
     441           0 :   if( FD_UNLIKELY( !acct->is_mutable ) ) {
     442           0 :     FD_LOG_CRIT(( "account is not mutable" ));
     443           0 :   }
     444           0 :   if( FD_UNLIKELY( !acct->meta ) ) {
     445           0 :     FD_LOG_CRIT(( "account is not setup" ));
     446           0 :   }
     447             :   /* Because the memory for an account is preallocated for the transaction
     448             :      up to the max account size, we only need to zero out bytes (for the case
     449             :      where the account grew) and update the account dlen. */
     450           0 :   ulong old_sz    = acct->meta->dlen;
     451           0 :   ulong new_sz    = dlen;
     452           0 :   ulong memset_sz = fd_ulong_sat_sub( new_sz, old_sz );
     453           0 :   fd_memset( acct->data+old_sz, 0, memset_sz );
     454             : 
     455           0 :   acct->meta->dlen = (uint)dlen;
     456           0 : }
     457             : 
     458             : ushort
     459           0 : fd_txn_account_is_borrowed( fd_txn_account_t const * acct ) {
     460           0 :   return !!acct->refcnt_excl;
     461           0 : }
     462             : 
     463             : int
     464           6 : fd_txn_account_is_mutable( fd_txn_account_t const * acct ) {
     465             :   /* A txn account is mutable if meta is non NULL */
     466           6 :   return acct->is_mutable;
     467           6 : }
     468             : 
     469             : int
     470           6 : fd_txn_account_is_readonly( fd_txn_account_t const * acct ) {
     471             :   /* A txn account is readonly if only the meta_ field is non NULL */
     472           6 :   return !acct->is_mutable;
     473           6 : }
     474             : 
     475             : int
     476           0 : fd_txn_account_try_borrow_mut( fd_txn_account_t * acct ) {
     477           0 :   return fd_txn_account_acquire_write( acct );
     478           0 : }
     479             : 
     480             : void
     481           0 : fd_txn_account_drop( fd_txn_account_t * acct ) {
     482           0 :   fd_txn_account_release_write_private( acct );
     483           0 : }
     484             : 
     485             : void
     486           0 : fd_txn_account_set_readonly( fd_txn_account_t * acct ) {
     487           0 :   acct->is_mutable = 0;
     488           0 : }
     489             : 
     490             : void
     491           0 : fd_txn_account_set_mutable( fd_txn_account_t * acct ) {
     492           0 :   acct->is_mutable = 1;
     493           0 : }
     494             : 
     495             : fd_solana_account_meta_t
     496           0 : fd_txn_account_get_solana_meta( fd_txn_account_t const * acct ) {
     497           0 :   fd_solana_account_meta_t meta = {
     498           0 :     .lamports   = acct->meta->lamports,
     499             :     .rent_epoch = ULONG_MAX,
     500           0 :     .executable = acct->meta->executable,
     501           0 :   };
     502           0 :   memcpy( meta.owner, acct->meta->owner, sizeof(fd_pubkey_t) );
     503           0 :   return meta;
     504           0 : }

Generated by: LCOV version 1.14