LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_accdb_svm.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 70 123 56.9 %
Date: 2026-04-10 06:33:15 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          15 :                     fd_accdb_ro_t *    ro ) {
      11          15 :   if( capture_ctx && capture_ctx->capture_solcap &&
      12          15 :       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          15 : }
      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          15 :                       int                       flags ) {
      41          15 :   if( FD_UNLIKELY( !fd_accdb_open_rw( accdb, rw, xid, pubkey, data_max, flags&~FD_ACCDB_FLAG_TRUNCATE ) ) ) {
      42           0 :     return NULL;
      43           0 :   }
      44             : 
      45          15 :   update->lamports_before = fd_accdb_ref_lamports( rw->ro );
      46             : 
      47          15 :   fd_lthash_value_t hash[1];
      48          15 :   fd_hashes_account_lthash( pubkey, rw->meta, fd_accdb_ref_data_const( rw->ro ), hash );
      49          15 :   fd_lthash_value_t * bank_lthash = fd_type_pun( fd_bank_lthash_locking_modify( bank ) );
      50          15 :   fd_lthash_sub( bank_lthash, hash );
      51          15 :   fd_bank_lthash_end_locking_modify( bank );
      52             : 
      53          15 :   return rw;
      54          15 : }
      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          15 :                        fd_accdb_svm_update_t * update ) {
      62             : 
      63          15 :   ulong * cap      = &bank->f.capitalization;
      64          15 :   ulong   lamports = fd_accdb_ref_lamports( rw->ro );
      65          15 :   if( lamports > update->lamports_before ) {
      66           6 :     ulong delta      = lamports - update->lamports_before;
      67           6 :     ulong cap_before = *cap;
      68           6 :     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           9 :   } 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          15 :   fd_lthash_value_t hash[1];
      84          15 :   fd_hashes_account_lthash( fd_accdb_ref_address( rw->ro ), rw->meta, fd_accdb_ref_data_const( rw->ro ), hash );
      85          15 :   fd_lthash_value_t * bank_lthash = fd_type_pun( fd_bank_lthash_locking_modify( bank ) );
      86          15 :   fd_lthash_add( bank_lthash, hash );
      87          15 :   fd_bank_lthash_end_locking_modify( bank );
      88             : 
      89          15 :   log_account_change( capture_ctx, bank, rw->ro );
      90             : 
      91          15 :   fd_accdb_close_rw( accdb, rw );
      92          15 : }
      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        1830 :                     int                       flags ) {
     139        1830 :   fd_accdb_rw_t rw[1];
     140        1830 :   if( !fd_accdb_open_rw( accdb, rw, xid, pubkey, sz, flags&FD_ACCDB_FLAG_CREATE ) ) {
     141           0 :     return;
     142           0 :   }
     143             : 
     144        1830 :   fd_lthash_value_t hash[1];
     145        1830 :   fd_hashes_account_lthash( pubkey, rw->meta, fd_accdb_ref_data_const( rw->ro ), hash );
     146             : 
     147        1830 :   ulong lamports = fd_accdb_ref_lamports( rw->ro );
     148        1830 :   if( FD_UNLIKELY( lamports < lamports_min ) ) {
     149         399 :     ulong delta = lamports_min - lamports;
     150         399 :     fd_accdb_ref_lamports_set( rw, lamports_min );
     151             : 
     152         399 :     ulong * cap = &bank->f.capitalization;
     153         399 :     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         399 :   }
     159             : 
     160        1830 :   fd_accdb_ref_owner_set   ( rw, owner      );
     161        1830 :   fd_accdb_ref_exec_bit_set( rw, !!exec_bit );
     162        1830 :   if( !!( flags & FD_ACCDB_FLAG_TRUNCATE ) ||
     163        1830 :       fd_accdb_ref_data_sz( rw->ro ) < sz ) {
     164        1830 :     fd_accdb_ref_data_sz_set( accdb, rw, sz, 0 );
     165        1830 :   }
     166        1830 :   fd_memcpy( fd_accdb_ref_data( rw ), data, sz );
     167             : 
     168        1830 :   fd_hashes_update_lthash( pubkey, rw->meta, hash, bank, capture_ctx );
     169        1830 :   fd_accdb_close_rw( accdb, rw );
     170        1830 : }
     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