Line data Source code
1 : #include "fd_blockhashes.h" 2 : 3 : fd_blockhashes_t * 4 : fd_blockhashes_init( fd_blockhashes_t * mem, 5 3 : ulong seed ) { 6 3 : if( FD_UNLIKELY( !mem ) ) { 7 0 : FD_LOG_WARNING(( "NULL mem" )); 8 0 : return NULL; 9 0 : } 10 3 : FD_TEST( fd_blockhash_deq_join( fd_blockhash_deq_new( &mem->d ) ) ); 11 3 : memset( mem->d.deque, 0x5a, sizeof(fd_blockhash_info_t) * FD_BLOCKHASHES_MAX ); 12 3 : FD_TEST( fd_blockhash_map_join( fd_blockhash_map_new( mem, FD_BLOCKHASH_MAP_CHAIN_MAX, seed ) ) ); 13 3 : return mem; 14 3 : } 15 : 16 : static void 17 0 : fd_blockhashes_pop_old( fd_blockhashes_t * blockhashes ) { 18 0 : if( FD_UNLIKELY( fd_blockhash_deq_empty( blockhashes->d.deque ) ) ) return; 19 0 : fd_blockhash_info_t * info = fd_blockhash_deq_pop_head_nocopy( blockhashes->d.deque ); 20 0 : info->exists = 0; 21 0 : fd_blockhash_map_ele_remove( blockhashes->map, &info->hash, NULL, blockhashes->d.deque ); 22 0 : } 23 : 24 : void 25 0 : fd_blockhashes_pop_new( fd_blockhashes_t * blockhashes ) { 26 0 : if( FD_UNLIKELY( fd_blockhash_deq_empty( blockhashes->d.deque ) ) ) return; 27 0 : fd_blockhash_info_t * info = fd_blockhash_deq_pop_tail_nocopy( blockhashes->d.deque ); 28 0 : info->exists = 0; 29 0 : fd_blockhash_map_ele_remove( blockhashes->map, &info->hash, NULL, blockhashes->d.deque ); 30 0 : } 31 : 32 : fd_blockhash_info_t * 33 : fd_blockhashes_push_new( fd_blockhashes_t * blockhashes, 34 450 : fd_hash_t const * hash ) { 35 450 : if( FD_UNLIKELY( fd_blockhash_deq_full( blockhashes->d.deque ) ) ) { 36 0 : fd_blockhashes_pop_old( blockhashes ); 37 0 : } 38 450 : if( FD_UNLIKELY( fd_blockhash_map_idx_query( blockhashes->map, hash, ULONG_MAX, blockhashes->d.deque )!=ULONG_MAX ) ) { 39 0 : char bh_cstr[ FD_BASE58_ENCODED_32_SZ ]; fd_base58_encode_32( hash->uc, NULL, bh_cstr ); 40 0 : FD_LOG_CRIT(( "Attempted to register duplicate blockhash %s", bh_cstr )); 41 0 : } 42 : 43 450 : fd_blockhash_info_t * info = fd_blockhash_deq_push_tail_nocopy( blockhashes->d.deque ); 44 450 : *info = (fd_blockhash_info_t) { .hash = *hash, .exists = 1 }; 45 : 46 450 : fd_blockhash_map_ele_insert( blockhashes->map, info, blockhashes->d.deque ); 47 : 48 450 : return info; 49 450 : } 50 : 51 : fd_blockhash_info_t * 52 : fd_blockhashes_push_old( fd_blockhashes_t * blockhashes, 53 0 : fd_hash_t const * hash ) { 54 0 : if( FD_UNLIKELY( fd_blockhash_deq_full( blockhashes->d.deque ) ) ) { 55 0 : return NULL; 56 0 : } 57 0 : if( FD_UNLIKELY( fd_blockhash_map_idx_query( blockhashes->map, hash, ULONG_MAX, blockhashes->d.deque )!=ULONG_MAX ) ) { 58 0 : char bh_cstr[ FD_BASE58_ENCODED_32_SZ ]; fd_base58_encode_32( hash->uc, NULL, bh_cstr ); 59 0 : FD_LOG_CRIT(( "Attempted to register duplicate blockhash %s", bh_cstr )); 60 0 : } 61 : 62 0 : fd_blockhash_info_t * info = fd_blockhash_deq_push_head_nocopy( blockhashes->d.deque ); 63 0 : *info = (fd_blockhash_info_t) { .hash = *hash, .exists = 1 }; 64 : 65 0 : fd_blockhash_map_ele_insert( blockhashes->map, info, blockhashes->d.deque ); 66 : 67 0 : return info; 68 0 : } 69 : 70 : 71 : FD_FN_PURE int 72 : fd_blockhashes_check_age( fd_blockhashes_t const * blockhashes, 73 : fd_hash_t const * blockhash, 74 450 : ulong max_age ) { 75 450 : ulong const idx = fd_blockhash_map_idx_query_const( blockhashes->map, blockhash, ULONG_MAX, blockhashes->d.deque ); 76 450 : if( FD_UNLIKELY( idx==ULONG_MAX ) ) return 0; 77 : /* Derive distance from tail (end) */ 78 450 : ulong const max = fd_blockhash_deq_max( blockhashes->d.deque ); 79 450 : ulong const end = (blockhashes->d.end - 1) & (max-1); 80 450 : ulong const age = end + fd_ulong_if( idx<=end, 0UL, max ) - idx; 81 450 : return age<=max_age; 82 450 : }