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: 44 50 88.0 %
Date: 2026-07-07 05:36:20 Functions: 6 6 100.0 %

          Line data    Source code
       1             : #include "fd_sysvar_epoch_rewards.h"
       2             : #include "fd_sysvar.h"
       3             : #include "../fd_system_ids.h"
       4             : 
       5             : static int
       6         219 : validate( fd_sysvar_epoch_rewards_t const * epoch_rewards ) {
       7         219 :   return epoch_rewards->active!=0 && epoch_rewards->active!=1;
       8             : 
       9         219 : }
      10             : 
      11             : static void
      12             : write_epoch_rewards( fd_bank_t *                 bank,
      13             :                      fd_accdb_t *                accdb,
      14             :                      fd_capture_ctx_t *          capture_ctx,
      15         396 :                      fd_sysvar_epoch_rewards_t * epoch_rewards ) {
      16         396 :   fd_sysvar_account_update( bank, accdb, capture_ctx, &fd_sysvar_epoch_rewards_id, epoch_rewards, FD_SYSVAR_EPOCH_REWARDS_BINCODE_SZ );
      17         396 : }
      18             : 
      19             : fd_sysvar_epoch_rewards_t *
      20             : fd_sysvar_epoch_rewards_read( fd_accdb_t *                accdb,
      21             :                               fd_accdb_fork_id_t          fork_id,
      22         219 :                               fd_sysvar_epoch_rewards_t * out ) {
      23         219 :   fd_acc_t acc = fd_accdb_read_one( accdb, fork_id, fd_sysvar_epoch_rewards_id.uc );
      24         219 :   if( FD_UNLIKELY( !acc.lamports ) ) {
      25           0 :     fd_accdb_unread_one( accdb, &acc );
      26           0 :     return NULL;
      27           0 :   }
      28         219 :   if( FD_UNLIKELY( acc.data_len!=FD_SYSVAR_EPOCH_REWARDS_BINCODE_SZ ) ) {
      29           0 :     fd_accdb_unread_one( accdb, &acc );
      30           0 :     return NULL;
      31           0 :   }
      32             : 
      33         219 :   fd_memcpy( out, acc.data, FD_SYSVAR_EPOCH_REWARDS_BINCODE_SZ );
      34             : 
      35         219 :   fd_accdb_unread_one( accdb, &acc );
      36         219 :   if( FD_UNLIKELY( validate( out ) ) ) return NULL;
      37         219 :   return out;
      38         219 : }
      39             : 
      40             : /* Since there are multiple sysvar epoch rewards updates within a single slot,
      41             :    we need to ensure that the cache stays updated after each change (versus with other
      42             :    sysvars which only get updated once per slot and then synced up after) */
      43             : void
      44             : fd_sysvar_epoch_rewards_distribute( fd_bank_t *        bank,
      45             :                                     fd_accdb_t *       accdb,
      46             :                                     fd_capture_ctx_t * capture_ctx,
      47          99 :                                     ulong              distributed ) {
      48          99 :   fd_sysvar_epoch_rewards_t epoch_rewards[1];
      49          99 :   FD_TEST( fd_sysvar_epoch_rewards_read( accdb, bank->accdb_fork_id, epoch_rewards ) );
      50          99 :   FD_TEST( epoch_rewards->active );
      51             : 
      52          99 :   ulong new_distributed = fd_ulong_sat_add( epoch_rewards->distributed_rewards, distributed );
      53          99 :   FD_TEST( new_distributed<=epoch_rewards->total_rewards );
      54          99 :   epoch_rewards->distributed_rewards += distributed;
      55             : 
      56          99 :   write_epoch_rewards( bank, accdb, capture_ctx, epoch_rewards );
      57          99 : }
      58             : 
      59             : void
      60             : fd_sysvar_epoch_rewards_set_inactive( fd_bank_t *        bank,
      61             :                                       fd_accdb_t *       accdb,
      62          90 :                                       fd_capture_ctx_t * capture_ctx ) {
      63          90 :   fd_sysvar_epoch_rewards_t epoch_rewards[1];
      64          90 :   FD_TEST( fd_sysvar_epoch_rewards_read( accdb, bank->accdb_fork_id, epoch_rewards ) );
      65          90 :   FD_TEST( epoch_rewards->total_rewards>=epoch_rewards->distributed_rewards );
      66             : 
      67          90 :   epoch_rewards->active = 0;
      68          90 :   write_epoch_rewards( bank, accdb, capture_ctx, epoch_rewards );
      69          90 : }
      70             : 
      71             : /* Create EpochRewards sysvar with calculated rewards
      72             : 
      73             :    https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L25 */
      74             : void
      75             : fd_sysvar_epoch_rewards_init( fd_bank_t *        bank,
      76             :                               fd_accdb_t *       accdb,
      77             :                               fd_capture_ctx_t * capture_ctx,
      78             :                               ulong              distributed_rewards,
      79             :                               ulong              distribution_starting_block_height,
      80             :                               ulong              num_partitions,
      81             :                               ulong              total_rewards,
      82             :                               uint128            total_points,
      83         207 :                               fd_hash_t const *  last_blockhash ) {
      84         207 :   fd_sysvar_epoch_rewards_t epoch_rewards = {
      85         207 :     .distribution_starting_block_height = distribution_starting_block_height,
      86         207 :     .num_partitions                     = num_partitions,
      87         207 :     .total_points                       = { .ud=total_points },
      88         207 :     .total_rewards                      = total_rewards,
      89         207 :     .distributed_rewards                = distributed_rewards,
      90         207 :     .active                             = 1,
      91         207 :     .parent_blockhash                   = *last_blockhash
      92         207 :   };
      93             : 
      94         207 :   FD_TEST( epoch_rewards.total_rewards>=epoch_rewards.distributed_rewards );
      95         207 :   write_epoch_rewards( bank, accdb, capture_ctx, &epoch_rewards );
      96         207 : }

Generated by: LCOV version 1.14