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 90 0.0 %
Date: 2025-03-20 12:08:36 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_runtime.h"
       5             : #include "../fd_borrowed_account.h"
       6             : #include "../fd_system_ids.h"
       7             : #include "../context/fd_exec_epoch_ctx.h"
       8             : 
       9             : static void
      10           0 : write_epoch_rewards( fd_exec_slot_ctx_t * slot_ctx, fd_sysvar_epoch_rewards_t * epoch_rewards ) {
      11           0 :   ulong sz = fd_sysvar_epoch_rewards_size( epoch_rewards );
      12           0 :   uchar enc[sz];
      13           0 :   fd_memset( enc, 0, sz );
      14           0 :   fd_bincode_encode_ctx_t ctx;
      15           0 :   ctx.data = enc;
      16           0 :   ctx.dataend = enc + sz;
      17           0 :   if ( fd_sysvar_epoch_rewards_encode( epoch_rewards, &ctx ) ) {
      18           0 :     FD_LOG_ERR(("fd_sysvar_epoch_rewards_encode failed"));
      19           0 :   }
      20             : 
      21           0 :   fd_sysvar_set( slot_ctx, fd_sysvar_owner_id.key, &fd_sysvar_epoch_rewards_id, enc, sz, slot_ctx->slot_bank.slot );
      22           0 : }
      23             : 
      24             : fd_sysvar_epoch_rewards_t *
      25             : fd_sysvar_epoch_rewards_read( fd_sysvar_epoch_rewards_t * result,
      26             :                               fd_sysvar_cache_t const *   sysvar_cache,
      27             :                               fd_acc_mgr_t *              acc_mgr,
      28           0 :                               fd_funk_txn_t *             funk_txn ) {
      29           0 :   fd_sysvar_epoch_rewards_t const * ret = (fd_sysvar_epoch_rewards_t const *)fd_sysvar_cache_epoch_rewards( sysvar_cache );
      30           0 :   if( FD_UNLIKELY( NULL != ret ) ) {
      31           0 :     fd_memcpy(result, ret, sizeof(fd_sysvar_epoch_rewards_t));
      32           0 :     return result;
      33           0 :   }
      34             : 
      35           0 :   FD_TXN_ACCOUNT_DECL( acc );
      36           0 :   int err = fd_acc_mgr_view( acc_mgr, funk_txn, &fd_sysvar_epoch_rewards_id, acc );
      37           0 :   if( FD_UNLIKELY( err != FD_ACC_MGR_SUCCESS ) ) {
      38           0 :     return NULL;
      39           0 :   }
      40             : 
      41           0 :   fd_bincode_decode_ctx_t decode = {
      42           0 :     .data    = acc->const_data,
      43           0 :     .dataend = acc->const_data + acc->const_meta->dlen
      44           0 :   };
      45             : 
      46           0 :   ulong total_sz = 0UL;
      47           0 :   err = fd_sysvar_epoch_rewards_decode_footprint( &decode, &total_sz );
      48             : 
      49           0 :   if( FD_UNLIKELY( err ) ) {
      50           0 :     return NULL;
      51           0 :   }
      52             : 
      53             :   /* We assume here that the data structure is properly allocated already.
      54             :      This could potentially be unsafe if not handled correctly by the caller. */
      55           0 :   fd_sysvar_epoch_rewards_decode( result, &decode );
      56             : 
      57           0 :   return result;
      58           0 : }
      59             : 
      60             : /* Since there are multiple sysvar epoch rewards updates within a single slot,
      61             :    we need to ensure that the cache stays updated after each change (versus with other
      62             :    sysvars which only get updated once per slot and then synced up after) */
      63             : void
      64             : fd_sysvar_epoch_rewards_distribute( fd_exec_slot_ctx_t * slot_ctx,
      65             :                                     ulong                distributed,
      66           0 :                                     fd_spad_t *          runtime_spad ) {
      67           0 :     fd_sysvar_epoch_rewards_t epoch_rewards[1];
      68           0 :     if ( FD_UNLIKELY( fd_sysvar_epoch_rewards_read( epoch_rewards,
      69           0 :                                                     slot_ctx->sysvar_cache,
      70           0 :                                                     slot_ctx->acc_mgr,
      71           0 :                                                     slot_ctx->funk_txn ) == NULL ) ) {
      72           0 :       FD_LOG_ERR(( "failed to read sysvar epoch rewards" ));
      73           0 :     }
      74           0 :     FD_TEST( epoch_rewards->active );
      75             : 
      76           0 :     FD_TEST( fd_ulong_sat_add( epoch_rewards->distributed_rewards, distributed ) <= epoch_rewards->total_rewards );
      77             : 
      78           0 :     epoch_rewards->distributed_rewards += distributed;
      79             : 
      80           0 :     write_epoch_rewards( slot_ctx, epoch_rewards );
      81             : 
      82             :     /* Sync the epoch rewards sysvar cache entry with the account */
      83           0 :     fd_sysvar_cache_restore_epoch_rewards( slot_ctx->sysvar_cache,
      84           0 :                                            slot_ctx->acc_mgr,
      85           0 :                                            slot_ctx->funk_txn,
      86           0 :                                            runtime_spad,
      87           0 :                                            slot_ctx->runtime_wksp );
      88           0 : }
      89             : 
      90             : void
      91             : fd_sysvar_epoch_rewards_set_inactive( fd_exec_slot_ctx_t * slot_ctx,
      92           0 :                                       fd_spad_t *          runtime_spad ) {
      93           0 :     fd_sysvar_epoch_rewards_t epoch_rewards[1];
      94           0 :     if ( FD_UNLIKELY( fd_sysvar_epoch_rewards_read( epoch_rewards,
      95           0 :                                                     slot_ctx->sysvar_cache,
      96           0 :                                                     slot_ctx->acc_mgr,
      97           0 :                                                     slot_ctx->funk_txn ) == NULL ) ) {
      98           0 :       FD_LOG_ERR(( "failed to read sysvar epoch rewards" ));
      99           0 :     }
     100             : 
     101           0 :     if ( FD_LIKELY( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, partitioned_epoch_rewards_superfeature ) ) ) {
     102           0 :       FD_TEST( epoch_rewards->total_rewards >= epoch_rewards->distributed_rewards );
     103           0 :     } else {
     104           0 :       FD_TEST( epoch_rewards->total_rewards == epoch_rewards->distributed_rewards );
     105           0 :     }
     106             : 
     107             : 
     108           0 :     epoch_rewards->active = 0;
     109             : 
     110           0 :     write_epoch_rewards( slot_ctx, epoch_rewards );
     111             : 
     112             :     /* Sync the epoch rewards sysvar cache entry with the account */
     113           0 :     fd_sysvar_cache_restore_epoch_rewards( slot_ctx->sysvar_cache,
     114           0 :                                            slot_ctx->acc_mgr,
     115           0 :                                            slot_ctx->funk_txn,
     116           0 :                                            runtime_spad,
     117           0 :                                            slot_ctx->runtime_wksp );
     118           0 : }
     119             : 
     120             : /* Create EpochRewards syavar with calculated rewards
     121             : 
     122             :    https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L25 */
     123             : void
     124             : fd_sysvar_epoch_rewards_init(
     125             :     fd_exec_slot_ctx_t * slot_ctx,
     126             :     ulong total_rewards,
     127             :     ulong distributed_rewards,
     128             :     ulong distribution_starting_block_height,
     129             :     ulong num_partitions,
     130             :     fd_point_value_t point_value,
     131             :     const fd_hash_t * last_blockhash
     132           0 : ) {
     133           0 :     FD_TEST( total_rewards >= distributed_rewards );
     134             : 
     135           0 :     fd_sysvar_epoch_rewards_t epoch_rewards = {
     136           0 :       .distribution_starting_block_height = distribution_starting_block_height,
     137           0 :       .num_partitions = num_partitions,
     138           0 :       .total_points = point_value.points,
     139           0 :       .total_rewards = total_rewards,
     140           0 :       .distributed_rewards = distributed_rewards,
     141           0 :       .active = 1
     142           0 :     };
     143             : 
     144             :     /* On clusters where partitioned_epoch_rewards_superfeature is enabled, we should use point_value.rewards.
     145             :        On other clusters, including those where enable_partitioned_epoch_reward is enabled, we should use total_rewards.
     146             : 
     147             :        https://github.com/anza-xyz/agave/blob/b9c9ecccbb05d9da774d600bdbef2cf210c57fa8/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L36-L43 */
     148           0 :     if( FD_LIKELY( FD_FEATURE_ACTIVE( slot_ctx->slot_bank.slot, slot_ctx->epoch_ctx->features, partitioned_epoch_rewards_superfeature ) ) ) {
     149           0 :       epoch_rewards.total_rewards = point_value.rewards;
     150           0 :     }
     151             : 
     152           0 :     fd_memcpy( &epoch_rewards.parent_blockhash, last_blockhash, FD_HASH_FOOTPRINT );
     153             : 
     154           0 :     write_epoch_rewards( slot_ctx, &epoch_rewards );
     155           0 : }

Generated by: LCOV version 1.14