Skip to content

Commit 718788c

Browse files
committed
docs(discovery): drop the speculative sections and home the metric with the rest
"If lean ever meets a real network" and the two `tcp` notes described a future whose shape is not settled: what to do about a live fork schedule, and the interop cost of publishing no `tcp` entry. Neither is something an operator reading this page acts on today, and both would need rewriting rather than updating once lean's fork story lands. `lean_discovered_peers_dialed_total` moves to `docs/metrics.md`, where every other metric is already documented in table form. It goes under the custom (non-leanMetrics) heading, since that table's Supported column tracks spec conformance and discv5 discovery is ours alone.
1 parent 6ec0b7a commit 718788c

3 files changed

Lines changed: 15 additions & 35 deletions

File tree

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ actual_slot = finalized_slot + 1 + relative_index
283283
### Peer Discovery (discv5, opt-in)
284284
- Off by default; `--discovery.enable` plus `--discovery.port` (own UDP socket, must differ from `--gossipsub-port`)
285285
- Reuses ethrex's `DiscoveryServer` + `PeerTable` with discv4 disabled; `spawn` takes the prepared lean ENR, so the record ethrex serves is the one we report
286-
- ENR follows the beacon phase0 spec: `ip`/`udp`/`quic`/`secp256k1`/`eth2`/`attnets`, deliberately **no** `tcp`
286+
- ENR follows the beacon phase0 spec: `ip`/`udp`/`quic`/`secp256k1`/`eth2`/`attnets`
287287
- Admission mirrors lighthouse: `eth2.fork_digest` must match, `next_fork_*` may differ, `quic` entry required. Handed to the peer table as `LeanFilter: PeerFilter`, so records are judged on arrival, not at dial time; a reject is re-judged on a higher-`seq` ENR
288288
- Candidates ranked by uncovered attestation subnets. See [`docs/discovery.md`](docs/discovery.md)
289289

docs/discovery.md

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,6 @@ The layout follows the discovery domain of the beacon-chain
5353
| `eth2` | SSZ `ENRForkID`, 16 bytes |
5454
| `attnets` | subscribed attestation subnet bitfield |
5555

56-
There is no `tcp` entry: the spec defines it as the libp2p TCP listening port
57-
and ethlambda speaks QUIC only.
58-
5956
The local ENR is logged once at startup.
6057

6158
This same record is handed to ethrex's `DiscoveryServer`, so it is what answers
@@ -102,8 +99,8 @@ answer different questions:
10299
Neither absence is an error, and a record carrying just one of them is still
103100
kept. The ENRs `lean-quickstart` generates today carry `ip`/`quic`/`secp256k1`
104101
and no `udp`, so they stay reachable but contribute nothing to discovery. Every
105-
beacon-chain bootnode published today is the mirror image: `ip`/`udp`/`tcp` and
106-
no `quic`, usable as a discv5 seed but never dialed. A record with neither is
102+
beacon-chain bootnode published today is the mirror image: a `udp` port but no
103+
`quic`, usable as a discv5 seed but never dialed. A record with neither is
107104
dropped with a warning, as is one missing an `ip` or a `secp256k1` key.
108105

109106
The ENR a node logs at startup is only useful to a peer if that node was
@@ -114,18 +111,6 @@ names no reachable host. Set `--discovery.advertise-ip` before pointing other
114111
nodes at this one's ENR: `127.0.0.1` on a local devnet, or the host's public
115112
address otherwise.
116113

117-
## If lean ever meets a real network
118-
119-
Two details are worth copying the day lean peers with a network carrying a live
120-
fork schedule:
121-
122-
- Learn the fork digest by plurality vote over discovered ENRs rather than
123-
hardcoding it, so a fork does not strand the node. Bootnode records are poor
124-
witnesses here: mainnet's still advertise the phase0 digest.
125-
- Gossip message ids follow Altair's function, which inserts the topic length
126-
and topic bytes between the domain and the payload. Phase0's shorter form
127-
produces ids no peer agrees with, which breaks IWANT/IHAVE silently.
128-
129114
## Known limitations
130115

131116
### One lean devnet is not separated from another
@@ -138,18 +123,6 @@ another**: two devnets running this code will peer with each other. Closing that
138123
gap requires lean adopting a genesis-derived fork digest, which is a
139124
cross-client change to gossip topic names.
140125

141-
### A beacon-chain client cannot discover us, and `tcp` is why
142-
143-
Beyond the fork digest never matching a real beacon network, there is a second,
144-
independent blocker. Lighthouse's discovery predicate is stricter than the spec
145-
text: alongside the `fork_digest` comparison it requires
146-
`enr.tcp4().is_some() || enr.tcp6().is_some()`, and it applies that as a
147-
discv5 query filter, so a `tcp`-less record is dropped before lighthouse's dial
148-
logic ever sees it. Our records deliberately carry no `tcp`, so they would be
149-
filtered out even if the digests did match. That is the right trade for a
150-
QUIC-only client, but it means the omission is a real interop cost and not a
151-
free simplification.
152-
153126
### `attnets` is not a fixed-width SSZ `Bitvector`
154127

155128
The spec's `attnets` is `Bitvector[ATTESTATION_SUBNET_COUNT]`, a constant every
@@ -160,8 +133,3 @@ lengths. The bit-packing convention is identical to the spec's; only the width
160133
is negotiable. Readers tolerate a foreign length by treating bits past the end
161134
as unset, and a peer's advertised subnets are clamped to the local committee
162135
count before they influence anything.
163-
164-
## Metrics
165-
166-
`lean_discovered_peers_dialed_total` counts dials initiated by discovery.
167-
Connection outcomes are covered by the existing peer connect/disconnect metrics.

docs/metrics.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,18 @@ The metrics below are not part of the [leanMetrics specification](https://github
126126
| `lean_reqresp_request_size_bytes` | Histogram | Bytes size of a req/resp request (raw SSZ or snappy on-wire) | On req/resp request send/receive | protocol=status,blocks_by_root<br>compression=raw,snappy | 64, 128, 256, 512, 1024, 4096, 16384, 65536 |
127127
| `lean_reqresp_response_chunk_size_bytes` | Histogram | Bytes size of a single req/resp response chunk (raw SSZ or snappy on-wire) | On req/resp response chunk send/receive | protocol=status,blocks_by_root<br>compression=raw,snappy | 128, 1024, 10000, 100000, 500000, 1000000, 5000000, 10000000 |
128128

129+
### Peer Discovery
130+
131+
Only emitted when discv5 discovery is enabled (`--discovery.enable`); see
132+
[Peer discovery](./discovery.md). Counts dials discovery initiated, as opposed to
133+
the static bootnode dials every node makes. Connection outcomes are not repeated
134+
here: a discovery dial that succeeds or fails shows up in
135+
`lean_peer_connection_events_total` like any other.
136+
137+
| Name | Type | Usage | Sample collection event | Labels |
138+
|------|------|-------|-------------------------|--------|
139+
| `lean_discovered_peers_dialed_total` | Counter | Peers dialed as a result of discv5 discovery | On dialing a discovered peer | |
140+
129141
### Gossip Arrival Timing
130142

131143
These histograms record the absolute distance between a gossip message's arrival and the start of the interval it was due in, so an arrival that is early by some amount and one that is late by the same amount land in the same bucket; the counters' `position` label is what tells them apart. `inside` means the message arrived within the interval it was due in, not merely somewhere in the right slot: an attestation for slot 10 that lands during slot 10's interval 2 is `after`, not `inside`, since it missed the AttestationProduction interval it was actually due in.

0 commit comments

Comments
 (0)