From f5d667491c90ce4aa3b6e9e8014c312183dcf961 Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Wed, 29 May 2024 15:34:27 +0100 Subject: [PATCH] capture reverts from compressed ops --- src/executor/utils.ts | 65 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/src/executor/utils.ts b/src/executor/utils.ts index 352a1fcc..62dc5f7a 100644 --- a/src/executor/utils.ts +++ b/src/executor/utils.ts @@ -37,7 +37,9 @@ import { concat, decodeErrorResult, hexToBytes, - numberToHex + numberToHex, + formatTransactionRequest, + RpcRequestError } from "viem" export function simulatedOpsToResults( @@ -192,15 +194,19 @@ export async function filterOpsAndEstimateGas( .mempoolUserOperation as CompressedUserOperation ) - gasLimit = await publicClient.estimateGas({ + const tx = formatTransactionRequest({ to: bundleBulker, - account: wallet, + from: wallet.address, data: createCompressedCalldata(opsToSend, perOpInflatorId), gas: fixedGasLimitForEstimation, nonce: nonce, - blockTag, ...gasOptions }) + + gasLimit = await publicClient.request({ + method: "eth_estimateGas", + params: [tx, blockTag] + }) } return { simulatedOps, gasLimit, resubmitAllOps: false } @@ -321,6 +327,57 @@ export async function filterOpsAndEstimateGas( { error: JSON.stringify(err) }, "failed to parse error result" ) + return { + simulatedOps: [], + gasLimit: 0n, + resubmitAllOps: false + } + } + } else if (err instanceof RpcRequestError) { + try { + const errorHexData = (err.cause as unknown as any).data + + const errorResult = decodeErrorResult({ + abi: isUserOpV06 ? EntryPointV06Abi : EntryPointV07Abi, + data: errorHexData + }) + logger.debug( + { + errorName: errorResult.errorName, + args: errorResult.args, + userOpHashes: simulatedOps + .filter((op) => op.reason === undefined) + .map((op) => op.owh.userOperationHash) + }, + "user op in batch invalid" + ) + + if (errorResult.errorName !== "FailedOp") { + logger.error( + { + errorName: errorResult.errorName, + args: errorResult.args + }, + "unexpected error result" + ) + return { + simulatedOps: [], + gasLimit: 0n, + resubmitAllOps: false + } + } + + const failingOp = simulatedOps.filter( + (op) => op.reason === undefined + )[Number(errorResult.args[0])] + + failingOp.reason = errorResult.args[1] + } catch (e: unknown) { + logger.error( + { error: JSON.stringify(e) }, + "failed to parse error result" + ) + return { simulatedOps: [], gasLimit: 0n,