feat(p2p): add highlighted peer observability#2854
Conversation
Greptile SummaryThis PR adds a targeted observability layer for "highlighted" libp2p peers — identified by peer ID or secp256k1 public key — so attack-simulator traffic can be followed across connection, stream, pubsub, scoring, wire-validation, and SSV-validation layers without noise from the rest of the mesh.
Confidence Score: 3/5Safe to merge for functionality, but scoring.go now builds per-peer log fields on every inspection cycle instead of only on log cycles, which could noticeably increase allocations on production nodes with many peers. The observability wiring is correct end-to-end and the nil-safe Observer design prevents crashes. The one behavioural change worth addressing before merging is in scoring.go: the fields slice and the peerObserver.Observe call are now executed for every peer on every inspection cycle, not just on log-frequency cycles. On a busy node this is a meaningful increase in allocations that grows linearly with peer count and inversely with logFrequency. network/topics/scoring.go — the log-field construction was moved before the logFrequency gate, causing per-cycle work for all peers. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
CFG["Config\nHighlightedPeers / HighlightedPeerLabel"] --> OBS["peertrace.Observer\n(New / parsePeer)"]
OBS --> CONN["connections.ConnHandler\nconnected / disconnected / filtered"]
OBS --> STREAM["streams.StreamController\nrequest / response / oversized"]
OBS --> TRACER["topics.psTracer\npubsub trace events"]
OBS --> SCORING["topics.scoreInspector\npubsub_peer_score"]
OBS --> CTRL["topics.topicsCtrl\npubsub_message_delivered\nObserveValidation"]
OBS --> VALIF["validation.messageValidator\nObserveSSVValidation"]
CTRL -->|"wrappedValidator\nrecordPubsubMessageReceived"| CTRL2["pubsub topic validator\naccept / ignore / reject"]
VALIF -->|"outcome + reason + QBFT fields"| EVT["SSVValidationEvent\n(accepted / ignored / rejected)"]
OBS -->|"Observe / ObserveValidation\nObserveSSVValidation"| METRICS["OTel Counters\nhighlighted_peer.events\nhighlighted_peer.validations\nhighlighted_peer.ssv_validations"]
Reviews (1): Last reviewed commit: "feat(p2p): add highlighted peer observab..." | Re-trigger Greptile |
Summary
Adds targeted observability for attack-simulator traffic by letting an SSV node highlight one or more configured libp2p peers, including peers configured by their secp256k1 public key. The stage attack-simulator public key can now be passed through
P2P_HIGHLIGHTED_PEERS, with an optionalP2P_HIGHLIGHTED_PEER_LABELsuch asattack-simulator.The implementation wires a shared highlighted peer observer through P2P setup and message validation so we can follow traffic from the attack simulator across connection, stream, pubsub, peer score, wire validation, and SSV-level validation paths.
What changed
network/peers/peertraceto parse highlighted peer IDs/public keys and emit consistent logs and metrics.P2P_HIGHLIGHTED_PEERSandP2P_HIGHLIGHTED_PEER_LABEL.ssv.p2p.highlighted_peerfor events, pubsub validation outcomes, and SSV validation outcomes.config/config.example.yaml.Why
When running attack-simulator against a stage SSV node, it was difficult to tell whether attack traffic reached the node, whether it passed wire-level pubsub validation, and how far it progressed through SSV message validation. Highlighting the simulator peer gives us a low-noise view of simulator-originated traffic and enough context to understand whether each attack is affecting gossip, scoring, stream handling, or SSV validation.
Validation
goplsdiagnostics on edited Go files: cleangit diff --check: cleanok github.com/ssvlabs/ssv/network/peers/peertrace (cached)
ok github.com/ssvlabs/ssv/network/topics (cached)
ok github.com/ssvlabs/ssv/network/p2p (cached) [no tests to run]
go test ./network/streams ./network/peers/connections ./network/peers/peertrace ./message/validation -timeout 60sNote:
go_vulncheck ./...could not run locally because the scanner binary is built with Go 1.25 while this checkout requires Go 1.26. No dependency changes are included in this PR.