Line data Source code
1 : #ifndef HEADER_fd_src_discof_repair_fd_inflight_h 2 : #define HEADER_fd_src_discof_repair_fd_inflight_h 3 : 4 : #include "../../flamenco/types/fd_types.h" 5 : #include "fd_policy.h" 6 : 7 : /* fd_inflights tracks repair requests that are inflight to other 8 : validators. This module is useful for metrics and reporting. 9 : In-exact updates of orphan requests and highest window requests from 10 : this module are non-critical, but exact updates of shred requests are 11 : critical. Repair tile relies on this module to be able to re-request 12 : any shreds that it has sent, because policy next does not request any 13 : shred twice. 14 : (TODO should this be rolled into policy.h?) 15 : 16 : Requests are key-ed by nonce as in the current strategy (see 17 : fd_policy.h), all requests have a unique nonce. The chances that an 18 : inflight request does not get a response are non-negligible due to 19 : shred tile upstream deduping duplicates. */ 20 : 21 : /* Max number of pending requests */ 22 0 : #define FD_INFLIGHT_REQ_MAX (1<<20) 23 : 24 : struct __attribute__((aligned(128UL))) fd_inflight { 25 : ulong nonce; /* unique identifier for the request */ 26 : ulong next; /* reserved for internal use by fd_pool and fd_map_chain */ 27 : long timestamp_ns; /* timestamp when request was created (nanoseconds) */ 28 : fd_pubkey_t pubkey; /* public key of the peer */ 29 : 30 : ulong slot; /* slot of the request */ 31 : ulong shred_idx; /* shred index of the request */ 32 : 33 : /* Reserved for DLL eviction */ 34 : ulong prevll; /* pool index of previous element in DLL */ 35 : ulong nextll; /* pool index of next element in DLL */ 36 : }; 37 : typedef struct fd_inflight fd_inflight_t; 38 : 39 : #define POOL_NAME fd_inflight_pool 40 0 : #define POOL_T fd_inflight_t 41 : #include "../../util/tmpl/fd_pool.c" 42 : 43 : #define MAP_NAME fd_inflight_map 44 0 : #define MAP_KEY nonce 45 : #define MAP_ELE_T fd_inflight_t 46 : #include "../../util/tmpl/fd_map_chain.c" 47 : 48 : #define DLIST_NAME fd_inflight_dlist 49 : #define DLIST_ELE_T fd_inflight_t 50 0 : #define DLIST_PREV prevll 51 0 : #define DLIST_NEXT nextll 52 : #include "../../util/tmpl/fd_dlist.c" 53 : 54 : struct fd_inflights { 55 : fd_inflight_t * pool; 56 : fd_inflight_map_t * map; 57 : fd_inflight_dlist_t * dlist; 58 : }; 59 : typedef struct fd_inflights fd_inflights_t; 60 : 61 : FD_FN_CONST static inline ulong 62 0 : fd_inflights_align( void ) { return 128UL; } 63 : 64 : FD_FN_CONST static inline ulong 65 0 : fd_inflights_footprint( void ) { 66 0 : return FD_LAYOUT_FINI( 67 0 : FD_LAYOUT_APPEND( 68 0 : FD_LAYOUT_APPEND( 69 0 : FD_LAYOUT_APPEND( 70 0 : FD_LAYOUT_APPEND( 71 0 : FD_LAYOUT_INIT, 72 0 : alignof(fd_inflights_t), sizeof(fd_inflights_t) ), 73 0 : fd_inflight_pool_align(), fd_inflight_pool_footprint ( FD_INFLIGHT_REQ_MAX ) ), 74 0 : fd_inflight_map_align(), fd_inflight_map_footprint ( FD_INFLIGHT_REQ_MAX ) ), 75 0 : fd_inflight_dlist_align(), fd_inflight_dlist_footprint() ), 76 0 : fd_inflights_align() ); 77 0 : } 78 : 79 : void * 80 : fd_inflights_new( void * shmem ); 81 : 82 : fd_inflights_t * 83 : fd_inflights_join( void * shmem ); 84 : 85 : void 86 : fd_inflights_request_insert( fd_inflights_t * table, ulong nonce, fd_pubkey_t const * pubkey, ulong slot, ulong shred_idx ); 87 : 88 : long 89 : fd_inflights_request_remove( fd_inflights_t * table, ulong nonce, fd_pubkey_t * peer_out ); 90 : 91 : /* Important! Caller must guarantee that the request list is not empty. 92 : This function cannot fail and will always try to populate the output 93 : parameters. Typical use should only call this after 94 : fd_inflights_should_drain returns true. */ 95 : 96 : void 97 : fd_inflights_request_pop( fd_inflights_t * table, ulong * nonce_out, ulong * slot_out, ulong * shred_idx_out ); 98 : 99 : static inline int 100 0 : fd_inflights_should_drain( fd_inflights_t * table, long now ) { 101 : /* peek at head */ 102 0 : if( FD_UNLIKELY( fd_inflight_dlist_is_empty( table->dlist, table->pool ) ) ) return 0; 103 : 104 0 : fd_inflight_t * inflight_req = fd_inflight_dlist_ele_peek_head( table->dlist, table->pool ); 105 0 : if( FD_UNLIKELY( inflight_req->timestamp_ns + FD_POLICY_DEDUP_TIMEOUT < now ) ) return 1; 106 0 : return 0; 107 0 : } 108 : 109 : 110 : fd_inflight_t * 111 : fd_inflights_request_query ( fd_inflights_t * table, ulong nonce ); 112 : 113 : void 114 : fd_inflights_print( fd_inflight_map_t * map, fd_inflight_t * pool ); 115 : 116 : #endif /* HEADER_fd_src_discof_repair_fd_inflight_h */