LCOV - code coverage report
Current view: top level - flamenco/stakes - fd_stake_delegations.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 197 321 61.4 %
Date: 2025-09-19 04:41:14 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         516 : #define POOL_T    fd_stake_delegation_t
       8    27298809 : #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          99 : #define MAP_KEY                stake_account
      15         144 : #define MAP_KEY_EQ(k0,k1)      (fd_pubkey_eq( k0, k1 ))
      16         348 : #define MAP_KEY_HASH(key,seed) (fd_funk_rec_key_hash1( (uchar *)key, 0, seed ))
      17         198 : #define MAP_NEXT               next_
      18             : #include "../../util/tmpl/fd_map_chain.c"
      19             : 
      20             : static inline fd_stake_delegation_t *
      21         366 : fd_stake_delegations_get_pool( fd_stake_delegations_t const * stake_delegations ) {
      22         366 :   return fd_stake_delegation_pool_join( (uchar *)stake_delegations + stake_delegations->pool_offset_ );
      23         366 : }
      24             : 
      25             : static inline fd_stake_delegation_map_t *
      26         291 : fd_stake_delegations_get_map( fd_stake_delegations_t const * stake_delegations ) {
      27         291 :   return fd_stake_delegation_map_join( (uchar *)stake_delegations + stake_delegations->map_offset_ );
      28         291 : }
      29             : 
      30             : ulong
      31        1413 : 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        1413 :   return fd_ulong_max( fd_ulong_max( fd_stake_delegation_map_align(),
      36        1413 :                        fd_stake_delegation_pool_align() ), alignof(fd_stake_delegations_t) );
      37        1413 : }
      38             : 
      39             : ulong
      40         159 : fd_stake_delegations_footprint( ulong max_stake_accounts ) {
      41             : 
      42         159 :   ulong map_chain_cnt = fd_stake_delegation_map_chain_cnt_est( max_stake_accounts );
      43             : 
      44         159 :   ulong l = FD_LAYOUT_INIT;
      45         159 :   l = FD_LAYOUT_APPEND( l, fd_stake_delegations_align(),     sizeof(fd_stake_delegations_t) );
      46         159 :   l = FD_LAYOUT_APPEND( l, fd_stake_delegation_pool_align(), fd_stake_delegation_pool_footprint( max_stake_accounts ) );
      47         159 :   l = FD_LAYOUT_APPEND( l, fd_stake_delegation_map_align(),  fd_stake_delegation_map_footprint( map_chain_cnt ) );
      48         159 :   return FD_LAYOUT_FINI( l, fd_stake_delegations_align() );
      49         159 : }
      50             : 
      51             : void *
      52             : fd_stake_delegations_new( void * mem,
      53             :                           ulong  max_stake_accounts,
      54          36 :                           int    leave_tombstones ) {
      55          36 :   if( FD_UNLIKELY( !mem ) ) {
      56           3 :     FD_LOG_WARNING(( "NULL mem" ));
      57           3 :     return NULL;
      58           3 :   }
      59             : 
      60          33 :   if( FD_UNLIKELY( !max_stake_accounts ) ) {
      61           3 :     FD_LOG_WARNING(( "max_stake_accounts is 0" ));
      62           3 :     return NULL;
      63           3 :   }
      64             : 
      65          30 :   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          30 :   ulong map_chain_cnt = fd_stake_delegation_map_chain_cnt_est( max_stake_accounts );
      71             : 
      72          30 :   FD_SCRATCH_ALLOC_INIT( l, mem );
      73          30 :   fd_stake_delegations_t * stake_delegations = FD_SCRATCH_ALLOC_APPEND( l, fd_stake_delegations_align(),     sizeof(fd_stake_delegations_t) );
      74          30 :   void *                   pool_mem          = FD_SCRATCH_ALLOC_APPEND( l, fd_stake_delegation_pool_align(), fd_stake_delegation_pool_footprint( max_stake_accounts ) );
      75          30 :   void *                   map_mem           = FD_SCRATCH_ALLOC_APPEND( l, fd_stake_delegation_map_align(),  fd_stake_delegation_map_footprint( map_chain_cnt ) );
      76             : 
      77          30 :   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          30 :   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          30 :   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          30 :   stake_delegations->pool_offset_        = (ulong)pool_mem - (ulong)mem;
      94          30 :   stake_delegations->map_offset_         = (ulong)map_mem - (ulong)mem;
      95          30 :   stake_delegations->max_stake_accounts_ = max_stake_accounts;
      96          30 :   stake_delegations->leave_tombstones_   = leave_tombstones;
      97             : 
      98          30 :   FD_COMPILER_MFENCE();
      99          30 :   FD_VOLATILE( stake_delegations->magic ) = FD_STAKE_DELEGATIONS_MAGIC;
     100          30 :   FD_COMPILER_MFENCE();
     101             : 
     102          30 :   return mem;
     103          30 : }
     104             : 
     105             : fd_stake_delegations_t *
     106         129 : fd_stake_delegations_join( void * mem ) {
     107         129 :   if( FD_UNLIKELY( !mem ) ) {
     108           3 :     FD_LOG_WARNING(( "NULL mem" ));
     109           3 :     return NULL;
     110           3 :   }
     111             : 
     112         126 :   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         126 :   fd_stake_delegations_t * stake_delegations = (fd_stake_delegations_t *)mem;
     118             : 
     119         126 :   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         120 :   ulong map_chain_cnt = fd_stake_delegation_map_chain_cnt_est( stake_delegations->max_stake_accounts_ );
     125             : 
     126         120 :   FD_SCRATCH_ALLOC_INIT( l, stake_delegations );
     127         120 :   stake_delegations = FD_SCRATCH_ALLOC_APPEND( l, fd_stake_delegations_align(),     sizeof(fd_stake_delegations_t) );
     128         120 :   void * pool_mem   = FD_SCRATCH_ALLOC_APPEND( l, fd_stake_delegation_pool_align(), fd_stake_delegation_pool_footprint( stake_delegations->max_stake_accounts_ ) );
     129         120 :   void * map_mem    = FD_SCRATCH_ALLOC_APPEND( l, fd_stake_delegation_map_align(),  fd_stake_delegation_map_footprint( map_chain_cnt ) );
     130             : 
     131         120 :   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         120 :   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         120 :   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         120 :   return stake_delegations;
     147         120 : }
     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         114 :                              double                   warmup_cooldown_rate ) {
     204             : 
     205         114 :   fd_stake_delegation_t * stake_delegation_pool = fd_stake_delegations_get_pool( stake_delegations );
     206         114 :   if( FD_UNLIKELY( !stake_delegation_pool ) ) {
     207           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation pool" ));
     208           0 :   }
     209         114 :   fd_stake_delegation_map_t * stake_delegation_map = fd_stake_delegations_get_map( stake_delegations );
     210         114 :   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         114 :   ulong idx = fd_stake_delegation_map_idx_query_const(
     222         114 :       stake_delegation_map,
     223         114 :       stake_account,
     224         114 :       ULONG_MAX,
     225         114 :       stake_delegation_pool );
     226             : 
     227         114 :   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          93 :   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          93 :   fd_stake_delegation_t * stake_delegation = fd_stake_delegation_pool_ele_acquire( stake_delegation_pool );
     250          93 :   if( FD_UNLIKELY( !stake_delegation ) ) {
     251           0 :     FD_LOG_CRIT(( "unable to acquire stake delegation" ));
     252           0 :   }
     253             : 
     254          93 :   stake_delegation->stake_account        = *stake_account;
     255          93 :   stake_delegation->vote_account         = *vote_account;
     256          93 :   stake_delegation->stake                = stake;
     257          93 :   stake_delegation->activation_epoch     = activation_epoch;
     258          93 :   stake_delegation->deactivation_epoch   = deactivation_epoch;
     259          93 :   stake_delegation->credits_observed     = credits_observed;
     260          93 :   stake_delegation->warmup_cooldown_rate = warmup_cooldown_rate;
     261          93 :   stake_delegation->is_tombstone         = 0;
     262             : 
     263          93 :   if( FD_UNLIKELY( !fd_stake_delegation_map_ele_insert(
     264          93 :         stake_delegation_map,
     265          93 :         stake_delegation,
     266          93 :         stake_delegation_pool ) ) ) {
     267           0 :     FD_LOG_CRIT(( "unable to insert stake delegation into map" ));
     268           0 :   }
     269             : 
     270          93 : }
     271             : 
     272             : void
     273             : fd_stake_delegations_remove( fd_stake_delegations_t * stake_delegations,
     274          24 :                              fd_pubkey_t const *      stake_account ) {
     275          24 :   fd_stake_delegation_t * stake_delegation_pool = fd_stake_delegations_get_pool( stake_delegations );
     276          24 :   if( FD_UNLIKELY( !stake_delegation_pool ) ) {
     277           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation pool" ));
     278           0 :   }
     279          24 :   fd_stake_delegation_map_t * stake_delegation_map = fd_stake_delegations_get_map( stake_delegations );
     280          24 :   if( FD_UNLIKELY( !stake_delegation_map ) ) {
     281           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation map" ));
     282           0 :   }
     283             : 
     284          24 :   ulong delegation_idx = fd_stake_delegation_map_idx_query(
     285          24 :       stake_delegation_map,
     286          24 :       stake_account,
     287          24 :       ULONG_MAX,
     288          24 :       stake_delegation_pool );
     289             : 
     290          24 :   if( stake_delegations->leave_tombstones_==1 ) {
     291             :     /* If we are configured to leave tombstones, we need to either
     292             :        update the entry's is_tombstone flag or insert a new entry. */
     293             : 
     294           9 :     fd_stake_delegation_t * stake_delegation = NULL;
     295           9 :     if( delegation_idx!=ULONG_MAX ) {
     296             :       /* The delegation was found, update the is_tombstone flag. */
     297           3 :       stake_delegation = fd_stake_delegation_pool_ele( stake_delegation_pool, delegation_idx );
     298           6 :     } else {
     299             :       /* Otherwise, acquire an element from the pool and add it into the
     300             :          map. */
     301           6 :       stake_delegation = fd_stake_delegation_pool_ele_acquire( stake_delegation_pool );
     302           6 :       stake_delegation->stake_account = *stake_account;
     303           6 :       fd_stake_delegation_map_ele_insert( stake_delegation_map, stake_delegation, stake_delegation_pool );
     304           6 :     }
     305           9 :     stake_delegation->is_tombstone = 1;
     306             : 
     307          15 :   } else {
     308             :     /* If we are not configured to leave tombstones, we need to remove
     309             :        the entry from the map and release it from the pool. */
     310          15 :     if( FD_UNLIKELY( delegation_idx == ULONG_MAX ) ) {
     311             :       /* The delegation was not found, nothing to do. */
     312           0 :       return;
     313           0 :     }
     314             : 
     315             :     /* To be safe, we should set the next_ pointer to the null idx. */
     316             : 
     317          15 :     fd_stake_delegation_t * stake_delegation = fd_stake_delegation_pool_ele( stake_delegation_pool, delegation_idx );
     318          15 :     if( FD_UNLIKELY( !stake_delegation ) ) {
     319           0 :       FD_LOG_CRIT(( "unable to retrieve stake delegation" ));
     320           0 :     }
     321             : 
     322          15 :     ulong idx = fd_stake_delegation_map_idx_remove( stake_delegation_map, stake_account, ULONG_MAX, stake_delegation_pool );
     323          15 :     if( FD_UNLIKELY( idx==ULONG_MAX ) ) {
     324           0 :       FD_LOG_CRIT(( "unable to remove stake delegation" ));
     325           0 :     }
     326             : 
     327          15 :     stake_delegation->next_ = fd_stake_delegation_pool_idx_null( stake_delegation_pool );
     328             : 
     329          15 :     fd_stake_delegation_pool_idx_release( stake_delegation_pool, delegation_idx );
     330          15 :   }
     331          24 : }
     332             : 
     333             : void
     334             : fd_stake_delegations_refresh( fd_stake_delegations_t * stake_delegations,
     335             :                               fd_funk_t *              funk,
     336           0 :                               fd_funk_txn_t *          funk_txn ) {
     337             : 
     338           0 :   fd_stake_delegation_map_t * stake_delegation_map = fd_stake_delegations_get_map( stake_delegations );
     339           0 :   if( FD_UNLIKELY( !stake_delegation_map ) ) {
     340           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation map" ));
     341           0 :   }
     342             : 
     343           0 :   fd_stake_delegation_t * stake_delegation_pool = fd_stake_delegations_get_pool( stake_delegations );
     344           0 :   if( FD_UNLIKELY( !stake_delegation_pool ) ) {
     345           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation pool" ));
     346           0 :   }
     347             : 
     348           0 :   for( ulong i=0UL; i<stake_delegations->max_stake_accounts_; i++ ) {
     349             : 
     350           0 :     fd_stake_delegation_t * stake_delegation = fd_stake_delegation_pool_ele( fd_stake_delegations_get_pool( stake_delegations ), i );
     351             : 
     352           0 :     if( !fd_stake_delegation_map_ele_query_const(
     353           0 :             fd_stake_delegations_get_map( stake_delegations ),
     354           0 :             &stake_delegation->stake_account,
     355           0 :             NULL,
     356           0 :             fd_stake_delegations_get_pool( stake_delegations ) ) ) {
     357             :       /* This means that the stake delegation is not in the map, so we
     358             :          can skip it. */
     359           0 :       continue;
     360           0 :     }
     361             : 
     362           0 :     FD_TXN_ACCOUNT_DECL( acct_rec );
     363           0 :     int err = fd_txn_account_init_from_funk_readonly(
     364           0 :         acct_rec,
     365           0 :         &stake_delegation->stake_account,
     366           0 :         funk,
     367           0 :         funk_txn );
     368             : 
     369           0 :     if( FD_UNLIKELY( err || fd_txn_account_get_lamports( acct_rec )==0UL ) ) {
     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 :       continue;
     373           0 :     }
     374             : 
     375           0 :     fd_stake_state_v2_t stake_state;
     376           0 :     err = fd_stake_get_state( acct_rec, &stake_state );
     377           0 :     if( FD_UNLIKELY( err ) ) {
     378           0 :       fd_stake_delegation_map_idx_remove( stake_delegation_map, &stake_delegation->stake_account, ULONG_MAX, stake_delegation_pool );
     379           0 :       fd_stake_delegation_pool_idx_release( stake_delegation_pool, i );
     380           0 :     }
     381             : 
     382           0 :     if( FD_UNLIKELY( !fd_stake_state_v2_is_stake( &stake_state ) ) ) {
     383           0 :       fd_stake_delegation_map_idx_remove( stake_delegation_map, &stake_delegation->stake_account, ULONG_MAX, stake_delegation_pool );
     384           0 :       fd_stake_delegation_pool_idx_release( stake_delegation_pool, i );
     385           0 :     }
     386             : 
     387           0 :     fd_stake_delegations_update(
     388           0 :         stake_delegations,
     389           0 :         &stake_delegation->stake_account,
     390           0 :         &stake_state.inner.stake.stake.delegation.voter_pubkey,
     391           0 :         stake_state.inner.stake.stake.delegation.stake,
     392           0 :         stake_state.inner.stake.stake.delegation.activation_epoch,
     393           0 :         stake_state.inner.stake.stake.delegation.deactivation_epoch,
     394           0 :         stake_state.inner.stake.stake.credits_observed,
     395           0 :         stake_state.inner.stake.stake.delegation.warmup_cooldown_rate );
     396           0 :   }
     397           0 : }
     398             : 
     399             : fd_stake_delegation_t const *
     400             : fd_stake_delegations_query( fd_stake_delegations_t const * stake_delegations,
     401          96 :                             fd_pubkey_t const *            stake_account ) {
     402             : 
     403          96 :   if( FD_UNLIKELY( !stake_delegations ) ) {
     404           0 :     FD_LOG_CRIT(( "NULL stake_delegations" ));
     405           0 :     return NULL;
     406           0 :   }
     407             : 
     408          96 :   if( FD_UNLIKELY( !stake_account ) ) {
     409           0 :     FD_LOG_CRIT(( "NULL stake_account" ));
     410           0 :     return NULL;
     411           0 :   }
     412             : 
     413          96 :   fd_stake_delegation_t const * stake_delegation_pool = fd_stake_delegations_get_pool( stake_delegations );
     414          96 :   if( FD_UNLIKELY( !stake_delegation_pool ) ) {
     415           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation pool" ));
     416           0 :   }
     417             : 
     418          96 :   fd_stake_delegation_map_t const * stake_delegation_map = fd_stake_delegations_get_map( stake_delegations );
     419          96 :   if( FD_UNLIKELY( !stake_delegation_map ) ) {
     420           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation map" ));
     421           0 :   }
     422             : 
     423          96 :   return fd_stake_delegation_map_ele_query_const(
     424          96 :       stake_delegation_map,
     425          96 :       stake_account,
     426          96 :       NULL,
     427          96 :       stake_delegation_pool );
     428          96 : }
     429             : 
     430             : ulong
     431          75 : fd_stake_delegations_cnt( fd_stake_delegations_t const * stake_delegations ) {
     432          75 :   if( FD_UNLIKELY( !stake_delegations ) ) {
     433           0 :     FD_LOG_CRIT(( "NULL stake_delegations" ));
     434           0 :   }
     435             : 
     436          75 :   fd_stake_delegation_t const * stake_delegation_pool = fd_stake_delegations_get_pool( stake_delegations );
     437          75 :   if( FD_UNLIKELY( !stake_delegation_pool ) ) {
     438           0 :     FD_LOG_CRIT(( "unable to retrieve join to stake delegation map" ));
     439           0 :   }
     440             : 
     441          75 :   return fd_stake_delegation_pool_used( stake_delegation_pool );
     442          75 : }
     443             : 
     444             : fd_stake_delegation_t *
     445          84 : fd_stake_delegations_iter_ele( fd_stake_delegations_iter_t * iter ) {
     446          84 :   ulong idx = fd_stake_delegation_map_iter_idx( iter->iter, iter->map, iter->pool );
     447          84 :   return fd_stake_delegation_pool_ele( iter->pool, idx );
     448          84 : }
     449             : 
     450             : fd_stake_delegations_iter_t *
     451             : fd_stake_delegations_iter_init( fd_stake_delegations_iter_t *  iter,
     452          57 :                                 fd_stake_delegations_t const * stake_delegations ) {
     453          57 :   if( FD_UNLIKELY( !stake_delegations ) ) {
     454           0 :     FD_LOG_CRIT(( "NULL stake_delegations" ));
     455           0 :   }
     456             : 
     457          57 :   iter->map  = fd_stake_delegations_get_map( stake_delegations );
     458          57 :   iter->pool = fd_stake_delegations_get_pool( stake_delegations );
     459          57 :   iter->iter = fd_stake_delegation_map_iter_init( iter->map, iter->pool );
     460             : 
     461          57 :   return iter;
     462          57 : }
     463             : 
     464             : void
     465          84 : fd_stake_delegations_iter_next( fd_stake_delegations_iter_t * iter ) {
     466          84 :   iter->iter = fd_stake_delegation_map_iter_next( iter->iter, iter->map, iter->pool );
     467          84 : }
     468             : 
     469             : int
     470         141 : fd_stake_delegations_iter_done( fd_stake_delegations_iter_t * iter ) {
     471         141 :   return fd_stake_delegation_map_iter_done( iter->iter, iter->map, iter->pool );
     472         141 : }

Generated by: LCOV version 1.14