Skip to content

Flake: test_publish_after_identify_still_works does not wait for GossipSub mesh GRAFT #1454

Description

@acul71

Description

tests/core/pubsub/test_gossipsub_identify_aware_publish.py::test_publish_after_identify_still_works flakes on CI (e.g. tox (3.13, core) on PR #1203, job 95452018160).

Failure:

AssertionError: Normal publish (after identify) was not delivered.

(from trio.TooSlowError inside wait_for_pubsub_payload, 10s cap)

Same commit passed tox (3.10/3.11/3.12, core); failure is timing-dependent, not health-monitor related.

Root cause

The test waits for pubsub stream and SUBSCRIBE RPC (wait_for_peer, wait_for_subscription) then publishes. That is necessary but not sufficient for GossipSub delivery.

After subscribe() before connect(), GossipSub.join() creates an empty mesh[topic]. Peers are added to the mesh and receive GRAFT on the heartbeat loop, which:

  1. Starts with await trio.sleep(heartbeat_initial_delay) (default 0.1s)
  2. Then runs every heartbeat_interval (100s in this test file via _HEARTBEAT_DISABLED = 100 to avoid mcache sliding on slow CI)

If connect/identify completes after the first 0.1s heartbeat, the next mesh repair is ~100s later. The test only waits 10s for the payload → flake. If identify finishes before 0.1s, the first heartbeat GRAFTs the peer and the test passes.

Relevant code:

  • Test: tests/core/pubsub/test_gossipsub_identify_aware_publish.py (test_publish_after_identify_still_works)
  • Heartbeat delay: libp2p/pubsub/gossipsub.py (heartbeat()trio.sleep(heartbeat_initial_delay))
  • Mesh fill on heartbeat: mesh_heartbeat() / emit_graft

What is already event-driven (good)

  • Pubsub.wait_for_peer / wait_for_subscriptiontrio.Event + fail_after cap
  • wait_for_pubsub_payload — blocks on async for subscription, 10s is only a safety cap

What is still time-driven (problem)

  • Mesh membership after subscribe-before-connect relies on heartbeat timing, not an event the test waits on.
  • Same file still has await trio.sleep(4) in test_three_nodes_publish_before_full_mesh (explicit time wait).

Proposed fix

  1. Add a test helper (or use existing patterns) to wait until peer B is in gossipsub.mesh[topic] on both sides (or until GRAFT has been emitted for that topic), event-based with a reasonable timeout — not a longer sleep.
  2. Use it in test_publish_after_identify_still_works after the existing wait_for_peer / wait_for_subscription calls and before publish.
  3. Optionally replace trio.sleep(4) in the three-node test with the same mesh-ready wait.

Alternative (narrower): trigger an immediate mesh maintenance pass when a new gossipsub peer subscribes to a topic we are already subscribed to, instead of waiting for the next heartbeat — but that is a production-code change; test-side mesh wait is the minimal fix.

Related

Are you planning to do it yourself in a pull request?

Yes

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions