fix: block-staleness watchdog for substrate subscription - #424
Merged
Merged
Conversation
SubstrateConnectionManager only reconnected when the connect/subscribe coroutine raised. A hung reconnect (seen Aug 12: AsyncSubstrateInterface connect stalled after "Unable to reconnect because there are currently open subscriptions") never raises and never returns, so the retry loop, the callers' task.done() checks, and the validator heartbeat all missed it — the data service went a week without block callbacks or HF uploads. Run connect+subscribe as an inner task and watch block arrival times: if no block lands for 120s (finney block time ~12s), cancel the inner task and reconnect. This also bounds hung connects. Public interface is unchanged, so validator and data service both get the fix with no call-site changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HMMzP49s22hUddCYNTAS1
This reverts commit 6fb0cd1.
This reverts commit c6a10ef.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
SubstrateConnectionManager.start_subscription()only reconnects when the connect/subscribe coroutine raises. On Aug 12 a validator's data service hit a reconnect that hung instead: the websocket dropped (Unable to reconnect because there are currently open subscriptions), the retry loop loggedConnecting to async substrate..., and theAsyncSubstrateInterfaceconnect stalled forever — no exception, no return.Every existing safety layer misses this mode:
substrate_task.done()checks (data_service.start(),BaseNeuron.check_substrate_connection()) never fire because a hung task is never done;self.step, which increments every second in the main loop regardless of chain connectivity.Result: the data service ran as a zombie for a week — process "online", no block callbacks, no dataset downloads, no HF uploads (~20k media backlog).
Fix
Run connect+subscribe as an inner task and watch block arrival — the one signal that's true in every failure mode. Every block stamps
last_block_time; if no block lands for 120s (finney block time ~12s), cancel the inner task and rebuild the connection. This also bounds hung connects. The raise-and-retry path is preserved.Public interface (
start_subscription_task()/stop()) is unchanged, so the validator and data service both inherit the fix with zero call-site changes; their existing.done()checks remain as an outer layer.Verification
Simulated four scenarios against the patched class (subclass with fake
_connect_and_subscribe):Also running in production on the affected validator's data service since 2026-08-20; block subscription and hourly HF upload cycles healthy.