NETWORK FORENSICS — Solana × Alpenglow

Which Client Built Each Solana Block: Reading the Footer

6 min read
SolanaAlpenglowClientsGossip

"What share of Solana runs which client?" is a question that gets answered with a dashboard number every few months, and the number is usually a guess from gossip. That changes when Alpenglow activates, in a way the dashboards have not caught up with: under Alpenglow, every block names the software that built it, in the block itself, and stamps its own nanosecond clock next to the name. The alpenglow feature gate had not activated on mainnet as of 17 September 2026.

Combined with a field gossip has carried for years, that will make client share a per-block measurement anyone with an RPC connection can make — and it will make "did my fills follow a particular builder" a question with a data source. Here is what is in the footer, what gossip already tells you, and the honest limits of self-reported strings.


The Footer: A Client String and a Clock

An Alpenglow block carries a footer, and the validator writes two things into it.

  • A user-agent string. Agave writes agave/<version>. The field is capped at 255 bytes by a one-byte length prefix and is whatever the producing client chooses to put there. Another client writes its own name.
  • A producer timestamp in nanoseconds. The leader's own wall clock at production. It is not free-form: the runtime rejects the block if the timestamp is not strictly after the parent's and not more than two slot durations later. Within that window it is whatever the leader says.

Since Agave 4.3 a Geyser plugin can receive the footer directly, with the slot and bank it belongs to, independent of entries. So a data pipeline can attribute every block to a client without parsing anything else.

Worth knowing: the footer is an Alpenglow structure, and the alpenglow gate had not activated on mainnet as of 17 September 2026. Blocks produced under the current consensus have no per-block client string; until the gate flips, the only attribution available is the gossip field below.


Gossip Already Carries a Client ID

Every validator broadcasts a contact-info record in gossip that includes its software version and a client ID — an enumeration the reference client maintains. The current list, from the source:

Client IDs in gossipSolanaLabs · JitoLabs · Frankendancer · Agave · AgavePaladin · Firedancer · AgaveBam · Sig · Rakurai · HarmonicFiredancer · HarmonicAgave · HarmonicFrankendancer · FireBAM · Raiku

Fourteen entries, and the list reads as a map of the ecosystem: the two full clients, the hybrid, the MEV and block-engine variants of each, and the alternative clients. getClusterNodes exposes the ID as a string on any RPC, alongside the node's feature-set hash and shred version. Weighting by stake gives you client share of stake today; joining to the leader schedule gives you client share of blocks before the footer even exists.


What You Can Measure, Block by Block

Put the two sources together and three measurements fall out.

  • Client share of blocks produced. Footer string per block, or leader schedule joined to gossip client ID. The former is authoritative once live; the latter works now.
  • Clock skew per producer. The footer timestamp minus the block's derived time, per validator. A producer whose declared clock runs consistently ahead or behind is visible after a few slots.
  • Whether your outcomes correlate with a builder. If your transactions land at a different rate, or sit at a different position in the block, under one client than another, the footer is the field that lets you group by it. The block-engine variants in the list are the ones traders will want to test first.

The Limits, Which Are Real

Both fields are self-declared. Agave writes its version because that is what the code says; nothing forces any client to tell the truth, and the gossip client ID passes sanitisation without any check. A validator can call itself whatever it likes. In practice clients are honest because there is no incentive to lie and the fingerprint of their behaviour gives them away, but the data is testimony, not proof.

The nanosecond clock is bounded, not verified. Within its allowed window it is the leader's word.

And the footer only exists after Alpenglow activates, which had not happened on mainnet as of 17 September 2026. Until then, gossip client IDs joined to the leader schedule are the measurement, with the caveat that a validator can change software between gossip refresh and block production.


The Clock That Comes With It

Alpenglow also adds an on-chain nanosecond clock, at a program-derived address seeded with the word alpenclock under the Alpenglow program. It is a system-owned account holding a single signed 64-bit integer of nanoseconds, updated by consensus. Once that gate is live, programs and users have sub-second on-chain time for the first time, derived from the producer timestamps above and bounded by the same rules.

For anyone who has ever timestamped something by multiplying slots by 400 milliseconds, it is the replacement, and that arithmetic has already broken: mainnet ran 400 ms slots until 21 August 2026, runs 300 ms today, and moves to 250 ms from epoch 1037. The on-chain clock survives the slot-time reductions that break that arithmetic.


Client Attribution: Questions People Actually Ask

How can I tell which client produced a Solana block?

Under Alpenglow the block footer carries a user-agent string written by the producer, for example agave/<version>. Before that, join the leader schedule to each validator’s client ID from gossip.

What is the Alpenglow block footer?

A structure at the end of each block holding the producer’s client string, capped at 255 bytes, and its nanosecond timestamp, which must fall between the parent’s time and two slot durations later.

How do I measure Solana client diversity?

Call getClusterNodes, take each validator’s clientId, and weight by stake or by slots in the leader schedule. The list of client IDs in the reference client currently has fourteen entries.

Is the Solana client string trustworthy?

It is self-declared and unchecked, so it is testimony rather than proof. Clients have no incentive to lie and their behaviour fingerprints them, but treat the field as a label, not a verification.


How to Get a Client Census Today

Call getClusterNodes, keep clientId, pubkey and version. Fetch the current leader schedule. Join on pubkey, weight each validator by its slots in the epoch. That is client share of block production for this epoch, from one RPC, and it takes a minute.

When the footer goes live, the same join becomes a per-block fact instead of a per-epoch estimate. The consensus change that brings it is in Alpenglow Finality in Numbers, and the reward rule that decides what a producer earns for the block is in the post on vote rewards.

— The Footer Arrives With One Gate —

Per-block attribution starts the epoch Alpenglow activates.

Until then the gossip join is the measurement. The upgrades tracker reads the feature-gate accounts from the chain every minute and shows the state on each cluster, so you know which of the two methods you are on.

Open the Upgrades Tracker ↗

Fields read from the Agave validator source at commit beee69b958: core/src/block_creation_loop.rs, runtime/src/block_component_processor.rs and version/src/client_ids.rs. The client-ID enumeration grows with the ecosystem — re-read it rather than copying the list above.

xroot.devOn-chain research, published in full
𝕏 @xrootdev
← Back to all notes