Line data Source code
1 : #include "fd_vote_tracker.h" 2 : #include "../../flamenco/types/fd_types.h" 3 : 4 0 : #define VOTE_TRACKER_MAX (512UL) 5 : 6 : struct fd_vote_tracker_ele { 7 : fd_signature_t vote_sig; 8 : fd_pubkey_t identity_pubkey; 9 : ulong next_; /* Internal pool/map use */ 10 : }; 11 : typedef struct fd_vote_tracker_ele fd_vote_tracker_ele_t; 12 : 13 : #define DEQUE_NAME fd_vote_tracker_deq 14 0 : #define DEQUE_T fd_vote_tracker_ele_t 15 0 : #define DEQUE_MAX 512 /* must be a power of 2 */ 16 : #include "../../util/tmpl/fd_deque.c" 17 : 18 : #define MAP_NAME fd_vote_tracker_map 19 : #define MAP_ELE_T fd_vote_tracker_ele_t 20 : #define MAP_KEY_T fd_signature_t 21 0 : #define MAP_KEY vote_sig 22 0 : #define MAP_NEXT next_ 23 0 : #define MAP_KEY_EQ(k0,k1) fd_signature_eq( (k0), (k1) ) 24 0 : #define MAP_KEY_HASH(k,s) fd_hash( s, (k)->uc, sizeof(fd_signature_t) ) 25 : #include "../../util/tmpl/fd_map_chain.c" 26 : 27 : struct fd_vote_tracker { 28 : ulong magic; 29 : ulong deq_offset; 30 : ulong map_offset; 31 : }; 32 : typedef struct fd_vote_tracker fd_vote_tracker_t; 33 : 34 : static inline fd_vote_tracker_ele_t * 35 0 : fd_vote_tracker_deq_get( fd_vote_tracker_t * vote_tracker ) { 36 0 : return fd_vote_tracker_deq_join( (uchar *)vote_tracker + vote_tracker->deq_offset ); 37 0 : } 38 : 39 : static inline fd_vote_tracker_map_t * 40 0 : fd_vote_tracker_map_get( fd_vote_tracker_t * vote_tracker ) { 41 0 : return fd_vote_tracker_map_join( (uchar *)vote_tracker + vote_tracker->map_offset ); 42 0 : } 43 : 44 : ulong 45 0 : fd_vote_tracker_align( void ) { 46 0 : return fd_ulong_max( fd_ulong_max( fd_vote_tracker_map_align(), fd_vote_tracker_deq_align() ), alignof(fd_vote_tracker_t) ); 47 0 : } 48 : 49 : ulong 50 0 : fd_vote_tracker_footprint( void ) { 51 0 : ulong map_chain_cnt = fd_vote_tracker_map_chain_cnt_est( VOTE_TRACKER_MAX ); 52 0 : ulong l = FD_LAYOUT_INIT; 53 0 : l = FD_LAYOUT_APPEND( l, fd_vote_tracker_align(), sizeof(fd_vote_tracker_t) ); 54 0 : l = FD_LAYOUT_APPEND( l, fd_vote_tracker_deq_align(), fd_vote_tracker_deq_footprint() ); 55 0 : l = FD_LAYOUT_APPEND( l, fd_vote_tracker_map_align(), fd_vote_tracker_map_footprint( map_chain_cnt ) ); 56 0 : return FD_LAYOUT_FINI( l, fd_vote_tracker_align() ); 57 0 : } 58 : 59 : void * 60 : fd_vote_tracker_new( void * mem, 61 0 : ulong seed ) { 62 0 : if( FD_UNLIKELY( !mem ) ) { 63 0 : FD_LOG_WARNING(( "NULL mem" )); 64 0 : return NULL; 65 0 : } 66 : 67 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, fd_vote_tracker_align() ) ) ) { 68 0 : FD_LOG_WARNING(( "misaligned mem" )); 69 0 : return NULL; 70 0 : } 71 : 72 0 : ulong map_chain_cnt = fd_vote_tracker_map_chain_cnt_est( VOTE_TRACKER_MAX ); 73 : 74 0 : FD_SCRATCH_ALLOC_INIT( l, mem ); 75 0 : fd_vote_tracker_t * vote_tracker = FD_SCRATCH_ALLOC_APPEND( l, fd_vote_tracker_align(), sizeof(fd_vote_tracker_t) ); 76 0 : void * deq_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_vote_tracker_deq_align(), fd_vote_tracker_deq_footprint() ); 77 0 : void * map_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_vote_tracker_map_align(), fd_vote_tracker_map_footprint( map_chain_cnt ) ); 78 : 79 0 : if( FD_UNLIKELY( FD_SCRATCH_ALLOC_FINI( l, fd_vote_tracker_align() )!=(ulong)mem+fd_vote_tracker_footprint() ) ) { 80 0 : FD_LOG_WARNING(( "fd_vote_tracker_new: bad layout" )); 81 0 : return NULL; 82 0 : } 83 : 84 0 : if( FD_UNLIKELY( !fd_vote_tracker_deq_new( deq_mem ) ) ) { 85 0 : FD_LOG_WARNING(( "fd_vote_tracker_new: bad deq" )); 86 0 : return NULL; 87 0 : } 88 : 89 0 : if( FD_UNLIKELY( !fd_vote_tracker_map_new( map_mem, map_chain_cnt, seed ) ) ) { 90 0 : FD_LOG_WARNING(( "fd_vote_tracker_new: bad map" )); 91 0 : return NULL; 92 0 : } 93 : 94 0 : vote_tracker->deq_offset = (ulong)deq_mem - (ulong)mem; 95 0 : vote_tracker->map_offset = (ulong)map_mem - (ulong)mem; 96 : 97 0 : return vote_tracker; 98 : 99 0 : } 100 : 101 : fd_vote_tracker_t * 102 0 : fd_vote_tracker_join( void * mem ) { 103 0 : return (fd_vote_tracker_t *)mem; 104 0 : } 105 : 106 : void 107 : fd_vote_tracker_insert( fd_vote_tracker_t * vote_tracker, 108 : fd_pubkey_t const * identity_pubkey, 109 0 : fd_signature_t const * vote_sig ) { 110 0 : fd_vote_tracker_ele_t * deq = fd_vote_tracker_deq_get( vote_tracker ); 111 0 : fd_vote_tracker_map_t * map = fd_vote_tracker_map_get( vote_tracker ); 112 0 : if( fd_vote_tracker_deq_full( deq ) ) { 113 0 : fd_vote_tracker_ele_t * ele = fd_vote_tracker_deq_pop_head_nocopy( deq ); 114 0 : fd_vote_tracker_map_ele_remove( map, &ele->vote_sig, NULL, deq ); 115 0 : } 116 0 : fd_vote_tracker_ele_t * ele = fd_vote_tracker_deq_push_tail_nocopy( deq ); 117 0 : ele->vote_sig = *vote_sig; 118 0 : ele->identity_pubkey = *identity_pubkey; 119 0 : fd_vote_tracker_map_ele_insert( map, ele, deq ); 120 0 : } 121 : 122 : int 123 : fd_vote_tracker_query_sig( fd_vote_tracker_t * vote_tracker, 124 : fd_signature_t const * vote_sig, 125 0 : fd_pubkey_t * * identity_pubkey_out ) { 126 0 : fd_vote_tracker_ele_t * deq = fd_vote_tracker_deq_get( vote_tracker ); 127 0 : fd_vote_tracker_map_t * map = fd_vote_tracker_map_get( vote_tracker ); 128 0 : fd_vote_tracker_ele_t * ele = fd_vote_tracker_map_ele_query( map, vote_sig, NULL, deq ); 129 0 : FD_TEST( identity_pubkey_out ); 130 0 : *identity_pubkey_out = ele ? &ele->identity_pubkey : NULL; 131 0 : return ele!=NULL; 132 0 : } 133 : 134 : void 135 0 : fd_vote_tracker_reset( fd_vote_tracker_t * vote_tracker ) { 136 0 : fd_vote_tracker_deq_remove_all( fd_vote_tracker_deq_get( vote_tracker ) ); 137 0 : fd_vote_tracker_map_reset( fd_vote_tracker_map_get( vote_tracker ) ); 138 0 : }