waitForTransactionReceipt foot gun #3983
Unanswered
dcposch
asked this question in
Idea / Feature Request
Replies: 1 comment
-
|
This behavior has existed since the inception of Viem, and also exists in Ethers. We can make it disabled by default for Viem v3. For now, you can disable it by passing |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Check existing issues
Viem Version
2.23.2
Current Behavior
waitForTransactionReceipt sometimes returns a receipt for a completely different transaction.
This is very surprising behavior and cost us a day of debugging:
On digging through the code, it's because it is doing a lot of extra work (including downloading whole blocks and scanning transactions) to find a replacement transaction at the same sender + nonce.
Expected Behavior
The docs make it sound like replacement transactions are an optional feature:
...so it's unexpected that waitForTransactionReceipt would return a different tx, esp when not passing
onReplaced.Proposed fix
By default
waitForTransactionReceiptshould throw an error when the tx hash you're looking for didn't make it onchain, not return a different transaction.Fixing this will also make your RPC usage more efficient. Instead of calling
eth_getBlockByNumber, downloading and scanning entire blocks' worth of transactions (which is surprising, unexpected behavior by itself) you can poll the sender EOA's nonce with a lightereth_getTransactionCountcall.If you see that the transaction count is >= the nonce of the transaction we're looking for, but the one we're looking for is not available, then throw an "transaction replaced" error.
--
Optionally keep the current behavior only if
onReplacedis passed. In fact, I would consider replacingonReplacedwith eg. asearchForReplacementboolean option, so that callers get a consistent promise-await interface instead of a callback.Steps To Reproduce
writeContractcall with another transaction from the same wallet at same noncewaitForTransactionReceiptreturns this other transaction's receipt, not the one it was called to look for.Link to Minimal Reproducible Example
No response
Anything else?
No response
Beta Was this translation helpful? Give feedback.
All reactions