LCOV - code coverage report
Current view: top level - flamenco/gossip - fd_gossip_types.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 22 0.0 %
Date: 2025-09-19 04:41:14 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_gossip_fd_gossip_types_h
       2             : #define HEADER_fd_src_flamenco_gossip_fd_gossip_types_h
       3             : 
       4             : /* The gossip tile produces an output stream of update messages as it
       5             :    runs, which are published to a link for other tiles to consume.
       6             : 
       7             :    The formt and protocol of the update messages is defined here.
       8             : 
       9             :    Messages are published one by one incrementally, as they are
      10             :    received, although expirations or removals will not be published
      11             :    except for contact information which publishes a removal stream so
      12             :    that consumers of the updates can mirror the true gossip table.
      13             : 
      14             :    Not all gossip messages are published, and some are consumed just by
      15             :    the gossip tile itself. */
      16             : 
      17             : #include "../types/fd_types_custom.h"
      18             : #include "../../util/net/fd_net_headers.h"
      19             : 
      20             : /* The tag is the kind of gossip message that is being sent.  It will be
      21             :    put both in the fragment signature, and in the message itself. */
      22             : 
      23           0 : #define FD_GOSSIP_UPDATE_TAG_CONTACT_INFO        (0)
      24           0 : #define FD_GOSSIP_UPDATE_TAG_CONTACT_INFO_REMOVE (1)
      25           0 : #define FD_GOSSIP_UPDATE_TAG_LOWEST_SLOT         (2)
      26           0 : #define FD_GOSSIP_UPDATE_TAG_VOTE                (3)
      27           0 : #define FD_GOSSIP_UPDATE_TAG_DUPLICATE_SHRED     (4)
      28           0 : #define FD_GOSSIP_UPDATE_TAG_SNAPSHOT_HASHES     (5)
      29             : 
      30             : /* The maximum number of contact infos that may be present at any one
      31             :    time.  If new contact infos are added, a removal will be issued first
      32             :    to make space.  This is a hard limit, and the consumer of the contact
      33             :    info messages can assume it is always respected.
      34             : 
      35             :    The contact info messages are designed to be consumed in an
      36             :    incremental way.  In particular, CONTACT_INFO and CONTACT_INFO_REMOVE
      37             :    messages are both sent with an idx field, which is the index of the
      38             :    contact info in an imaginary array of contact infos.  Updates will
      39             :    always have the same idx for the same pubkey, and removes will
      40             :    likewise have the same idx for the pubkey being removed.  A consumer
      41             :    of contact info updates can therefore simply maintain a local array
      42             :    of contact infos, and update it with the idx field.  */
      43             : 
      44           0 : #define FD_CONTACT_INFO_TABLE_SIZE (32768UL)
      45             : 
      46           0 : #define FD_CONTACT_INFO_SOCKET_GOSSIP            ( 0)
      47           0 : #define FD_CONTACT_INFO_SOCKET_SERVE_REPAIR_QUIC ( 1)
      48           0 : #define FD_CONTACT_INFO_SOCKET_RPC               ( 2)
      49           0 : #define FD_CONTACT_INFO_SOCKET_RPC_PUBSUB        ( 3)
      50           0 : #define FD_CONTACT_INFO_SOCKET_SERVE_REPAIR      ( 4)
      51           0 : #define FD_CONTACT_INFO_SOCKET_TPU               ( 5)
      52           0 : #define FD_CONTACT_INFO_SOCKET_TPU_FORWARDS      ( 6)
      53           0 : #define FD_CONTACT_INFO_SOCKET_TPU_FORWARDS_QUIC ( 7)
      54           0 : #define FD_CONTACT_INFO_SOCKET_TPU_QUIC          ( 8)
      55           0 : #define FD_CONTACT_INFO_SOCKET_TPU_VOTE          ( 9)
      56           0 : #define FD_CONTACT_INFO_SOCKET_TVU               (10)
      57           0 : #define FD_CONTACT_INFO_SOCKET_TVU_QUIC          (11)
      58           0 : #define FD_CONTACT_INFO_SOCKET_TPU_VOTE_QUIC     (12)
      59             : #define FD_CONTACT_INFO_SOCKET_ALPENGLOW         (13)
      60           0 : #define FD_CONTACT_INFO_SOCKET_LAST              (13)
      61             : 
      62             : /* https://github.com/anza-xyz/agave/blob/540d5bc56cd44e3cc61b179bd52e9a782a2c99e4/version/src/lib.rs#L95-L105 */
      63             : 
      64             : #define FD_CONTACT_INFO_VERSION_CLIENT_SOLANA_LABS (0)
      65             : #define FD_CONTACT_INFO_VERSION_CLIENT_JITO_LABS   (1)
      66           0 : #define FD_CONTACT_INFO_VERSION_CLIENT_FIREDANCER  (2)
      67             : #define FD_CONTACT_INFO_VERSION_CLIENT_AGAVE       (3)
      68             : 
      69             : /* A contact info represents a peer node in the cluster that is
      70             :    publishing information about itself to the gossip network.  It it
      71             :    sent when the tag is FD_GOSSIP_UPDATE_TAG_CONTACT_INFO.
      72             : 
      73             :    Contact infos are already deduplicated, so the same pubkey will not
      74             :    appear twice, and the number of contact infos outstanding is limited
      75             :    to FD_CONTACT_INFO_TABLE_SIZE.  If more contact infos are received,
      76             :    the oldest ones are first removed with a
      77             :    FD_GOSSIP_UPDATE_TAG_CONTACT_INFO_REMOVE fragment.
      78             : 
      79             :    Contact infos are regularly updated, for example if a node changes
      80             :    its IP address or port.  More typically nodes just periodically
      81             :    republish their contact info with an updated wallclock.  When an
      82             :    existing contact info is updated, a FD_GOSSIP_UPDATE_TAG_CONTACT_INFO
      83             :    fragment is sent with the same pubkey.
      84             : 
      85             :    Contact information is not well-validated by the gossip network, and
      86             :    for example the wallclock may be old, or in the future, and the
      87             :    sockets may be unroutable or invalid (a private network), and the
      88             :    version fields are completely arbitrary.
      89             : 
      90             :    However, the pubkey is authenticated, as messages are signed. */
      91             : 
      92             : struct fd_contact_info {
      93             :   fd_pubkey_t pubkey;          /* The identity public key of the peer node */
      94             :   ushort      shred_version;   /* The shred version of the peer node, should be non-zero but not required */
      95             : 
      96             :   long        instance_creation_wallclock_nanos;
      97             :   long        wallclock_nanos; /* The timestamp on the producer side of when the contact info was signed */
      98             : 
      99             :   /* Peer nodes declare a list of ip:port pairs corresponding to
     100             :      standard Solana protocols that they support.  A value of 0:0
     101             :      indicates the node does not advertise that protocol.  For example,
     102             :      sockets[ FD_CONTACT_INFO_SOCKET_RPC ] is the IP address and port
     103             :      for the RPC service of the node. */
     104             :   fd_ip4_port_t sockets[ FD_CONTACT_INFO_SOCKET_LAST+1UL ];
     105             : 
     106             :   struct {
     107             :     ushort client; /* Any ushort in [0, USHORT_MAX], although typically one of FD_CONTACT_INFO_VERSION_CLIENT_* indicating the self-reported client version */
     108             : 
     109             :     ushort major;  /* The self-reported major version of the client */
     110             :     ushort minor;  /* The self-reported minor version of the client */
     111             :     ushort patch;  /* The self-reported patch version of the client */
     112             : 
     113             :     uint   commit; /* The self-reported commit hash of the client, in little-endian order, or 0 if no commit hash was provided */
     114             :     uint   feature_set; /* The self-reported feature set of the client, in little-endian order */
     115             :   } version;
     116             : };
     117             : 
     118             : typedef struct fd_contact_info fd_contact_info_t;
     119             : 
     120             : /* A gossip vote represents a vote transaction that was sent to us by a
     121             :    peer node.  It is sent when the tag is FD_GOSSIP_UPDATE_TAG_VOTE.
     122             :    Votes are typically sent over the TPU, but also via. gossip for
     123             :    redundancy.
     124             : 
     125             :    The transaction is not validated or parsed in any way yet, and in
     126             :    particular the signatures have not been verified.   Transaction data
     127             :    is arbitrary and could be empty or corrupt or malicious. */
     128             : 
     129             : struct fd_gossip_vote {
     130             :   uchar vote_tower_index;
     131             :   ulong txn_sz;
     132             :   uchar txn[ 1232UL ];
     133             : };
     134             : 
     135             : typedef struct fd_gossip_vote fd_gossip_vote_t;
     136             : 
     137             : #define FD_GOSSIP_DUPLICATE_SHRED_MAX_CHUNKS (1054UL)
     138             : 
     139             : /* An edge case in the network is "equivocation" when a node publishes
     140             :    conflicting shred data for its leader slot.  In future this may be
     141             :    a slashable offense, but for now it simply "proven" on the chain and
     142             :    communicated among peers. */
     143             : 
     144             : struct fd_gossip_duplicate_shred {
     145             :   ushort index;
     146             :   ulong  slot;
     147             :   uchar  num_chunks;
     148             :   uchar  chunk_index;
     149             :   long   wallclock; /* in nanos */
     150             :   ulong  chunk_len;
     151             :   uchar  chunk[ FD_GOSSIP_DUPLICATE_SHRED_MAX_CHUNKS ];
     152             : };
     153             : 
     154             : typedef struct fd_gossip_duplicate_shred fd_gossip_duplicate_shred_t;
     155             : 
     156             : struct fd_gossip_snapshot_hash_pair {
     157             :   ulong slot;
     158             :   uchar hash[ 32UL ];
     159             : };
     160             : 
     161             : typedef struct fd_gossip_snapshot_hash_pair fd_gossip_snapshot_hash_pair_t;
     162             : 
     163             : #define FD_GOSSIP_SNAPSHOT_HASHES_MAX_INCREMENTAL (25UL)
     164             : 
     165             : /* Each peer node which is serving snapshots will periodically
     166             :    publish a snapshot hash update, which contains the hashes of the
     167             :    latest snapshots it has available.  This is sent when the tag is
     168             :    FD_GOSSIP_UPDATE_TAG_SNAPSHOT_HASHES.
     169             : 
     170             :    The full field indicates the full snapshot slot and hash, and then a
     171             :    list of recent incremental snapshots is provided which build on top
     172             :    of the full snapshot. */
     173             : 
     174             : struct fd_gossip_snapshot_hashes {
     175             :   fd_gossip_snapshot_hash_pair_t full[ 1 ];
     176             : 
     177             :   ulong                          incremental_len;
     178             :   fd_gossip_snapshot_hash_pair_t incremental[ FD_GOSSIP_SNAPSHOT_HASHES_MAX_INCREMENTAL ];
     179             : };
     180             : 
     181             : typedef struct fd_gossip_snapshot_hashes fd_gossip_snapshot_hashes_t;
     182             : 
     183             : struct fd_gossip_update_message {
     184             :   uchar tag;
     185             :   uchar origin_pubkey[ 32UL ];
     186             :   ulong origin_stake;
     187             :   long  wallclock_nanos;
     188             : 
     189             :   union {
     190             :     struct {
     191             :       ulong             idx; /* Index into flat array to place this contact info, see comments on FD_CONTACT_INFO_TABLE_SIZE */
     192             :       fd_contact_info_t contact_info[ 1 ];
     193             :     } contact_info;
     194             : 
     195             :     struct {
     196             :       ulong idx; /* Index into flat array of contact info to remove, see FD_CONTACT_INFO_TABLE_SIZE */
     197             :     } contact_info_remove;
     198             : 
     199             :     ulong                       lowest_slot;
     200             :     fd_gossip_vote_t            vote;
     201             :     fd_gossip_duplicate_shred_t duplicate_shred;
     202             :     fd_gossip_snapshot_hashes_t snapshot_hashes;
     203             :   };
     204             : };
     205             : 
     206             : typedef struct fd_gossip_update_message fd_gossip_update_message_t;
     207             : 
     208             : #endif /* HEADER_fd_src_flamenco_gossip_fd_gossip_types_h */

Generated by: LCOV version 1.14