Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mouseless0x committed Oct 29, 2024
1 parent ec6fe4a commit b0d3a2b
Show file tree
Hide file tree
Showing 15 changed files with 242 additions and 182 deletions.
3 changes: 3 additions & 0 deletions src/cli/alto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
compatibilityOptions,
debugOptions,
gasEstimationOptions,
gasPriceOptions,
logOptions,
rpcOptions,
serverOptions
Expand Down Expand Up @@ -67,6 +68,8 @@ export function getAltoCli(): yargs.Argv {
.group(Object.keys(debugOptions), "Debug Options:")
.options(gasEstimationOptions)
.group(Object.keys(gasEstimationOptions), "Gas Estimation Options:")
.options(gasPriceOptions)
.group(Object.keys(gasPriceOptions), "Gas Price Options:")
// blank scriptName so that help text doesn't display the cli name before each command
.scriptName("")
.demandCommand(1)
Expand Down
38 changes: 21 additions & 17 deletions src/cli/config/bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,6 @@ export const bundlerArgsSchema = z.object({
"max-bundle-wait": z.number().int().min(0),
"max-bundle-size": z.number().int().min(0),

"gas-price-bump": z
.string()
.transform((val) => BigInt(val))
.default("100"),
"gas-price-floor-percent": z.number().int().min(0),
"gas-price-expiry": z.number().int().min(0),
"gas-price-multipliers": z
.string()
.transform((value) => value.split(",").map(BigInt))
.refine(
(values) => values.length === 3,
"Must contain 3 comma seperated items in format: slow,standard,fast"
)
.transform(([slow, standard, fast]) => ({ slow, standard, fast })),
"gas-price-refresh-interval": z.number().int().min(0),

"mempool-max-parallel-ops": z.number().int().min(0).default(10),
"mempool-max-queued-ops": z.number().int().min(0).default(0),
"enforce-unique-senders-per-bundle": z.boolean().default(true),
Expand Down Expand Up @@ -199,6 +183,22 @@ export const debugArgsSchema = z.object({
tenderly: z.boolean()
})

export const gasPriceArgsSchema = z.object({
"gas-price-staleness-threshold": z.number().int().min(0),
"gas-price-bump": z
.string()
.transform((val) => BigInt(val))
.default("100"),
"gas-price-multipliers": z
.string()
.transform((value) => value.split(",").map(BigInt))
.refine(
(values) => values.length === 3,
"Must contain 3 comma seperated items in format: slow,standard,fast"
)
.transform(([slow, standard, fast]) => ({ slow, standard, fast }))
})

export const gasEstimationArgsSchema = z.object({
"binary-search-tolerance-delta": z
.string()
Expand Down Expand Up @@ -235,6 +235,9 @@ export type ILogArgsInput = z.input<typeof logArgsSchema>
export type IDebugArgs = z.infer<typeof debugArgsSchema>
export type IDebugArgsInput = z.input<typeof debugArgsSchema>

export type IGasPriceArgs = z.infer<typeof gasPriceArgsSchema>
export type IGasPriceArgsInput = z.input<typeof gasPriceArgsSchema>

export type IGasEstimationArgs = z.infer<typeof gasEstimationArgsSchema>
export type IGasEstimationArgsInput = z.input<typeof gasEstimationArgsSchema>

Expand All @@ -246,7 +249,8 @@ export const optionArgsSchema = z.object({
...rpcArgsSchema.shape,
...bundleCopmressionArgsSchema.shape,
...debugArgsSchema.shape,
...gasEstimationArgsSchema.shape
...gasEstimationArgsSchema.shape,
...gasPriceArgsSchema.shape
})

export type IOptions = z.infer<typeof optionArgsSchema>
Expand Down
58 changes: 24 additions & 34 deletions src/cli/config/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
ICompatibilityArgsInput,
IDebugArgsInput,
IGasEstimationArgsInput,
IGasPriceArgsInput,
ILogArgsInput,
IOptionsInput,
IRpcArgsInput,
Expand Down Expand Up @@ -101,46 +102,12 @@ export const bundlerOptions: CliCommandOptions<IBundlerArgsInput> = {
require: true,
default: true
},
"gas-price-bump": {
description: "Amount to multiply the gas prices fetched from the node",
type: "string",
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",
type: "number",
require: true,
default: 101
},
"gas-price-expiry": {
description:
"Maximum that the gas prices fetched using pimlico_getUserOperationGasPrice will be accepted for (seconds)",
type: "number",
require: false,
default: 10
},
"gas-price-multipliers": {
description:
"Amount to multiply the gas prices fetched using pimlico_getUserOperationGasPrice (format: slow,standard,fast)",
type: "string",
require: false,
default: "100,100,100"
},
"gas-price-refresh-interval": {
description:
"How to often to refresh the gas prices (seconds). If 0, then gas prices are refreshed on every request",
type: "number",
require: false,
default: 0
},
"mempool-max-parallel-ops": {
description:
"Maximum amount of parallel user ops to keep in the meempool (same sender, different nonce keys)",
Expand Down Expand Up @@ -195,6 +162,29 @@ export const bundlerOptions: CliCommandOptions<IBundlerArgsInput> = {
}
}

export const gasPriceOptions: CliCommandOptions<IGasPriceArgsInput> = {
"gas-price-bump": {
description: "Amount to multiply the gas prices fetched from the node",
type: "string",
require: false,
default: "100"
},
"gas-price-staleness-threshold": {
description:
"Maximum that the gas prices fetched using pimlico_getUserOperationGasPrice will be accepted for (number of blocks)",
type: "number",
require: false,
default: 10
},
"gas-price-multipliers": {
description:
"Amount to multiply the gas prices fetched using pimlico_getUserOperationGasPrice (format: slow,standard,fast)",
type: "string",
require: false,
default: "100,100,100"
}
}

export const gasEstimationOptions: CliCommandOptions<IGasEstimationArgsInput> =
{
"binary-search-tolerance-delta": {
Expand Down
2 changes: 2 additions & 0 deletions src/cli/setupServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,8 @@ export const setupServer = async ({
"dumping mempool before shutdown"
)

gasPriceManager.shutdown()

process.exit(0)
}

Expand Down
8 changes: 4 additions & 4 deletions src/executor/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export class Executor {
): Promise<ReplaceTransactionResult> {
const newRequest = { ...transactionInfo.transactionRequest }

const gasPriceParameters = await this.gasPriceManager.getGasPrice()
const gasPriceParameters = await this.gasPriceManager.latestGasPrice()

newRequest.maxFeePerGas = maxBigInt(
gasPriceParameters.maxFeePerGas,
Expand Down Expand Up @@ -489,7 +489,7 @@ export class Executor {

const wallets = Array.from(allWallets)

const gasPrice = await this.gasPriceManager.getGasPrice()
const gasPrice = await this.gasPriceManager.latestGasPrice()
const promises = wallets.map((wallet) => {
flushStuckTransaction(
this.config.publicClient,
Expand Down Expand Up @@ -657,7 +657,7 @@ export class Executor {
})
childLogger.debug("bundling user operation")

const gasPriceParameters = await this.gasPriceManager.getGasPrice()
const gasPriceParameters = await this.gasPriceManager.latestGasPrice()
childLogger.debug({ gasPriceParameters }, "got gas price")

const nonce = await this.config.publicClient.getTransactionCount({
Expand Down Expand Up @@ -936,7 +936,7 @@ export class Executor {
})
childLogger.debug("bundling compressed user operation")

const gasPriceParameters = await this.gasPriceManager.getGasPrice()
const gasPriceParameters = await this.gasPriceManager.latestGasPrice()
childLogger.debug({ gasPriceParameters }, "got gas price")

const nonce = await this.config.publicClient.getTransactionCount({
Expand Down
2 changes: 1 addition & 1 deletion src/executor/executorManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ export class ExecutorManager {
await this.refreshUserOperationStatuses()

// for all still not included check if needs to be replaced (based on gas price)
const gasPriceParameters = await this.gasPriceManager.getGasPrice()
const gasPriceParameters = await this.gasPriceManager.latestGasPrice()
this.logger.trace(
{ gasPriceParameters },
"fetched gas price parameters"
Expand Down
2 changes: 1 addition & 1 deletion src/executor/senderManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export class SenderManager {

if (Object.keys(balancesMissing).length > 0) {
const { maxFeePerGas, maxPriorityFeePerGas } =
await this.gasPriceManager.getGasPrice()
await this.gasPriceManager.latestGasPrice()

if (this.config.refillHelperContract) {
const instructions = []
Expand Down
5 changes: 3 additions & 2 deletions src/handlers/arbitrumGasPriceManager.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { TimedQueue } from "@alto/utils"
import { maxUint128 } from "viem"
import { TimedQueue } from "../utils/timedQueue"

export class ArbitrumManager {
private l1BaseFeeQueue: TimedQueue
private l2BaseFeeQueue: TimedQueue

constructor(maxQueueSize: number) {
constructor() {
const queueValidity = 15_000
const maxQueueSize = 250
this.l1BaseFeeQueue = new TimedQueue(maxQueueSize, queueValidity)
this.l2BaseFeeQueue = new TimedQueue(maxQueueSize, queueValidity)
}
Expand Down
Loading

0 comments on commit b0d3a2b

Please sign in to comment.