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: 26 72 36.1 %
Date: 2025-01-08 12:08:44 Functions: 2 5 40.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_borrowed_account.h"
       5             : #include "../fd_system_ids.h"
       6             : #include "../context/fd_exec_slot_ctx.h"
       7             : #include "../context/fd_exec_epoch_ctx.h"
       8             : 
       9             : static void
      10        1845 : write_epoch_rewards( fd_exec_slot_ctx_t * slot_ctx, fd_sysvar_epoch_rewards_t * epoch_rewards ) {
      11        1845 :   ulong sz = fd_sysvar_epoch_rewards_size( epoch_rewards );
      12        1845 :   uchar enc[sz];
      13        1845 :   fd_memset( enc, 0, sz );
      14        1845 :   fd_bincode_encode_ctx_t ctx;
      15        1845 :   ctx.data = enc;
      16        1845 :   ctx.dataend = enc + sz;
      17        1845 :   if ( fd_sysvar_epoch_rewards_encode( epoch_rewards, &ctx ) ) {
      18           0 :     FD_LOG_ERR(("fd_sysvar_epoch_rewards_encode failed"));
      19           0 :   }
      20             : 
      21        1845 :   fd_sysvar_set( slot_ctx, fd_sysvar_owner_id.key, &fd_sysvar_epoch_rewards_id, enc, sz, slot_ctx->slot_bank.slot );
      22        1845 : }
      23             : 
      24             : fd_sysvar_epoch_rewards_t *
      25             : fd_sysvar_epoch_rewards_read(
      26             :     fd_sysvar_epoch_rewards_t * result,
      27             :     fd_exec_slot_ctx_t const * slot_ctx
      28           0 : ) {
      29           0 :   fd_sysvar_epoch_rewards_t const * ret = fd_sysvar_cache_epoch_rewards( slot_ctx->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_BORROWED_ACCOUNT_DECL(acc);
      36           0 :   int err = fd_acc_mgr_view( slot_ctx->acc_mgr, slot_ctx->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 :       .valloc  = {0}  /* valloc not required */ };
      45             : 
      46           0 :   if( FD_UNLIKELY( fd_sysvar_epoch_rewards_decode( result, &decode )!=FD_BINCODE_SUCCESS ) )
      47           0 :     return NULL;
      48             : 
      49           0 :   return result;
      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(
      57             :     fd_exec_slot_ctx_t * slot_ctx,
      58             :     ulong distributed
      59           0 : ) {
      60           0 :     fd_sysvar_epoch_rewards_t epoch_rewards[1];
      61           0 :     if ( FD_UNLIKELY( fd_sysvar_epoch_rewards_read( epoch_rewards, slot_ctx ) == NULL ) ) {
      62           0 :       FD_LOG_ERR(( "failed to read sysvar epoch rewards" ));
      63           0 :     }
      64           0 :     FD_TEST( epoch_rewards->active );
      65             : 
      66           0 :     FD_TEST( fd_ulong_sat_add( epoch_rewards->distributed_rewards, distributed ) <= epoch_rewards->total_rewards );
      67             : 
      68           0 :     epoch_rewards->distributed_rewards += distributed;
      69             : 
      70           0 :     write_epoch_rewards( slot_ctx, epoch_rewards );
      71             : 
      72             :     /* Sync the epoch rewards sysvar cache entry with the account */
      73           0 :     fd_sysvar_cache_restore_epoch_rewards( slot_ctx->sysvar_cache, slot_ctx->acc_mgr, slot_ctx->funk_txn );
      74           0 : }
      75             : 
      76             : void
      77             : fd_sysvar_epoch_rewards_set_inactive(
      78             :   fd_exec_slot_ctx_t * slot_ctx
      79           0 : ) {
      80           0 :     fd_sysvar_epoch_rewards_t epoch_rewards[1];
      81           0 :     if ( FD_UNLIKELY( fd_sysvar_epoch_rewards_read( epoch_rewards, slot_ctx ) == NULL ) ) {
      82           0 :       FD_LOG_ERR(( "failed to read sysvar epoch rewards" ));
      83           0 :     }
      84             : 
      85           0 :     if ( FD_LIKELY( FD_FEATURE_ACTIVE( slot_ctx, partitioned_epoch_rewards_superfeature ) ) ) {
      86           0 :       FD_TEST( epoch_rewards->total_rewards >= epoch_rewards->distributed_rewards );
      87           0 :     } else {
      88           0 :       FD_TEST( epoch_rewards->total_rewards == epoch_rewards->distributed_rewards );
      89           0 :     }
      90             : 
      91             : 
      92           0 :     epoch_rewards->active = 0;
      93             : 
      94           0 :     write_epoch_rewards( slot_ctx, epoch_rewards );
      95             : 
      96             :     /* Sync the epoch rewards sysvar cache entry with the account */
      97           0 :     fd_sysvar_cache_restore_epoch_rewards( slot_ctx->sysvar_cache, slot_ctx->acc_mgr, slot_ctx->funk_txn );
      98           0 : }
      99             : 
     100             : /* Create EpochRewards syavar with calculated rewards
     101             : 
     102             :    https://github.com/anza-xyz/agave/blob/cbc8320d35358da14d79ebcada4dfb6756ffac79/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L25 */
     103             : void
     104             : fd_sysvar_epoch_rewards_init(
     105             :     fd_exec_slot_ctx_t * slot_ctx,
     106             :     ulong total_rewards,
     107             :     ulong distributed_rewards,
     108             :     ulong distribution_starting_block_height,
     109             :     ulong num_partitions,
     110             :     fd_point_value_t point_value,
     111             :     const fd_hash_t * last_blockhash
     112        1845 : ) {
     113        1845 :     FD_TEST( total_rewards >= distributed_rewards );
     114             : 
     115        1845 :     fd_sysvar_epoch_rewards_t epoch_rewards = {
     116        1845 :       .distribution_starting_block_height = distribution_starting_block_height,
     117        1845 :       .num_partitions = num_partitions,
     118        1845 :       .total_points = point_value.points,
     119        1845 :       .total_rewards = total_rewards,
     120        1845 :       .distributed_rewards = distributed_rewards,
     121        1845 :       .active = 1
     122        1845 :     };
     123             : 
     124             :     /* On clusters where partitioned_epoch_rewards_superfeature is enabled, we should use point_value.rewards.
     125             :        On other clusters, including those where enable_partitioned_epoch_reward is enabled, we should use total_rewards.
     126             : 
     127             :        https://github.com/anza-xyz/agave/blob/b9c9ecccbb05d9da774d600bdbef2cf210c57fa8/runtime/src/bank/partitioned_epoch_rewards/sysvar.rs#L36-L43 */
     128        1845 :     if ( FD_LIKELY( FD_FEATURE_ACTIVE( slot_ctx, partitioned_epoch_rewards_superfeature ) ) ) {
     129           9 :       epoch_rewards.total_rewards = point_value.rewards;
     130           9 :     }
     131             : 
     132        1845 :     fd_memcpy( &epoch_rewards.parent_blockhash, last_blockhash, FD_HASH_FOOTPRINT );
     133             : 
     134        1845 :     write_epoch_rewards( slot_ctx, &epoch_rewards );
     135        1845 : }

Generated by: LCOV version 1.14