LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_accdb_svm.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 92 106 86.8 %
Date: 2026-10-16 04:29:28 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 "../capture/fd_capture_ctx.h"
       5             : #include "../events/fd_event_runtime.h"
       6             : 
       7             : static void
       8             : log_account_change( fd_bank_t const *  bank,
       9             :                     fd_acc_t * ro,
      10       10155 :                     fd_capture_ctx_t * capture_ctx ) {
      11       10155 :   if( FD_UNLIKELY( capture_ctx &&
      12       10155 :                    capture_ctx->capture_solcap &&
      13       10155 :                   bank->f.slot>=capture_ctx->solcap_start_slot ) ) {
      14           0 :     fd_solana_account_meta_t solana_meta[1];
      15           0 :     fd_solana_account_meta_init( solana_meta, ro->lamports, ro->owner, ro->executable );
      16           0 :     fd_capture_link_write_account_update(
      17           0 :         capture_ctx,
      18           0 :         capture_ctx->current_txn_idx,
      19           0 :         (fd_pubkey_t const *)ro->pubkey,
      20           0 :         solana_meta,
      21           0 :         bank->f.slot,
      22           0 :         ro->data,
      23           0 :         ro->data_len );
      24           0 :   }
      25       10155 : }
      26             : 
      27             : fd_acc_t
      28             : fd_accdb_svm_open_rw( fd_bank_t *             bank,
      29             :                       fd_accdb_t *            accdb,
      30             :                       fd_accdb_svm_update_t * update,
      31             :                       fd_pubkey_t const *     pubkey,
      32       10167 :                       int                     create ) {
      33       10167 :   fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
      34       10167 :   if( FD_UNLIKELY( !acc.lamports && !create ) ) {
      35          12 :     fd_accdb_unwrite_one( accdb, &acc );
      36          12 :     return acc;
      37          12 :   }
      38             : 
      39       10155 :   update->lamports_before = acc.lamports;
      40       10155 :   update->data_len_before = acc.data_len;
      41       10155 :   update->skip_event_diff = 0;
      42       10155 :   fd_memcpy( update->owner_before, acc.owner, 32UL );
      43             : 
      44       10155 :   fd_lthash_value_t hash[1];
      45       10155 :   fd_hashes_account_lthash_simple( acc.pubkey, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, hash );
      46             : 
      47       10155 :   fd_lthash_value_t * bank_lthash = fd_bank_lthash_locking_modify( bank );
      48       10155 :   fd_lthash_sub( bank_lthash, hash );
      49       10155 :   fd_bank_lthash_end_locking_modify( bank );
      50             : 
      51       10155 :   return acc;
      52       10167 : }
      53             : 
      54             : void
      55             : fd_accdb_svm_close_rw( fd_bank_t *             bank,
      56             :                        fd_accdb_t *            accdb,
      57             :                        fd_capture_ctx_t *      capture_ctx,
      58             :                        fd_acc_t *              acc,
      59       10155 :                        fd_accdb_svm_update_t * update ) {
      60       10155 :   if( FD_UNLIKELY( acc->lamports>update->lamports_before ) ) {
      61         249 :     ulong delta = acc->lamports-update->lamports_before;
      62         249 :     FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
      63        9906 :   } else if( FD_UNLIKELY( acc->lamports<update->lamports_before ) ) {
      64          69 :     ulong delta = update->lamports_before-acc->lamports;
      65          69 :     FD_TEST( !__builtin_usubl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
      66          69 :   }
      67             : 
      68       10155 :   fd_lthash_value_t hash[1];
      69       10155 :   fd_hashes_account_lthash_simple( acc->pubkey, acc->owner, acc->lamports, acc->executable, acc->data, acc->data_len, hash );
      70             : 
      71       10155 :   fd_lthash_value_t * bank_lthash = fd_bank_lthash_locking_modify( bank );
      72       10155 :   fd_lthash_add( bank_lthash, hash );
      73       10155 :   fd_bank_lthash_end_locking_modify( bank );
      74             : 
      75       10155 :   log_account_change( bank, acc, capture_ctx );
      76       10155 :   if( FD_UNLIKELY( fd_bank_report_runtime_diffs( bank ) && !update->skip_event_diff ) ) fd_event_runtime_block_account( bank, acc->pubkey, update->owner_before, acc->owner, update->lamports_before, acc->lamports, update->data_len_before, acc->data_len, acc->executable );
      77       10155 :   acc->commit = 1;
      78       10155 :   fd_accdb_unwrite_one( accdb, acc );
      79       10155 : }
      80             : 
      81             : void
      82             : fd_accdb_svm_credit( fd_bank_t *         bank,
      83             :                      fd_accdb_t *        accdb,
      84             :                      fd_capture_ctx_t *  capture_ctx,
      85             :                      fd_pubkey_t const * pubkey,
      86             :                      ulong               lamports_add,
      87          81 :                      int                 is_vote_reward ) {
      88          81 :   if( FD_UNLIKELY( !lamports_add ) ) return;
      89             : 
      90          78 :   fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
      91             : 
      92          78 :   ulong lamports_pre = acc.lamports;
      93          78 :   FD_TEST( !__builtin_uaddl_overflow( acc.lamports, lamports_add, &acc.lamports ) );
      94          78 :   FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, lamports_add, &bank->f.capitalization ) );
      95             : 
      96          78 :   fd_hashes_update_pair( pubkey->uc, acc.owner, lamports_pre, acc.executable, acc.data, acc.data_len,
      97          78 :                                      acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len,
      98          78 :                          bank, capture_ctx );
      99          78 :   if( FD_UNLIKELY( fd_bank_report_runtime_diffs( bank ) ) ) {
     100           0 :     if( FD_UNLIKELY( is_vote_reward ) ) fd_event_runtime_reward_emit( bank, FD_EVENT_RUNTIME_REWARD_KIND_VOTE, acc.pubkey, acc.owner, lamports_pre, acc.lamports, 0UL, 0UL, 0UL );
     101           0 :     else                                fd_event_runtime_block_account( bank, acc.pubkey, acc.owner, acc.owner, lamports_pre, acc.lamports, acc.data_len, acc.data_len, acc.executable );
     102           0 :   }
     103          78 :   acc.commit = 1;
     104          78 :   fd_accdb_unwrite_one( accdb, &acc );
     105          78 : }
     106             : 
     107             : void
     108             : fd_accdb_svm_write( fd_bank_t *         bank,
     109             :                     fd_accdb_t *        accdb,
     110             :                     fd_capture_ctx_t *  capture_ctx,
     111             :                     fd_pubkey_t const * pubkey,
     112             :                     fd_pubkey_t const * owner,
     113             :                     void const *        data,
     114             :                     ulong               sz,
     115             :                     ulong               lamports_min,
     116             :                     int                 exec_bit,
     117        8784 :                     int                 skip_event_diff ) {
     118        8784 :   fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
     119        8784 :   ulong lamports_pre = acc.lamports;
     120        8784 :   ulong data_len_pre = acc.data_len;
     121        8784 :   uchar owner_pre[ 32 ]; fd_memcpy( owner_pre, acc.owner, 32UL );
     122             : 
     123        8784 :   if( FD_UNLIKELY( acc.lamports<lamports_min ) ) {
     124         492 :     ulong delta = lamports_min - acc.lamports;
     125         492 :     acc.lamports = lamports_min;
     126         492 :     FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
     127         492 :   }
     128             : 
     129        8784 :   fd_memcpy( acc.owner, owner, 32UL );
     130        8784 :   acc.executable = !!exec_bit;
     131             : 
     132        8784 :   fd_memcpy( acc.data, data, sz );
     133        8784 :   acc.data_len = sz;
     134             : 
     135        8784 :   fd_hashes_update_pair( pubkey->uc, acc.prior_owner, acc.prior_lamports, acc.prior_executable, acc.prior_data, acc.prior_data_len,
     136        8784 :                                      acc.owner,       acc.lamports,       acc.executable,       acc.data,       acc.data_len,
     137        8784 :                          bank, capture_ctx );
     138        8784 :   if( FD_UNLIKELY( fd_bank_report_runtime_diffs( bank ) && !skip_event_diff ) ) fd_event_runtime_block_account( bank, acc.pubkey, owner_pre, acc.owner, lamports_pre, acc.lamports, data_len_pre, acc.data_len, acc.executable );
     139        8784 :   acc.commit = 1;
     140        8784 :   fd_accdb_unwrite_one( accdb, &acc );
     141        8784 : }
     142             : 
     143             : ulong
     144             : fd_accdb_svm_remove( fd_bank_t *         bank,
     145             :                      fd_accdb_t *        accdb,
     146             :                      fd_capture_ctx_t *  capture_ctx,
     147         414 :                      fd_pubkey_t const * pubkey ) {
     148         414 :   fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
     149         414 :   if( FD_UNLIKELY( !acc.lamports ) ) {
     150         384 :     fd_accdb_unwrite_one( accdb, &acc );
     151         384 :     return 0UL;
     152         384 :   }
     153             : 
     154          30 :   ulong burned = acc.lamports;
     155             : 
     156          30 :   fd_lthash_value_t hash[1];
     157          30 :   fd_hashes_account_lthash_simple( acc.pubkey, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, hash );
     158             : 
     159          30 :   bank->f.capitalization -= burned;
     160          30 :   acc.lamports = 0UL;
     161             : 
     162          30 :   fd_lthash_value_t post[1];
     163          30 :   fd_hashes_update_simple( post, hash, pubkey->uc, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, bank, capture_ctx );
     164          30 :   if( FD_UNLIKELY( fd_bank_report_runtime_diffs( bank ) ) ) fd_event_runtime_block_account( bank, acc.pubkey, acc.owner, acc.owner, burned, 0UL, acc.data_len, 0UL, 0 );
     165          30 :   acc.commit = 1;
     166          30 :   fd_accdb_unwrite_one( accdb, &acc );
     167          30 :   return burned;
     168         414 : }

Generated by: LCOV version 1.14