LCOV - code coverage report
Current view: top level - flamenco/gossip - fd_gossip.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 1 0.0 %
Date: 2026-10-22 18:10:43 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_gossip_fd_gossip_h
       2             : #define HEADER_fd_src_flamenco_gossip_fd_gossip_h
       3             : 
       4             : #include "fd_gossip_message.h"
       5             : #include "fd_gossip_out.h"
       6             : #include "fd_gossip_purged.h"
       7             : #include "fd_ping_tracker.h"
       8             : #include "fd_active_set.h"
       9             : #include "../stakes/fd_stake_weight.h"
      10             : #include "../../util/rng/fd_rng.h"
      11             : #include "../../util/net/fd_net_headers.h"
      12             : 
      13             : /* The Solana gossip protocol is used so that distributed nodes can
      14             :    share key-value pairs and reach an eventually consistent consensus on
      15             :    what's in the key-value store.
      16             : 
      17             :    It is peer to peer, and proceeds with these key pieces:
      18             : 
      19             :     - To join the cluster, a node must first contact a known node
      20             :       (an entrypoint) and register itself, by sending its own contact
      21             :       information key-value pair.  Contact information is the UDP
      22             :       address and port.
      23             : 
      24             :     - The cluster will then agree on that key-value pair, and start
      25             :       broadcasting updates to the node.
      26             : 
      27             :     - Each node must periodically send new messages it has received to
      28             :       a (somewhat) random selection of peers (referred to as the active
      29             :       set).
      30             : 
      31             :     - In addition, each node can periodically send a "pull request" to
      32             :       a random selection of peers, asking them to send any messages
      33             :       they have that the node does not.  This is used to ensure that
      34             :       nodes are eventually consistent in case they miss some pushed
      35             :       messages.  Bloom filters are used to track which messages have
      36             :       been received, and to avoid sending duplicates.
      37             : 
      38             :     - Each node can also send prune messages to peers, asking them
      39             :       to stop forwarding (pushing) messages from a particular origin.
      40             :       This is used to avoid receiving too many duplicate messages from
      41             :       the same origin.
      42             : 
      43             :     - Nodes with stake are always considered part of the network, but
      44             :       low staked nodes need to maintain a connection by responding to
      45             :       ping messages.  These pings are to prevent DDoS attacks which
      46             :       reflect off gossip nodes.
      47             : 
      48             :    Other than this, everything else is implementation details.  For
      49             :    specifics on the network and wire protocol, see https://github.com/eigerco/solana-spec/blob/main/gossip-protocol-spec.md
      50             :    and for more details on the Agave implementation, see https://github.com/eigerco/solana-spec/blob/main/implementation-details.md
      51             : 
      52             :    The Solana gossip protocol is heavily based on Plum Tree, see
      53             :    https://www.dpss.inesc-id.pt/~ler/reports/srds07.pdf for details. */
      54             : 
      55             : struct fd_gossip_private;
      56             : typedef struct fd_gossip_private fd_gossip_t;
      57             : 
      58             : typedef void (*fd_gossip_send_fn)( void *                 ctx,
      59             :                                    fd_stem_context_t *    stem,
      60             :                                    uchar const *          data,
      61             :                                    ulong                  sz,
      62             :                                    fd_ip4_port_t const *  peer_address,
      63             :                                    ulong                  now );
      64             : 
      65             : typedef void (*fd_gossip_sign_fn)( void *         ctx,
      66             :                                    uchar const *  data,
      67             :                                    ulong          sz,
      68             :                                    int            sign_type );
      69             : 
      70             : /* FD_GOSSIP_SIGN_PEND_MAX is the most sign requests in flight, the
      71             :    depth of the sign links. */
      72             : 
      73           0 : #define FD_GOSSIP_SIGN_PEND_MAX (128UL)
      74             : 
      75             : struct fd_gossip_metrics {
      76             :   ulong crds_rx_count[ FD_METRICS_ENUM_GOSSIP_CRDS_RESULT_CNT ];
      77             : 
      78             :   ulong sign_pend_full_cnt;
      79             : 
      80             :   ulong message_tx[ FD_METRICS_ENUM_GOSSIP_MESSAGE_TYPE_CNT ];
      81             :   ulong message_tx_bytes[ FD_METRICS_ENUM_GOSSIP_MESSAGE_TYPE_CNT ];
      82             : 
      83             :   ulong crds_tx_pull_response[ FD_METRICS_ENUM_CRDS_VALUE_TYPE_CNT ];
      84             :   ulong crds_tx_pull_response_bytes[ FD_METRICS_ENUM_CRDS_VALUE_TYPE_CNT ];
      85             : };
      86             : 
      87             : typedef struct fd_gossip_metrics fd_gossip_metrics_t;
      88             : 
      89             : FD_PROTOTYPES_BEGIN
      90             : 
      91             : FD_FN_CONST ulong
      92             : fd_gossip_align( void );
      93             : 
      94             : FD_FN_CONST ulong
      95             : fd_gossip_footprint( ulong max_values,
      96             :                      ulong entrypoints_len );
      97             : 
      98             : void *
      99             : fd_gossip_new( void *                           shmem,
     100             :                fd_rng_t *                       rng,
     101             :                uchar const                      ping_seed[ static 32 ],
     102             :                ulong                            max_values,
     103             :                ulong                            entrypoints_len,
     104             :                fd_ip4_port_t const *            entrypoints,
     105             :                uchar const *                    identity_pubkey,
     106             :                fd_gossip_contact_info_t const * my_contact_info,
     107             :                long                             now,
     108             :                fd_gossip_send_fn                send_fn,
     109             :                void *                           send_ctx,
     110             :                fd_gossip_sign_fn                sign_fn,
     111             :                void *                           sign_ctx,
     112             :                fd_ping_tracker_change_fn        ping_tracker_change_fn,
     113             :                void *                           ping_tracker_change_fn_ctx,
     114             :                fd_gossip_activity_update_fn     activity_update_fn,
     115             :                void *                           activity_update_fn_ctx,
     116             :                fd_gossip_out_ctx_t *            gossip_update_out,
     117             :                fd_gossip_out_ctx_t *            gossip_net_out );
     118             : 
     119             : fd_gossip_t *
     120             : fd_gossip_join( void * shgossip );
     121             : 
     122             : fd_gossip_metrics_t const *
     123             : fd_gossip_metrics( fd_gossip_t const * gossip );
     124             : 
     125             : fd_crds_metrics_t const *
     126             : fd_gossip_crds_metrics( fd_gossip_t const * gossip );
     127             : 
     128             : fd_ping_tracker_metrics_t const *
     129             : fd_gossip_ping_tracker_metrics( fd_gossip_t const * gossip );
     130             : 
     131             : fd_gossip_purged_metrics_t const *
     132             : fd_gossip_purged_metrics2( fd_gossip_t const * gossip );
     133             : 
     134             : fd_active_set_metrics_t const *
     135             : fd_gossip_active_set_metrics2( fd_gossip_t const * gossip );
     136             : 
     137             : void
     138             : fd_gossip_set_identity( fd_gossip_t * gossip,
     139             :                         uchar const * identity_pubkey,
     140             :                         long          now,
     141             :                         ulong         identity_outset );
     142             : 
     143             : void
     144             : fd_gossip_set_shred_version( fd_gossip_t * gossip,
     145             :                              ushort        shred_version );
     146             : 
     147             : void
     148             : fd_gossip_stakes_update( fd_gossip_t *             gossip,
     149             :                          fd_stake_weight_t const * stake_weights,
     150             :                          ulong                     stake_weights_cnt );
     151             : 
     152             : /* fd_gossip_advance advances the gossip protocol to the provided time,
     153             :    performing any necessary updates and actions along the way.  The
     154             :    actions performed include,
     155             : 
     156             :    Advancing gossip forward will cause a variety of things to happen,
     157             : 
     158             :     - Pings will be sent to any peer nodes that are not validated, or
     159             :       need their token refreshed.
     160             : 
     161             :     - Old entries in the CRDS will be expired.
     162             : 
     163             :     - Partially constructed push messages may need to be periodically
     164             :       flushed.
     165             : 
     166             :     - A new pull request will be periodically sent out to a random peer,
     167             :       to request any messages we might be missing.
     168             : 
     169             :     - Contact info messages will be periodically sent out to a random
     170             :       selection of peers, to inform them of our current contact info.
     171             : 
     172             :     - The active set of peers that we are pushing to will be
     173             :       periodically rotated, with one new peer entering and one old peer
     174             :       leaving, based on stake weights.
     175             : 
     176             : 
     177             :    Only actions which are necessary and useful will be performed, and
     178             :    the function is idempotent and fast otherwise.  advance should be
     179             :    called as often as possible. */
     180             : 
     181             : void
     182             : fd_gossip_advance( fd_gossip_t *       gossip,
     183             :                    long                now,
     184             :                    fd_stem_context_t * stem,
     185             :                    int *               charge_busy );
     186             : 
     187             : long
     188             : fd_gossip_next_deadline( fd_gossip_t const * gossip );
     189             : 
     190             : /* fd_gossip_rx handles an incoming packet received on the gossip socket
     191             :    from the network.  It is expected that the packet is a UDP packet but
     192             :    otherwise no assumptions are made about the contents of the packet,
     193             :    in particular it might be malformed, corrupted, malicious, and so on.
     194             : 
     195             :    now is the current time in nanoseconds, and is used to determine
     196             :    whether the packet is stale or not, and to update the internal state
     197             :    of the gossip protocol.
     198             : 
     199             :    Receiving a packet might cause response packets to need to be sent
     200             :    back to the gossip network.  The response packets are queued for
     201             :    later sending.  The caller is responsible for sending the response
     202             :    packets by calling fd_gossip_tx(). */
     203             : 
     204             : void
     205             : fd_gossip_rx( fd_gossip_t *       gossip,
     206             :               fd_ip4_port_t       peer,
     207             :               uchar const *       data,
     208             :               ulong               data_sz,
     209             :               long                now,
     210             :               fd_stem_context_t * stem );
     211             : 
     212             : /* fd_gossip_sign_response delivers the signature of the oldest sign
     213             :    request still in flight and completes the message it was for */
     214             : 
     215             : void
     216             : fd_gossip_sign_response( fd_gossip_t *       gossip,
     217             :                          uchar const *       signature,
     218             :                          fd_stem_context_t * stem,
     219             :                          long                now );
     220             : 
     221             : ulong
     222             : fd_gossip_sign_pend_cnt( fd_gossip_t const * gossip );
     223             : 
     224             : /* fd_gossip_ping_tracker_track marks a peer for ping tracking.  The
     225             :    gossip implementation internally keeps track of peers that are
     226             :    sending us contact info messages, but certain messages are already
     227             :    filtered out by the gossvf layer.  If gossvf is filtering out
     228             :    messages because it believes the peer is not active, it will still
     229             :    ask the gossip layer to attempt to ping them, which it notifies with
     230             :    this function. */
     231             : 
     232             : void
     233             : fd_gossip_ping_tracker_track( fd_gossip_t * gossip,
     234             :                               uchar const * peer_pubkey,
     235             :                               fd_ip4_port_t peer_address,
     236             :                               long          now );
     237             : 
     238             : int
     239             : fd_gossip_push_vote( fd_gossip_t * gossip,
     240             :                      uchar const * txn,
     241             :                      ulong         txn_sz,
     242             :                      long          now );
     243             : 
     244             : int
     245             : fd_gossip_push_duplicate_shred( fd_gossip_t *                       gossip,
     246             :                                 fd_gossip_duplicate_shred_t const * duplicate_shred,
     247             :                                 long                                now );
     248             : 
     249             : FD_PROTOTYPES_END
     250             : 
     251             : #endif /* HEADER_fd_src_flamenco_gossip_fd_gossip_h */

Generated by: LCOV version 1.14