LCOV - code coverage report
Current view: top level - choreo/tower - fd_epoch_stakes.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 39 62 62.9 %
Date: 2025-12-06 04:45:29 Functions: 3 4 75.0 %

          Line data    Source code
       1             : #include "fd_epoch_stakes.h"
       2             : 
       3             : void *
       4             : fd_epoch_stakes_new( void * shmem,
       5           9 :                      ulong  slot_max ) {
       6           9 :   if( FD_UNLIKELY( !shmem ) ) {
       7           0 :     FD_LOG_WARNING(( "NULL mem" ));
       8           0 :     return NULL;
       9           0 :   }
      10           9 :   fd_wksp_t * wksp = fd_wksp_containing( shmem );
      11           9 :   if( FD_UNLIKELY( !wksp ) ) {
      12           0 :       FD_LOG_WARNING(( "shmem must be part of a workspace" ));
      13           0 :       return NULL;
      14           0 :   }
      15           9 :   ulong footprint = fd_epoch_stakes_footprint( slot_max );
      16           9 :   if( FD_UNLIKELY( !footprint ) ) {
      17           0 :     FD_LOG_WARNING(( "bad slot_max (%lu)", slot_max ));
      18           0 :     return NULL;
      19           0 :   }
      20             :   /* verify aligned to fd_epoch_stakes_align() */
      21           9 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)shmem, fd_epoch_stakes_align() ) ) ) {
      22           0 :     FD_LOG_WARNING(( "misaligned mem" ));
      23           0 :     return NULL;
      24           0 :   }
      25             : 
      26           9 :   int lg_slot_cnt = fd_ulong_find_msb( fd_ulong_pow2_up( slot_max ) ) + 1;
      27             : 
      28           9 :   FD_SCRATCH_ALLOC_INIT( l, shmem );
      29           9 :   fd_epoch_stakes_t * epoch_stakes          = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_epoch_stakes_t),       sizeof(fd_epoch_stakes_t) );
      30           9 :   void *              voter_stake_map       = FD_SCRATCH_ALLOC_APPEND( l, fd_voter_stake_map_align(),       fd_voter_stake_map_footprint ( FD_VOTER_MAX * slot_max ) );
      31           9 :   void *              voter_stake_pool      = FD_SCRATCH_ALLOC_APPEND( l, fd_voter_stake_pool_align(),      fd_voter_stake_pool_footprint( FD_VOTER_MAX * slot_max ) );
      32           9 :   void *              epoch_stakes_slot_map = FD_SCRATCH_ALLOC_APPEND( l, fd_epoch_stakes_slot_map_align(), fd_epoch_stakes_slot_map_footprint( lg_slot_cnt ) );
      33           9 :   void *              used_acc_scratch      = FD_SCRATCH_ALLOC_APPEND( l, fd_used_acc_scratch_align(),      fd_used_acc_scratch_footprint( FD_VOTER_MAX * slot_max ) );
      34           9 :   FD_TEST( FD_SCRATCH_ALLOC_FINI( l, fd_epoch_stakes_align() ) == (ulong)shmem + footprint );
      35             : 
      36           9 :   epoch_stakes->voter_stake_map  = fd_voter_stake_map_join      ( fd_voter_stake_map_new      ( voter_stake_map,  FD_VOTER_MAX * slot_max, 0 ) );
      37           9 :   epoch_stakes->voter_stake_pool = fd_voter_stake_pool_join     ( fd_voter_stake_pool_new     ( voter_stake_pool, FD_VOTER_MAX * slot_max ) );
      38           9 :   epoch_stakes->slot_stakes_map  = fd_epoch_stakes_slot_map_join( fd_epoch_stakes_slot_map_new( epoch_stakes_slot_map, lg_slot_cnt, 0UL ) );      /* FIXME seed? */
      39           9 :   epoch_stakes->used_acc_scratch = fd_used_acc_scratch_join     ( fd_used_acc_scratch_new     ( used_acc_scratch, FD_VOTER_MAX * slot_max ) );
      40           9 :   return shmem;
      41           9 : }
      42             : 
      43             : fd_epoch_stakes_t *
      44           9 : fd_epoch_stakes_join( void * shepoch_stakes ) {
      45           9 :   return shepoch_stakes;
      46           9 : }
      47             : 
      48             : ulong
      49          45 : fd_epoch_stakes_slot_stakes_add( fd_epoch_stakes_t * epoch_stakes, ulong slot, fd_hash_t const * vote_account, ulong stake, ulong prev_voter_idx ) {
      50          45 :   fd_voter_stake_t * pool = epoch_stakes->voter_stake_pool;
      51          45 :   if( FD_UNLIKELY( !fd_voter_stake_pool_free( pool ) ) ) FD_LOG_CRIT(( "no free voter stakes in pool" ));
      52          45 :   fd_voter_stake_t * new_voter_stake = fd_voter_stake_pool_ele_acquire( pool );
      53          45 :   new_voter_stake->key   = (fd_voter_stake_key_t){ .vote_account = *vote_account, .slot = slot };
      54          45 :   new_voter_stake->stake = stake;
      55          45 :   new_voter_stake->prev  = prev_voter_idx;
      56          45 :   fd_voter_stake_map_ele_insert( epoch_stakes->voter_stake_map, new_voter_stake, pool );
      57             : 
      58             :   /* now update the slot_stakes_map to point to the new head of the linkedlist */
      59          45 :   fd_epoch_stakes_slot_t * slot_stakes = fd_epoch_stakes_slot_map_query( epoch_stakes->slot_stakes_map, slot, NULL );
      60          45 :   if( FD_UNLIKELY( !slot_stakes ) ) {
      61          30 :     slot_stakes = fd_epoch_stakes_slot_map_insert( epoch_stakes->slot_stakes_map, slot );
      62          30 :   }
      63          45 :   slot_stakes->voter_stake_idx = fd_voter_stake_pool_idx( pool, new_voter_stake );
      64          45 :   return slot_stakes->voter_stake_idx;
      65          45 : }
      66             : 
      67             : void
      68           0 : fd_epoch_stakes_slot_stakes_remove( fd_epoch_stakes_t * epoch_stakes, fd_epoch_stakes_slot_t * slot ) {
      69             :   /* walk stakes linkedlist and remove the voter stake at the given index */
      70           0 :   ulong voter_idx = slot->voter_stake_idx;
      71           0 :   while( FD_UNLIKELY( voter_idx != ULONG_MAX ) ) {
      72           0 :     fd_voter_stake_t * voter_stake = fd_voter_stake_pool_ele( epoch_stakes->voter_stake_pool, voter_idx );
      73           0 :     voter_idx = voter_stake->prev;
      74           0 :     fd_voter_stake_t * remove = fd_voter_stake_map_ele_remove( epoch_stakes->voter_stake_map, &voter_stake->key, NULL, epoch_stakes->voter_stake_pool );
      75           0 :     if( FD_UNLIKELY( !remove ) ) FD_LOG_CRIT(( "invariant violation: voter stake does not exist in map" ));
      76           0 :     fd_voter_stake_pool_ele_release( epoch_stakes->voter_stake_pool, voter_stake );
      77           0 :   }
      78           0 :   fd_epoch_stakes_slot_map_remove( epoch_stakes->slot_stakes_map, slot );
      79           0 : }

Generated by: LCOV version 1.14