LCOV - code coverage report
Current view: top level - disco/repair - fd_rserve.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 17 0.0 %
Date: 2026-11-12 04:25:03 Functions: 0 8 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_disco_repair_fd_rserve_h
       2             : #define HEADER_fd_src_disco_repair_fd_rserve_h
       3             : 
       4             : #include "../../flamenco/fd_flamenco_base.h"
       5             : #include "../shred/fd_fec_set.h"
       6             : #include "../../ballet/bmtree/fd_bmtree.h"
       7             : 
       8             : /* Repair server. */
       9             : 
      10             : /* TODO: We want to consider not using a ping-cache, and instead rely on
      11             :    the existing set of "good" nodes we'd need to know about from Gossip.
      12             :    A ping-cache is a simple solution for the time being. */
      13             : 
      14             : /* Ping cache TTL in nanoseconds (1280 seconds). */
      15             : #define FD_RSERVE_PING_CACHE_TTL_NS (1280UL * 1000000000UL)
      16             : /* Token rotation period in nanoseconds (640 seconds, half of TTL). */
      17             : #define FD_RSERVE_TOKEN_ROTATE_NS   (640UL * 1000000000UL)
      18             : 
      19             : 
      20             : struct __attribute__((packed)) ping_cache_key {
      21             :   fd_pubkey_t pubkey; /* pubkey of the node which sent the ping */
      22             :   uint        ip4;    /* source ipv4 address of the pong */
      23             :   ushort      port;   /* source udp port of the pong */
      24             : };
      25             : typedef struct ping_cache_key ping_cache_key_t;
      26             : 
      27             : typedef struct {
      28             :   ping_cache_key_t key;  /* (pubkey, address) that completed a ping */
      29             :   ulong       next;      /* Pool free-list next. */
      30             :   struct {
      31             :     ulong prev;
      32             :     ulong next;
      33             :   } map;                 /* fd_map_chain prev/next. */
      34             :   struct {
      35             :     ulong prev;
      36             :     ulong next;
      37             :   } dlist;               /* LRU dlist prev/next. */
      38             :   ulong       timestamp; /* The time at which the pong was received. Stored in nanoseconds. */
      39             : } ping_cache_entry_t;
      40             : 
      41             : #define POOL_NAME  ping_pool
      42           0 : #define POOL_T     ping_cache_entry_t
      43             : #include "../../util/tmpl/fd_pool.c"
      44             : 
      45             : #define MAP_NAME                           ping_map
      46           0 : #define MAP_ELE_T                          ping_cache_entry_t
      47             : #define MAP_KEY_T                          ping_cache_key_t
      48           0 : #define MAP_KEY                            key
      49           0 : #define MAP_PREV                           map.prev
      50           0 : #define MAP_NEXT                           map.next
      51           0 : #define MAP_KEY_EQ(k0,k1)                  (!memcmp((k0),(k1),sizeof(ping_cache_key_t)))
      52           0 : #define MAP_KEY_HASH(key,seed)             fd_ulong_hash( fd_hash( (seed), key->pubkey.uc, sizeof(fd_pubkey_t) ) ^ ((ulong)(key)->ip4) ^ (((ulong)(key)->port)<<32) ^ (seed) )
      53             : #define MAP_OPTIMIZE_RANDOM_ACCESS_REMOVAL 1
      54             : #include "../../util/tmpl/fd_map_chain.c"
      55             : 
      56             : #define DLIST_NAME  ping_dlist
      57             : #define DLIST_ELE_T ping_cache_entry_t
      58           0 : #define DLIST_PREV  dlist.prev
      59           0 : #define DLIST_NEXT  dlist.next
      60             : #include "../../util/tmpl/fd_dlist.c"
      61             : 
      62             : typedef struct {
      63             :   ping_cache_entry_t * ping_pool;
      64             :   ping_map_t         * ping_map;
      65             :   ping_dlist_t       * ping_dlist;
      66             : 
      67             :   uchar secret_master[ 32 ];
      68             :   uchar secret_cur   [ 32 ];
      69             :   uchar secret_prev  [ 32 ];
      70             :   ulong token_idx;
      71             :   ulong last_rotate_ts;
      72             : 
      73             :   ulong seed;
      74             : } fd_rserve_t;
      75             : 
      76             : FD_FN_CONST static inline ulong
      77           0 : fd_rserve_align( void ) {
      78           0 :   return 128UL;
      79           0 : }
      80             : 
      81             : ulong
      82             : fd_rserve_footprint( ulong ping_cache_entries );
      83             : 
      84             : void *
      85             : fd_rserve_new( void      * shmem,
      86             :                ulong       ping_cache_entries,
      87             :                ulong       seed,
      88             :                uchar const secret[ 32 ] );
      89             : 
      90             : fd_rserve_t *
      91             : fd_rserve_join( void * shrserve );
      92             : 
      93             : void *
      94             : fd_rserve_leave( fd_rserve_t const * rserve );
      95             : 
      96             : void *
      97             : fd_rserve_delete( void * rserve );
      98             : 
      99             : void
     100             : fd_rserve_ping_token( fd_rserve_t const * rserve,
     101             :                       uchar               token[ 32 ],
     102             :                       fd_pubkey_t const * from,
     103             :                       uint                ip4,
     104             :                       ushort              port );
     105             : 
     106             : int
     107             : fd_rserve_pong_token_verify( fd_rserve_t const * rserve,
     108             :                              uchar const       * pong_hash,
     109             :                              fd_pubkey_t const * from,
     110             :                              uint                ip4,
     111             :                              ushort              port );
     112             : 
     113             : void
     114             : fd_rserve_maybe_rotate( fd_rserve_t * rserve,
     115             :                         ulong         now_ns );
     116             : 
     117             : /* fd_blockdb stores metadata of completed blocks, keyed by
     118             :    (slot, block_id), for serving Alpenglow block id repair requests.
     119             :    Entries live in a fixed array and are overwritten oldest-first. */
     120             : 
     121           0 : #define FD_BLOCKDB_ALIGN (128UL)
     122             : 
     123             : /* The double-merkle tree has at most FD_FEC_BLK_MAX+1 leaves (FEC roots
     124             :    plus the parent-info leaf), so at most 11 layers and 10 proof nodes. */
     125             : 
     126           0 : #define FD_BLOCKDB_TREE_LAYER_MAX (11UL)
     127             : #define FD_BLOCKDB_PROOF_NODE_MAX (FD_BLOCKDB_TREE_LAYER_MAX-1UL)
     128             : 
     129             : struct fd_blockdb_key {
     130             :   ulong     slot;
     131             :   fd_hash_t block_id;
     132             : };
     133             : typedef struct fd_blockdb_key fd_blockdb_key_t;
     134             : 
     135             : FD_STATIC_ASSERT( sizeof(fd_blockdb_key_t)==40UL, fd_blockdb_key_t );
     136             : 
     137             : /* merkle_roots holds the first FD_SHRED_MERKLE_NODE_SZ bytes of each FEC
     138             :    set's merkle root, the only bytes the block id commits to.  Only the
     139             :    first fec_set_cnt entries are meaningful. */
     140             : 
     141             : struct fd_blockdb_blk {
     142             :   fd_blockdb_key_t key;
     143             :   ulong            parent_slot;
     144             :   fd_hash_t        parent_block_id;
     145             :   uint             fec_set_cnt;
     146             :   uint             next; /* map chain */
     147             :   uint             prev; /* map chain */
     148             :   uchar            merkle_roots[ FD_FEC_BLK_MAX ][ FD_SHRED_MERKLE_NODE_SZ ];
     149             : };
     150             : typedef struct fd_blockdb_blk fd_blockdb_blk_t;
     151             : 
     152             : struct fd_blockdb {
     153             :   ulong              ele_max;
     154             :   ulong              seq;     /* total inserts, next slot is seq%ele_max */
     155             :   fd_blockdb_blk_t * ele;
     156             :   void *             map;
     157             :   void *             tree;    /* scratch for building proofs */
     158             : };
     159             : typedef struct fd_blockdb fd_blockdb_t;
     160             : 
     161             : FD_PROTOTYPES_BEGIN
     162             : 
     163             : FD_FN_CONST static inline ulong
     164           0 : fd_blockdb_align( void ) {
     165           0 :   return FD_BLOCKDB_ALIGN;
     166           0 : }
     167             : 
     168             : /* fd_blockdb_footprint returns the footprint for ele_max entries, or 0
     169             :    if ele_max is zero or not less than UINT_MAX. */
     170             : 
     171             : ulong
     172             : fd_blockdb_footprint( ulong ele_max );
     173             : 
     174             : void *
     175             : fd_blockdb_new( void * shmem,
     176             :                 ulong  ele_max,
     177             :                 ulong  seed );
     178             : 
     179             : fd_blockdb_t *
     180             : fd_blockdb_join( void * shblockdb );
     181             : 
     182             : void *
     183             : fd_blockdb_leave( fd_blockdb_t const * blockdb );
     184             : 
     185             : void *
     186             : fd_blockdb_delete( void * shblockdb );
     187             : 
     188             : /* fd_blockdb_insert stores a block, overwriting the oldest entry when
     189             :    full.  Re-inserting an existing key updates it in place.
     190             :    merkle_roots points to fec_set_cnt 20B roots.  Returns NULL if
     191             :    fec_set_cnt is 0 or exceeds FD_FEC_BLK_MAX. */
     192             : 
     193             : fd_blockdb_blk_t *
     194             : fd_blockdb_insert( fd_blockdb_t *    blockdb,
     195             :                    ulong             slot,
     196             :                    fd_hash_t const * block_id,
     197             :                    ulong             parent_slot,
     198             :                    fd_hash_t const * parent_block_id,
     199             :                    uint              fec_set_cnt,
     200             :                    uchar const *     merkle_roots );
     201             : 
     202             : /* fd_blockdb_query returns the entry for (slot, block_id), or NULL.
     203             :    The pointer is invalidated by the next insert. */
     204             : 
     205             : fd_blockdb_blk_t const *
     206             : fd_blockdb_query( fd_blockdb_t const * blockdb,
     207             :                   ulong                slot,
     208             :                   fd_hash_t const *    block_id );
     209             : 
     210             : /* fd_blockdb_proof writes blk's double-merkle inclusion proof for leaf
     211             :    leaf_idx to proof, as 20B nodes from leaf to root.  Leaves are the FEC
     212             :    roots, then the parent-info leaf at fec_set_cnt.  Returns the node
     213             :    count, or -1 if leaf_idx>fec_set_cnt. */
     214             : 
     215             : int
     216             : fd_blockdb_proof( fd_blockdb_t *           blockdb,
     217             :                   fd_blockdb_blk_t const * blk,
     218             :                   ulong                    leaf_idx,
     219             :                   uchar                    proof[ FD_BLOCKDB_PROOF_NODE_MAX*FD_SHRED_MERKLE_NODE_SZ ] );
     220             : 
     221             : FD_PROTOTYPES_END
     222             : 
     223             : #endif /* HEADER_fd_src_disco_repair_fd_rserve_h */

Generated by: LCOV version 1.14