LCOV - code coverage report
Current view: top level - flamenco/runtime/program/vote - fd_authorized_voters.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 71 85 83.5 %
Date: 2026-11-11 12:40:43 Functions: 6 7 85.7 %

          Line data    Source code
       1             : #include "fd_authorized_voters.h"
       2             : #include "fd_vote_codec_tmpl.h"
       3             : #include "fd_vote_state_v3.h"
       4             : #include "fd_vote_state_v4.h"
       5             : #include "fd_vote_state_v5.h"
       6             : 
       7             : int
       8        2990 : fd_authorized_voters_is_empty( fd_vote_authorized_voters_t * self ) {
       9        2990 :   return fd_vote_authorized_voters_treap_ele_cnt( self->treap ) == 0;
      10        2990 : }
      11             : 
      12             : int
      13         102 : fd_authorized_voters_contains( fd_vote_authorized_voters_t * self, ulong epoch ) {
      14         102 :   return !!fd_vote_authorized_voters_treap_ele_query( self->treap, epoch, self->pool );
      15         102 : }
      16             : 
      17             : fd_vote_authorized_voter_t *
      18           0 : fd_authorized_voters_last( fd_vote_authorized_voters_t * self ) {
      19           0 :   fd_vote_authorized_voters_treap_rev_iter_t iter =
      20           0 :       fd_vote_authorized_voters_treap_rev_iter_init( self->treap, self->pool );
      21           0 :   return fd_vote_authorized_voters_treap_rev_iter_ele( iter, self->pool );
      22           0 : }
      23             : 
      24             : void
      25             : fd_authorized_voters_purge_authorized_voters( fd_vote_authorized_voters_t * self,
      26        1574 :                                               ulong                         current_epoch ) {
      27             : 
      28             :   // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/authorized_voters.rs#L46
      29        1574 :   ulong expired_keys[ MAX_AUTHORIZED_VOTERS_CAPACITY ];
      30        1574 :   ulong key_cnt                                     = 0;
      31        1574 :   for( fd_vote_authorized_voters_treap_fwd_iter_t iter =
      32        1574 :            fd_vote_authorized_voters_treap_fwd_iter_init( self->treap, self->pool );
      33        3948 :        !fd_vote_authorized_voters_treap_fwd_iter_done( iter );
      34        2374 :        iter = fd_vote_authorized_voters_treap_fwd_iter_next( iter, self->pool ) ) {
      35        2374 :     fd_vote_authorized_voter_t * ele =
      36        2374 :         fd_vote_authorized_voters_treap_fwd_iter_ele( iter, self->pool );
      37        2374 :     if( ele->epoch < current_epoch ) expired_keys[key_cnt++] = ele->epoch;
      38        2374 :   }
      39             : 
      40             :   // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/authorized_voters.rs#L52
      41        2356 :   for( ulong i = 0; i < key_cnt; i++ ) {
      42         782 :     fd_vote_authorized_voter_t * ele =
      43         782 :         fd_vote_authorized_voters_treap_ele_query( self->treap, expired_keys[i], self->pool );
      44         782 :     fd_vote_authorized_voters_treap_ele_remove( self->treap, ele, self->pool );
      45         782 :     fd_vote_authorized_voters_pool_ele_release( self->pool, ele );
      46         782 :   }
      47             : 
      48             :   // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/authorized_voters.rs#L60
      49        1574 :   FD_TEST( !fd_authorized_voters_is_empty( self ) );
      50             : 
      51        1574 : }
      52             : 
      53             : fd_vote_authorized_voter_t *
      54             : fd_authorized_voters_get_or_calculate_authorized_voter_for_epoch( fd_vote_authorized_voters_t * self,
      55             :                                                                   ulong                         epoch,
      56        1576 :                                                                   int *                         existed ) {
      57        1576 :   *existed                                  = 0;
      58        1576 :   ulong                        latest_epoch = 0;
      59        1576 :   fd_vote_authorized_voter_t * res =
      60        1576 :       fd_vote_authorized_voters_treap_ele_query( self->treap, epoch, self->pool );
      61             :   // "predecessor" would be more big-O optimal here, but mirroring labs logic
      62             :   // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/authorized_voters.rs#L93
      63        1576 :   if( FD_UNLIKELY( !res ) ) {
      64         692 :     for( fd_vote_authorized_voters_treap_fwd_iter_t iter =
      65         692 :              fd_vote_authorized_voters_treap_fwd_iter_init( self->treap, self->pool );
      66        1481 :          !fd_vote_authorized_voters_treap_fwd_iter_done( iter );
      67         789 :          iter = fd_vote_authorized_voters_treap_fwd_iter_next( iter, self->pool ) ) {
      68         789 :       fd_vote_authorized_voter_t * ele =
      69         789 :           fd_vote_authorized_voters_treap_fwd_iter_ele( iter, self->pool );
      70         789 :       if( ele->epoch < epoch && ( latest_epoch == 0 || ele->epoch > latest_epoch ) ) {
      71         781 :         latest_epoch = ele->epoch;
      72         781 :         res          = ele;
      73         781 :       }
      74         789 :     }
      75         692 :     *existed = 0;
      76         692 :     return res;
      77         884 :   } else {
      78         884 :     *existed = 1;
      79         884 :     return res;
      80         884 :   }
      81           0 :   return res;
      82        1576 : }
      83             : 
      84             : fd_vote_authorized_voter_t *
      85             : fd_authorized_voters_get_and_cache_authorized_voter_for_epoch( fd_vote_authorized_voters_t * self,
      86        1576 :                                                                ulong                         epoch ) {
      87        1576 :   int                          existed = 0;
      88             :   // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/authorized_voters.rs#L29
      89        1576 :   fd_vote_authorized_voter_t * res =
      90        1576 :       fd_authorized_voters_get_or_calculate_authorized_voter_for_epoch( self, epoch, &existed );
      91        1576 :   if( !res ) return NULL;
      92             :   // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/authorized_voters.rs#L32
      93        1575 :   if( !existed ) {
      94             :     /* insert cannot fail because !existed */
      95         691 :     if( FD_UNLIKELY( !fd_vote_authorized_voters_pool_free( self->pool ) ) ) {
      96           0 :       FD_LOG_CRIT(( "invariant violation: max authorized voter count of vote account exceeded" ));
      97           0 :     }
      98         691 :     fd_vote_authorized_voter_t * ele = fd_vote_authorized_voters_pool_ele_acquire( self->pool );
      99         691 :     ele->epoch                       = epoch;
     100         691 :     ele->pubkey                      = res->pubkey;
     101         691 :     ele->prio                        = ele->pubkey.uc[0];
     102             :     // https://github.com/anza-xyz/agave/blob/v2.0.1/sdk/program/src/vote/authorized_voters.rs#L33
     103         691 :     fd_vote_authorized_voters_treap_ele_insert( self->treap, ele, self->pool );
     104         691 :     return ele;
     105         691 :   }
     106         884 :   return res;
     107        1575 : }
     108             : 
     109             : int
     110             : fd_authorized_voters_get_and_update_authorized_voter( fd_vote_state_versioned_t * self,
     111             :                                                       ulong                       current_epoch,
     112        1361 :                                                       fd_pubkey_t **              pubkey /* out */ ) {
     113        1361 :   switch( self->kind ) {
     114           0 :     case fd_vote_state_versioned_enum_v3:
     115           0 :       return fd_vote_state_v3_get_and_update_authorized_voter( &self->v3, current_epoch, pubkey );
     116        1361 :     case fd_vote_state_versioned_enum_v4:
     117        1361 :       return fd_vote_state_v4_get_and_update_authorized_voter( &self->v4, current_epoch, pubkey );
     118           0 :     case fd_vote_state_versioned_enum_v5:
     119           0 :       return fd_vote_state_v5_get_and_update_authorized_voter( &self->v5, current_epoch, pubkey );
     120           0 :     default:
     121           0 :       FD_LOG_CRIT(( "unsupported vote state versioned discriminant: %u", self->kind ));
     122        1361 :   }
     123        1361 : }

Generated by: LCOV version 1.14