Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_runtime_fd_blockhashes_h 2 : #define HEADER_fd_src_flamenco_runtime_fd_blockhashes_h 3 : 4 : #include "../types/fd_types.h" 5 : #include "../../funk/fd_funk_base.h" /* fd_funk_rec_key_hash1 */ 6 : 7 : /* fd_blockhashes.h provides a "blockhash queue" API. The blockhash 8 : queue is a consensus-relevant data structure that is part of the slot 9 : bank. 10 : 11 : See solana_accounts_db::blockhash_queue::BlockhashQueue. */ 12 : 13 3 : #define FD_BLOCKHASHES_MAX 301 14 : 15 : /* See solana_accounts_db::blockhash_queue::HashInfo. */ 16 : 17 : struct fd_blockhash_info { 18 : fd_hash_t hash; 19 : fd_fee_calculator_t fee_calculator; 20 : ushort next; 21 : ushort exists : 1; 22 : }; 23 : 24 : typedef struct fd_blockhash_info fd_blockhash_info_t; 25 : 26 : /* Declare a static size deque for the blockhash queue. */ 27 : 28 : #define DEQUE_NAME fd_blockhash_deq 29 450 : #define DEQUE_T fd_blockhash_info_t 30 35775 : #define DEQUE_MAX 512 /* must be a power of 2 */ 31 : #include "../../util/tmpl/fd_deque.c" 32 : 33 : /* Declare a separately chained hash map over the blockhash queue. */ 34 : 35 : #define FD_BLOCKHASH_MAP_CHAIN_MAX (512UL) 36 : #define FD_BLOCKHASH_MAP_FOOTPRINT (1048UL) 37 : 38 : #define MAP_NAME fd_blockhash_map 39 : #define MAP_ELE_T fd_blockhash_info_t 40 : #define MAP_KEY_T fd_hash_t 41 450 : #define MAP_KEY hash 42 1803 : #define MAP_IDX_T ushort 43 570 : #define MAP_NEXT next 44 570 : #define MAP_KEY_EQ(k0,k1) fd_hash_eq( (k0), (k1) ) 45 1350 : #define MAP_KEY_HASH(k,s) fd_funk_rec_key_hash1( (k->uc), 0, (s) ) 46 : #include "../../util/tmpl/fd_map_chain.c" 47 : 48 : /* fd_blockhashes_t is the class representing a blockhash queue. 49 : 50 : It is a static size container housing sub-structures as plain old 51 : struct members. Safe to declare as a local variable assuming the 52 : stack is sufficiently sized. Entirely self-contained and position- 53 : independent (safe to clone via fd_memcpy and safe to map into another 54 : address space). 55 : 56 : Under the hood it is an array-backed double-ended queue, and a 57 : separately-chained hash index on top. New entries are inserted to 58 : the **tail** of the queue. */ 59 : 60 : struct fd_blockhashes { 61 : 62 : union { 63 : fd_blockhash_map_t map[1]; 64 : uchar map_mem[ FD_BLOCKHASH_MAP_FOOTPRINT ]; 65 : }; 66 : 67 : fd_blockhash_deq_private_t d; 68 : 69 : }; 70 : 71 : typedef struct fd_blockhashes fd_blockhashes_t; 72 : 73 : FD_PROTOTYPES_BEGIN 74 : 75 : fd_blockhashes_t * 76 : fd_blockhashes_init( fd_blockhashes_t * mem, 77 : ulong seed ); 78 : 79 : /* fd_blockhashes_push_new adds a new slot to the blockhash queue. 80 : The caller fills the returned pointer with blockhash queue info 81 : (currently only lamports_per_signature). Called as part of regular 82 : runtime processing. Evicts the oldest entry if the queue is full 83 : (practically always the case except for the first few blocks after 84 : genesis). Always returns a valid pointer. */ 85 : 86 : fd_blockhash_info_t * 87 : fd_blockhashes_push_new( fd_blockhashes_t * blockhashes, 88 : fd_hash_t const * hash ); 89 : 90 : /* fd_blockhashes_push_old behaves like the above, but adding a new 91 : oldest entry instead. Returns NULL if there is no more space. 92 : Useful for testing. */ 93 : 94 : fd_blockhash_info_t * 95 : fd_blockhashes_push_old( fd_blockhashes_t * blockhashes, 96 : fd_hash_t const * hash ); 97 : 98 : /* fd_blockhashes_pop_new removes the newest blockhash queue entry. */ 99 : 100 : void 101 : fd_blockhashes_pop_new( fd_blockhashes_t * blockhashes ); 102 : 103 : FD_FN_PURE int 104 : fd_blockhashes_check_age( fd_blockhashes_t const * blockhashes, 105 : fd_hash_t const * blockhash, 106 : ulong max_age ); 107 : 108 : FD_FN_PURE static inline fd_hash_t const * 109 0 : fd_blockhashes_peek_last( fd_blockhashes_t const * blockhashes ) { 110 0 : if( FD_UNLIKELY( fd_blockhash_deq_empty( blockhashes->d.deque ) ) ) return 0; 111 0 : return &fd_blockhash_deq_peek_tail_const( blockhashes->d.deque )->hash; 112 0 : } 113 : 114 : FD_PROTOTYPES_END 115 : 116 : #endif /* HEADER_fd_src_flamenco_runtime_fd_blockhashes_h */