From b087b8cfa684da91a422db841f4a1929e38bda41 Mon Sep 17 00:00:00 2001 From: mouseless <97399882+mouseless-eth@users.noreply.github.com> Date: Fri, 24 Jan 2025 02:22:05 +0000 Subject: [PATCH] add resubmit timeout flag --- src/cli/alto.ts | 3 + src/cli/config/bundler.ts | 86 +++++++++-------- src/cli/config/options.ts | 159 +++++++++++++++++--------------- src/executor/executor.ts | 8 +- src/executor/executorManager.ts | 5 +- 5 files changed, 143 insertions(+), 118 deletions(-) diff --git a/src/cli/alto.ts b/src/cli/alto.ts index 7c01c932..ff000bf0 100644 --- a/src/cli/alto.ts +++ b/src/cli/alto.ts @@ -7,6 +7,7 @@ import { bundlerOptions, compatibilityOptions, debugOptions, + executorOptions, gasEstimationOptions, logOptions, rpcOptions, @@ -71,6 +72,8 @@ export function getAltoCli(): yargs.Argv { .group(Object.keys(compatibilityOptions), "Compatibility Options:") .options(serverOptions) .group(Object.keys(serverOptions), "Server Options:") + .options(executorOptions) + .group(Object.keys(executorOptions), "Executor Options:") .options(rpcOptions) .group(Object.keys(rpcOptions), "RPC Options:") .options(logOptions) diff --git a/src/cli/config/bundler.ts b/src/cli/config/bundler.ts index e45316ab..17a04e13 100644 --- a/src/cli/config/bundler.ts +++ b/src/cli/config/bundler.ts @@ -27,43 +27,7 @@ export const bundlerArgsSchema = z.object({ return validatedAddresses }), "deterministic-deployer-address": addressSchema, - "entrypoint-simulation-contract": z.preprocess( - (v) => (v === "" ? undefined : v), - addressSchema.optional() - ), - "refill-helper-contract": addressSchema.optional(), - "no-profit-bundling": z.boolean(), "safe-mode": z.boolean(), - "utility-private-key": hexData32Schema - .transform((val) => privateKeyToAccount(val) satisfies Account) - .optional(), - "utility-wallet-monitor": z.boolean(), - "utility-wallet-monitor-interval": z.number(), - "executor-private-keys": z.union([ - z - .array(hexData32Schema) - .transform((vals) => - vals.map((val) => privateKeyToAccount(val) satisfies Account) - ), - z - .string() - .regex(/^0x(?:[0-9a-f]{2}){32}(?:,0x(?:[0-9a-f]{2}){32})*$/) - .transform((val) => - val - .split(",") - .map( - (val) => - privateKeyToAccount(val as Hex) satisfies Account - ) - ) - ]), - "max-executors": z.number().int().min(0).optional(), - "min-executor-balance": z - .string() - .transform((val) => BigInt(val)) - .optional(), - "executor-refill-interval": z.number().int().min(0), - "executor-gas-multiplier": z.string().transform((val) => BigInt(val)), "min-entity-stake": z.number().int().min(0), "min-entity-unstake-delay": z.number().int().min(0), @@ -119,12 +83,48 @@ export const bundlerArgsSchema = z.object({ "," )}` ), - "refilling-wallets": z.boolean().default(true), - "aa95-gas-multiplier": z.string().transform((val) => BigInt(val)), "enable-instant-bundling-endpoint": z.boolean(), "enable-experimental-7702-endpoints": z.boolean() }) +export const executorArgsSchema = z.object({ + "resubmit-timeout": z.number().int().min(0).default(15_000), + "refilling-wallets": z.boolean().default(true), + "aa95-gas-multiplier": z.string().transform((val) => BigInt(val)), + "refill-helper-contract": addressSchema.optional(), + "no-profit-bundling": z.boolean(), + "utility-private-key": hexData32Schema + .transform((val) => privateKeyToAccount(val) satisfies Account) + .optional(), + "utility-wallet-monitor": z.boolean(), + "utility-wallet-monitor-interval": z.number(), + "executor-private-keys": z.union([ + z + .array(hexData32Schema) + .transform((vals) => + vals.map((val) => privateKeyToAccount(val) satisfies Account) + ), + z + .string() + .regex(/^0x(?:[0-9a-f]{2}){32}(?:,0x(?:[0-9a-f]{2}){32})*$/) + .transform((val) => + val + .split(",") + .map( + (val) => + privateKeyToAccount(val as Hex) satisfies Account + ) + ) + ]), + "max-executors": z.number().int().min(0).optional(), + "min-executor-balance": z + .string() + .transform((val) => BigInt(val)) + .optional(), + "executor-refill-interval": z.number().int().min(0), + "executor-gas-multiplier": z.string().transform((val) => BigInt(val)) +}) + export const compatibilityArgsSchema = z.object({ "chain-type": z.enum([ "default", @@ -199,6 +199,10 @@ export const debugArgsSchema = z.object({ }) export const gasEstimationArgsSchema = z.object({ + "entrypoint-simulation-contract": z.preprocess( + (v) => (v === "" ? undefined : v), + addressSchema.optional() + ), "binary-search-tolerance-delta": z .string() .transform((val) => BigInt(val)) @@ -234,6 +238,9 @@ export type IBundlerArgsInput = z.input export type ICompatibilityArgs = z.infer export type ICompatibilityArgsInput = z.input +export type IExecutorArgs = z.infer +export type IExecutorArgsInput = z.input + export type IServerArgs = z.infer export type IServerArgsInput = z.input @@ -256,7 +263,8 @@ export const optionArgsSchema = z.object({ ...serverArgsSchema.shape, ...rpcArgsSchema.shape, ...debugArgsSchema.shape, - ...gasEstimationArgsSchema.shape + ...gasEstimationArgsSchema.shape, + ...executorArgsSchema.shape }) export type IOptions = z.infer diff --git a/src/cli/config/options.ts b/src/cli/config/options.ts index 493f0b39..65743efe 100644 --- a/src/cli/config/options.ts +++ b/src/cli/config/options.ts @@ -4,6 +4,7 @@ import type { IBundlerArgsInput, ICompatibilityArgsInput, IDebugArgsInput, + IExecutorArgsInput, IGasEstimationArgsInput, ILogArgsInput, IOptionsInput, @@ -25,56 +26,6 @@ export const bundlerOptions: CliCommandOptions = { require: false, default: "0x4e59b44847b379578588920ca78fbf26c0b4956c" }, - "entrypoint-simulation-contract": { - description: "Address of the EntryPoint simulations contract", - type: "string", - alias: "c", - require: false - }, - "refill-helper-contract": { - description: "Address of the Executor refill helper contract", - type: "string", - require: false - }, - "executor-private-keys": { - description: "Private keys of the executor accounts split by commas", - type: "string", - alias: "x", - require: true - }, - "utility-private-key": { - description: "Private key of the utility account", - type: "string", - alias: "u", - require: false - }, - "utility-wallet-monitor": { - description: "Either to enable utility wallet monitor or not", - type: "boolean", - default: true - }, - "utility-wallet-monitor-interval": { - description: "Interval for checking utility wallet balance", - type: "number", - default: 15 * 1000 // 15 seconds - }, - "max-executors": { - description: - "Maximum number of executor accounts to use from the list of executor private keys", - type: "number", - require: false - }, - "min-executor-balance": { - description: - "Minimum balance required for each executor account (below which the utility account will refill)", - type: "string" - }, - "executor-refill-interval": { - description: "Interval to refill the signer balance (seconds)", - type: "number", - require: true, - default: 60 * 20 - }, "min-entity-stake": { description: "Minimum stake required for a relay (in 10e18)", type: "number", @@ -112,12 +63,6 @@ export const bundlerOptions: CliCommandOptions = { require: false, default: "100" }, - "no-profit-bundling": { - description: - "Bundle tx such that all beneficiary fees are spent on gas fees", - type: "boolean", - default: false - }, "gas-price-floor-percent": { description: "The minimum percentage of incoming user operation gas prices compared to the gas price used by the bundler to submit bundles", @@ -179,19 +124,6 @@ export const bundlerOptions: CliCommandOptions = { require: false, default: null }, - "refilling-wallets": { - description: "Enable refilling wallets", - type: "boolean", - require: false, - default: true - }, - "aa95-gas-multiplier": { - description: - "Amount to multiply the current gas limit by if the bundling tx fails due to AA95", - type: "string", - require: false, - default: "125" - }, "enable-instant-bundling-endpoint": { description: "Should the bundler enable the pimlico_sendUserOperationNow endpoint", @@ -203,16 +135,17 @@ export const bundlerOptions: CliCommandOptions = { "Should the bundler enable the pimlico_experimental_sendUserOperation7702 and pimlico_experimental_estimateUserOperationGas7702 endpoint", type: "boolean", default: false - }, - "executor-gas-multiplier": { - description: "Amount to scale the gas estimations used for bundling", - type: "string", - default: "100" } } export const gasEstimationOptions: CliCommandOptions = { + "entrypoint-simulation-contract": { + description: "Address of the EntryPoint simulations contract", + type: "string", + alias: "c", + require: false + }, "binary-search-tolerance-delta": { description: "Defines the threshold for when to stop the gas estimation binary search", @@ -292,6 +225,84 @@ export const gasEstimationOptions: CliCommandOptions = } } +export const executorOptions: CliCommandOptions = { + "resubmit-timeout": { + description: + "Amount of time before retrying a failed userOperation (in ms)", + type: "number", + require: true, + default: 15_000 + }, + "aa95-gas-multiplier": { + description: + "Amount to multiply the current gas limit by if the bundling tx fails due to AA95", + type: "string", + require: false, + default: "125" + }, + "refilling-wallets": { + description: "Enable refilling wallets", + type: "boolean", + require: false, + default: true + }, + "executor-gas-multiplier": { + description: "Amount to scale the gas estimations used for bundling", + type: "string", + default: "100" + }, + "no-profit-bundling": { + description: + "Bundle tx such that all beneficiary fees are spent on gas fees", + type: "boolean", + default: false + }, + "refill-helper-contract": { + description: "Address of the Executor refill helper contract", + type: "string", + require: false + }, + "executor-private-keys": { + description: "Private keys of the executor accounts split by commas", + type: "string", + alias: "x", + require: true + }, + "utility-private-key": { + description: "Private key of the utility account", + type: "string", + alias: "u", + require: false + }, + "utility-wallet-monitor": { + description: "Either to enable utility wallet monitor or not", + type: "boolean", + default: true + }, + "utility-wallet-monitor-interval": { + description: "Interval for checking utility wallet balance", + type: "number", + default: 15 * 1000 // 15 seconds + }, + "max-executors": { + description: + "Maximum number of executor accounts to use from the list of executor private keys", + type: "number", + require: false + }, + "min-executor-balance": { + description: + "Minimum balance required for each executor account (below which the utility account will refill)", + type: "string" + }, + "executor-refill-interval": { + description: "Interval to refill the signer balance (seconds)", + type: "number", + require: true, + default: 60 * 20 + } +} + export const compatibilityOptions: CliCommandOptions = { "chain-type": { diff --git a/src/executor/executor.ts b/src/executor/executor.ts index a415e874..614ae4f7 100644 --- a/src/executor/executor.ts +++ b/src/executor/executor.ts @@ -145,14 +145,14 @@ export class Executor { return { status: "failed" } } - newRequest.maxFeePerGas = maxBigInt( + newRequest.maxFeePerGas = scaleBigIntByPercent( gasPriceParameters.maxFeePerGas, - (newRequest.maxFeePerGas * 11n + 9n) / 10n + 115n ) - newRequest.maxPriorityFeePerGas = maxBigInt( + newRequest.maxPriorityFeePerGas = scaleBigIntByPercent( gasPriceParameters.maxPriorityFeePerGas, - (newRequest.maxPriorityFeePerGas * 11n + 9n) / 10n + 115n ) newRequest.account = transactionInfo.executor diff --git a/src/executor/executorManager.ts b/src/executor/executorManager.ts index 4a0df0af..42137e21 100644 --- a/src/executor/executorManager.ts +++ b/src/executor/executorManager.ts @@ -822,7 +822,10 @@ export class ExecutorManager { ) await Promise.all( transactionInfos2.map(async (txInfo) => { - if (Date.now() - txInfo.lastReplaced < 5 * 60 * 1000) { + if ( + Date.now() - txInfo.lastReplaced < + this.config.resubmitTimeout + ) { return }