keep error data intact when replaying transaction

This commit is contained in:
Mark Spanbroek 2024-03-20 15:58:31 +01:00 committed by markspanbroek
parent 241ce6e8f3
commit 9cb033e865
1 changed files with 10 additions and 37 deletions

View File

@ -202,33 +202,6 @@ proc replay*(
trace "replaying transaction", gasLimit = tx.gasLimit, tx = $tx trace "replaying transaction", gasLimit = tx.gasLimit, tx = $tx
discard await provider.call(tx, BlockTag.init(blockNumber)) discard await provider.call(tx, BlockTag.init(blockNumber))
method getRevertReason*(
provider: Provider,
hash: TransactionHash,
blockNumber: UInt256): Future[?string] {.base, async: (raises: [ProviderError]).} =
without pastTx =? await provider.getTransaction(hash):
return none string
try:
await provider.replay(pastTx.toTransaction, blockNumber)
return none string
except ProviderError as e:
# should contain the revert reason
return some e.msg
method getRevertReason*(
provider: Provider,
receipt: TransactionReceipt): Future[?string] {.base, async: (raises: [ProviderError]).} =
if receipt.status != TransactionStatus.Failure:
return none string
without blockNumber =? receipt.blockNumber:
return none string
return await provider.getRevertReason(receipt.transactionHash, blockNumber - 1)
proc ensureSuccess( proc ensureSuccess(
provider: Provider, provider: Provider,
receipt: TransactionReceipt) {.async: (raises: [ProviderError]).} = receipt: TransactionReceipt) {.async: (raises: [ProviderError]).} =
@ -237,18 +210,18 @@ proc ensureSuccess(
## If no revert reason was obtained ## If no revert reason was obtained
# TODO: handle TransactionStatus.Invalid? # TODO: handle TransactionStatus.Invalid?
if receipt.status == TransactionStatus.Failure: if receipt.status != TransactionStatus.Failure:
logScope: return
transactionHash = receipt.transactionHash.to0xHex
trace "transaction failed, replaying transaction to get revert reason" without blockNumber =? receipt.blockNumber and
pastTx =? await provider.getTransaction(receipt.transactionHash):
raiseProviderError("Transaction reverted with unknown reason")
if revertReason =? await provider.getRevertReason(receipt): try:
trace "transaction revert reason obtained", revertReason await provider.replay(pastTx.toTransaction, blockNumber)
raiseProviderError(revertReason) raiseProviderError("Transaction reverted with unknown reason")
else: except ProviderError as error:
trace "transaction replay completed, no revert reason obtained" raise error
raiseProviderError("Transaction reverted with unknown reason")
proc confirm*( proc confirm*(
tx: TransactionResponse, tx: TransactionResponse,