LCOV - code coverage report
Current view: top level - flamenco/repair - fd_repair.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 66 0.0 %
Date: 2025-07-01 05:00:49 Functions: 0 1008 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_repair_fd_repair_h
       2             : #define HEADER_fd_src_flamenco_repair_fd_repair_h
       3             : 
       4             : #include "../gossip/fd_gossip.h"
       5             : #include "../../ballet/shred/fd_shred.h"
       6             : #include "../../disco/metrics/generated/fd_metrics_repair.h"
       7             : 
       8             : 
       9             : #define FD_REPAIR_DELIVER_FAIL_TIMEOUT -1
      10             : #define FD_REPAIR_DELIVER_FAIL_REQ_LIMIT_EXCEEDED -2
      11             : 
      12             : /* Maximum size of a network packet */
      13           0 : #define FD_REPAIR_MAX_PACKET_SIZE 1232
      14             : 
      15             : /* Scratch space is used by the repair library to allocate an
      16             :    active element table and to shuffle that table.
      17             :    TODO: update comment to reflect the reasoning behind
      18             :    these constants once they are fully understood and updated. */
      19           0 : #define FD_REPAIR_SCRATCH_MAX    (1UL << 30UL)
      20           0 : #define FD_REPAIR_SCRATCH_DEPTH  (1UL << 11UL)
      21             : 
      22             : /* Max number of validators that can be actively queried */
      23           0 : #define FD_ACTIVE_KEY_MAX (1<<12)
      24             : /* Max number of pending shred requests */
      25           0 : #define FD_NEEDED_KEY_MAX (1<<20)
      26             : /* Max number of sticky repair peers */
      27             : #define FD_REPAIR_STICKY_MAX   1024
      28             : /* Max number of validator identities in stake weights */
      29           0 : #define FD_STAKE_WEIGHTS_MAX (1<<14)
      30             : /* Max number of validator clients that we ping */
      31           0 : #define FD_REPAIR_PINGED_MAX (1<<14)
      32             : /* Sha256 pre-image size for pings */
      33           0 : #define FD_PING_PRE_IMAGE_SZ (48UL)
      34             : /* Number of peers to send requests to. */
      35           0 : #define FD_REPAIR_NUM_NEEDED_PEERS (2)
      36             : 
      37             : typedef fd_gossip_peer_addr_t fd_repair_peer_addr_t;
      38             : 
      39             : /* Hash a hash value */
      40             : FD_FN_PURE static inline
      41           0 : ulong fd_hash_hash( const fd_hash_t * key, ulong seed ) {
      42           0 :   return key->ul[0] ^ seed;
      43           0 : }
      44             : 
      45             : 
      46             : /* Test if two addresses are equal */
      47             : FD_FN_PURE static inline int
      48           0 : fd_repair_peer_addr_eq( const fd_repair_peer_addr_t * key1, const fd_repair_peer_addr_t * key2 ) {
      49           0 :   FD_STATIC_ASSERT(sizeof(fd_repair_peer_addr_t) == sizeof(ulong),"messed up size");
      50           0 :   return key1->l == key2->l;
      51           0 : }
      52             : 
      53             : /* Hash an address */
      54             : FD_FN_PURE static inline ulong
      55           0 : fd_repair_peer_addr_hash( const fd_repair_peer_addr_t * key, ulong seed ) {
      56           0 :   FD_STATIC_ASSERT(sizeof(fd_repair_peer_addr_t) == sizeof(ulong),"messed up size");
      57           0 :   return (key->l + seed + 7242237688154252699UL)*9540121337UL;
      58           0 : }
      59             : 
      60             : /* Efficiently copy an address */
      61             : static inline void
      62           0 : fd_repair_peer_addr_copy( fd_repair_peer_addr_t * keyd, const fd_repair_peer_addr_t * keys ) {
      63           0 :   FD_STATIC_ASSERT(sizeof(fd_repair_peer_addr_t) == sizeof(ulong),"messed up size");
      64           0 :   keyd->l = keys->l;
      65           0 : }
      66             : 
      67             : typedef uint fd_repair_nonce_t;
      68             : 
      69             : /* Active table element. This table is all validators that we are
      70             :    asking for repairs. */
      71             : struct fd_active_elem {
      72             :     fd_pubkey_t key;  /* Public identifier and map key */
      73             :     ulong next; /* used internally by fd_map_giant */
      74             : 
      75             :     fd_repair_peer_addr_t addr;
      76             :     // Might be worth keeping these fields, but currently response rate is pretty high.
      77             :     // latency could be a useful metric to keep track of.
      78             :     ulong avg_reqs; /* Moving average of the number of requests */
      79             :     ulong avg_reps; /* Moving average of the number of requests */
      80             :     long  avg_lat;  /* Moving average of response latency */
      81             :     ulong stake;
      82             : };
      83             : /* Active table */
      84             : typedef struct fd_active_elem fd_active_elem_t;
      85             : #define MAP_NAME     fd_active_table
      86             : #define MAP_KEY_T    fd_pubkey_t
      87           0 : #define MAP_KEY_EQ(a,b) (0==memcmp( (a),(b),sizeof(fd_pubkey_t) ))
      88           0 : #define MAP_KEY_HASH fd_hash_hash
      89           0 : #define MAP_T        fd_active_elem_t
      90             : #include "../../util/tmpl/fd_map_giant.c"
      91             : 
      92             : enum fd_needed_elem_type {
      93             :   fd_needed_window_index, fd_needed_highest_window_index, fd_needed_orphan
      94             : };
      95             : 
      96             : struct fd_inflight_key {
      97             :   enum fd_needed_elem_type type;
      98             :   ulong slot;
      99             :   uint shred_index;
     100             : };
     101             : typedef struct fd_inflight_key fd_inflight_key_t;
     102             : 
     103             : struct fd_inflight_elem {
     104             :   fd_inflight_key_t key;
     105             :   long               last_send_time;
     106             :   uint               req_cnt;
     107             :   ulong              next;
     108             : };
     109             : typedef struct fd_inflight_elem fd_inflight_elem_t;
     110             : 
     111             : FD_FN_PURE static inline int
     112           0 : fd_inflight_eq( const fd_inflight_key_t * key1, const fd_inflight_key_t * key2 ) {
     113           0 :   return (key1->type == key2->type) &&
     114           0 :          (key1->slot == key2->slot) &&
     115           0 :          (key1->shred_index == key2->shred_index);
     116           0 : }
     117             : 
     118             : FD_FN_PURE static inline ulong
     119           0 : fd_inflight_hash( const fd_inflight_key_t * key, ulong seed ) {
     120           0 :   return (key->slot + seed)*9540121337UL + key->shred_index*131U;
     121           0 : }
     122             : 
     123             : static inline void
     124           0 : fd_inflight_copy( fd_inflight_key_t * keyd, const fd_inflight_key_t * keys ) {
     125           0 :   *keyd = *keys;
     126           0 : }
     127             : 
     128             : #define MAP_NAME     fd_inflight_table
     129             : #define MAP_KEY_T    fd_inflight_key_t
     130           0 : #define MAP_KEY_EQ   fd_inflight_eq
     131           0 : #define MAP_KEY_HASH fd_inflight_hash
     132           0 : #define MAP_KEY_COPY fd_inflight_copy
     133           0 : #define MAP_T        fd_inflight_elem_t
     134             : #include "../../util/tmpl/fd_map_giant.c"
     135             : 
     136             : FD_FN_PURE static inline int
     137           0 : fd_repair_nonce_eq( const fd_repair_nonce_t * key1, const fd_repair_nonce_t * key2 ) {
     138           0 :   return *key1 == *key2;
     139           0 : }
     140             : 
     141             : FD_FN_PURE static inline ulong
     142           0 : fd_repair_nonce_hash( const fd_repair_nonce_t * key, ulong seed ) {
     143           0 :   return (*key + seed + 7242237688154252699UL)*9540121337UL;
     144           0 : }
     145             : 
     146             : static inline void
     147           0 : fd_repair_nonce_copy( fd_repair_nonce_t * keyd, const fd_repair_nonce_t * keys ) {
     148           0 :   *keyd = *keys;
     149           0 : }
     150             : 
     151             : struct fd_pinged_elem {
     152             :   fd_repair_peer_addr_t key;
     153             :   ulong next;
     154             :   fd_pubkey_t id;
     155             :   fd_hash_t token;
     156             :   int good;
     157             : };
     158             : typedef struct fd_pinged_elem fd_pinged_elem_t;
     159             : #define MAP_NAME     fd_pinged_table
     160             : #define MAP_KEY_T    fd_repair_peer_addr_t
     161           0 : #define MAP_KEY_EQ   fd_repair_peer_addr_eq
     162           0 : #define MAP_KEY_HASH fd_repair_peer_addr_hash
     163           0 : #define MAP_KEY_COPY fd_repair_peer_addr_copy
     164           0 : #define MAP_T        fd_pinged_elem_t
     165             : #include "../../util/tmpl/fd_map_giant.c"
     166             : 
     167             : struct fd_peer {
     168             :   fd_pubkey_t   key;
     169             :   fd_ip4_port_t ip4;
     170             : };
     171             : typedef struct fd_peer fd_peer_t;
     172             : /* Repair Metrics */
     173             : struct fd_repair_metrics {
     174             :   ulong recv_clnt_pkt;
     175             :   ulong recv_serv_pkt;
     176             :   ulong recv_serv_corrupt_pkt;
     177             :   ulong recv_serv_invalid_signature;
     178             :   ulong recv_serv_full_ping_table;
     179             :   ulong recv_serv_pkt_types[FD_METRICS_ENUM_REPAIR_SERV_PKT_TYPES_CNT];
     180             :   ulong recv_pkt_corrupted_msg;
     181             :   ulong send_pkt_cnt;
     182             :   ulong sent_pkt_types[FD_METRICS_ENUM_REPAIR_SENT_REQUEST_TYPES_CNT];
     183             : };
     184             : typedef struct fd_repair_metrics fd_repair_metrics_t;
     185             : #define FD_REPAIR_METRICS_FOOTPRINT ( sizeof( fd_repair_metrics_t ) )
     186             : /* Global data for repair service */
     187             : struct fd_repair {
     188             :     /* Current time in nanosecs */
     189             :     long now;
     190             :     /* My public/private key */
     191             :     fd_pubkey_t * public_key;
     192             :     uchar * private_key;
     193             :     /* My repair addresses */
     194             :     fd_repair_peer_addr_t service_addr;
     195             :     fd_repair_peer_addr_t intake_addr;
     196             :     /* Function used to send raw packets on the network */
     197             :     void * fun_arg;
     198             :     /* Table of validators that we are actively pinging, keyed by repair address */
     199             :     fd_active_elem_t * actives;
     200             : 
     201             :     /* TODO remove, along with good peer cache file */
     202             :     fd_pubkey_t actives_sticky[FD_REPAIR_STICKY_MAX]; /* cache of chosen repair peer samples */
     203             :     ulong       actives_sticky_cnt;
     204             :     ulong       actives_random_seed;
     205             : 
     206             :     fd_peer_t peers[ FD_ACTIVE_KEY_MAX ];
     207             :     ulong     peer_cnt; /* number of peers in the peers array */
     208             :     ulong     peer_idx; /* max number of peers in the peers array */
     209             : 
     210             :     /* Duplicate request detection table */
     211             :     fd_inflight_elem_t * dupdetect;
     212             : 
     213             :     /* Table of needed shreds */
     214             :     fd_repair_nonce_t oldest_nonce;
     215             :     fd_repair_nonce_t current_nonce;
     216             :     fd_repair_nonce_t next_nonce;
     217             :     /* Table of validator clients that we have pinged */
     218             :     fd_pinged_elem_t * pinged;
     219             :     /* Last batch of sends */
     220             :     long last_sends;
     221             :     /* Last statistics decay */
     222             :     long last_decay;
     223             :     /* Last statistics printout */
     224             :     long last_print;
     225             :     /* Last write to good peer cache file */
     226             :     long last_good_peer_cache_file_write;
     227             :     /* Random number generator */
     228             :     fd_rng_t rng[1];
     229             :     /* RNG seed */
     230             :     ulong seed;
     231             :     /* Stake weights */
     232             :     ulong stake_weights_cnt;
     233             :     fd_stake_weight_t * stake_weights;
     234             :     ulong stake_weights_temp_cnt;
     235             :     fd_stake_weight_t * stake_weights_temp;
     236             :     /* Path to the file where we write the cache of known good repair peers, to make cold booting faster */
     237             :     int good_peer_cache_file_fd;
     238             :     /* Metrics */
     239             :     fd_repair_metrics_t metrics;
     240             : };
     241             : typedef struct fd_repair fd_repair_t;
     242             : 
     243             : FD_FN_CONST static inline ulong
     244           0 : fd_repair_align ( void ) { return 128UL; }
     245             : 
     246             : FD_FN_CONST static inline ulong
     247           0 : fd_repair_footprint( void ) {
     248           0 :   ulong l = FD_LAYOUT_INIT;
     249           0 :   l = FD_LAYOUT_APPEND( l, alignof(fd_repair_t), sizeof(fd_repair_t) );
     250           0 :   l = FD_LAYOUT_APPEND( l, fd_active_table_align(), fd_active_table_footprint(FD_ACTIVE_KEY_MAX) );
     251           0 :   l = FD_LAYOUT_APPEND( l, fd_inflight_table_align(), fd_inflight_table_footprint(FD_NEEDED_KEY_MAX) );
     252           0 :   l = FD_LAYOUT_APPEND( l, fd_pinged_table_align(), fd_pinged_table_footprint(FD_REPAIR_PINGED_MAX) );
     253             :   /* regular and temp stake weights */
     254           0 :   l = FD_LAYOUT_APPEND( l, alignof(fd_stake_weight_t), FD_STAKE_WEIGHTS_MAX * sizeof(fd_stake_weight_t) );
     255           0 :   l = FD_LAYOUT_APPEND( l, alignof(fd_stake_weight_t), FD_STAKE_WEIGHTS_MAX * sizeof(fd_stake_weight_t) );
     256           0 :   return FD_LAYOUT_FINI(l, fd_repair_align() );
     257           0 : }
     258             : 
     259             : /* Global state of repair protocol */
     260             : FD_FN_CONST ulong         fd_repair_align    ( void );
     261             : FD_FN_CONST ulong         fd_repair_footprint( void );
     262             :             void *        fd_repair_new      ( void * shmem, ulong seed );
     263             :             fd_repair_t * fd_repair_join     ( void * shmap );
     264             :             void *        fd_repair_leave    ( fd_repair_t * join );
     265             :             void *        fd_repair_delete   ( void * shmap );
     266             : 
     267             : struct fd_repair_config {
     268             :     fd_pubkey_t * public_key;
     269             :     uchar * private_key;
     270             :     fd_repair_peer_addr_t service_addr;
     271             :     fd_repair_peer_addr_t intake_addr;
     272             :     int good_peer_cache_file_fd;
     273             : };
     274             : typedef struct fd_repair_config fd_repair_config_t;
     275             : 
     276             : /* Initialize the repair data structure */
     277             : int fd_repair_set_config( fd_repair_t * glob, const fd_repair_config_t * config );
     278             : 
     279             : /* Update the binding addr */
     280             : int fd_repair_update_addr( fd_repair_t * glob, const fd_repair_peer_addr_t * intake_addr, const fd_repair_peer_addr_t * service_addr );
     281             : 
     282             : /* Add a peer to talk to */
     283             : int fd_repair_add_active_peer( fd_repair_t * glob, fd_repair_peer_addr_t const * addr, fd_pubkey_t const * id );
     284             : 
     285             : /* Set the current protocol time inf nanosecs. Call this as often as feasible. */
     286             : void fd_repair_settime( fd_repair_t * glob, long ts );
     287             : 
     288             : /* Get the current protocol time in nanosecs */
     289             : long fd_repair_gettime( fd_repair_t * glob );
     290             : 
     291             : /* Start timed events and other protocol behavior. settime MUST be called before this. */
     292             : int fd_repair_start( fd_repair_t * glob );
     293             : 
     294             : /* Dispatch timed events and other protocol behavior. This should be
     295             :  * called inside the main spin loop. calling settime first is recommended. */
     296             : int fd_repair_continue( fd_repair_t * glob );
     297             : 
     298             : int fd_repair_inflight_remove( fd_repair_t * glob,
     299             :                                ulong         slot,
     300             :                                uint          shred_index );
     301             : 
     302             : /* Register a request for a shred */
     303             : int fd_repair_need_window_index( fd_repair_t * glob, ulong slot, uint shred_index );
     304             : 
     305             : int fd_repair_need_highest_window_index( fd_repair_t * glob, ulong slot, uint shred_index );
     306             : 
     307             : int fd_repair_need_orphan( fd_repair_t * glob, ulong slot );
     308             : 
     309             : int
     310             : fd_repair_construct_request_protocol( fd_repair_t          * glob,
     311             :                                       fd_repair_protocol_t * protocol,
     312             :                                       enum fd_needed_elem_type type,
     313             :                                       ulong                  slot,
     314             :                                       uint                   shred_index,
     315             :                                       fd_pubkey_t const    * recipient,
     316             :                                       uint                   nonce,
     317             :                                       long                   now );
     318             : 
     319             : void fd_repair_add_sticky( fd_repair_t * glob, fd_pubkey_t const * id );
     320             : 
     321             : void fd_repair_set_stake_weights_init( fd_repair_t             * repair,
     322             :                                        fd_stake_weight_t const * stake_weights,
     323             :                                        ulong                     stake_weights_cnt );
     324             : 
     325             : void fd_repair_set_stake_weights_fini( fd_repair_t * repair );
     326             : 
     327             : fd_repair_metrics_t *
     328             : fd_repair_get_metrics( fd_repair_t * repair );
     329             : 
     330             : 
     331             : #endif /* HEADER_fd_src_flamenco_repair_fd_repair_h */

Generated by: LCOV version 1.14