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