LCOV - code coverage report
Current view: top level - flamenco/stakes - fd_stake_delegations.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 196 314 62.4 %
Date: 2025-12-22 05:12:07 Functions: 16 17 94.1 %

          Line data    Source code
       1             : #include "fd_stake_delegations.h"
       2             : #include "../../funk/fd_funk_base.h"
       3             : #include "../runtime/fd_txn_account.h"
       4             : #include "../runtime/fd_acc_mgr.h"
       5             : #include "../runtime/program/fd_stake_program.h"
       6             : 
       7             : #define POOL_NAME fd_stake_delegation_pool
       8         534 : #define POOL_T    fd_stake_delegation_t
       9    18298812 : #define POOL_NEXT next_
      10             : #include "../../util/tmpl/fd_pool.c"
      11             : 
      12             : #define MAP_NAME               fd_stake_delegation_map
      13             : #define MAP_KEY_T              fd_pubkey_t
      14             : #define MAP_ELE_T              fd_stake_delegation_t
      15         102 : #define MAP_KEY                stake_account
      16         144 : #define MAP_KEY_EQ(k0,k1)      (fd_pubkey_eq( k0, k1 ))
      17         354 : #define MAP_KEY_HASH(key,seed) (fd_funk_rec_key_hash1( key->uc, seed ))
      18         204 : #define MAP_NEXT               next_
      19             : #include "../../util/tmpl/fd_map_chain.c"
      20             : 
      21             : static inline fd_stake_delegation_t *
      22         372 : fd_stake_delegations_get_pool( fd_stake_delegations_t const * stake_delegations ) {
      23         372 :   return fd_stake_delegation_pool_join( (uchar *)stake_delegations + stake_delegations->pool_offset_ );
      24         372 : }
      25             : 
      26             : static inline fd_stake_delegation_map_t *
      27         297 : fd_stake_delegations_get_map( fd_stake_delegations_t const * stake_delegations ) {
      28         297 :   return fd_stake_delegation_map_join( (uchar *)stake_delegations + stake_delegations->map_offset_ );
      29         297 : }
      30             : 
      31             : ulong
      32        1359 : fd_stake_delegations_align( void ) {
      33             :   /* The align of the struct should be the max of the align of the data
      34             :      structures that it contains. In this case, this is the map, the
      35             :      pool, and the struct itself. */
      36        1359 :   return fd_ulong_max( fd_ulong_max( fd_stake_delegation_map_align(),
      37        1359 :                        fd_stake_delegation_pool_align() ), alignof(fd_stake_delegations_t) );
      38        1359 : }
      39             : 
      40             : ulong
      41         171 : fd_stake_delegations_footprint( ulong max_stake_accounts ) {
      42             : 
      43         171 :   ulong map_chain_cnt = fd_stake_delegation_map_chain_cnt_est( max_stake_accounts );
      44             : 
      45         171 :   ulong l = FD_LAYOUT_INIT;
      46         171 :   l = FD_LAYOUT_APPEND( l, fd_stake_delegations_align(),     sizeof(fd_stake_delegations_t) );
      47         171 :   l = FD_LAYOUT_APPEND( l, fd_stake_delegation_pool_align(), fd_stake_delegation_pool_footprint( max_stake_accounts ) );
      48         171 :   l = FD_LAYOUT_APPEND( l, fd_stake_delegation_map_align(),  fd_stake_delegation_map_footprint( map_chain_cnt ) );
      49         171 :   return FD_LAYOUT_FINI( l, fd_stake_delegations_align() );
      50         171 : }
      51             : 
      52             : void *
      53             : fd_stake_delegations_new( void * mem,
      54             :                           ulong  max_stake_accounts,
      55          33 :                           int    leave_tombstones ) {
      56          33 :   if( FD_UNLIKELY( !mem ) ) {
      57           3 :     FD_LOG_WARNING(( "NULL mem" ));
      58           3 :     return NULL;
      59           3 :   }
      60             : 
      61          30 :   if( FD_UNLIKELY( !max_stake_accounts ) ) {
      62           3 :     FD_LOG_WARNING(( "max_stake_accounts is 0" ));
      63           3 :     return NULL;
      64           3 :   }
      65             : 
      66          27 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, fd_stake_delegations_align() ) ) ) {
      67           0 :     FD_LOG_WARNING(( "misaligned mem" ));
      68           0 :     return NULL;
      69           0 :   }
      70             : 
      71          27 :   ulong map_chain_cnt = fd_stake_delegation_map_chain_cnt_est( max_stake_accounts );
      72             : 
      73          27 :   FD_SCRATCH_ALLOC_INIT( l, mem );
      74          27 :   fd_stake_delegations_t * stake_delegations = FD_SCRATCH_ALLOC_APPEND( l, fd_stake_delegations_align(),     sizeof(fd_stake_delegations_t) );
      75          27 :   void *                   pool_mem          = FD_SCRATCH_ALLOC_APPEND( l, fd_stake_delegation_pool_align(), fd_stake_delegation_pool_footprint( max_stake_accounts ) );
      76          27 :   void *                   map_mem           = FD_SCRATCH_ALLOC_APPEND( l, fd_stake_delegation_map_align(),  fd_stake_delegation_map_footprint( map_chain_cnt ) );
      77             : 
      78          27 :   if( FD_UNLIKELY( FD_SCRATCH_ALLOC_FINI( l, fd_stake_delegations_align() )!=(ulong)mem+fd_stake_delegations_footprint( max_stake_accounts ) ) ) {
      79           0 :     FD_LOG_WARNING(( "fd_stake_delegations_new: bad layout" ));
      80           0 :     return NULL;
      81           0 :   }
      82             : 
      83          27 :   if( FD_UNLIKELY( !fd_stake_delegation_pool_new( pool_mem, max_stake_accounts ) ) ) {
      84           0 :     FD_LOG_WARNING(( "Failed to create stake delegations pool" ));
      85           0 :     return NULL;
      86           0 :   }
      87             : 
      88             :   /* TODO: The seed shouldn't be hardcoded. */
      89          27 :   if( FD_UNLIKELY( !fd_stake_delegation_map_new( map_mem, map_chain_cnt, 999UL ) ) ) {
      90           0 :     FD_LOG_WARNING(( "Failed to create stake delegations map" ));
      91           0 :     return NULL;
      92           0 :   }
      93             : 
      94          27 :   stake_delegations->pool_offset_        = (ulong)pool_mem - (ulong)mem;
      95          27 :   stake_delegations->map_offset_         = (ulong)map_mem - (ulong)mem;
      96          27 :   stake_delegations->max_stake_accounts_ = max_stake_accounts;
      97          27 :   stake_delegations->leave_tombstones_   = leave_tombstones;
      98             : 
      99          27 :   FD_COMPILER_MFENCE();
     100          27 :   FD_VOLATILE( stake_delegations->magic ) = FD_STAKE_DELEGATIONS_MAGIC;
     101          27 :   FD_COMPILER_MFENCE();
     102             : 
     103          27 :   return mem;
     104          27 : }
     105             : 
     106             : fd_stake_delegations_t *
     107         144 : fd_stake_delegations_join( void * mem ) {
     108         144 :   if( FD_UNLIKELY( !mem ) ) {
     109           3 :     FD_LOG_WARNING(( "NULL mem" ));
     110           3 :     return NULL;
     111           3 :   }
     112             : 
     113         141 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, fd_stake_delegations_align() ) ) ) {
     114           0 :     FD_LOG_WARNING(( "misaligned mem" ));
     115           0 :     return NULL;
     116           0 :   }
     117             : 
     118         141 :   fd_stake_delegations_t * stake_delegations = (fd_stake_delegations_t *)mem;
     119             : 
     120         141 :   if( FD_UNLIKELY( stake_delegations->magic != FD_STAKE_DELEGATIONS_MAGIC ) ) {
     121           6 :     FD_LOG_WARNING(( "Invalid stake delegations magic" ));
     122           6 :     return NULL;
     123           6 :   }
     124             : 
     125         135 :   ulong map_chain_cnt = fd_stake_delegation_map_chain_cnt_est( stake_delegations->max_stake_accounts_ );
     126             : 
     127         135 :   FD_SCRATCH_ALLOC_INIT( l, stake_delegations );
     128         135 :   stake_delegations = FD_SCRATCH_ALLOC_APPEND( l, fd_stake_delegations_align(),     sizeof(fd_stake_delegations_t) );
     129         135 :   void * pool_mem   = FD_SCRATCH_ALLOC_APPEND( l, fd_stake_delegation_pool_align(), fd_stake_delegation_pool_footprint( stake_delegations->max_stake_accounts_ ) );
     130         135 :   void * map_mem    = FD_SCRATCH_ALLOC_APPEND( l, fd_stake_delegation_map_align(),  fd_stake_delegation_map_footprint( map_chain_cnt ) );
     131             : 
     132         135 :   if( FD_UNLIKELY( FD_SCRATCH_ALLOC_FINI( l, fd_stake_delegations_align() )!=(ulong)mem+fd_stake_delegations_footprint( stake_delegations->max_stake_accounts_ ) ) ) {
     133           0 :     FD_LOG_WARNING(( "fd_stake_delegations_join: bad layout" ));
     134           0 :     return NULL;
     135           0 :   }
     136             : 
     137         135 :   if( FD_UNLIKELY( !fd_stake_delegation_pool_join( pool_mem ) ) ) {
     138           0 :     FD_LOG_WARNING(( "Failed to join stake delegations pool" ));
     139           0 :     return NULL;
     140           0 :   }
     141             : 
     142         135 :   if( FD_UNLIKELY( !fd_stake_delegation_map_join( map_mem ) ) ) {
     143           0 :     FD_LOG_WARNING(( "Failed to join stake delegations map" ));
     144           0 :     return NULL;
     145           0 :   }
     146             : 
     147         135 :   return stake_delegations;
     148         135 : }
     149             : 
     150             : void *
     151          12 : fd_stake_delegations_leave( fd_stake_delegations_t * self ) {
     152          12 :   if( FD_UNLIKELY( !self ) ) {
     153           3 :     FD_LOG_WARNING(( "NULL self" ));
     154           3 :     return NULL;
     155           3 :   }
     156             : 
     157           9 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)self, fd_stake_delegations_align() ) ) ) {
     158           0 :     FD_LOG_WARNING(( "misaligned self" ));
     159           0 :     return NULL;
     160           0 :   }
     161             : 
     162           9 :   fd_stake_delegations_t * stake_delegations = (fd_stake_delegations_t *)self;
     163             : 
     164           9 :   if( FD_UNLIKELY( stake_delegations->magic!=FD_STAKE_DELEGATIONS_MAGIC ) ) {
     165           0 :     FD_LOG_WARNING(( "Invalid stake delegations magic" ));
     166           0 :     return NULL;
     167           0 :   }
     168             : 
     169           9 :   return (void *)self;
     170           9 : }
     171             : 
     172             : void *
     173           6 : fd_stake_delegations_delete( void * mem ) {
     174           6 :   if( FD_UNLIKELY( !mem ) ) {
     175           3 :     FD_LOG_WARNING(( "NULL mem" ));
     176           3 :     return NULL;
     177           3 :   }
     178             : 
     179           3 :   if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, fd_stake_delegations_align() ) ) ) {
     180           0 :     FD_LOG_WARNING(( "misaligned mem" ));
     181           0 :     return NULL;
     182           0 :   }
     183             : 
     184           3 :   fd_stake_delegations_t * stake_delegations = (fd_stake_delegations_t *)mem;
     185             : 
     186           3 :   if( FD_UNLIKELY( stake_delegations->magic!=FD_STAKE_DELEGATIONS_MAGIC ) ) {
     187           0 :     FD_LOG_WARNING(( "Invalid stake delegations magic" ));
     188           0 :     return NULL;
     189           0 :   }
     190             : 
     191           3 :   stake_delegations->magic = 0UL;
     192             : 
     193           3 :   return mem;
     194           3 : }
     195             : 
     196             : void
     197             : fd_stake_delegations_update( fd_stake_delegations_t * stake_delegations,
     198             :                              fd_pubkey_t const *      stake_account,
     199             :                              fd_pubkey_t const *      vote_account,
     200             :                              ulong                    stake,
     201             :                              ulong                    activation_epoch,
     202             :                              ulong                    deactivation_epoch,
     203             :                              ulong                    credits_observed,
     204         117 :                              double                   warmup_cooldown_rate ) {
     205         117 :   fd_stake_delegation_t * stake_delegation_pool = fd_stake_delegations_get_pool( stake_delegations );
     206         117 :   if( FD_UNLIKELY( !stake_delegation_pool ) ) {
     207           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation pool" ));
     208           0 :   }
     209         117 :   fd_stake_delegation_map_t * stake_delegation_map = fd_stake_delegations_get_map( stake_delegations );
     210         117 :   if( FD_UNLIKELY( !stake_delegation_map ) ) {
     211           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation map" ));
     212           0 :   }
     213             : 
     214             :   /* First, handle the case where the stake delegation already exists
     215             :      and we just need to update the entry. The reason we do a const idx
     216             :      query is to allow fd_stake_delegations_update to be called while
     217             :      iterating over the map. It is unsafe to call
     218             :      fd_stake_delegation_map_ele_query() during iteration, but we only
     219             :      need to change fields which are not used for pool/map management. */
     220             : 
     221         117 :   ulong idx = fd_stake_delegation_map_idx_query_const(
     222         117 :       stake_delegation_map,
     223         117 :       stake_account,
     224         117 :       ULONG_MAX,
     225         117 :       stake_delegation_pool );
     226             : 
     227         117 :   if( idx!=ULONG_MAX ) {
     228             : 
     229          21 :     fd_stake_delegation_t * stake_delegation = fd_stake_delegation_pool_ele( stake_delegation_pool, idx );
     230          21 :     if( FD_UNLIKELY( !stake_delegation ) ) {
     231           0 :       FD_LOG_CRIT(( "unable to retrieve stake delegation" ));
     232           0 :     }
     233             : 
     234          21 :     stake_delegation->vote_account         = *vote_account;
     235          21 :     stake_delegation->stake                = stake;
     236          21 :     stake_delegation->activation_epoch     = activation_epoch;
     237          21 :     stake_delegation->deactivation_epoch   = deactivation_epoch;
     238          21 :     stake_delegation->credits_observed     = credits_observed;
     239          21 :     stake_delegation->warmup_cooldown_rate = warmup_cooldown_rate;
     240          21 :     stake_delegation->is_tombstone         = 0;
     241          21 :     return;
     242          21 :   }
     243             : 
     244             :   /* Otherwise, try to acquire a new node and populate it. */
     245          96 :   if( FD_UNLIKELY( !fd_stake_delegation_pool_free( stake_delegation_pool ) ) ) {
     246           0 :     FD_LOG_CRIT(( "no free stake delegations in pool" ));
     247           0 :   }
     248             : 
     249          96 :   fd_stake_delegation_t * stake_delegation = fd_stake_delegation_pool_ele_acquire( stake_delegation_pool );
     250             : 
     251          96 :   stake_delegation->stake_account        = *stake_account;
     252          96 :   stake_delegation->vote_account         = *vote_account;
     253          96 :   stake_delegation->stake                = stake;
     254          96 :   stake_delegation->activation_epoch     = activation_epoch;
     255          96 :   stake_delegation->deactivation_epoch   = deactivation_epoch;
     256          96 :   stake_delegation->credits_observed     = credits_observed;
     257          96 :   stake_delegation->warmup_cooldown_rate = warmup_cooldown_rate;
     258          96 :   stake_delegation->is_tombstone         = 0;
     259             : 
     260          96 :   if( FD_UNLIKELY( !fd_stake_delegation_map_ele_insert(
     261          96 :         stake_delegation_map,
     262          96 :         stake_delegation,
     263          96 :         stake_delegation_pool ) ) ) {
     264           0 :     FD_LOG_CRIT(( "unable to insert stake delegation into map" ));
     265           0 :   }
     266             : 
     267          96 : }
     268             : 
     269             : void
     270             : fd_stake_delegations_remove( fd_stake_delegations_t * stake_delegations,
     271          24 :                              fd_pubkey_t const *      stake_account ) {
     272          24 :   fd_stake_delegation_t * stake_delegation_pool = fd_stake_delegations_get_pool( stake_delegations );
     273          24 :   if( FD_UNLIKELY( !stake_delegation_pool ) ) {
     274           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation pool" ));
     275           0 :   }
     276          24 :   fd_stake_delegation_map_t * stake_delegation_map = fd_stake_delegations_get_map( stake_delegations );
     277          24 :   if( FD_UNLIKELY( !stake_delegation_map ) ) {
     278           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation map" ));
     279           0 :   }
     280             : 
     281          24 :   ulong delegation_idx = fd_stake_delegation_map_idx_query(
     282          24 :       stake_delegation_map,
     283          24 :       stake_account,
     284          24 :       ULONG_MAX,
     285          24 :       stake_delegation_pool );
     286             : 
     287          24 :   if( stake_delegations->leave_tombstones_==1 ) {
     288             :     /* If we are configured to leave tombstones, we need to either
     289             :        update the entry's is_tombstone flag or insert a new entry. */
     290             : 
     291           9 :     fd_stake_delegation_t * stake_delegation = NULL;
     292           9 :     if( delegation_idx!=ULONG_MAX ) {
     293             :       /* The delegation was found, update the is_tombstone flag. */
     294           3 :       stake_delegation = fd_stake_delegation_pool_ele( stake_delegation_pool, delegation_idx );
     295           6 :     } else {
     296             :       /* Otherwise, acquire an element from the pool and add it into the
     297             :          map. */
     298           6 :       stake_delegation = fd_stake_delegation_pool_ele_acquire( stake_delegation_pool );
     299           6 :       stake_delegation->stake_account = *stake_account;
     300           6 :       fd_stake_delegation_map_ele_insert( stake_delegation_map, stake_delegation, stake_delegation_pool );
     301           6 :     }
     302           9 :     stake_delegation->is_tombstone = 1;
     303             : 
     304          15 :   } else {
     305             :     /* If we are not configured to leave tombstones, we need to remove
     306             :        the entry from the map and release it from the pool. */
     307          15 :     if( FD_UNLIKELY( delegation_idx == ULONG_MAX ) ) {
     308             :       /* The delegation was not found, nothing to do. */
     309           0 :       return;
     310           0 :     }
     311             : 
     312             :     /* To be safe, we should set the next_ pointer to the null idx. */
     313             : 
     314          15 :     fd_stake_delegation_t * stake_delegation = fd_stake_delegation_pool_ele( stake_delegation_pool, delegation_idx );
     315          15 :     if( FD_UNLIKELY( !stake_delegation ) ) {
     316           0 :       FD_LOG_CRIT(( "unable to retrieve stake delegation" ));
     317           0 :     }
     318             : 
     319          15 :     ulong idx = fd_stake_delegation_map_idx_remove( stake_delegation_map, stake_account, ULONG_MAX, stake_delegation_pool );
     320          15 :     if( FD_UNLIKELY( idx==ULONG_MAX ) ) {
     321           0 :       FD_LOG_CRIT(( "unable to remove stake delegation" ));
     322           0 :     }
     323             : 
     324          15 :     stake_delegation->next_ = fd_stake_delegation_pool_idx_null( stake_delegation_pool );
     325             : 
     326          15 :     fd_stake_delegation_pool_idx_release( stake_delegation_pool, delegation_idx );
     327          15 :   }
     328          24 : }
     329             : 
     330             : void
     331             : fd_stake_delegations_refresh( fd_stake_delegations_t *  stake_delegations,
     332             :                               fd_funk_t *               funk,
     333           0 :                               fd_funk_txn_xid_t const * xid ) {
     334             : 
     335           0 :   fd_stake_delegation_map_t * stake_delegation_map = fd_stake_delegations_get_map( stake_delegations );
     336           0 :   if( FD_UNLIKELY( !stake_delegation_map ) ) {
     337           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation map" ));
     338           0 :   }
     339             : 
     340           0 :   fd_stake_delegation_t * stake_delegation_pool = fd_stake_delegations_get_pool( stake_delegations );
     341           0 :   if( FD_UNLIKELY( !stake_delegation_pool ) ) {
     342           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation pool" ));
     343           0 :   }
     344             : 
     345           0 :   for( ulong i=0UL; i<stake_delegations->max_stake_accounts_; i++ ) {
     346             : 
     347           0 :     fd_stake_delegation_t * stake_delegation = fd_stake_delegation_pool_ele( fd_stake_delegations_get_pool( stake_delegations ), i );
     348             : 
     349           0 :     if( !fd_stake_delegation_map_ele_query_const(
     350           0 :             fd_stake_delegations_get_map( stake_delegations ),
     351           0 :             &stake_delegation->stake_account,
     352           0 :             NULL,
     353           0 :             fd_stake_delegations_get_pool( stake_delegations ) ) ) {
     354             :       /* This means that the stake delegation is not in the map, so we
     355             :          can skip it. */
     356           0 :       continue;
     357           0 :     }
     358             : 
     359           0 :     int err = 0;
     360           0 :     fd_account_meta_t const * meta = fd_funk_get_acc_meta_readonly( funk, xid, &stake_delegation->stake_account, NULL, &err, NULL );
     361           0 :     if( FD_UNLIKELY( err || meta->lamports==0UL ) ) {
     362           0 :       fd_stake_delegation_map_idx_remove( stake_delegation_map, &stake_delegation->stake_account, ULONG_MAX, stake_delegation_pool );
     363           0 :       fd_stake_delegation_pool_idx_release( stake_delegation_pool, i );
     364           0 :       continue;
     365           0 :     }
     366             : 
     367           0 :     fd_stake_state_v2_t stake_state;
     368           0 :     err = fd_stake_get_state( meta, &stake_state );
     369           0 :     if( FD_UNLIKELY( err ) ) {
     370           0 :       fd_stake_delegation_map_idx_remove( stake_delegation_map, &stake_delegation->stake_account, ULONG_MAX, stake_delegation_pool );
     371           0 :       fd_stake_delegation_pool_idx_release( stake_delegation_pool, i );
     372           0 :     }
     373             : 
     374           0 :     if( FD_UNLIKELY( !fd_stake_state_v2_is_stake( &stake_state ) ) ) {
     375           0 :       fd_stake_delegation_map_idx_remove( stake_delegation_map, &stake_delegation->stake_account, ULONG_MAX, stake_delegation_pool );
     376           0 :       fd_stake_delegation_pool_idx_release( stake_delegation_pool, i );
     377           0 :     }
     378             : 
     379           0 :     fd_stake_delegations_update(
     380           0 :         stake_delegations,
     381           0 :         &stake_delegation->stake_account,
     382           0 :         &stake_state.inner.stake.stake.delegation.voter_pubkey,
     383           0 :         stake_state.inner.stake.stake.delegation.stake,
     384           0 :         stake_state.inner.stake.stake.delegation.activation_epoch,
     385           0 :         stake_state.inner.stake.stake.delegation.deactivation_epoch,
     386           0 :         stake_state.inner.stake.stake.credits_observed,
     387           0 :         stake_state.inner.stake.stake.delegation.warmup_cooldown_rate );
     388           0 :   }
     389           0 : }
     390             : 
     391             : fd_stake_delegation_t const *
     392             : fd_stake_delegations_query( fd_stake_delegations_t const * stake_delegations,
     393          96 :                             fd_pubkey_t const *            stake_account ) {
     394             : 
     395          96 :   if( FD_UNLIKELY( !stake_delegations ) ) {
     396           0 :     FD_LOG_CRIT(( "NULL stake_delegations" ));
     397           0 :     return NULL;
     398           0 :   }
     399             : 
     400          96 :   if( FD_UNLIKELY( !stake_account ) ) {
     401           0 :     FD_LOG_CRIT(( "NULL stake_account" ));
     402           0 :     return NULL;
     403           0 :   }
     404             : 
     405          96 :   fd_stake_delegation_t const * stake_delegation_pool = fd_stake_delegations_get_pool( stake_delegations );
     406          96 :   if( FD_UNLIKELY( !stake_delegation_pool ) ) {
     407           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation pool" ));
     408           0 :   }
     409             : 
     410          96 :   fd_stake_delegation_map_t const * stake_delegation_map = fd_stake_delegations_get_map( stake_delegations );
     411          96 :   if( FD_UNLIKELY( !stake_delegation_map ) ) {
     412           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation map" ));
     413           0 :   }
     414             : 
     415          96 :   return fd_stake_delegation_map_ele_query_const(
     416          96 :       stake_delegation_map,
     417          96 :       stake_account,
     418          96 :       NULL,
     419          96 :       stake_delegation_pool );
     420          96 : }
     421             : 
     422             : ulong
     423          75 : fd_stake_delegations_cnt( fd_stake_delegations_t const * stake_delegations ) {
     424          75 :   if( FD_UNLIKELY( !stake_delegations ) ) {
     425           0 :     FD_LOG_CRIT(( "NULL stake_delegations" ));
     426           0 :   }
     427             : 
     428          75 :   fd_stake_delegation_t const * stake_delegation_pool = fd_stake_delegations_get_pool( stake_delegations );
     429          75 :   if( FD_UNLIKELY( !stake_delegation_pool ) ) {
     430           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation map" ));
     431           0 :   }
     432             : 
     433          75 :   return fd_stake_delegation_pool_used( stake_delegation_pool );
     434          75 : }
     435             : 
     436             : fd_stake_delegation_t *
     437          87 : fd_stake_delegations_iter_ele( fd_stake_delegations_iter_t * iter ) {
     438          87 :   ulong idx = fd_stake_delegation_map_iter_idx( iter->iter, iter->map, iter->pool );
     439          87 :   return fd_stake_delegation_pool_ele( iter->pool, idx );
     440          87 : }
     441             : 
     442             : fd_stake_delegations_iter_t *
     443             : fd_stake_delegations_iter_init( fd_stake_delegations_iter_t *  iter,
     444          60 :                                 fd_stake_delegations_t const * stake_delegations ) {
     445          60 :   if( FD_UNLIKELY( !stake_delegations ) ) {
     446           0 :     FD_LOG_CRIT(( "NULL stake_delegations" ));
     447           0 :   }
     448             : 
     449          60 :   iter->map  = fd_stake_delegations_get_map( stake_delegations );
     450          60 :   iter->pool = fd_stake_delegations_get_pool( stake_delegations );
     451          60 :   iter->iter = fd_stake_delegation_map_iter_init( iter->map, iter->pool );
     452             : 
     453          60 :   return iter;
     454          60 : }
     455             : 
     456             : void
     457          87 : fd_stake_delegations_iter_next( fd_stake_delegations_iter_t * iter ) {
     458          87 :   iter->iter = fd_stake_delegation_map_iter_next( iter->iter, iter->map, iter->pool );
     459          87 : }
     460             : 
     461             : int
     462         147 : fd_stake_delegations_iter_done( fd_stake_delegations_iter_t * iter ) {
     463         147 :   return fd_stake_delegation_map_iter_done( iter->iter, iter->map, iter->pool );
     464         147 : }

Generated by: LCOV version 1.14