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: 45 51 88.2 %
Date: 2026-09-17 04:28:31 Functions: 6 6 100.0 %

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

Generated by: LCOV version 1.14