Skip to content

Async topic validator crashes gossipsub service #1118

@hayotensor

Description

@hayotensor

Summary

I just recently received this issue that shuts down the pubsub service when using an async topic validator:

When using a sync topic validator with the same logic, this issue doesn't occur

Expected behavior

MessageCache to successfully pop the topic history

Actual behavior

The key is attempting to be popped but it apparently doesn't exist

Relevant log output

2026-01-03 16:16:27,482 [ERROR] [async_service.Manager] <Manager[GossipSub] flags=SRcfe>: task heartbeat[daemon=True] exited with error: (b'\x00\x00\x00\x00iY\x86\xff', b'\x00$\x08\x01\x12 /X\x99\xbbp\xa2\xaa9\x93\xc2\xd6f\xa2\x99\x1e[vH"rac\x8e\x1e!\x8b\xff\x91\x0c)\xe7x')
Traceback (most recent call last):
  File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/tools/async_service/base.py", line 334, in _run_and_manage_task
    await task.run()
  File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/tools/async_service/trio_service.py", line 118, in run
    await self._async_fn(*self._async_fn_args)
  File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/pubsub/gossipsub.py", line 565, in heartbeat
    self.mcache.shift()
  File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/pubsub/mcache.py", line 102, in shift
    self.msgs.pop(entry.mid)
KeyError: (b'\x00\x00\x00\x00iY\x86\xff', b'\x00$\x08\x01\x12 /X\x99\xbbp\xa2\xaa9\x93\xc2\xd6f\xa2\x99\x1e[vH"rac\x8e\x1e!\x8b\xff\x91\x0c)\xe7x')
2026-01-03 16:16:27,496 [ERROR] [__main__] Fatal error: Exceptions from Trio nursery (1 sub-exception)
  + Exception Group Traceback (most recent call last):
  |   File "/home/bob/py-libp2p-subnet-gossip/subnet/cli/run_node.py", line 408, in main
  |     trio.run(server.run)
  |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/trio/_core/_run.py", line 2549, in run
  |     raise runner.main_task_outcome.error
  |   File "/home/bob/py-libp2p-subnet-gossip/subnet/server/server.py", line 134, in run
  |     async with host.run(listen_addrs=listen_addrs), trio.open_nursery() as nursery:
  |   File "/usr/lib/python3.10/contextlib.py", line 217, in __aexit__
  |     await self.gen.athrow(typ, value, traceback)
  |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/host/basic_host.py", line 357, in _run
  |     async with background_trio_service(network):
  |   File "/usr/lib/python3.10/contextlib.py", line 217, in __aexit__
  |     await self.gen.athrow(typ, value, traceback)
  |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/tools/async_service/trio_service.py", line 456, in background_trio_service
  |     async with trio.open_nursery() as nursery:
  |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/trio/_core/_run.py", line 1125, in __aexit__
  |     raise combined_error_from_nursery
  | exceptiongroup.ExceptionGroup: Exceptions from Trio nursery (1 sub-exception)
  +-+---------------- 1 ----------------
    | Exception Group Traceback (most recent call last):
    |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/tools/async_service/trio_service.py", line 461, in background_trio_service
    |     yield manager
    |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/host/basic_host.py", line 374, in _run
    |     yield
    |   File "/home/bob/py-libp2p-subnet-gossip/subnet/server/server.py", line 134, in run
    |     async with host.run(listen_addrs=listen_addrs), trio.open_nursery() as nursery:
    |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/trio/_core/_run.py", line 1125, in __aexit__
    |     raise combined_error_from_nursery
    | exceptiongroup.ExceptionGroup: Exceptions from Trio nursery (1 sub-exception)
    +-+---------------- 1 ----------------
      | Exception Group Traceback (most recent call last):
      |   File "/home/bob/py-libp2p-subnet-gossip/subnet/server/server.py", line 161, in run
      |     async with background_trio_service(dht):
      |   File "/usr/lib/python3.10/contextlib.py", line 217, in __aexit__
      |     await self.gen.athrow(typ, value, traceback)
      |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/tools/async_service/trio_service.py", line 456, in background_trio_service
      |     async with trio.open_nursery() as nursery:
      |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/trio/_core/_run.py", line 1125, in __aexit__
      |     raise combined_error_from_nursery
      | exceptiongroup.ExceptionGroup: Exceptions from Trio nursery (1 sub-exception)
      +-+---------------- 1 ----------------
        | Exception Group Traceback (most recent call last):
        |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/tools/async_service/trio_service.py", line 461, in background_trio_service
        |     yield manager
        |   File "/home/bob/py-libp2p-subnet-gossip/subnet/server/server.py", line 176, in run
        |     async with background_trio_service(pubsub):
        |   File "/usr/lib/python3.10/contextlib.py", line 217, in __aexit__
        |     await self.gen.athrow(typ, value, traceback)
        |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/tools/async_service/trio_service.py", line 456, in background_trio_service
        |     async with trio.open_nursery() as nursery:
        |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/trio/_core/_run.py", line 1125, in __aexit__
        |     raise combined_error_from_nursery
        | exceptiongroup.ExceptionGroup: Exceptions from Trio nursery (1 sub-exception)
        +-+---------------- 1 ----------------
          | Exception Group Traceback (most recent call last):
          |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/tools/async_service/trio_service.py", line 461, in background_trio_service
          |     yield manager
          |   File "/home/bob/py-libp2p-subnet-gossip/subnet/server/server.py", line 177, in run
          |     async with background_trio_service(gossipsub):
          |   File "/usr/lib/python3.10/contextlib.py", line 217, in __aexit__
          |     await self.gen.athrow(typ, value, traceback)
          |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/tools/async_service/trio_service.py", line 456, in background_trio_service
          |     async with trio.open_nursery() as nursery:
          |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/trio/_core/_run.py", line 1125, in __aexit__
          |     raise combined_error_from_nursery
          | exceptiongroup.ExceptionGroup: Exceptions from Trio nursery (1 sub-exception)
          +-+---------------- 1 ----------------
            | Exception Group Traceback (most recent call last):
            |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/tools/async_service/trio_service.py", line 248, in run
            |     raise ExceptionGroup(
            | exceptiongroup.ExceptionGroup: Encountered multiple Exceptions:  (1 sub-exception)
            +-+---------------- 1 ----------------
              | Traceback (most recent call last):
              |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/tools/async_service/base.py", line 334, in _run_and_manage_task
              |     await task.run()
              |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/tools/async_service/trio_service.py", line 118, in run
              |     await self._async_fn(*self._async_fn_args)
              |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/pubsub/gossipsub.py", line 565, in heartbeat
              |     self.mcache.shift()
              |   File "/home/bob/py-libp2p-subnet-gossip/.venv/lib/python3.10/site-packages/libp2p/pubsub/mcache.py", line 102, in shift
              |     self.msgs.pop(entry.mid)
              | KeyError: (b'\x00\x00\x00\x00iY\x86\xff', b'\x00$\x08\x01\x12 /X\x99\xbbp\xa2\xaa9\x93\xc2\xd6f\xa2\x99\x1e[vH"rac\x8e\x1e!\x8b\xff\x91\x0c)\xe7x')

Possible Solution

Unsure

Environment

Python version:
3.10.12 (main, Nov  4 2025, 08:48:33) [GCC 11.4.0]

Operating System: Linux-6.6.87.2-microsoft-standard-WSL2-x86_64-with-glibc2.35

python -m pip freeze result:
aioquic==1.3.0
alabaster==1.0.0
annotated-types==0.7.0
anyio==1.4.0
asttokens==3.0.1
async-exit-stack==1.0.1
async-generator==1.10
attrs==25.4.0
babel==2.17.0
backports.tarfile==1.2.0
base58==2.1.1
blake3==1.0.8
bracex==2.6
build==1.3.0
bump-my-version==1.2.6
cachetools==6.2.4
certifi==2025.11.12
cffi==2.0.0
cfgv==3.5.0
chardet==5.2.0
charset-normalizer==3.4.4
click==8.3.1
coincurve==21.0.0
colorama==0.4.6
cryptography==46.0.3
cytoolz==1.1.0
decorator==5.2.1
distlib==0.4.0
dnspython==2.8.0
docutils==0.21.2
ecdsa==0.19.1
eth-hash==0.7.1
eth-keys==0.7.0
eth-typing==5.2.1
eth-utils==5.3.1
exceptiongroup==1.3.1
execnet==2.1.2
executing==2.2.1
factory-boy==2.12.0
Faker==40.1.0
fastecdsa==2.3.2
filelock==3.20.2
grpcio==1.76.0
h11==0.16.0
httpcore==1.0.9
httpx==0.28.1
id==1.5.0
identify==2.6.15
idna==3.11
ifaddr==0.2.0
imagesize==1.4.1
importlib_metadata==8.7.1
iniconfig==2.3.0
ipython==8.37.0
jaraco.classes==3.4.0
jaraco.context==6.0.2
jaraco.functools==4.4.0
jedi==0.19.2
jeepney==0.9.0
Jinja2==3.1.6
keyring==25.7.0
libp2p @ git+https://github.com/libp2p/py-libp2p.git@c63724ff360bb8ff02d468249c32a93c587a8f9e
librt==0.7.7
lru-dict==1.4.1
markdown-it-py==4.0.0
MarkupSafe==3.0.3
matplotlib-inline==0.2.1
mdurl==0.1.2
miniupnpc==2.3.3
mmh3==5.2.0
more-itertools==10.8.0
morphys==1.0
multiaddr==0.0.11
mypy==1.19.1
mypy-protobuf==4.0.0
mypy_extensions==1.1.0
netaddr==1.3.0
nh3==0.3.2
nodeenv==1.10.0
noiseprotocol==0.3.1
outcome==1.3.0.post0
p2pclient==0.2.0
packaging==25.0
parso==0.8.5
pathspec==0.12.1
pexpect==4.9.0
platformdirs==4.5.1
pluggy==1.6.0
pre_commit==4.5.1
prompt_toolkit==3.0.52
protobuf==6.33.2
psutil==7.2.1
ptyprocess==0.7.0
pure_eval==0.2.3
py-bip39-bindings==0.3.0
py-cid==0.4.0
py-ed25519-zebra-bindings==1.3.0
py-libp2p-subnet @ file:///home/bob/py-libp2p-subnet-gossip
py-multibase==2.0.0
py-multicodec==1.0.0
py-multihash==3.0.0
py-sr25519-bindings==0.2.3
pyasn1==0.6.1
pyasn1_modules==0.4.2
pycparser==2.23
pycryptodome==3.23.0
pydantic==2.12.5
pydantic-settings==2.12.0
pydantic_core==2.41.5
Pygments==2.19.2
pylsqpack==0.3.23
pymultihash==0.8.2
PyNaCl==1.6.2
pyOpenSSL==25.3.0
pyproject-api==1.10.0
pyproject_hooks==1.2.0
pyrefly==0.17.1
pytest==9.0.2
pytest-rerunfailures==16.1
pytest-timeout==2.4.0
pytest-trio==0.8.0
pytest-xdist==3.8.0
python-baseconv==1.2.2
python-dotenv==1.2.1
PyYAML==6.0.3
questionary==2.1.1
readme_renderer==44.0
requests==2.32.5
requests-toolbelt==1.0.0
rfc3986==2.0.0
rich==14.2.0
rich-click==1.9.5
rocksdict==0.3.29
rpcudp==5.0.1
ruff==0.14.10
scalecodec===v2.0.0a2-ht
SecretStorage==3.5.0
service-identity==24.2.0
six==1.17.0
sniffio==1.3.1
snowballstemmer==3.0.1
sortedcontainers==2.4.0
Sphinx==8.1.3
sphinx-rtd-theme==3.0.2
sphinxcontrib-applehelp==2.0.0
sphinxcontrib-devhelp==2.0.0
sphinxcontrib-htmlhelp==2.1.0
sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==2.0.0
sphinxcontrib-serializinghtml==2.0.0
stack-data==0.6.3
substrate-interface===v1.7.11-ht
tenacity==9.1.2
tomli==2.3.0
tomlkit==0.13.3
toolz==1.1.0
towncrier==24.8.0
tox==4.33.0
traitlets==5.14.3
trio==0.32.0
trio-typing==0.10.0
trio-websocket==0.12.2
twine==6.2.0
types-protobuf==6.32.1.20251210
typing-inspection==0.4.2
typing_extensions==4.15.0
tzdata==2025.3
u-msgpack-python==2.8.0
urllib3==2.6.2
varint==1.0.2
virtualenv==20.35.4
wcmatch==10.1
wcwidth==0.2.14
websocket-client==1.9.0
wsproto==1.3.2
xxhash==3.6.0
zeroconf==0.147.3
zipp==3.23.0

Would you like to work on fixing this bug ?

Maybe

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions