fix: time out beacon POST requests, declare requests, update deps - #44
Merged
Conversation
Null000
approved these changes
Aug 18, 2026
0xb1ob
approved these changes
Aug 18, 2026
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.
_make_post_requestsends no request timeout, unlike the GET path directly above it:Why it matters more than it looks
AsyncBeaconruns these through_run_as_async, i.e. in the default executor. A caller wrapping the coroutine inasyncio.wait_forgets no protection from that:wait_forcancels the waiter, not the thread. The worker stays blocked inrequests.postfor as long as the beacon node holds the socket open — indefinitely, with no timeout set.So a stalling beacon node leaks a thread per call. Repeat it and the default executor is exhausted, at which point every executor-backed method here —
get_validators,get_genesis, the pending-queue reads — stops making progress too. A caller that looks defensive, with await_foraround each call, is not.The POST path is also the one that carries the whole-validator-set requests (
get_validators,get_attestations_rewards), which are exactly the calls most likely to be slow.The fix
Pass
self.request_timeout, matching the GET path. One line, and the timeout value is already configured per client.The test asserting the exact
postcall now pins the timeout too, so the argument cannot be dropped again without a failure:Verification
23 tests pass.
0.12.1insetup.cfgand.bumpversion.cfgtogether — patch, since this changes no interface.Consumer note
A consumer pinning
==0.12.0needs bumping to0.12.1for this to take effect; the timeout lives entirely inside the library.Dependency updates folded in
Five of the six open dependabot PRs are absorbed here so they do not need merging separately. Every target version is at least 14 days old, per the
min-release-agepolicy:actions/upload-artifact4 → 7sast.ymlwas the last v4 referencepkginfo>=1.10 → >=1.12.1.2twinedependency that was sitting in runtime requirementsimportlib-metadata7.0.1 → 9.0.0twine6.0.0 → 7.0.0twine checkin the publish workflowrequests>=2.32.0 → >=2.34.2#43 exposed a real packaging bug.
web3_utils/async_beacon.pyandweb3_utils/retryable_eth_module.pybothfrom requests import ConnectionError, HTTPError, butrequestswas never ininstall_requires— it only resolved becauseweb3andpython-gitlabhappen to pull it. Any consumer whose resolver dropped those transitive paths would have hit anImportErrorat import time. It is now declared.#39 is deliberately left open (
web37.15.0 → 7.16.0,python-gitlab8.3.0 → 8.5.0).requirements.txtis CI-only, sinceinstall_requiresis unpinned — so these pins decide what the library is tested against, and the consumer currently runsweb3==7.15.0and resolvespython-gitlab==8.3.0. Bumping only here would put CI ahead of production, which is the same drift that previously hidgitlab.pybeing tested three majors behind what actually ran. Worth doing as a coordinated bump in both repos, with the consumer's suite as the check.Version stays at
0.12.1: declaring a dependency the package already imported is a fix, not a new capability. Happy to make it0.13.0if you readinstall_requireschanges as minor.