LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_accdb_svm.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 72 123 58.5 %
Date: 2026-05-27 08:23:31 Functions: 6 6 100.0 %

          Line data    Source code
       1             : #include "fd_accdb_svm.h"
       2             : #include "fd_hashes.h"
       3             : #include "fd_bank.h"
       4             : #include "../accdb/fd_accdb_sync.h"
       5             : #include "../capture/fd_capture_ctx.h"
       6             : 
       7             : static void
       8             : log_account_change( fd_capture_ctx_t * capture_ctx,
       9             :                     fd_bank_t const *  bank,
      10        5349 :                     fd_accdb_ro_t *    ro ) {
      11        5349 :   if( capture_ctx && capture_ctx->capture_solcap &&
      12        5349 :       bank->f.slot>=capture_ctx->solcap_start_slot ) {
      13           0 :     fd_solana_account_meta_t solana_meta[1];
      14           0 :     fd_solana_account_meta_init(
      15           0 :         solana_meta,
      16           0 :         fd_accdb_ref_lamports  ( ro ),
      17           0 :         fd_accdb_ref_owner     ( ro ),
      18           0 :         !!fd_accdb_ref_exec_bit( ro )
      19           0 :     );
      20           0 :     fd_capture_link_write_account_update(
      21           0 :         capture_ctx,
      22           0 :         capture_ctx->current_txn_idx,
      23           0 :         fd_accdb_ref_address( ro ),
      24           0 :         solana_meta,
      25           0 :         bank->f.slot,
      26           0 :         fd_accdb_ref_data_const( ro ),
      27           0 :         fd_accdb_ref_data_sz   ( ro )
      28           0 :     );
      29           0 :   }
      30        5349 : }
      31             : 
      32             : fd_accdb_rw_t *
      33             : fd_accdb_svm_open_rw( fd_accdb_user_t *         accdb,
      34             :                       fd_bank_t *               bank,
      35             :                       fd_funk_txn_xid_t const * xid,
      36             :                       fd_accdb_rw_t *           rw,
      37             :                       fd_accdb_svm_update_t *   update,
      38             :                       fd_pubkey_t const *       pubkey,
      39             :                       ulong                     data_max,
      40        5370 :                       int                       flags ) {
      41        5370 :   if( FD_UNLIKELY( !fd_accdb_open_rw( accdb, rw, xid, pubkey, data_max, flags&~FD_ACCDB_FLAG_TRUNCATE ) ) ) {
      42          21 :     return NULL;
      43          21 :   }
      44             : 
      45        5349 :   update->lamports_before = fd_accdb_ref_lamports( rw->ro );
      46             : 
      47        5349 :   fd_lthash_value_t hash[1];
      48        5349 :   fd_hashes_account_lthash( pubkey, rw->meta, fd_accdb_ref_data_const( rw->ro ), hash );
      49        5349 :   fd_lthash_value_t * bank_lthash = fd_type_pun( fd_bank_lthash_locking_modify( bank ) );
      50        5349 :   fd_lthash_sub( bank_lthash, hash );
      51        5349 :   fd_bank_lthash_end_locking_modify( bank );
      52             : 
      53        5349 :   return rw;
      54        5370 : }
      55             : 
      56             : void
      57             : fd_accdb_svm_close_rw( fd_accdb_user_t *       accdb,
      58             :                        fd_bank_t *             bank,
      59             :                        fd_capture_ctx_t *      capture_ctx,
      60             :                        fd_accdb_rw_t *         rw,
      61        5349 :                        fd_accdb_svm_update_t * update ) {
      62             : 
      63        5349 :   ulong * cap      = &bank->f.capitalization;
      64        5349 :   ulong   lamports = fd_accdb_ref_lamports( rw->ro );
      65        5349 :   if( lamports > update->lamports_before ) {
      66          15 :     ulong delta      = lamports - update->lamports_before;
      67          15 :     ulong cap_before = *cap;
      68          15 :     if( FD_UNLIKELY( __builtin_uaddl_overflow( cap_before, delta, cap ) ) ) {
      69           0 :       FD_BASE58_ENCODE_32_BYTES( fd_accdb_ref_address( rw->ro ), addr_b58 );
      70           0 :       FD_LOG_EMERG(( "bank capitalization overflow detected (slot=%lu addr=%s delta=%lu cap_before=%lu)",
      71           0 :                      bank->f.slot, addr_b58, delta, cap_before ));
      72           0 :     }
      73        5334 :   } else if( lamports < update->lamports_before ) {
      74           0 :     ulong delta      = update->lamports_before - lamports;
      75           0 :     ulong cap_before = *cap;
      76           0 :     if( FD_UNLIKELY( __builtin_usubl_overflow( cap_before, delta, cap ) ) ) {
      77           0 :       FD_BASE58_ENCODE_32_BYTES( fd_accdb_ref_address( rw->ro ), addr_b58 );
      78           0 :       FD_LOG_EMERG(( "bank capitalization underflow detected (slot=%lu addr=%s delta=%lu cap_before=%lu)",
      79           0 :                      bank->f.slot, addr_b58, delta, cap_before ));
      80           0 :     }
      81           0 :   }
      82             : 
      83        5349 :   fd_lthash_value_t hash[1];
      84        5349 :   fd_hashes_account_lthash( fd_accdb_ref_address( rw->ro ), rw->meta, fd_accdb_ref_data_const( rw->ro ), hash );
      85        5349 :   fd_lthash_value_t * bank_lthash = fd_type_pun( fd_bank_lthash_locking_modify( bank ) );
      86        5349 :   fd_lthash_add( bank_lthash, hash );
      87        5349 :   fd_bank_lthash_end_locking_modify( bank );
      88             : 
      89        5349 :   log_account_change( capture_ctx, bank, rw->ro );
      90             : 
      91        5349 :   fd_accdb_close_rw( accdb, rw );
      92        5349 : }
      93             : 
      94             : void
      95             : fd_accdb_svm_credit( fd_accdb_user_t *         accdb,
      96             :                      fd_bank_t *               bank,
      97             :                      fd_funk_txn_xid_t const * xid,
      98             :                      fd_capture_ctx_t *        capture_ctx,
      99             :                      fd_pubkey_t const *       pubkey,
     100           6 :                      ulong                     lamports_add ) {
     101           6 :   if( FD_UNLIKELY( !lamports_add ) ) return;
     102             : 
     103           6 :   fd_accdb_rw_t rw[1];
     104           6 :   FD_TEST( fd_accdb_open_rw( accdb, rw, xid, pubkey, 0UL, FD_ACCDB_FLAG_CREATE ) );
     105           6 :   fd_lthash_value_t hash[1];
     106           6 :   fd_hashes_account_lthash( pubkey, rw->meta, fd_accdb_ref_data_const( rw->ro ), hash );
     107             : 
     108           6 :   ulong lamports = fd_accdb_ref_lamports( rw->ro );
     109           6 :   if( FD_UNLIKELY( __builtin_uaddl_overflow( lamports, lamports_add, &lamports ) ) ) {
     110           0 :     FD_BASE58_ENCODE_32_BYTES( pubkey->key, addr_b58 );
     111           0 :     FD_LOG_EMERG(( "integer overflow while crediting %lu lamports to %s (previous balance %lu)",
     112           0 :                     lamports_add, addr_b58, fd_accdb_ref_lamports( rw->ro ) ));
     113           0 :   }
     114           6 :   fd_accdb_ref_lamports_set( rw, lamports );
     115             : 
     116           6 :   ulong * cap = &bank->f.capitalization;
     117           6 :   if( FD_UNLIKELY( __builtin_uaddl_overflow( *cap, lamports_add, cap ) ) ) {
     118           0 :     FD_BASE58_ENCODE_32_BYTES( pubkey->key, addr_b58 );
     119           0 :     FD_LOG_EMERG(( "bank capitalization overflow detected (slot=%lu addr=%s delta=%lu cap_before=%lu)",
     120           0 :                    bank->f.slot, addr_b58, lamports_add, *cap - lamports_add ));
     121           0 :   }
     122             : 
     123           6 :   fd_hashes_update_lthash( pubkey, rw->meta, hash, bank, capture_ctx );
     124           6 :   fd_accdb_close_rw( accdb, rw );
     125           6 : }
     126             : 
     127             : void
     128             : fd_accdb_svm_write( fd_accdb_user_t *         accdb,
     129             :                     fd_bank_t *               bank,
     130             :                     fd_funk_txn_xid_t const * xid,
     131             :                     fd_capture_ctx_t *        capture_ctx,
     132             :                     fd_pubkey_t const *       pubkey,
     133             :                     fd_pubkey_t const *       owner,
     134             :                     void const *              data,
     135             :                     ulong                     sz,
     136             :                     ulong                     lamports_min,
     137             :                     int                       exec_bit,
     138        4644 :                     int                       flags ) {
     139        4644 :   fd_accdb_rw_t rw[1];
     140        4644 :   if( !fd_accdb_open_rw( accdb, rw, xid, pubkey, sz, flags&FD_ACCDB_FLAG_CREATE ) ) {
     141           0 :     return;
     142           0 :   }
     143             : 
     144        4644 :   fd_lthash_value_t hash[1];
     145        4644 :   fd_hashes_account_lthash( pubkey, rw->meta, fd_accdb_ref_data_const( rw->ro ), hash );
     146             : 
     147        4644 :   ulong lamports = fd_accdb_ref_lamports( rw->ro );
     148        4644 :   if( FD_UNLIKELY( lamports < lamports_min ) ) {
     149         450 :     ulong delta = lamports_min - lamports;
     150         450 :     fd_accdb_ref_lamports_set( rw, lamports_min );
     151             : 
     152         450 :     ulong * cap = &bank->f.capitalization;
     153         450 :     if( FD_UNLIKELY( __builtin_uaddl_overflow( *cap, delta, cap ) ) ) {
     154           0 :       FD_BASE58_ENCODE_32_BYTES( pubkey->key, addr_b58 );
     155           0 :       FD_LOG_EMERG(( "bank capitalization overflow detected (slot=%lu addr=%s delta=%lu cap_before=%lu)",
     156           0 :                      bank->f.slot, addr_b58, delta, *cap - delta ));
     157           0 :     }
     158         450 :   }
     159             : 
     160        4644 :   fd_accdb_ref_owner_set   ( rw, owner      );
     161        4644 :   fd_accdb_ref_exec_bit_set( rw, !!exec_bit );
     162        4644 :   if( !!( flags & FD_ACCDB_FLAG_TRUNCATE ) ||
     163        4644 :       fd_accdb_ref_data_sz( rw->ro ) < sz ) {
     164        4644 :     fd_accdb_ref_data_sz_set( accdb, rw, sz, 0 );
     165        4644 :   }
     166        4644 :   fd_memcpy( fd_accdb_ref_data( rw ), data, sz );
     167             : 
     168        4644 :   fd_hashes_update_lthash( pubkey, rw->meta, hash, bank, capture_ctx );
     169        4644 :   fd_accdb_close_rw( accdb, rw );
     170        4644 : }
     171             : 
     172             : ulong
     173             : fd_accdb_svm_remove( fd_accdb_user_t *         accdb,
     174             :                      fd_bank_t *               bank,
     175             :                      fd_funk_txn_xid_t const * xid,
     176             :                      fd_capture_ctx_t *        capture_ctx,
     177          78 :                      fd_pubkey_t const *       pubkey ) {
     178          78 :   fd_accdb_rw_t rw[1];
     179          78 :   if( !fd_accdb_open_rw( accdb, rw, xid, pubkey, 0UL, 0 ) ) return 0UL;
     180             : 
     181           0 :   fd_lthash_value_t hash[1];
     182           0 :   fd_hashes_account_lthash( pubkey, rw->meta, fd_accdb_ref_data_const( rw->ro ), hash );
     183             : 
     184           0 :   ulong lamports = fd_accdb_ref_lamports( rw->ro );
     185           0 :   bank->f.capitalization -= lamports;
     186           0 :   fd_accdb_ref_lamports_set( rw, 0UL );
     187             : 
     188           0 :   fd_hashes_update_lthash( pubkey, rw->meta, hash, bank, capture_ctx );
     189           0 :   fd_accdb_close_rw( accdb, rw );
     190           0 :   return lamports;
     191          78 : }

Generated by: LCOV version 1.14