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

Generated by: LCOV version 1.14