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