feat(transaction-controller): extract revert reason for on-chain failures#8589
Draft
matthewwalsh0 wants to merge 1 commit intomainfrom
Draft
feat(transaction-controller): extract revert reason for on-chain failures#8589matthewwalsh0 wants to merge 1 commit intomainfrom
matthewwalsh0 wants to merge 1 commit intomainfrom
Conversation
eff0b70 to
f5196a9
Compare
…ures When a transaction's receipt has a failure status (0x0), replay the call via eth_estimateGas and decode the returned revert data so users see why the transaction failed instead of just 'Transaction failed on-chain'. - Add extractRevertReason util that decodes Error(string), Panic(uint256) with named codes, custom error selectors, and empty reverts; falls back to the provider error message when no revert data is surfaced - Add revertReason?: string field to TransactionMeta for consumers that prefer not to parse error strings - Append the decoded reason to the existing 'Transaction failed on-chain' error message via a new OnChainFailureError subclass eth_estimateGas is used instead of eth_call as a workaround for a bug in eth-json-rpc-middleware's RetryOnEmptyMiddleware: its isExecutionRevertedError check fails to recognise EIP-1474 / Infura-style revert errors (code 3, suffixed message), causing it to retry reverted calls 10 times and discard the original error data. eth_estimateGas returns the same revert payload but bypasses that middleware. A separate upstream PR fixes the underlying bug.
4 tasks
f5196a9 to
988450c
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.
Explanation
When a transaction fails on-chain (its receipt has
status: 0x0), the controller currently records a genericTransaction failed on-chainerror with no information about why it failed. The actual revert reason —ERC20: transfer amount exceeds balance,Panic: arithmetic overflow, etc. — is lost, even though it is recoverable from any standard JSON-RPC endpoint.This PR extracts a human-readable revert reason for every on-chain failure and surfaces it in two places:
revertReason?: stringfield onTransactionMeta— for consumers that don't want to parse error strings.Transaction failed on-chain: ERC20: transfer amount exceeds balance.How it works
When
PendingTransactionTrackerdetects a receipt withstatus === 0x0, it replays the original call viaeth_callat the block where the transaction was mined. The EVM returns the same revert as it did when the transaction was included, and the response is decoded:Error(string)(selector0x08c379a0) → the embedded messagePanic(uint256)(selector0x4e487b71) → e.g.Panic: arithmetic overflow or underflow (0x11)reverted with custom error 0xdeadbeefexecution reverted: ...)undefinedThe whole extraction is wrapped in a try/catch and never throws, so it's safe to run on every failed receipt with no impact on the existing failure path.
Why eth_call (not debug_traceCall / debug_traceTransaction)
eth_callworks on every standard JSON-RPC endpoint (Infura, QuickNode, public RPCs).debug_*methods are paywalled or unsupported on most providers. The replay approach has been used by ethers.js and viem for years and gives the same fidelity for the common cases.References
Resolves the gap identified in Failed Transaction Analysis — the most common Pay failure (
ERC20: transfer amount exceeds balance) was completely opaque to consumers.Changelog
```
Added
```
Checklist