From 605819528e8819294ddcb794504909e0a59e5a48 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Wed, 6 Nov 2024 04:03:10 +0000 Subject: [PATCH] update --- src/error.ts | 38 +++++++++----------------------- src/modes/index.ts | 19 ++++++++++++++++ src/modes/interOrderbook.ts | 24 ++++++++++++++++---- src/modes/intraOrderbook.ts | 24 ++++++++++++++++---- src/modes/routeProcessor.ts | 25 +++++++++++++++++---- src/processOrders.ts | 7 +++++- src/types.ts | 1 + test/mode-routeProcessor.test.js | 8 +++---- 8 files changed, 102 insertions(+), 44 deletions(-) diff --git a/src/error.ts b/src/error.ts index a6fb07e5..d243a670 100644 --- a/src/error.ts +++ b/src/error.ts @@ -4,16 +4,6 @@ import { InvalidInputRpcError, ExecutionRevertedError, TransactionRejectedRpcError, - // TipAboveFeeCapError, - // TransactionTypeNotSupportedError, - // IntrinsicGasTooLowError, - // IntrinsicGasTooHighError, - // InsufficientFundsError, - // NonceMaxValueError, - // NonceTooLowError, - // NonceTooHighError, - // FeeCapTooLowError, - // FeeCapTooHighError, } from "viem"; /** @@ -54,21 +44,15 @@ export function errorSnapshot(header: string, err: any): string { * "viem/_types/utils/errors/getNodeError" since not a default export */ export function containsNodeError(err: BaseError): boolean { - return ( - err instanceof TransactionRejectedRpcError || - err instanceof InvalidInputRpcError || - err instanceof ExecutionRevertedError || - // err instanceof FeeCapTooHighError || - // err instanceof FeeCapTooLowError || - // err instanceof NonceTooHighError || - // err instanceof NonceTooLowError || - // err instanceof NonceMaxValueError || - // err instanceof InsufficientFundsError || - // err instanceof IntrinsicGasTooHighError || - // err instanceof IntrinsicGasTooLowError || - // err instanceof TransactionTypeNotSupportedError || - // err instanceof TipAboveFeeCapError || - (err instanceof RpcRequestError && err.code === ExecutionRevertedError.code) || - ("cause" in err && containsNodeError(err.cause as any)) - ); + try { + return ( + err instanceof TransactionRejectedRpcError || + err instanceof InvalidInputRpcError || + err instanceof ExecutionRevertedError || + (err instanceof RpcRequestError && err.code === ExecutionRevertedError.code) || + ("cause" in err && containsNodeError(err.cause as any)) + ); + } catch (error) { + return false; + } } diff --git a/src/modes/index.ts b/src/modes/index.ts index 35a0f849..4ba045c5 100644 --- a/src/modes/index.ts +++ b/src/modes/index.ts @@ -98,6 +98,7 @@ export async function findOpp({ spanAttributes, rawtx: undefined, oppBlockNumber: undefined, + noneNodeError: undefined, }; if ((allResults[0] as any)?.reason?.spanAttributes) { spanAttributes["route-processor"] = JSON.stringify( @@ -114,6 +115,24 @@ export async function findOpp({ (allResults[2] as any).reason.spanAttributes, ); } + if ( + "value" in (allResults[0] as any).reason && + "noneNodeError" in (allResults[0] as any).reason.value + ) { + result.noneNodeError = (allResults[0] as any).reason.value.noneNodeError; + } else if ( + result.noneNodeError === undefined && + "value" in (allResults[1] as any).reason && + "noneNodeError" in (allResults[1] as any).reason.value + ) { + result.noneNodeError = (allResults[1] as any).reason.value.noneNodeError; + } else if ( + result.noneNodeError === undefined && + "value" in (allResults[2] as any).reason && + "noneNodeError" in (allResults[2] as any).reason.value + ) { + result.noneNodeError = (allResults[2] as any).reason.value.noneNodeError; + } throw result; } } diff --git a/src/modes/interOrderbook.ts b/src/modes/interOrderbook.ts index 21dd5f98..7a0b2d33 100644 --- a/src/modes/interOrderbook.ts +++ b/src/modes/interOrderbook.ts @@ -104,8 +104,10 @@ export async function dryrun({ spanAttributes["blockNumber"] = blockNumber; gasLimit = ethers.BigNumber.from(await signer.estimateGas(rawtx)); } catch (e) { - spanAttributes["isNodeError"] = containsNodeError(e as BaseError); - spanAttributes["error"] = errorSnapshot("", e); + const isNodeError = containsNodeError(e as BaseError); + const errMsg = errorSnapshot("", e); + spanAttributes["isNodeError"] = isNodeError; + spanAttributes["error"] = errMsg; spanAttributes["rawtx"] = JSON.stringify( { ...rawtx, @@ -113,6 +115,12 @@ export async function dryrun({ }, withBigintSerializer, ); + if (!isNodeError) { + result.value = { + noneNodeError: errMsg, + estimatedProfit: ethers.constants.Zero, + }; + } return Promise.reject(result); } let gasCost = gasLimit.mul(gasPrice); @@ -150,8 +158,10 @@ export async function dryrun({ task, ]); } catch (e) { - spanAttributes["isNodeError"] = containsNodeError(e as BaseError); - spanAttributes["error"] = errorSnapshot("", e); + const isNodeError = containsNodeError(e as BaseError); + const errMsg = errorSnapshot("", e); + spanAttributes["isNodeError"] = isNodeError; + spanAttributes["error"] = errMsg; spanAttributes["rawtx"] = JSON.stringify( { ...rawtx, @@ -159,6 +169,12 @@ export async function dryrun({ }, withBigintSerializer, ); + if (!isNodeError) { + result.value = { + noneNodeError: errMsg, + estimatedProfit: ethers.constants.Zero, + }; + } return Promise.reject(result); } } diff --git a/src/modes/intraOrderbook.ts b/src/modes/intraOrderbook.ts index 25d230a0..094864a5 100644 --- a/src/modes/intraOrderbook.ts +++ b/src/modes/intraOrderbook.ts @@ -92,8 +92,10 @@ export async function dryrun({ gasLimit = ethers.BigNumber.from(await signer.estimateGas(rawtx)); } catch (e) { // reason, code, method, transaction, error, stack, message - spanAttributes["isNodeError"] = containsNodeError(e as BaseError); - spanAttributes["error"] = errorSnapshot("", e); + const isNodeError = containsNodeError(e as BaseError); + const errMsg = errorSnapshot("", e); + spanAttributes["isNodeError"] = isNodeError; + spanAttributes["error"] = errMsg; spanAttributes["rawtx"] = JSON.stringify( { ...rawtx, @@ -101,6 +103,12 @@ export async function dryrun({ }, withBigintSerializer, ); + if (!isNodeError) { + result.value = { + noneNodeError: errMsg, + estimatedProfit: ethers.constants.Zero, + }; + } return Promise.reject(result); } let gasCost = gasLimit.mul(gasPrice); @@ -163,8 +171,10 @@ export async function dryrun({ [clear2Calldata, withdrawInputCalldata, withdrawOutputCalldata], ]); } catch (e) { - spanAttributes["isNodeError"] = containsNodeError(e as BaseError); - spanAttributes["error"] = errorSnapshot("", e); + const isNodeError = containsNodeError(e as BaseError); + const errMsg = errorSnapshot("", e); + spanAttributes["isNodeError"] = isNodeError; + spanAttributes["error"] = errMsg; spanAttributes["rawtx"] = JSON.stringify( { ...rawtx, @@ -172,6 +182,12 @@ export async function dryrun({ }, withBigintSerializer, ); + if (!isNodeError) { + result.value = { + noneNodeError: errMsg, + estimatedProfit: ethers.constants.Zero, + }; + } return Promise.reject(result); } } diff --git a/src/modes/routeProcessor.ts b/src/modes/routeProcessor.ts index 165f64d3..0c8dad26 100644 --- a/src/modes/routeProcessor.ts +++ b/src/modes/routeProcessor.ts @@ -170,8 +170,10 @@ export async function dryrun({ gasLimit = ethers.BigNumber.from(await signer.estimateGas(rawtx)); } catch (e) { // reason, code, method, transaction, error, stack, message - spanAttributes["isNodeError"] = containsNodeError(e as BaseError); - spanAttributes["error"] = errorSnapshot("", e); + const isNodeError = containsNodeError(e as BaseError); + const errMsg = errorSnapshot("", e); + spanAttributes["isNodeError"] = isNodeError; + spanAttributes["error"] = errMsg; spanAttributes["rawtx"] = JSON.stringify( { ...rawtx, @@ -180,6 +182,12 @@ export async function dryrun({ withBigintSerializer, ); result.reason = RouteProcessorDryrunHaltReason.NoOpportunity; + if (!isNodeError) { + result.value = { + noneNodeError: errMsg, + estimatedProfit: ethers.constants.Zero, + }; + } return Promise.reject(result); } let gasCost = gasLimit.mul(gasPrice); @@ -217,8 +225,10 @@ export async function dryrun({ task, ]); } catch (e) { - spanAttributes["isNodeError"] = containsNodeError(e as BaseError); - spanAttributes["error"] = errorSnapshot("", e); + const isNodeError = containsNodeError(e as BaseError); + const errMsg = errorSnapshot("", e); + spanAttributes["isNodeError"] = isNodeError; + spanAttributes["error"] = errMsg; spanAttributes["rawtx"] = JSON.stringify( { ...rawtx, @@ -227,6 +237,12 @@ export async function dryrun({ withBigintSerializer, ); result.reason = RouteProcessorDryrunHaltReason.NoOpportunity; + if (!isNodeError) { + result.value = { + noneNodeError: errMsg, + estimatedProfit: ethers.constants.Zero, + }; + } return Promise.reject(result); } } @@ -338,6 +354,7 @@ export async function findOpp({ if (i !== 1) { delete e.spanAttributes["error"]; delete e.spanAttributes["rawtx"]; + delete e.spanAttributes["isNodeError"]; } allHopsAttributes.push(JSON.stringify(e.spanAttributes)); diff --git a/src/processOrders.ts b/src/processOrders.ts index 597cdb7e..5dff892f 100644 --- a/src/processOrders.ts +++ b/src/processOrders.ts @@ -242,7 +242,11 @@ export const processOrders = async ( if (result.report.status === ProcessPairReportStatus.ZeroOutput) { span.setStatus({ code: SpanStatusCode.OK, message: "zero max output" }); } else if (result.report.status === ProcessPairReportStatus.NoOpportunity) { - span.setStatus({ code: SpanStatusCode.OK, message: "no opportunity" }); + if (result.error && typeof result.error === "string") { + span.setStatus({ code: SpanStatusCode.ERROR, message: result.error }); + } else { + span.setStatus({ code: SpanStatusCode.OK, message: "no opportunity" }); + } } else if (result.report.status === ProcessPairReportStatus.FoundOpportunity) { span.setStatus({ code: SpanStatusCode.OK, message: "found opportunity" }); } else { @@ -573,6 +577,7 @@ export async function processPair(args: { for (const attrKey in e.spanAttributes) { spanAttributes["details." + attrKey] = e.spanAttributes[attrKey]; } + result.error = e?.noneNodeError; result.report = { status: ProcessPairReportStatus.NoOpportunity, tokenPair: pair, diff --git a/src/types.ts b/src/types.ts index 23f992fe..f616810d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -192,6 +192,7 @@ export type DryrunValue = { routeVisual?: string[]; oppBlockNumber?: number; estimatedProfit: BigNumber; + noneNodeError?: string; }; export type DryrunResult = { diff --git a/test/mode-routeProcessor.test.js b/test/mode-routeProcessor.test.js index 2f2997a6..e599b75d 100644 --- a/test/mode-routeProcessor.test.js +++ b/test/mode-routeProcessor.test.js @@ -457,8 +457,8 @@ describe("Test route processor find opp", async function () { spanAttributes: { hops: [ `{"amountIn":"${formatUnits(vaultBalance)}","amountOut":"${formatUnits(getAmountOut(vaultBalance), 6)}","marketPrice":"${formatUnits(getCurrentPrice(vaultBalance))}","route":${JSON.stringify(expectedRouteVisual)},"blockNumber":${oppBlockNumber},"isNodeError":false,"error":${JSON.stringify(errorSnapshot("", ethers.errors.UNPREDICTABLE_GAS_LIMIT))},"rawtx":${JSON.stringify(rawtx)}}`, - `{"amountIn":"${formatUnits(vaultBalance.div(2))}","amountOut":"${formatUnits(getAmountOut(vaultBalance.div(2)), 6)}","marketPrice":"${formatUnits(getCurrentPrice(vaultBalance.div(2)))}","route":${JSON.stringify(expectedRouteVisual)},"blockNumber":${oppBlockNumber},"isNodeError":false}`, - `{"amountIn":"${formatUnits(vaultBalance.div(4))}","amountOut":"${formatUnits(getAmountOut(vaultBalance.div(4)), 6)}","marketPrice":"${formatUnits(getCurrentPrice(vaultBalance.div(4)))}","route":${JSON.stringify(expectedRouteVisual)},"blockNumber":${oppBlockNumber},"isNodeError":false}`, + `{"amountIn":"${formatUnits(vaultBalance.div(2))}","amountOut":"${formatUnits(getAmountOut(vaultBalance.div(2)), 6)}","marketPrice":"${formatUnits(getCurrentPrice(vaultBalance.div(2)))}","route":${JSON.stringify(expectedRouteVisual)},"blockNumber":${oppBlockNumber}}`, + `{"amountIn":"${formatUnits(vaultBalance.div(4))}","amountOut":"${formatUnits(getAmountOut(vaultBalance.div(4)), 6)}","marketPrice":"${formatUnits(getCurrentPrice(vaultBalance.div(4)))}","route":${JSON.stringify(expectedRouteVisual)},"blockNumber":${oppBlockNumber}}`, ], }, }; @@ -652,8 +652,8 @@ describe("Test find opp with retries", async function () { spanAttributes: { hops: [ `{"amountIn":"${formatUnits(vaultBalance)}","amountOut":"${formatUnits(getAmountOut(vaultBalance), 6)}","marketPrice":"${formatUnits(getCurrentPrice(vaultBalance))}","route":${JSON.stringify(expectedRouteVisual)},"blockNumber":${oppBlockNumber},"isNodeError":false,"error":${JSON.stringify(errorSnapshot("", ethers.errors.UNPREDICTABLE_GAS_LIMIT))},"rawtx":${JSON.stringify(rawtx)}}`, - `{"amountIn":"${formatUnits(vaultBalance.div(2))}","amountOut":"${formatUnits(getAmountOut(vaultBalance.div(2)), 6)}","marketPrice":"${formatUnits(getCurrentPrice(vaultBalance.div(2)))}","route":${JSON.stringify(expectedRouteVisual)},"blockNumber":${oppBlockNumber},"isNodeError":false}`, - `{"amountIn":"${formatUnits(vaultBalance.div(4))}","amountOut":"${formatUnits(getAmountOut(vaultBalance.div(4)), 6)}","marketPrice":"${formatUnits(getCurrentPrice(vaultBalance.div(4)))}","route":${JSON.stringify(expectedRouteVisual)},"blockNumber":${oppBlockNumber},"isNodeError":false}`, + `{"amountIn":"${formatUnits(vaultBalance.div(2))}","amountOut":"${formatUnits(getAmountOut(vaultBalance.div(2)), 6)}","marketPrice":"${formatUnits(getCurrentPrice(vaultBalance.div(2)))}","route":${JSON.stringify(expectedRouteVisual)},"blockNumber":${oppBlockNumber}}`, + `{"amountIn":"${formatUnits(vaultBalance.div(4))}","amountOut":"${formatUnits(getAmountOut(vaultBalance.div(4)), 6)}","marketPrice":"${formatUnits(getCurrentPrice(vaultBalance.div(4)))}","route":${JSON.stringify(expectedRouteVisual)},"blockNumber":${oppBlockNumber}}`, ], }, };