LCOV - code coverage report
Current view: top level - flamenco/stakes - fd_vote_states.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 158 290 54.5 %
Date: 2026-01-19 05:27:37 Functions: 13 19 68.4 %

          Line data    Source code
       1             : #include "fd_vote_states.h"
       2             : #include "../types/fd_types.h"
       3             : #include "../runtime/program/fd_vote_program.h"
       4             : 
       5             : #define POOL_NAME fd_vote_state_pool
       6        3264 : #define POOL_T    fd_vote_state_ele_t
       7    41607039 : #define POOL_NEXT next_
       8             : #include "../../util/tmpl/fd_pool.c"
       9             : 
      10             : #define MAP_NAME               fd_vote_state_map
      11             : #define MAP_KEY_T              fd_pubkey_t
      12             : #define MAP_ELE_T              fd_vote_state_ele_t
      13           6 : #define MAP_KEY                vote_account
      14          15 : #define MAP_KEY_EQ(k0,k1)      (fd_pubkey_eq( k0, k1 ))
      15          30 : #define MAP_KEY_HASH(key,seed) (fd_hash( seed, key, sizeof(fd_pubkey_t) ))
      16          15 : #define MAP_NEXT               next_
      17             : #include "../../util/tmpl/fd_map_chain.c"
      18             : 
      19             : static fd_vote_state_ele_t *
      20         150 : fd_vote_states_get_pool( fd_vote_states_t const * vote_states ) {
      21         150 :   return fd_vote_state_pool_join( (uchar *)vote_states + vote_states->pool_offset_ );
      22         150 : }
      23             : 
      24             : static fd_vote_state_map_t *
      25         102 : fd_vote_states_get_map( fd_vote_states_t const * vote_states ) {
      26         102 :   return fd_vote_state_map_join( (uchar *)vote_states + vote_states->map_offset_ );
      27         102 : }
      28             : 
      29             : ulong
      30       16644 : fd_vote_states_align( void ) {
      31             :   /* The align of the struct should be the max of the align of the data
      32             :      structures that it contains.  In this case, this is the map, the
      33             :      pool, and the struct itself. */
      34       16644 :   return fd_ulong_max( fd_ulong_max( fd_vote_state_map_align(),
      35       16644 :                        fd_vote_state_pool_align() ), alignof(fd_vote_states_t) );
      36       16644 : }
      37             : 
      38             : ulong
      39        2082 : fd_vote_states_footprint( ulong max_vote_accounts ) {
      40             : 
      41        2082 :   ulong map_chain_cnt = fd_vote_state_map_chain_cnt_est( max_vote_accounts );
      42             : 
      43        2082 :   ulong l = FD_LAYOUT_INIT;
      44        2082 :   l = FD_LAYOUT_APPEND( l,  fd_vote_states_align(),     sizeof(fd_vote_states_t) );
      45        2082 :   l = FD_LAYOUT_APPEND( l,  fd_vote_state_pool_align(), fd_vote_state_pool_footprint( max_vote_accounts ) );
      46        2082 :   l = FD_LAYOUT_APPEND( l,  fd_vote_state_map_align(),  fd_vote_state_map_footprint( map_chain_cnt ) );
      47        2082 :   return FD_LAYOUT_FINI( l, fd_vote_states_align() );
      48        2082 : }
      49             : 
      50             : void *
      51             : fd_vote_states_new( void * mem,
      52             :                     ulong  max_vote_accounts,
      53        1044 :                     ulong  seed ) {
      54        1044 :   if( FD_UNLIKELY( !mem ) ) {
      55           3 :     FD_LOG_WARNING(( "NULL mem" ));
      56           3 :     return NULL;
      57           3 :   }
      58             : 
      59        1041 :   if( FD_UNLIKELY( !max_vote_accounts ) ) {
      60           3 :     FD_LOG_WARNING(( "max_vote_accounts is 0" ));
      61           3 :     return NULL;
      62           3 :   }
      63             : 
      64        1038 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, fd_vote_states_align() ) ) ) {
      65           0 :     FD_LOG_WARNING(( "misaligned mem" ));
      66           0 :     return NULL;
      67           0 :   }
      68             : 
      69        1038 :   ulong map_chain_cnt = fd_vote_state_map_chain_cnt_est( max_vote_accounts );
      70             : 
      71        1038 :   FD_SCRATCH_ALLOC_INIT( l, mem );
      72        1038 :   fd_vote_states_t * vote_states = FD_SCRATCH_ALLOC_APPEND( l, fd_vote_states_align(),     sizeof(fd_vote_states_t) );
      73        1038 :   void *             pool_mem    = FD_SCRATCH_ALLOC_APPEND( l, fd_vote_state_pool_align(), fd_vote_state_pool_footprint( max_vote_accounts ) );
      74        1038 :   void *             map_mem     = FD_SCRATCH_ALLOC_APPEND( l, fd_vote_state_map_align(),  fd_vote_state_map_footprint( map_chain_cnt ) );
      75             : 
      76        1038 :   if( FD_UNLIKELY( FD_SCRATCH_ALLOC_FINI( l, fd_vote_states_align() )!=(ulong)mem+fd_vote_states_footprint( max_vote_accounts ) ) ) {
      77           0 :     FD_LOG_WARNING(( "fd_vote_states_new: bad layout" ));
      78           0 :     return NULL;
      79           0 :   }
      80             : 
      81        1038 :   vote_states->max_vote_accounts_ = max_vote_accounts;
      82        1038 :   vote_states->pool_offset_       = (ulong)pool_mem - (ulong)mem;
      83        1038 :   vote_states->map_offset_        = (ulong)map_mem - (ulong)mem;
      84             : 
      85        1038 :   fd_vote_state_ele_t * vote_states_pool = fd_vote_state_pool_join( fd_vote_state_pool_new( pool_mem, max_vote_accounts ) );
      86        1038 :   if( FD_UNLIKELY( !vote_states_pool ) ) {
      87           0 :     FD_LOG_WARNING(( "Failed to create vote states pool" ));
      88           0 :     return NULL;
      89           0 :   }
      90             : 
      91    41608068 :   for( ulong i=0UL; i<max_vote_accounts; i++ ) {
      92    41607030 :     fd_vote_state_ele_t * vote_state = fd_vote_state_pool_ele( vote_states_pool, i );
      93    41607030 :     vote_state->idx = i;
      94    41607030 :   }
      95             : 
      96        1038 :   if( FD_UNLIKELY( !fd_vote_state_map_join( fd_vote_state_map_new( map_mem, map_chain_cnt, seed ) ) ) ) {
      97           0 :     FD_LOG_WARNING(( "Failed to create vote states map" ));
      98           0 :     return NULL;
      99           0 :   }
     100             : 
     101        1038 :   FD_COMPILER_MFENCE();
     102        1038 :   FD_VOLATILE( vote_states->magic ) = FD_VOTE_STATES_MAGIC;
     103        1038 :   FD_COMPILER_MFENCE();
     104             : 
     105        1038 :   return mem;
     106        1038 : }
     107             : 
     108             : fd_vote_states_t *
     109        1044 : fd_vote_states_join( void * mem ) {
     110        1044 :   if( FD_UNLIKELY( !mem ) ) {
     111           3 :     FD_LOG_WARNING(( "NULL mem" ));
     112           3 :     return NULL;
     113           3 :   }
     114             : 
     115        1041 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, fd_vote_states_align() ) ) ) {
     116           0 :     FD_LOG_WARNING(( "misaligned mem" ));
     117           0 :     return NULL;
     118           0 :   }
     119             : 
     120        1041 :   fd_vote_states_t * vote_states = (fd_vote_states_t *)mem;
     121             : 
     122        1041 :   if( FD_UNLIKELY( vote_states->magic != FD_VOTE_STATES_MAGIC ) ) {
     123           3 :     FD_LOG_WARNING(( "Invalid vote states magic" ));
     124           3 :     return NULL;
     125           3 :   }
     126             : 
     127        1038 :   ulong map_chain_cnt = fd_vote_state_map_chain_cnt_est( vote_states->max_vote_accounts_ );
     128        1038 :   FD_SCRATCH_ALLOC_INIT( l, vote_states );
     129        1038 :   vote_states     = FD_SCRATCH_ALLOC_APPEND( l, fd_vote_states_align(),     sizeof(fd_vote_states_t) );
     130        1038 :   void * pool_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_vote_state_pool_align(), fd_vote_state_pool_footprint( vote_states->max_vote_accounts_ ) );
     131        1038 :   void * map_mem  = FD_SCRATCH_ALLOC_APPEND( l, fd_vote_state_map_align(),  fd_vote_state_map_footprint( map_chain_cnt ) );
     132             : 
     133        1038 :   if( FD_UNLIKELY( FD_SCRATCH_ALLOC_FINI( l, fd_vote_states_align() )!=(ulong)mem+fd_vote_states_footprint( vote_states->max_vote_accounts_ ) ) ) {
     134           0 :     FD_LOG_WARNING(( "fd_vote_states_join: bad layout" ));
     135           0 :     return NULL;
     136           0 :   }
     137             : 
     138        1038 :   if( FD_UNLIKELY( !fd_vote_state_pool_join( pool_mem ) ) ) {
     139           0 :     FD_LOG_WARNING(( "Failed to join vote states pool" ));
     140           0 :     return NULL;
     141           0 :   }
     142             : 
     143        1038 :   if( FD_UNLIKELY( !fd_vote_state_map_join( map_mem ) ) ) {
     144           0 :     FD_LOG_WARNING(( "Failed to join vote states map" ));
     145           0 :     return NULL;
     146           0 :   }
     147             : 
     148        1038 :   return vote_states;
     149        1038 : }
     150             : 
     151             : void
     152           0 : fd_vote_states_init( fd_vote_states_t * vote_states ) {
     153           0 :   fd_vote_state_map_t * vote_state_map  = fd_vote_states_get_map( vote_states );
     154           0 :   fd_vote_state_map_reset( vote_state_map );
     155           0 :   fd_vote_state_ele_t * vote_state_pool = fd_vote_states_get_pool( vote_states );
     156           0 :   fd_vote_state_pool_reset( vote_state_pool );
     157           0 : }
     158             : 
     159             : fd_vote_state_ele_t *
     160             : fd_vote_states_update( fd_vote_states_t *  vote_states,
     161           6 :                        fd_pubkey_t const * vote_account ) {
     162             : 
     163           6 :   fd_vote_state_ele_t * vote_state_pool = fd_vote_states_get_pool( vote_states );
     164           6 :   fd_vote_state_map_t * vote_state_map  = fd_vote_states_get_map( vote_states );
     165             : 
     166           6 :   if( FD_UNLIKELY( !vote_state_pool ) ) {
     167           0 :     FD_LOG_CRIT(( "unable to retrieve join to vote state pool" ));
     168           0 :   }
     169           6 :   if( FD_UNLIKELY( !vote_state_map ) ) {
     170           0 :     FD_LOG_CRIT(( "unable to retrieve join to vote state map" ));
     171           0 :   }
     172             : 
     173             :   /* First, handle the case where the vote state already exists
     174             :      and we just need to update the entry.  The reason we do a const idx
     175             :      query is to allow fd_vote_states_update to be called while
     176             :      iterating over the map.  It is unsafe to call
     177             :      fd_vote_state_map_ele_query() during iteration, but we only
     178             :      need to change fields which are not used for pool/map management. */
     179             : 
     180           6 :   ulong idx = fd_vote_state_map_idx_query_const(
     181           6 :       vote_state_map,
     182           6 :       vote_account,
     183           6 :       ULONG_MAX,
     184           6 :       vote_state_pool );
     185             : 
     186           6 :   if( idx!=ULONG_MAX ) {
     187           0 :     fd_vote_state_ele_t * vote_state = fd_vote_state_pool_ele( vote_state_pool, idx );
     188           0 :     if( FD_UNLIKELY( !vote_state ) ) {
     189           0 :       FD_LOG_CRIT(( "unable to retrieve vote state" ));
     190           0 :     }
     191             : 
     192             :     /* TODO: can do something smarter where we only update the
     193             :        comission and the credits coresponding to the new epoch. */
     194           0 :     return vote_state;
     195           0 :   }
     196             : 
     197             :   /* If the vote state does not exist, we need to create a new entry. */
     198             :   /* Otherwise, try to acquire a new node and populate it. */
     199           6 :   if( FD_UNLIKELY( !fd_vote_state_pool_free( vote_state_pool ) ) ) {
     200           0 :     FD_LOG_CRIT(( "no free vote states in pool" ));
     201           0 :   }
     202             : 
     203           6 :   fd_vote_state_ele_t * vote_state = fd_vote_state_pool_ele_acquire( vote_state_pool );
     204             : 
     205           6 :   vote_state->vote_account = *vote_account;
     206           6 :   vote_state->stake        = 0UL;
     207           6 :   vote_state->stake_t_1    = 0UL;
     208           6 :   vote_state->stake_t_2    = 0UL;
     209             : 
     210           6 :   if( FD_UNLIKELY( !fd_vote_state_map_ele_insert(
     211           6 :         vote_state_map,
     212           6 :         vote_state,
     213           6 :         vote_state_pool ) ) ) {
     214           0 :     FD_LOG_CRIT(( "unable to insert stake delegation into map" ));
     215           0 :   }
     216           6 :   return vote_state;
     217           6 : }
     218             : 
     219             : void
     220             : fd_vote_states_remove( fd_vote_states_t *  vote_states,
     221           3 :                        fd_pubkey_t const * vote_account ) {
     222           3 :   fd_vote_state_ele_t * vote_state_pool = fd_vote_states_get_pool( vote_states );
     223           3 :   fd_vote_state_map_t * vote_state_map  = fd_vote_states_get_map( vote_states );
     224           3 :   if( FD_UNLIKELY( !vote_state_pool ) ) {
     225           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation pool" ));
     226           0 :   }
     227           3 :   if( FD_UNLIKELY( !vote_state_map ) ) {
     228           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation map" ));
     229           0 :   }
     230             : 
     231           3 :   ulong vote_state_idx = fd_vote_state_map_idx_query_const(
     232           3 :       vote_state_map,
     233           3 :       vote_account,
     234           3 :       ULONG_MAX,
     235           3 :       vote_state_pool );
     236           3 :   if( FD_UNLIKELY( vote_state_idx == ULONG_MAX ) ) {
     237             :     /* The vote state was not found, nothing to do. */
     238           0 :     return;
     239           0 :   }
     240             : 
     241           3 :   fd_vote_state_ele_t * vote_state = fd_vote_state_pool_ele( vote_state_pool, vote_state_idx );
     242           3 :   if( FD_UNLIKELY( !vote_state ) ) {
     243           0 :     FD_LOG_CRIT(( "unable to retrieve vote state" ));
     244           0 :   }
     245             : 
     246           3 :   ulong idx = fd_vote_state_map_idx_remove( vote_state_map, vote_account, ULONG_MAX, vote_state_pool );
     247           3 :   if( FD_UNLIKELY( idx==ULONG_MAX ) ) {
     248           0 :     FD_LOG_CRIT(( "unable to remove vote state" ));
     249           0 :   }
     250             : 
     251             :   /* Set vote state's next_ pointer to the null idx. */
     252           3 :   vote_state->next_ = fd_vote_state_pool_idx_null( vote_state_pool );
     253             : 
     254           3 :   fd_vote_state_pool_idx_release( vote_state_pool, vote_state_idx );
     255           3 : }
     256             : 
     257             : fd_vote_state_ele_t *
     258             : fd_vote_states_update_from_account( fd_vote_states_t *  vote_states,
     259             :                                     fd_pubkey_t const * vote_account,
     260             :                                     uchar const *       account_data,
     261           0 :                                     ulong               account_data_len ) {
     262             : 
     263             :   /* TODO: Instead of doing this messy + unbounded decode, it should be
     264             :      replaced with a more efficient decode that just reads the fields
     265             :      we need directly. */
     266             : 
     267           0 :   fd_bincode_decode_ctx_t ctx = {
     268           0 :     .data    = account_data,
     269           0 :     .dataend = account_data + account_data_len,
     270           0 :   };
     271             : 
     272           0 :   uchar __attribute__((aligned(FD_VOTE_STATE_VERSIONED_ALIGN))) vote_state_versioned[ FD_VOTE_STATE_VERSIONED_FOOTPRINT ];
     273             : 
     274           0 :   fd_vote_state_versioned_t * vsv = fd_vote_state_versioned_decode( vote_state_versioned, &ctx );
     275           0 :   if( FD_UNLIKELY( vsv==NULL ) ) {
     276           0 :     FD_LOG_CRIT(( "unable to decode vote state versioned" ));
     277           0 :   }
     278             : 
     279           0 :   fd_pubkey_t node_account;
     280           0 :   uchar       commission;
     281           0 :   long        last_vote_timestamp;
     282           0 :   ulong       last_vote_slot;
     283             : 
     284           0 :   switch( vsv->discriminant ) {
     285           0 :   case fd_vote_state_versioned_enum_v0_23_5:
     286           0 :     node_account        = vsv->inner.v0_23_5.node_pubkey;
     287           0 :     commission          = vsv->inner.v0_23_5.commission;
     288           0 :     last_vote_timestamp = vsv->inner.v0_23_5.last_timestamp.timestamp;
     289           0 :     last_vote_slot      = vsv->inner.v0_23_5.last_timestamp.slot;
     290           0 :     break;
     291           0 :   case fd_vote_state_versioned_enum_v1_14_11:
     292           0 :     node_account        = vsv->inner.v1_14_11.node_pubkey;
     293           0 :     commission          = vsv->inner.v1_14_11.commission;
     294           0 :     last_vote_timestamp = vsv->inner.v1_14_11.last_timestamp.timestamp;
     295           0 :     last_vote_slot      = vsv->inner.v1_14_11.last_timestamp.slot;
     296           0 :     break;
     297           0 :   case fd_vote_state_versioned_enum_v3:
     298           0 :     node_account        = vsv->inner.v3.node_pubkey;
     299           0 :     commission          = vsv->inner.v3.commission;
     300           0 :     last_vote_timestamp = vsv->inner.v3.last_timestamp.timestamp;
     301           0 :     last_vote_slot      = vsv->inner.v3.last_timestamp.slot;
     302           0 :     break;
     303           0 :   case fd_vote_state_versioned_enum_v4:
     304             :   /* Commission calculation is deliberate according to this:
     305             :      https://github.com/anza-xyz/agave/blob/v3.1.1/vote/src/vote_state_view/field_frames.rs#L353 */
     306           0 :     node_account        = vsv->inner.v4.node_pubkey;
     307           0 :     commission          = (uchar)fd_ushort_min( vsv->inner.v4.inflation_rewards_commission_bps/100, UCHAR_MAX );
     308           0 :     last_vote_timestamp = vsv->inner.v4.last_timestamp.timestamp;
     309           0 :     last_vote_slot      = vsv->inner.v4.last_timestamp.slot;
     310           0 :     break;
     311           0 :   default:
     312           0 :     __builtin_unreachable();
     313           0 :   }
     314             : 
     315           0 :   fd_vote_state_ele_t * vote_state = fd_vote_states_update( vote_states, vote_account );
     316             : 
     317           0 :   vote_state->node_account        = node_account;
     318           0 :   vote_state->commission          = commission;
     319           0 :   vote_state->last_vote_timestamp = last_vote_timestamp;
     320           0 :   vote_state->last_vote_slot      = last_vote_slot;
     321             : 
     322           0 :   return vote_state;
     323           0 : }
     324             : 
     325             : void
     326          15 : fd_vote_states_reset_stakes( fd_vote_states_t * vote_states ) {
     327          15 :   fd_vote_state_ele_t * vote_state_pool = fd_vote_states_get_pool( vote_states );
     328          15 :   fd_vote_state_map_t * vote_state_map  = fd_vote_states_get_map( vote_states );
     329          15 :   if( FD_UNLIKELY( !vote_state_pool ) ) {
     330           0 :     FD_LOG_CRIT(( "unable to retrieve join to vote state pool" ));
     331           0 :   }
     332          15 :   if( FD_UNLIKELY( !vote_state_map ) ) {
     333           0 :     FD_LOG_CRIT(( "unable to retrieve join to vote state map" ));
     334           0 :   }
     335             : 
     336          15 :   for( fd_vote_state_map_iter_t iter = fd_vote_state_map_iter_init( vote_state_map, vote_state_pool );
     337          21 :        !fd_vote_state_map_iter_done( iter, vote_state_map, vote_state_pool );
     338          15 :        iter = fd_vote_state_map_iter_next( iter, vote_state_map, vote_state_pool ) ) {
     339           6 :     ulong idx = fd_vote_state_map_iter_idx( iter, vote_state_map, vote_state_pool );
     340             : 
     341           6 :     fd_vote_state_ele_t * vote_state = fd_vote_state_pool_ele( vote_state_pool, idx );
     342           6 :     if( FD_UNLIKELY( !vote_state ) ) {
     343           0 :       FD_LOG_CRIT(( "unable to retrieve vote state" ));
     344           0 :     }
     345             : 
     346           6 :     vote_state->stake = 0UL;
     347           6 :   }
     348          15 : }
     349             : 
     350             : fd_vote_state_ele_t *
     351             : fd_vote_states_query( fd_vote_states_t const * vote_states,
     352          12 :                       fd_pubkey_t const *      vote_account ) {
     353             : 
     354             :   /* map_chain's _ele_query function isn't safe for concurrent access.
     355             :      The solution is to use the idx_query_const function, which is safe
     356             :      for concurrent access.  The caller is still responsible for
     357             :      synchronizing concurrent writers to the fd_vote_state_ele_t. */
     358          12 :   ulong idx = fd_vote_state_map_idx_query_const(
     359          12 :       fd_vote_states_get_map( vote_states ),
     360          12 :       vote_account,
     361          12 :       ULONG_MAX,
     362          12 :       fd_vote_states_get_pool( vote_states ) );
     363          12 :   if( FD_UNLIKELY( idx==ULONG_MAX ) ) {
     364           3 :     return NULL;
     365           3 :   }
     366             : 
     367           9 :   fd_vote_state_ele_t * vote_state = fd_vote_state_pool_ele( fd_vote_states_get_pool( vote_states ), idx );
     368           9 :   if( FD_UNLIKELY( !vote_state ) ) {
     369           0 :     FD_LOG_CRIT(( "unable to retrieve vote state" ));
     370           0 :   }
     371             : 
     372           9 :   return vote_state;
     373           9 : }
     374             : 
     375             : /* fd_vote_states_query_const is the same as fd_vote_states but instead
     376             :    returns a const pointer. */
     377             : 
     378             : fd_vote_state_ele_t const *
     379             : fd_vote_states_query_const( fd_vote_states_t const * vote_states,
     380           0 :                             fd_pubkey_t const *      vote_account ) {
     381           0 :   return fd_vote_state_map_ele_query_const(
     382           0 :       fd_vote_states_get_map( vote_states ),
     383           0 :       vote_account,
     384           0 :       NULL,
     385           0 :       fd_vote_states_get_pool( vote_states ) );
     386           0 : }
     387             : 
     388             : ulong
     389           0 : fd_vote_states_max( fd_vote_states_t const * vote_states ) {
     390           0 :   return vote_states->max_vote_accounts_;
     391           0 : }
     392             : 
     393             : ulong
     394          39 : fd_vote_states_cnt( fd_vote_states_t const * vote_states ) {
     395          39 :   return fd_vote_state_pool_used( fd_vote_states_get_pool( vote_states ) );
     396          39 : }
     397             : 
     398             : fd_vote_state_ele_t *
     399           0 : fd_vote_states_iter_ele( fd_vote_states_iter_t * iter ) {
     400           0 :   ulong idx = fd_vote_state_map_iter_idx( iter->iter, iter->map, iter->pool );
     401           0 :   return fd_vote_state_pool_ele( iter->pool, idx );
     402           0 : }
     403             : 
     404             : fd_vote_states_iter_t *
     405             : fd_vote_states_iter_init( fd_vote_states_iter_t *  iter,
     406          66 :                           fd_vote_states_t const * vote_states ) {
     407          66 :   if( FD_UNLIKELY( !iter ) ) {
     408           0 :     FD_LOG_CRIT(( "NULL iter_mem" ));
     409           0 :   }
     410          66 :   if( FD_UNLIKELY( !vote_states ) ) {
     411           0 :     FD_LOG_CRIT(( "NULL vote_states" ));
     412           0 :   }
     413             : 
     414          66 :   iter->map  = fd_vote_states_get_map( vote_states );
     415          66 :   iter->pool = fd_vote_states_get_pool( vote_states );
     416          66 :   iter->iter = fd_vote_state_map_iter_init( iter->map, iter->pool );
     417             : 
     418          66 :   return iter;
     419          66 : }
     420             : 
     421             : int
     422          66 : fd_vote_states_iter_done( fd_vote_states_iter_t * iter ) {
     423          66 :   return fd_vote_state_map_iter_done( iter->iter, iter->map, iter->pool );
     424          66 : }
     425             : 
     426             : void
     427           0 : fd_vote_states_iter_next( fd_vote_states_iter_t * iter ) {
     428           0 :   iter->iter = fd_vote_state_map_iter_next( iter->iter, iter->map, iter->pool );
     429           0 : }

Generated by: LCOV version 1.14