Skip to content

test(networking): add gossipsub handler behavioral test vectors#615

Merged
tcoratger merged 1 commit intoleanEthereum:mainfrom
tcoratger:test/gossipsub-handler-behavior-test-vectors
Apr 15, 2026
Merged

test(networking): add gossipsub handler behavioral test vectors#615
tcoratger merged 1 commit intoleanEthereum:mainfrom
tcoratger:test/gossipsub-handler-behavior-test-vectors

Conversation

@tcoratger
Copy link
Copy Markdown
Collaborator

Summary

Introduces a new GossipsubHandlerTest fixture that tests gossipsub protocol decisions, not wire encoding. This is a fundamentally different kind of test vector — it captures what the node DOES when it receives GRAFT/PRUNE/IHAVE/IWANT/messages, not what bytes it produces.

Each vector defines:

  • Initial state: mesh topology, peer subscriptions, backoff timers, seen/message caches
  • Incoming event: an RPC from a specific peer
  • Expected output: outbound RPCs sent + resulting mesh topology

Why this matters

If two clients disagree on whether to accept a GRAFT, they have incompatible mesh topologies. If they disagree on IHAVE filtering, lazy pull breaks. These are the most interop-critical decisions after wire format.

Vectors (14 total)

Handler Count What's tested
GRAFT 5 Accept, reject (capacity at d_high), reject (backoff), ignore (unsubscribed), idempotent
PRUNE 2 Remove from mesh + set backoff, zero backoff
IHAVE 3 Unseen triggers IWANT, seen produces no IWANT, mixed filtering
IWANT 1 Cached message returned as full message
Message 3 Forward to mesh except sender, duplicate not forwarded, IDONTWANT peer skipped

Design decisions

  • No randomness: handler code paths don't use random.sample() — fully deterministic
  • Time control: single now timestamp, backoffs are absolute values, time.time() is patched
  • Peer names: simple Base58-valid strings ("peerAx", "senderX"), converted internally
  • New fixture class: separate from NetworkingCodecTest because the semantics are different (state+event→behavior vs input→encoding)

Test plan

  • uvx tox -e all-checks passes
  • uv run fill --fork=devnet --clean -n auto -- tests/consensus/devnet/networking/ generates all 107 fixtures
  • Verified GRAFT accept adds peer to mesh with no RPCs sent
  • Verified GRAFT reject (backoff) sends PRUNE with 60s backoff
  • Verified IHAVE for unseen message triggers IWANT with exact message ID
  • Verified message forwarding skips sender and IDONTWANT peers

🤖 Generated with Claude Code

Introduces a new GossipsubHandlerTest fixture that tests protocol
DECISIONS, not wire encoding. Each vector defines an initial state
(mesh topology, peers, caches, backoffs), an incoming RPC event,
and captures the expected outbound RPCs plus resulting mesh state.

This is the first behavioral test fixture for gossipsub. It complements
the existing encoding vectors (RPC protobuf, message IDs, topic strings)
by testing the logic layer: what does the node DO when it receives a
GRAFT, PRUNE, IHAVE, IWANT, or published message?

14 test vectors covering:
- GRAFT: accept, reject (capacity), reject (backoff), ignore (unsubscribed), idempotent
- PRUNE: remove from mesh with backoff, zero backoff
- IHAVE: unseen triggers IWANT, seen produces no IWANT, mixed filtering
- IWANT: cached message returned
- Message: forward to mesh except sender, duplicate not forwarded, IDONTWANT peer skipped

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tcoratger tcoratger merged commit 1036ba1 into leanEthereum:main Apr 15, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant