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 messagestable.zig
: where gossip data is storeddata.zig
: various gossip data definitionspull_request.zig
: logic for sending pull requestspull_response.zig
: logic for sending pull responses (/handling incoming pull requests)gossip_shards.zig
: datastructure which stores gossip data hashes for quick lookup (used ingossip_table
and constructing pull responses)active_set.zig
: logic for deriving a list of peers to send push messages toping_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 servicefuzz_table.zig
: a fuzzing client for testing the gossip table
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 are located at the bottom of service.zig
:
BenchmarkGossipServiceGeneral
: benchmarks ping, push, and pull response messagesBenchmarkGossipServicePullRequest
: benchmarks pull request messages (which require a bit more work to construct)
You can run both benchmarks using: ./zig-out/bin/benchmark gossip
.
We support two fuzzing options:
fuzz_service.zig
: fuzzing the gossip servicefuzz_table.zig
: afuzzing the gossip table
zig build -Dno-run fuzz
fuzz gossip_service <seed> <number_of_actions>
zig build -Dno-run fuzz
fuzz gossip_table <seed> <number_of_actions>
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.
The verify messages thread verifies all incoming packets and forwards valid gossip messages to the process messages thread.
The process messages thread handles all verified incoming gossip 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