LCOV - code coverage report
Current view: top level - flamenco/stakes - fd_vote_states.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 160 351 45.6 %
Date: 2025-09-19 04:41:14 Functions: 12 19 63.2 %

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

Generated by: LCOV version 1.14