Line data Source code
1 : #ifndef HEADER_fd_src_discof_restore_utils_fd_sspeer_selector_h 2 : #define HEADER_fd_src_discof_restore_utils_fd_sspeer_selector_h 3 : 4 : /* The snapshot peer selector (sspeer_selector) continuously selects 5 : the most optimal snapshot peer to download snapshots from. The 6 : most optimal peer is defined as the closest peer that serves the 7 : most recent snapshot. */ 8 : 9 : #include "../../../util/fd_util_base.h" 10 : #include "../../../util/net/fd_net_headers.h" 11 : #include "../../../flamenco/types/fd_types_custom.h" 12 : #include "fd_sspeer.h" 13 : 14 0 : #define FD_SSPEER_SELECTOR_MAGIC (0xF17EDA2CE5593350) /* FIREDANCE SSPING V0 */ 15 : 16 : /* fd_sscluster_slot stores the highest full and incremental slot pair 17 : seen in the cluster. */ 18 : struct fd_sscluster_slot { 19 : ulong full; 20 : ulong incremental; 21 : }; 22 : 23 : typedef struct fd_sscluster_slot fd_sscluster_slot_t; 24 : 25 : /* fd_sspeer_t represents a selected peer from the snapshot peer 26 : selector, including the peer's address, resolved snapshot slots, 27 : and selector score. */ 28 : struct fd_sspeer { 29 : fd_ip4_port_t addr; /* address of the peer */ 30 : ulong full_slot; 31 : ulong incr_slot; 32 : ulong score; /* selector score of peer */ 33 : uchar full_hash[ FD_HASH_FOOTPRINT ]; 34 : uchar incr_hash[ FD_HASH_FOOTPRINT ]; 35 : }; 36 : 37 : typedef struct fd_sspeer fd_sspeer_t; 38 : 39 : struct fd_sspeer_selector_private; 40 : typedef struct fd_sspeer_selector_private fd_sspeer_selector_t; 41 : 42 : FD_PROTOTYPES_BEGIN 43 : 44 : FD_FN_CONST ulong 45 : fd_sspeer_selector_align( void ); 46 : 47 : FD_FN_CONST ulong 48 : fd_sspeer_selector_footprint( ulong max_peers ); 49 : 50 : void * 51 : fd_sspeer_selector_new( void * shmem, 52 : ulong max_peers, 53 : int incremental_snapshot_fetch, 54 : ulong seed ); 55 : 56 : fd_sspeer_selector_t * 57 : fd_sspeer_selector_join( void * shselector ); 58 : 59 : void * 60 : fd_sspeer_selector_leave( fd_sspeer_selector_t * selector ); 61 : 62 : void * 63 : fd_sspeer_selector_delete( void * shselector ); 64 : 65 : /* Update the selector when an http server is resolved. The peer is 66 : identified by key. The values that can be updated are slot and 67 : hash, for both full and incremental snapshots. On success it 68 : returns 0, -1 if key==NULL, and -2 if the key was not found. */ 69 : int 70 : fd_sspeer_selector_update_on_resolve( fd_sspeer_selector_t * selector, 71 : fd_sspeer_key_t const * key, 72 : ulong full_slot, 73 : ulong incr_slot, 74 : uchar const full_hash[ FD_HASH_FOOTPRINT ], 75 : uchar const incr_hash[ FD_HASH_FOOTPRINT ] ); 76 : 77 : /* Update the selector when a ping response is received. The only 78 : value that can be updated is the latency. If multiple peers 79 : advertise the same address, the update is applied to all of them, 80 : since ssping cannot distinguish between these peers. It returns 81 : the number of peers that have been updated. */ 82 : ulong 83 : fd_sspeer_selector_update_on_ping( fd_sspeer_selector_t * selector, 84 : fd_ip4_port_t addr, 85 : ulong latency ); 86 : 87 : /* Add a peer to the selector. If the peer already exists, 88 : fd_sspeer_selector_add updates the existing peer's score using the 89 : given peer latency and snapshot info. Returns the updated score. */ 90 : ulong 91 : fd_sspeer_selector_add( fd_sspeer_selector_t * selector, 92 : fd_sspeer_key_t const * key, 93 : fd_ip4_port_t addr, 94 : ulong peer_latency, 95 : ulong full_slot, 96 : ulong incr_slot, 97 : uchar const full_hash[ FD_HASH_FOOTPRINT ], 98 : uchar const incr_hash[ FD_HASH_FOOTPRINT ] ); 99 : 100 : /* Remove a peer from the selector. Peers are removed when they are 101 : not reachable or serving corrupted/malformed snapshots. This is a 102 : no-op if the peer does not exist in the selector. When removing by 103 : address, all peers advertising that address will be removed. */ 104 : void 105 : fd_sspeer_selector_remove( fd_sspeer_selector_t * selector, 106 : fd_sspeer_key_t const * key ); 107 : 108 : void 109 : fd_sspeer_selector_remove_by_addr( fd_sspeer_selector_t * selector, 110 : fd_ip4_port_t addr ); 111 : 112 : /* Select the best peer to download a snapshot from. incremental 113 : indicates to select a peer to download an incremental snapshot. If 114 : incremental is set, base_slot must be a valid full snapshot slot. */ 115 : fd_sspeer_t 116 : fd_sspeer_selector_best( fd_sspeer_selector_t * selector, 117 : int incremental, 118 : ulong base_slot ); 119 : 120 : /* Updates the selector's internal cluster slot and re-score all peers 121 : when the cluster slot updates (moves forward) */ 122 : void 123 : fd_sspeer_selector_process_cluster_slot( fd_sspeer_selector_t * selector, 124 : ulong full_slot, 125 : ulong incr_slot ); 126 : 127 : /* Obtain the cluster slot from the selector. It is the highest 128 : resolved full/incremental slot pair seen from snapshot hashes or 129 : from resolved http peers. */ 130 : fd_sscluster_slot_t 131 : fd_sspeer_selector_cluster_slot( fd_sspeer_selector_t * selector ); 132 : 133 : /* Helper functions to count how many elements exist in both peer maps 134 : (by_key and by_addr). Mainly used in unit tests. These are not 135 : optimized for performance. */ 136 : ulong 137 : fd_sspeer_selector_peer_map_by_key_ele_cnt( fd_sspeer_selector_t * selector ); 138 : 139 : ulong 140 : fd_sspeer_selector_peer_map_by_addr_ele_cnt( fd_sspeer_selector_t * selector ); 141 : 142 : FD_PROTOTYPES_END 143 : 144 : #endif /* HEADER_fd_src_discof_restore_utils_fd_sspeer_selector_h */