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: 0 68 0.0 %
Date: 2025-10-13 04:42:14 Functions: 0 5 0.0 %

          Line data    Source code
       1             : #include "fd_sysvar_epoch_rewards.h"
       2             : #include "fd_sysvar.h"
       3             : #include "../fd_acc_mgr.h"
       4             : #include "../fd_txn_account.h"
       5             : #include "../fd_system_ids.h"
       6             : 
       7             : static void
       8             : write_epoch_rewards( fd_bank_t *                 bank,
       9             :                      fd_funk_t *                 funk,
      10             :                      fd_funk_txn_xid_t const *   xid,
      11             :                      fd_capture_ctx_t *          capture_ctx,
      12           0 :                      fd_sysvar_epoch_rewards_t * epoch_rewards ) {
      13           0 :   ulong sz = fd_sysvar_epoch_rewards_size( epoch_rewards );
      14           0 :   uchar enc[sz];
      15           0 :   fd_memset( enc, 0, sz );
      16           0 :   fd_bincode_encode_ctx_t ctx = {
      17           0 :     .data    = enc,
      18           0 :     .dataend = enc + sz
      19           0 :   };
      20           0 :   if( FD_UNLIKELY( fd_sysvar_epoch_rewards_encode( epoch_rewards, &ctx ) ) ) {
      21           0 :     FD_LOG_ERR(( "fd_sysvar_epoch_rewards_encode failed" ));
      22           0 :   }
      23             : 
      24           0 :   fd_sysvar_account_update( bank, funk, xid, capture_ctx, &fd_sysvar_epoch_rewards_id, enc, sz );
      25           0 : }
      26             : 
      27             : fd_sysvar_epoch_rewards_t *
      28             : fd_sysvar_epoch_rewards_read( fd_funk_t *                 funk,
      29             :                               fd_funk_txn_xid_t const *   xid,
      30           0 :                               fd_sysvar_epoch_rewards_t * out ) {
      31           0 :   FD_TXN_ACCOUNT_DECL( acc );
      32           0 :   int err = fd_txn_account_init_from_funk_readonly( acc, &fd_sysvar_epoch_rewards_id, funk, xid );
      33           0 :   if( FD_UNLIKELY( err != FD_ACC_MGR_SUCCESS ) ) {
      34           0 :     return NULL;
      35           0 :   }
      36             : 
      37             :   /* This check is needed as a quirk of the fuzzer. If a sysvar account
      38             :      exists in the accounts database, but doesn't have any lamports,
      39             :      this means that the account does not exist. This wouldn't happen
      40             :      in a real execution environment. */
      41           0 :   if( FD_UNLIKELY( fd_txn_account_get_lamports( acc )==0UL ) ) {
      42           0 :     return NULL;
      43           0 :   }
      44             : 
      45           0 :   return fd_bincode_decode_static(
      46           0 :       sysvar_epoch_rewards, out,
      47           0 :       fd_txn_account_get_data( acc ),
      48           0 :       fd_txn_account_get_data_len( acc ),
      49           0 :       &err );
      50           0 : }
      51             : 
      52             : /* Since there are multiple sysvar epoch rewards updates within a single slot,
      53             :    we need to ensure that the cache stays updated after each change (versus with other
      54             :    sysvars which only get updated once per slot and then synced up after) */
      55             : void
      56             : fd_sysvar_epoch_rewards_distribute( fd_bank_t *               bank,
      57             :                                     fd_funk_t *               funk,
      58             :                                     fd_funk_txn_xid_t const * xid,
      59             :                                     fd_capture_ctx_t *        capture_ctx,
      60           0 :                                     ulong                     distributed ) {
      61           0 :   fd_sysvar_epoch_rewards_t epoch_rewards[1];
      62           0 :   if( FD_UNLIKELY( !fd_sysvar_epoch_rewards_read( funk, xid, epoch_rewards ) ) ) {
      63           0 :     FD_LOG_ERR(( "failed to read sysvar epoch rewards" ));
      64           0 :   }
      65             : 
      66           0 :   if( FD_UNLIKELY( !epoch_rewards->active ) ) {
      67           0 :     FD_LOG_ERR(( "sysvar epoch rewards is not active" ));
      68           0 :   }
      69             : 
      70           0 :   if( FD_UNLIKELY( fd_ulong_sat_add( epoch_rewards->distributed_rewards, distributed ) > epoch_rewards->total_rewards ) ) {
      71           0 :     FD_LOG_ERR(( "distributed rewards overflow" ));
      72           0 :   }
      73             : 
      74           0 :   epoch_rewards->distributed_rewards += distributed;
      75             : 
      76           0 :   write_epoch_rewards( bank, funk, xid, capture_ctx, epoch_rewards );
      77           0 : }
      78             : 
      79             : void
      80             : fd_sysvar_epoch_rewards_set_inactive( fd_bank_t *               bank,
      81             :                                       fd_funk_t *               funk,
      82             :                                       fd_funk_txn_xid_t const * xid,
      83           0 :                                       fd_capture_ctx_t *        capture_ctx ) {
      84           0 :   fd_sysvar_epoch_rewards_t epoch_rewards[1];
      85           0 :   if( FD_UNLIKELY( !fd_sysvar_epoch_rewards_read( funk, xid, epoch_rewards ) ) ) {
      86           0 :     FD_LOG_ERR(( "failed to read sysvar epoch rewards" ));
      87           0 :   }
      88             : 
      89           0 :   if( FD_UNLIKELY( epoch_rewards->total_rewards < epoch_rewards->distributed_rewards ) ) {
      90           0 :     FD_LOG_ERR(( "distributed rewards overflow" ));
      91           0 :   }
      92             : 
      93           0 :   epoch_rewards->active = 0;
      94             : 
      95           0 :   write_epoch_rewards( bank, funk, xid, capture_ctx, epoch_rewards );
      96           0 : }
      97             : 
      98             : /* Create EpochRewards sysvar with calculated rewards
      99             : 
     100             :    https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L25 */
     101             : void
     102             : fd_sysvar_epoch_rewards_init( fd_bank_t *               bank,
     103             :                               fd_funk_t *               funk,
     104             :                               fd_funk_txn_xid_t const * xid,
     105             :                               fd_capture_ctx_t *        capture_ctx,
     106             :                               ulong                     distributed_rewards,
     107             :                               ulong                     distribution_starting_block_height,
     108             :                               ulong                     num_partitions,
     109             :                               ulong                     total_rewards,
     110             :                               uint128                   total_points,
     111           0 :                               fd_hash_t const *         last_blockhash ) {
     112           0 :   fd_sysvar_epoch_rewards_t epoch_rewards = {
     113           0 :     .distribution_starting_block_height = distribution_starting_block_height,
     114           0 :     .num_partitions                     = num_partitions,
     115           0 :     .total_points                       = total_points,
     116           0 :     .total_rewards                      = total_rewards,
     117           0 :     .distributed_rewards                = distributed_rewards,
     118           0 :     .active                             = 1,
     119           0 :     .parent_blockhash                   = *last_blockhash
     120           0 :   };
     121             : 
     122           0 :   if( FD_UNLIKELY( epoch_rewards.total_rewards<distributed_rewards ) ) {
     123           0 :     FD_LOG_ERR(( "total rewards overflow" ));
     124           0 :   }
     125             : 
     126           0 :   write_epoch_rewards( bank, funk, xid, capture_ctx, &epoch_rewards );
     127           0 : }

Generated by: LCOV version 1.14