This repository has one goal: connect to Solana gossip and print observed slots.
Everything else in the codebase (handshake, packet decode, CRDS handling, logging) exists only to support that slot-printing workflow.
IMPORTANT The dto/model.go and dto/model_test.go were initally writting by me, but got tired of errors in https://github.com/gagliardetto/binary lib and the lack of documentation by agave source code, that I end up using AI for it. Be ready to read a bunch of "working" code that just looks messy. Also due to this we are using a forked version of gaglardetto/binary lib which fix the bin:"optional" tag.
- Connects to Solana gossip entrypoints.
- Performs TCP IP echo handshake and starts UDP gossip flow.
- Receives gossip traffic and extracts slot-related data.
- Prints slots observed from gossip messages.
- Logs runtime and decode issues to stdout and a file via zerolog.
runtime/: executable entrypoint (main.go).services/: gossip service runtime logic, networking, CRDS state.dto/: protocol and CRDS wire model encode/decode definitions..env.example: basic environment variable template.
- Go
1.25.5(as declared ingo.mod). - You'll need to open the TPC and UDP ports you specified in
.env.
- Clone and enter the repository.
- Copy env file:
cp .env.example .env- (Optional) adjust ports and environment in
.env. - Run:
go run ./runtime/main.goOn first start, if id.json is not found, a new keypair is generated and stored locally.
Use this when you want to test slot printing without connecting to public clusters.
- Start a local validator with gossip on
127.0.0.1:8001:
RUST_LOG=solana_gossip=info ./target/release/solana-test-validator --reset --ledger /tmp/solana-test-ledger --gossip-port 8001 --rpc-port 8899 --limit-ledger-size 5NOTE: Assumes you compile solana-test-validator with cargo build --release --bin solana-test-validator, I think if you have solana-cli installed you already haave solana-test-validator, not sure tbh.
- In this repository, create/update
.envfor local mode:
UDP_PORT=9005
TCP_PORT=9005
LOG_LEVEL=info
LOG_FILE=gossip.log
# Leave ENV unset for local mode (or set to any value other than testnet/mainnet)NOTE: if you run solana-test-validator make sure these UDP/TCP ports are not already bind by solana-testnet-validator.
- Start the slot printer in a second terminal:
go run ./runtime/main.goIf everything is wired correctly, you should see the process receive gossip traffic and print observed slots.
Loaded from .env by runtime/main.go.
UDP_PORT(default8001)TCP_PORT(default8001)ENVtestnet-> testnet entrypointsmainnet-> mainnet-beta entrypoints- anything else (or unset) -> local entrypoint
127.0.0.1:8001
DISPLAY_SLOTS: set totrueto print observed slots to stdout (default: disabled)
LOG_LEVEL:trace,debug,info(default), orerrorLOG_FILE: output file path (defaultgossip.log)
Logs are written to both stdout and LOG_FILE.
UDP_PORT=9005
TCP_PORT=9005
ENV=testnet
LOG_LEVEL=info
LOG_FILE=gossip.log
DISPLAY_SLOTS=trueThis project is intentionally narrow:
- It is not a validator.
- It is not a full gossip implementation for production operations.
- It is not meant to index or persist the full CRDS state.
The target outcome is simply to observe and print slot updates from live gossip traffic.
Because slot data is extracted from gossip packets, wire compatibility still matters for decoding correctness.
The module uses:
github.com/gagliardetto/solana-go- a replaced binary package in
go.mod:github.com/gagliardetto/binary => github.com/Gealber/binary
Several CRDS payloads with vector fields use explicit marshal/unmarshal logic to match on-wire layout and avoid decode drift.
This usually indicates byte offset drift while decoding an earlier field in the same packet, not a new/unsupported CRDS variant.
What to check:
- Vector length prefixes are decoded exactly as expected by Solana wire format.
- Optional/tagged fields match Rust layout.
- Any recently changed DTO struct with slices or nested enums.
- Confirm
ENVis set correctly. - Confirm ports are open and not already in use.
- Confirm outbound access to Solana entrypoints.
- Ensure process has write permission to the directory.
- If
LOG_FILEincludes a folder, runtime will attempt to create it.
This is a narrow utility focused on printing slots from Solana gossip traffic.