Fix reuse_block=True raising in async reads#3370
Open
Yupsecous wants to merge 1 commit into
Open
Conversation
thewhaleking
reviewed
Jun 3, 2026
Contributor
There was a problem hiding this comment.
This code should really live within test_async_subtensor.py, and probably doesn't need to be so verbose.
Many AsyncSubtensor methods resolved block_hash and then forwarded both the resolved block_hash and reuse_block into a child that re-resolved, tripping determine_block_hash's mutual-exclusion guard (ValueError: Cannot specify both reuse_block and block_hash/block). So reuse_block=True raised for ~23 public read methods after any prior query. Forward only the resolved block_hash to the child (dropping the now-redundant block/reuse_block) across all 25 affected call sites. Behavior-preserving for the block/block_hash/default paths; adds regression tests covering reuse_block=True for every affected method.
07ebf67 to
29ccfdb
Compare
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.
Fix reuse_block=True raising ValueError across async read methods
Bug
reuse_block=TrueraisesValueError: Cannot specify both reuse_block and block_hash/blockfor ~23AsyncSubtensorread methods after any prior chainquery. No separate issue was filed; the full reproduction, root cause, and fix
are described below.
Description of the Change
determine_block_hash(reuse_block=True)returnssubstrate.last_block_hash(non-
Noneafter any prior query). Many methods resolvedblock_hashonce andthen forwarded both the resolved
block_hashandreuse_blockinto achild helper, whose own
determine_block_hashthen hit its mutual-exclusionguard and raised.
This change forwards only the already-resolved
block_hashto the child(dropping the now-redundant
block/reuse_block) at all 25 affected callsites across 23 methods — e.g.
difficulty,tempo,immunity_period,get_delegate_take,get_root_claimable_stake,get_neuron_for_pubkey_and_subnet,is_hotkey_delegate,filter_netuids_by_registered_hotkeys,compose_call. Every forwarded child wasverified to use
block/reuse_blockonly for hash resolution, so passingonly
block_hashloses no information.Alternate Designs
Relaxing
determine_block_hash's guard to toleratereuse_blocktogether with amatching
block_hashwas rejected: the guard is documented, intended validation,and the real defect is the double-resolution at the call sites, not the guard.
Possible Drawbacks
None expected. Behavior is unchanged for the
block,block_hash, and default(no-arg) paths; only the previously-broken
reuse_block=Truepath changes (fromraising to returning data). Two look-alikes were deliberately left unchanged:
get_liquidity_list(itsquery_mapruns before resolution, so it alreadyforwards raw args and resolves once) and
is_in_admin_freeze_window→get_next_epoch_start_block(which reads the rawblock number for its return value, so it must keep raw args).
Verification Process
stagingwith theValueErrorfor every affected method, and passes with the fix.tests/unit_tests/test_async_subtensor_reuse_block.pydrives the realdetermine_block_hashpath (the resolving child is not mocked) across all23 methods, asserting (a) no guard
ValueError, (b)determine_block_hashnever re-receives the guard-tripping combination, and (c) the reused
last_block_hashthreads to the leaf substrate call. Adds a no-cached-blockedge case and a
block_hash-equivalence check.updated to the corrected signature; all
result == ...output assertions wereleft unchanged.
test_async_subtensor.py+ newfile → 262 passed; full
tests/unit_tests→ 1169 passed (the onlyfailures are 3 pre-existing, unrelated environment issues — two
test_dendriteon aiohttp 3.14, one needing the
torchextra — identical on pristinestaging);ruff format --check,ruff check,mypyclean.Release Notes
Fixed
reuse_block=TrueraisingValueErroron manyAsyncSubtensorreadmethods (e.g.
difficulty,tempo,get_delegate_take).Branch Acknowledgement
[x] I am acknowledging that I am opening this branch against
staging