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 : }
|