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