LCOV - code coverage report
Current view: top level - flamenco/stakes - fd_stake_delegations.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 202 319 63.3 %
Date: 2026-01-17 04:55:09 Functions: 17 18 94.4 %

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

Generated by: LCOV version 1.14