LCOV - code coverage report
Current view: top level - flamenco/runtime - fd_accdb_svm.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 95 114 83.3 %
Date: 2026-11-11 12:40:43 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        1832 :                     fd_capture_ctx_t * capture_ctx ) {
      11        1832 :   if( FD_UNLIKELY( capture_ctx &&
      12        1832 :                    capture_ctx->capture_solcap &&
      13        1832 :                   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        1832 : }
      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        1832 :                       int                     create ) {
      33        1832 :   fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
      34        1832 :   if( FD_UNLIKELY( !acc.lamports && !create ) ) {
      35           0 :     fd_accdb_unwrite_one( accdb, &acc );
      36           0 :     return acc;
      37           0 :   }
      38             : 
      39        1832 :   update->lamports_before = acc.lamports;
      40        1832 :   update->data_len_before = acc.data_len;
      41        1832 :   update->skip_event_diff = 0;
      42        1832 :   fd_memcpy( update->owner_before, acc.owner, 32UL );
      43             : 
      44        1832 :   if( bank->lthash_mode==FD_BANK_LTHASH_MODE_INBAND ) {
      45        1832 :     fd_lthash_value_t hash[1];
      46        1832 :     fd_hashes_account_lthash_simple( acc.pubkey, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, hash );
      47             : 
      48        1832 :     fd_lthash_value_t * bank_lthash = fd_bank_lthash_locking_modify( bank );
      49        1832 :     fd_lthash_sub( bank_lthash, hash );
      50        1832 :     fd_bank_lthash_end_locking_modify( bank );
      51        1832 :   }
      52             : 
      53        1832 :   return acc;
      54        1832 : }
      55             : 
      56             : void
      57             : fd_accdb_svm_close_rw( fd_bank_t *             bank,
      58             :                        fd_accdb_t *            accdb,
      59             :                        fd_capture_ctx_t *      capture_ctx,
      60             :                        fd_acc_t *              acc,
      61        1832 :                        fd_accdb_svm_update_t * update ) {
      62        1832 :   if( FD_UNLIKELY( acc->lamports>update->lamports_before ) ) {
      63         337 :     ulong delta = acc->lamports-update->lamports_before;
      64         337 :     FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
      65        1495 :   } else if( FD_UNLIKELY( acc->lamports<update->lamports_before ) ) {
      66         101 :     ulong delta = update->lamports_before-acc->lamports;
      67         101 :     FD_TEST( !__builtin_usubl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
      68         101 :   }
      69             : 
      70        1832 :   if( bank->lthash_mode==FD_BANK_LTHASH_MODE_INBAND ) {
      71        1832 :     fd_lthash_value_t hash[1];
      72        1832 :     fd_hashes_account_lthash_simple( acc->pubkey, acc->owner, acc->lamports, acc->executable, acc->data, acc->data_len, hash );
      73             : 
      74        1832 :     fd_lthash_value_t * bank_lthash = fd_bank_lthash_locking_modify( bank );
      75        1832 :     fd_lthash_add( bank_lthash, hash );
      76        1832 :     fd_bank_lthash_end_locking_modify( bank );
      77        1832 :   } else if( bank->lthash_mode==FD_BANK_LTHASH_MODE_OOB_RECORD ) {
      78           0 :     fd_bank_lthash_record( bank, acc->pubkey );
      79           0 :   }
      80             : 
      81        1832 :   log_account_change( bank, acc, capture_ctx );
      82        1832 :   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 );
      83        1832 :   acc->commit = 1;
      84        1832 :   fd_accdb_unwrite_one( accdb, acc );
      85        1832 : }
      86             : 
      87             : void
      88             : fd_accdb_svm_credit( fd_bank_t *         bank,
      89             :                      fd_accdb_t *        accdb,
      90             :                      fd_capture_ctx_t *  capture_ctx,
      91             :                      fd_pubkey_t const * pubkey,
      92             :                      ulong               lamports_add,
      93          50 :                      int                 is_vote_reward ) {
      94          50 :   if( FD_UNLIKELY( !lamports_add ) ) return;
      95             : 
      96          48 :   fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
      97             : 
      98          48 :   ulong lamports_pre = acc.lamports;
      99          48 :   FD_TEST( !__builtin_uaddl_overflow( acc.lamports, lamports_add, &acc.lamports ) );
     100          48 :   FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, lamports_add, &bank->f.capitalization ) );
     101             : 
     102          48 :   fd_hashes_update_pair( pubkey->uc, acc.owner, lamports_pre, acc.executable, acc.data, acc.data_len,
     103          48 :                                      acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len,
     104          48 :                          bank, capture_ctx );
     105          48 :   if( FD_UNLIKELY( fd_bank_report_runtime_diffs( bank ) ) ) {
     106           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 );
     107           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 );
     108           0 :   }
     109          48 :   acc.commit = 1;
     110          48 :   fd_accdb_unwrite_one( accdb, &acc );
     111          48 : }
     112             : 
     113             : void
     114             : fd_accdb_svm_write( fd_bank_t *         bank,
     115             :                     fd_accdb_t *        accdb,
     116             :                     fd_capture_ctx_t *  capture_ctx,
     117             :                     fd_pubkey_t const * pubkey,
     118             :                     fd_pubkey_t const * owner,
     119             :                     void const *        data,
     120             :                     ulong               sz,
     121             :                     ulong               lamports_min,
     122             :                     int                 exec_bit,
     123        1650 :                     int                 skip_event_diff ) {
     124        1650 :   fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
     125        1650 :   ulong lamports_pre = acc.lamports;
     126        1650 :   ulong data_len_pre = acc.data_len;
     127        1650 :   uchar owner_pre[ 32 ]; fd_memcpy( owner_pre, acc.owner, 32UL );
     128             : 
     129        1650 :   if( FD_UNLIKELY( acc.lamports<lamports_min ) ) {
     130           3 :     ulong delta = lamports_min - acc.lamports;
     131           3 :     acc.lamports = lamports_min;
     132           3 :     FD_TEST( !__builtin_uaddl_overflow( bank->f.capitalization, delta, &bank->f.capitalization ) );
     133           3 :   }
     134             : 
     135        1650 :   fd_memcpy( acc.owner, owner, 32UL );
     136        1650 :   acc.executable = !!exec_bit;
     137             : 
     138        1650 :   fd_memcpy( acc.data, data, sz );
     139        1650 :   acc.data_len = sz;
     140             : 
     141        1650 :   fd_hashes_update_pair( pubkey->uc, acc.prior_owner, acc.prior_lamports, acc.prior_executable, acc.prior_data, acc.prior_data_len,
     142        1650 :                                      acc.owner,       acc.lamports,       acc.executable,       acc.data,       acc.data_len,
     143        1650 :                          bank, capture_ctx );
     144        1650 :   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 );
     145        1650 :   acc.commit = 1;
     146        1650 :   fd_accdb_unwrite_one( accdb, &acc );
     147        1650 : }
     148             : 
     149             : ulong
     150             : fd_accdb_svm_remove( fd_bank_t *         bank,
     151             :                      fd_accdb_t *        accdb,
     152             :                      fd_capture_ctx_t *  capture_ctx,
     153         611 :                      fd_pubkey_t const * pubkey ) {
     154         611 :   fd_acc_t acc = fd_accdb_write_one( accdb, bank->accdb_fork_id, pubkey->uc );
     155         611 :   if( FD_UNLIKELY( !acc.lamports ) ) {
     156         585 :     fd_accdb_unwrite_one( accdb, &acc );
     157         585 :     return 0UL;
     158         585 :   }
     159             : 
     160          26 :   ulong burned = acc.lamports;
     161             : 
     162          26 :   fd_lthash_value_t hash[1]; /* read by fd_hashes_update_simple only in INBAND mode */
     163          26 :   if( bank->lthash_mode==FD_BANK_LTHASH_MODE_INBAND ) {
     164          26 :     fd_hashes_account_lthash_simple( acc.pubkey, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, hash );
     165          26 :   }
     166             : 
     167          26 :   bank->f.capitalization -= burned;
     168          26 :   acc.lamports = 0UL;
     169             : 
     170          26 :   fd_lthash_value_t post[1];
     171          26 :   fd_hashes_update_simple( post, hash, pubkey->uc, acc.owner, acc.lamports, acc.executable, acc.data, acc.data_len, bank, capture_ctx );
     172          26 :   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 );
     173          26 :   acc.commit = 1;
     174          26 :   fd_accdb_unwrite_one( accdb, &acc );
     175          26 :   return burned;
     176         611 : }

Generated by: LCOV version 1.14