Skip to content

Latest commit

 

History

History

gossip

Gossip

Solana's gossip protocol allows validators to share information about the state of the network.

The main code is located in /src/gossip/.

For an introduction to Solana's gossip protocol, check out the technical sections of our Sig announcement blog post.

Checkout the full engineering blog post here: https://blog.syndica.io/sig-engineering-1-gossip-protocol/.

The main struct files include:

  • service.zig: reading, processing, and sending gossip messages
  • table.zig: where gossip data is stored
  • data.zig: various gossip data definitions
  • pull_request.zig: logic for sending pull requests
  • pull_response.zig: logic for sending pull responses (/handling incoming pull requests)
  • gossip_shards.zig: datastructure which stores gossip data hashes for quick lookup (used in gossip_table and constructing pull responses)
  • active_set.zig: logic for deriving a list of peers to send push messages to
  • ping_pong.zig: logic for sending ping/pong messages as a heartbeat check

Other files include:

  • fuzz_service.zig: a fuzzing client for testing the gossip service
  • fuzz_table.zig: a fuzzing client for testing the gossip table

Usage

Simple usage of the gossip service is as follows:

const service = try GossipService.create(
    // general allocator
    std.heap.page_allocator,
    // allocator specifically for gossip values
    std.heap.page_allocator,
    // information about the current node to share with the network (via gossip)
    contact_info,
    // keypair for signing messages
    my_keypair,
    // entrypoints to discover peers
    entrypoints,
    // logger
    logger,
);

// start the gossip service (ie, spin up the threads
// to process and generate messages)
try service.start(.{
    .spy_node = false,
    .dump = false,
});

Note: a spy_node is a node that listens to gossip messages but does not send any. This is useful for debugging and monitoring the network.

Note: dump is a flag to print out the gossip table to a file every 10 seconds (see dump_service.zig for more).

Note: for an easy to use example, see initGossipFromCluster in helpers.zig.

Benchmarks

Benchmarks are located at the bottom of service.zig:

  • BenchmarkGossipServiceGeneral: benchmarks ping, push, and pull response messages
  • BenchmarkGossipServicePullRequest: benchmarks pull request messages (which require a bit more work to construct)

You can run both benchmarks using: ./zig-out/bin/benchmark gossip.

Fuzzing

We support two fuzzing options:

  • fuzz_service.zig: fuzzing the gossip service
  • fuzz_table.zig: afuzzing the gossip table

Fuzzing the Service

zig build -Dno-run fuzz

fuzz gossip_service <seed> <number_of_actions>

Fuzzing the Table

zig build -Dno-run fuzz

fuzz gossip_table <seed> <number_of_actions>

Architecture

Gossip Service

The gossip service runs three main threads:

  • verify packet
  • process messages
  • build messages

and two auxillary threads for reading and writing to the gossip socket.

Gossip Service Diagram

Verify Messages

The verify messages thread verifies all incoming packets and forwards valid gossip messages to the process messages thread.

Gossip Service Diagram

Process Messages

The process messages thread handles all verified incoming gossip messages.

Process Messages Diagram

Handle Ping Messages

Handle Ping Messages Diagram

Handle Pong Messages

Handle Pong Messages Diagram

Handle Pull Requests

Handle Pull Requests Diagram

Handle Pull Responses

Handle Pull Responses Diagram

Handle Push Messages

Handle Push Messages Diagram

Handle Prune Messages

Handle Prune Messages Diagram

Build Messages

The build messages thread uses the internal gossip service state to achieve two primary objectives:

  • build pull requests to obtain missing data from peers
  • build push messages to inform peers of our current state

Build Messages Diagram

Build Pull Requests

Build Pull Requests

Build Push Messages

Build Push Messages