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