LCOV - code coverage report
Current view: top level - flamenco/runtime/sysvar - fd_sysvar_epoch_rewards.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 52 75 69.3 %
Date: 2026-11-11 12:40:43 Functions: 6 7 85.7 %

          Line data    Source code
       1             : #include "fd_sysvar_epoch_rewards.h"
       2             : #include "../../events/fd_event_runtime.h"
       3             : #include "fd_sysvar.h"
       4             : #include "../fd_system_ids.h"
       5             : #include "../fd_accdb_svm.h"
       6             : #include "fd_sysvar_rent.h"
       7             : 
       8             : static int
       9         648 : validate( fd_sysvar_epoch_rewards_t const * epoch_rewards ) {
      10         648 :   return epoch_rewards->active!=0 && epoch_rewards->active!=1;
      11             : 
      12         648 : }
      13             : 
      14             : static void
      15             : write_epoch_rewards( fd_bank_t *                 bank,
      16             :                      fd_accdb_t *                accdb,
      17             :                      fd_capture_ctx_t *          capture_ctx,
      18         111 :                      fd_sysvar_epoch_rewards_t * epoch_rewards ) {
      19         111 :   fd_sysvar_account_update( bank, accdb, capture_ctx, &fd_sysvar_epoch_rewards_id, epoch_rewards, FD_SYSVAR_EPOCH_REWARDS_BINCODE_SZ );
      20         111 : }
      21             : 
      22             : /* write_epoch_rewards with the balance set to the rent exempt minimum,
      23             :    burning any surplus.
      24             :    Agave: create_account with RENT_UNADJUSTED_INITIAL_BALANCE followed by
      25             :    adjust_sysvar_balance_for_rent. */
      26             : static void
      27             : write_epoch_rewards_reset_balance( fd_bank_t *                 bank,
      28             :                                    fd_accdb_t *                accdb,
      29             :                                    fd_capture_ctx_t *          capture_ctx,
      30           0 :                                    fd_sysvar_epoch_rewards_t * epoch_rewards ) {
      31           0 :   fd_accdb_svm_update_t update[1];
      32           0 :   fd_acc_t              acc = fd_accdb_svm_open_rw( bank, accdb, update, &fd_sysvar_epoch_rewards_id, 1 );
      33           0 :   fd_memcpy( acc.owner, &fd_sysvar_owner_id, 32UL );
      34           0 :   acc.executable = 0;
      35           0 :   fd_memcpy( acc.data, epoch_rewards, FD_SYSVAR_EPOCH_REWARDS_BINCODE_SZ );
      36           0 :   acc.data_len = FD_SYSVAR_EPOCH_REWARDS_BINCODE_SZ;
      37           0 :   acc.lamports = fd_ulong_max( fd_rent_exempt_minimum_balance( &bank->f.rent, acc.data_len ), FD_SYSVAR_RENT_UNADJUSTED_INITIAL_BALANCE );
      38           0 :   fd_accdb_svm_close_rw( bank, accdb, capture_ctx, &acc, update );
      39           0 : }
      40             : 
      41             : fd_sysvar_epoch_rewards_t *
      42             : fd_sysvar_epoch_rewards_read( fd_accdb_t *                accdb,
      43             :                               fd_accdb_fork_id_t          fork_id,
      44         694 :                               fd_sysvar_epoch_rewards_t * out ) {
      45         694 :   fd_acc_t acc = fd_accdb_read_one( accdb, fork_id, fd_sysvar_epoch_rewards_id.uc );
      46         694 :   if( FD_UNLIKELY( !acc.lamports ) ) {
      47          46 :     fd_accdb_unread_one( accdb, &acc );
      48          46 :     return NULL;
      49          46 :   }
      50         648 :   if( FD_UNLIKELY( acc.data_len<FD_SYSVAR_EPOCH_REWARDS_BINCODE_SZ ) ) {
      51           0 :     fd_accdb_unread_one( accdb, &acc );
      52           0 :     return NULL;
      53           0 :   }
      54             : 
      55         648 :   fd_memcpy( out, acc.data, FD_SYSVAR_EPOCH_REWARDS_BINCODE_SZ );
      56             : 
      57         648 :   fd_accdb_unread_one( accdb, &acc );
      58         648 :   if( FD_UNLIKELY( validate( out ) ) ) return NULL;
      59         648 :   return out;
      60         648 : }
      61             : 
      62             : void
      63             : fd_sysvar_epoch_rewards_distribute( fd_bank_t *        bank,
      64             :                                     fd_accdb_t *       accdb,
      65             :                                     fd_capture_ctx_t * capture_ctx,
      66             :                                     ulong              distributed,
      67          41 :                                     ulong              debit_block_reward_lamports ) {
      68          41 :   fd_sysvar_epoch_rewards_t epoch_rewards[1];
      69          41 :   FD_TEST( fd_sysvar_epoch_rewards_read( accdb, bank->accdb_fork_id, epoch_rewards ) );
      70          41 :   FD_TEST( epoch_rewards->active );
      71             : 
      72          41 :   ulong new_distributed = fd_ulong_sat_add( epoch_rewards->distributed_rewards, distributed );
      73          41 :   FD_TEST( new_distributed<=epoch_rewards->total_rewards );
      74          41 :   epoch_rewards->distributed_rewards += distributed;
      75             : 
      76          41 :   write_epoch_rewards( bank, accdb, capture_ctx, epoch_rewards );
      77             : 
      78          41 :   if( FD_UNLIKELY( !debit_block_reward_lamports ) ) return;
      79             : 
      80           0 :   fd_accdb_svm_update_t update[1];
      81           0 :   fd_acc_t              acc = fd_accdb_svm_open_rw( bank, accdb, update, &fd_sysvar_epoch_rewards_id, 0 );
      82             :   /* https://github.com/anza-xyz/agave/blob/v4.4.0-alpha.5/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L101 */
      83           0 :   FD_TEST( acc.lamports>=debit_block_reward_lamports );
      84           0 :   acc.lamports -= debit_block_reward_lamports;
      85             :   /* https://github.com/anza-xyz/agave/blob/v4.4.0-alpha.5/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L102-L105 */
      86           0 :   FD_TEST( acc.lamports>=fd_rent_exempt_minimum_balance( &bank->f.rent, acc.data_len ) );
      87           0 :   fd_accdb_svm_close_rw( bank, accdb, capture_ctx, &acc, update );
      88           0 : }
      89             : 
      90             : void
      91             : fd_sysvar_epoch_rewards_set_inactive( fd_bank_t *        bank,
      92             :                                       fd_accdb_t *       accdb,
      93          42 :                                       fd_capture_ctx_t * capture_ctx ) {
      94          42 :   fd_sysvar_epoch_rewards_t epoch_rewards[1];
      95          42 :   FD_TEST( fd_sysvar_epoch_rewards_read( accdb, bank->accdb_fork_id, epoch_rewards ) );
      96          42 :   FD_TEST( epoch_rewards->total_rewards>=epoch_rewards->distributed_rewards );
      97             : 
      98          42 :   epoch_rewards->active = 0;
      99             : 
     100          42 :   if( FD_FEATURE_ACTIVE_BANK( bank, block_revenue_sharing ) ) {
     101             :     /* Don't inherit the balance to ensure that any remaining lamports
     102             :        get burned: the balance is reset to the rent-exempt minimum and
     103             :        capitalization is updated.
     104             :        https://github.com/anza-xyz/agave/blob/v4.4.0-alpha.5/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L120-L135 */
     105           0 :     write_epoch_rewards_reset_balance( bank, accdb, capture_ctx, epoch_rewards );
     106          42 :   } else {
     107          42 :     write_epoch_rewards( bank, accdb, capture_ctx, epoch_rewards );
     108          42 :   }
     109          42 : }
     110             : 
     111             : /* Create EpochRewards sysvar with calculated rewards
     112             : 
     113             :    https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L25 */
     114             : void
     115             : fd_sysvar_epoch_rewards_init( fd_bank_t *        bank,
     116             :                               fd_accdb_t *       accdb,
     117             :                               fd_capture_ctx_t * capture_ctx,
     118             :                               ulong              distributed_rewards,
     119             :                               ulong              distribution_starting_block_height,
     120             :                               ulong              num_partitions,
     121             :                               ulong              total_rewards,
     122             :                               uint128            total_points,
     123             :                               fd_hash_t const *  last_blockhash,
     124          28 :                               ulong              block_rewards ) {
     125          28 :   fd_sysvar_epoch_rewards_t epoch_rewards = {
     126          28 :     .distribution_starting_block_height = distribution_starting_block_height,
     127          28 :     .num_partitions                     = num_partitions,
     128          28 :     .total_points                       = { .ud=total_points },
     129          28 :     .total_rewards                      = total_rewards,
     130          28 :     .distributed_rewards                = distributed_rewards,
     131          28 :     .active                             = 1,
     132          28 :     .parent_blockhash                   = *last_blockhash
     133          28 :   };
     134             : 
     135          28 :   FD_TEST( epoch_rewards.total_rewards>=epoch_rewards.distributed_rewards );
     136          28 :   if( FD_UNLIKELY( fd_bank_report_runtime_diffs( bank ) ) ) fd_event_runtime_epoch_rewards( &epoch_rewards );
     137          28 :   write_epoch_rewards( bank, accdb, capture_ctx, &epoch_rewards );
     138             : 
     139             :   /* https://github.com/anza-xyz/agave/blob/v4.4.0-alpha.5/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L58-L69 */
     140          28 :   if( block_rewards ) {
     141           0 :     fd_accdb_svm_credit( bank, accdb, capture_ctx, &fd_sysvar_epoch_rewards_id, block_rewards, 0 );
     142           0 :   }
     143          28 : }

Generated by: LCOV version 1.14