Repository navigation
fix(qa): wallet stub RPC for staged QA + release 2.15.0 - #1237
Merged
Merged
Conversation
…et.base.org The v2.14.0 release build (run 37649288177) failed Staged QA (all_2) on sqlite with 463/463 tests passing: the incidents gate found two "[ChainClient] Failed to get USDC/ETH balance: Server error '503 Service Unavailable' for url 'https://mainnet.base.org'" ERRORs. The wallet adapter auto-loads for base-mainnet and its context-enrichment tool wallet:get_statement queries balances during context gathering, so QA was gated on a third party's uptime. The QA runner now starts a stub JSON-RPC server (tools/qa_runner/ mock_chain_rpc.py, same lifecycle as the mock logshipper, OS-assigned port) and sets the adapter's existing WALLET_X402_RPC_URL env var to it. An operator-exported WALLET_X402_RPC_URL still wins. The stub answers the read calls ChainClient issues with deterministic zero balances and refuses eth_sendRawTransaction. The ChainClient error is deliberately NOT added to EXPECTED_QA_INCIDENT_PATTERNS - that would hide real wallet failures. Tests include two negative checks: without the override the wallet targets https://mainnet.base.org, and a stub forced to answer 503 reproduces the exact ChainClient ERROR lines from the failed run. black also normalised pre-existing formatting in server.py (a mis-indented block and a long signature); no behaviour change there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F4gtPV4CQ22A8B4mTUBfdu
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
The start line printed a chain-link emoji, which test_no_emoji_in_runtime_output rejects: on a Windows cp1252 console an emoji raises UnicodeEncodeError and kills the process. Use [STUB]. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F4gtPV4CQ22A8B4mTUBfdu
Releases the token single-count fix (#1241), resource pressure that acts (#1242: RECLAIM / THROTTLE / SHED / DRAIN, no token budget by default, config-graph token budgets, device-class memory budgets) and the hermetic staged-QA wallet stub (#1237). Breaking (#1242): - resource_signal_defer_total, resource_signal_reject_total and resource_signal_shutdown_total are removed; - the /v1/system/resources "action" values are renamed; - SHED answers new inbound work with 503 + Retry-After. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F4gtPV4CQ22A8B4mTUBfdu
|
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
On the v2.14.0 release build (run 37649288177), the Staged QA (all_2) sqlite leg failed even though all 463 tests passed. The incidents gate (
_has_incidents_occurred/EXPECTED_QA_INCIDENT_PATTERNS) found two unexpected ERROR lines:Root cause: the wallet adapter always loads at startup (
bootstrap_helpers._load_single_adapter(runtime, "wallet", ...)) with x402 set to base-mainnet. Its context-enrichment toolwallet:get_statementqueries balances during context gathering, and QA never overrode the RPC URL, so every QA run called the publichttps://mainnet.base.org. QA therefore failed whenever that third-party endpoint was down. The postgres leg passed only because the RPC happened to answer at that moment.Fix
tools/qa_runner/mock_chain_rpc.py(new) is a stub JSON-RPC server with the same thread lifecycle asMockLogshipperServer. It binds to127.0.0.1on an OS-assigned port, so the two--parallel-backendslegs never collide. It returns fixed values for the callsChainClientmakes:eth_chainIdreturns0x2105(8453) andnet_versionreturns8453.eth_getBalancereturns0x0.eth_callreturns a 32-byte zero word, which covers ERC-20balanceOf,allowanceand the EntryPointgetNonce.eth_blockNumber,eth_getTransactionCount,eth_gasPrice,eth_estimateGas,eth_getTransactionReceipt(returnsnull) andeth_getBlockByNumber(withbaseFeePerGas) also return fixed values.eth_sendRawTransactionreturns a JSON-RPC error, because QA must never submit a transaction. Unknown methods return-32601.tools/qa_runner/server.py:APIServerManager.start()starts the stub next to the mock logshipper. It then points the wallet at the stub through the adapter's existingWALLET_X402_RPC_URLenv var (adapter._load_config_from_envpasses it toX402ProviderConfig.rpc_url, then toChainClient(rpc_url=...)). No adapter change was needed. AWALLET_X402_RPC_URLthat the operator exports still takes precedence, using the same rule asapply_module_server_env.stop()shuts the stub down.EXPECTED_QA_INCIDENT_PATTERNS. Allow-listing the ChainClient error would hide real wallet failures. A test pins that the pattern list does not mentionChainClientormainnet.base.org.blackalso cleaned up some existing formatting inserver.py: a mis-indented provider-detection block and a longapply_module_server_envsignature. Behaviour is unchanged.Tests
tests/tools/qa_runner/test_wallet_stub_rpc.py: 15 passed. The wholetests/tools/qa_runner/suite also passes (409 passed, 5 skipped).ChainClientpointed at the stub runsget_usdc_balance,get_eth_balanceandget_block_numberwith no ERROR logs.WalletAdapter._load_config_from_envintoX402Provider._fetch_balance_from_chain, which is theget_statementpath. The stub sees exactlyeth_callandeth_getBalance, and nothing is logged at ERROR.apply_wallet_rpc_stub_envsets the URL when a stub is running, leaves it alone when the operator exported one, and does nothing when there is no stub. A source check confirms thatstart()creates the stub and applies it to the agent env, and thatstop()stops it.ChainClienttargetshttps://mainnet.base.org.[ChainClient] Failed to get USDC balance ... 503and the matching ETH line, both at ERROR.python3 -m mypyon the changed files:mock_chain_rpc.pyand the test file are clean. Every error mypy reports inserver.pyis on lines that existed before this PR. Nothing new.Not verified
I did not do a local
qa_runnerrun against a live server. This machine's ownciris_serveralready holds the node's fixed HTTP port 4243, so a QA agent could not bind it and its auth calls would go to the live node. CI's staged QA is the first full-server check: look for theStub chain RPC served N calls: ...line at shutdown, and for no ChainClient incidents.🤖 Generated with Claude Code
https://claude.ai/code/session_01F4gtPV4CQ22A8B4mTUBfdu