Skip to content

Commit

Permalink
Merge branch '2024-12-02-l1-gas' into 2024-12-03-quote-gas-limit
Browse files Browse the repository at this point in the history
  • Loading branch information
rouzwelt authored Dec 26, 2024
2 parents 3d5cd29 + da8b3a9 commit 607ce9e
Show file tree
Hide file tree
Showing 13 changed files with 85 additions and 46 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ Other optional arguments are:
- `--owner-profile`, Specifies the owner limit, example: --owner-profile 0x123456=12 . Will override the 'OWNER_PROFILE' in env variables
- `--public-rpc`, Allows to use public RPCs as fallbacks, default is false. Will override the 'PUBLIC_RPC' in env variables
- `--gas-price-multiplier`, Option to multiply the gas price fetched from the rpc as percentage, default is 107, ie +7%. Will override the 'GAS_PRICE_MULTIPLIER' in env variables
- `--gas-limit-multiplier`, Option to multiply the gas limit estimation from the rpc as percentage, default is 105, ie +5%. Will override the 'GAS_LIMIT_MULTIPLIER' in env variables
- `--tx-gas`, Option to set a static gas limit for all submitting txs. Will override the 'TX_GAS' in env variables
- `--gas-limit-multiplier`, Option to multiply the gas limit estimation from the rpc as percentage, default is 100, ie no change. Will override the 'GAS_LIMIT_MULTIPLIER' in env variables
- `--tx-gas`, Option to set a gas limit for all submitting txs optionally with appended percentage sign to apply as percentage to original gas. Will override the 'TX_GAS' in env variables
- `--quote-gas`, Option to set a static gas limit for quote read calls, default is 1 milion. Will override the 'QUOTE_GAS' in env variables
- `--rp-only`, Only clear orders through RP4, excludes intra and inter orderbook clears. Will override the 'RP_ONLY' in env variablesin env variables
- `-V` or `--version`, output the version number
Expand Down Expand Up @@ -264,10 +264,10 @@ ROUTE="single"
# Option to multiply the gas price fetched from the rpc as percentage, default is 107, ie +7%
GAS_PRICE_MULTIPLIER=

# Option to multiply the gas limit estimation from the rpc as percentage, default is 105, ie +5%
# Option to multiply the gas limit estimation from the rpc as percentage, default is 100, ie no change
GAS_LIMIT_MULTIPLIER=

# Option to set a static gas limit for all submitting txs
# Option to set a gas limit for all submitting txs optionally with appended percentage sign to apply as percentage to original gas
TX_GAS=

# Option to set a static gas limit for quote read calls, default is 1 milion
Expand Down
4 changes: 2 additions & 2 deletions example.env
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ ROUTE="single"
# Option to multiply the gas price fetched from the rpc as percentage, default is 107, ie +7%
GAS_PRICE_MULTIPLIER=

# Option to multiply the gas limit estimation from the rpc as percentage, default is 105, ie +5%
# Option to multiply the gas limit estimation from the rpc as percentage, default is 100, ie no change
GAS_LIMIT_MULTIPLIER=

# Option to set a static gas limit for all submitting txs
# Option to set a gas limit for all submitting txs optionally with appended percentage sign to apply as percentage to original gas
TX_GAS=

# Option to set a static gas limit for quote read calls, default is 1 milion
Expand Down
18 changes: 6 additions & 12 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,11 @@ const getOptions = async (argv: any, version?: string) => {
)
.option(
"--gas-limit-multiplier <integer>",
"Option to multiply the gas limit estimation from the rpc as percentage, default is 105, ie +5%. Will override the 'GAS_LIMIT_MULTIPLIER' in env variables",
"Option to multiply the gas limit estimation from the rpc as percentage, default is 100, ie no change. Will override the 'GAS_LIMIT_MULTIPLIER' in env variables",
)
.option(
"--tx-gas <integer>",
"Option to set a static gas limit for all submitting txs. Will override the 'TX_GAS' in env variables",
"Option to set a gas limit for all submitting txs optionally with appended percentage sign to apply as percentage to original gas. Will override the 'TX_GAS' in env variables",
)
.option(
"--quote-gas <integer>",
Expand Down Expand Up @@ -458,18 +458,12 @@ export async function startup(argv: any, version?: string, tracer?: Tracer, ctx?
throw "invalid gasLimitMultiplier value, must be an integer greater than zero";
} else throw "invalid gasLimitMultiplier value, must be an integer greater than zero";
} else {
options.gasLimitMultiplier = 105;
options.gasLimitMultiplier = 100;
}
if (options.txGas) {
if (typeof options.txGas === "number") {
if (options.txGas <= 0 || !Number.isInteger(options.txGas))
throw "invalid txGas value, must be an integer greater than zero";
else options.txGas = BigInt(options.txGas);
} else if (typeof options.txGas === "string" && /^[0-9]+$/.test(options.txGas)) {
options.txGas = BigInt(options.txGas);
if (options.txGas <= 0n)
throw "invalid txGas value, must be an integer greater than zero";
} else throw "invalid txGas value, must be an integer greater than zero";
if (typeof options.txGas !== "string" || !/^[0-9]+%?$/.test(options.txGas)) {
throw "invalid txGas value, must be an integer greater than zero optionally with appended percentage sign to apply as percentage to original gas";
}
}
if (options.quoteGas) {
try {
Expand Down
27 changes: 19 additions & 8 deletions src/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ export function errorSnapshot(
* Checks if a viem BaseError is from eth node, copied from
* "viem/_types/utils/errors/getNodeError" since not a default export
*/
export function containsNodeError(err: BaseError): boolean {
export function containsNodeError(err: BaseError, circuitBreaker = 0): boolean {
if (circuitBreaker > 25) return false;
try {
const snapshot = errorSnapshot("", err);
const parsed = parseRevertError(err);
Expand All @@ -145,7 +146,7 @@ export function containsNodeError(err: BaseError): boolean {
err instanceof InsufficientFundsError ||
(err instanceof RpcRequestError && err.code === ExecutionRevertedError.code) ||
(snapshot.includes("exceeds allowance") && !snapshot.includes("out of gas")) ||
("cause" in err && containsNodeError(err.cause as any))
("cause" in err && containsNodeError(err.cause as any, ++circuitBreaker))
);
} catch (error) {
return false;
Expand All @@ -155,14 +156,15 @@ export function containsNodeError(err: BaseError): boolean {
/**
* Checks if a viem BaseError is timeout error
*/
export function isTimeout(err: BaseError): boolean {
export function isTimeout(err: BaseError, circuitBreaker = 0): boolean {
if (circuitBreaker > 25) return false;
try {
return (
err instanceof TimeoutError ||
err instanceof TransactionNotFoundError ||
err instanceof TransactionReceiptNotFoundError ||
err instanceof WaitForTransactionReceiptTimeoutError ||
("cause" in err && isTimeout(err.cause as any))
("cause" in err && isTimeout(err.cause as any, ++circuitBreaker))
);
} catch (error) {
return false;
Expand Down Expand Up @@ -227,14 +229,23 @@ export async function handleRevert(
/**
* Parses a revert error to TxRevertError type
*/
export function parseRevertError(error: BaseError): TxRevertError {
export function parseRevertError(error: BaseError, circuitBreaker = 0): TxRevertError {
if (circuitBreaker > 25) {
return {
raw: {
code: -2,
message:
"Couldn't extract rpc error from the viem error object because the viem error object is circular",
},
};
}
if ("cause" in error) {
return parseRevertError(error.cause as any);
return parseRevertError(error.cause as any, ++circuitBreaker);
} else {
let decoded: DecodedError | undefined;
const raw: RawError = {
code: (error as any).code ?? NaN,
message: error.message,
code: (error as any).code ?? -2,
message: error.message ?? "No error msg",
data: (error as any).data ?? undefined,
};
if ("data" in error && isHex(error.data)) {
Expand Down
3 changes: 2 additions & 1 deletion src/modes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ export async function findOpp({
fromToken: Token;
}): Promise<DryrunResult> {
try {
gasPrice = BigNumber.from(await viemClient.getGasPrice())
const gp = BigNumber.from(await viemClient.getGasPrice())
.mul(config.gasPriceMultiplier)
.div("100")
.toBigInt();
if (gp > gasPrice) gasPrice = gp;
} catch {
/**/
}
Expand Down
3 changes: 0 additions & 3 deletions src/modes/interOrderbook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,6 @@ export async function dryrun({
}
}
rawtx.gas = gasLimit.toBigInt();
if (typeof config.txGas === "bigint") {
rawtx.gas = config.txGas;
}

// if reached here, it means there was a success and found opp
spanAttributes["oppBlockNumber"] = blockNumber;
Expand Down
3 changes: 0 additions & 3 deletions src/modes/intraOrderbook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,6 @@ export async function dryrun({
}
}
rawtx.gas = gasLimit.toBigInt();
if (typeof config.txGas === "bigint") {
rawtx.gas = config.txGas;
}

// if reached here, it means there was a success and found opp
spanAttributes["oppBlockNumber"] = blockNumber;
Expand Down
4 changes: 1 addition & 3 deletions src/modes/routeProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export async function dryrun({
config.route,
);
if (route.status == "NoWay") {
if (hasPriceMatch) hasPriceMatch.value = false;
spanAttributes["route"] = "no-way";
result.reason = RouteProcessorDryrunHaltReason.NoRoute;
return Promise.reject(result);
Expand Down Expand Up @@ -286,9 +287,6 @@ export async function dryrun({
}
}
rawtx.gas = gasLimit.toBigInt();
if (typeof config.txGas === "bigint") {
rawtx.gas = config.txGas;
}

// if reached here, it means there was a success and found opp
// rest of span attr are not needed since they are present in the result.data
Expand Down
20 changes: 17 additions & 3 deletions src/tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ export async function handleTransaction(
let txhash: `0x${string}`, txUrl: string;
let time = 0;
const sendTx = async () => {
if (writeSigner !== undefined) {
rawtx.gas = undefined;
}
rawtx.gas = getTxGas(config, rawtx.gas!);
txhash =
writeSigner !== undefined
? await writeSigner.sendTx({
Expand Down Expand Up @@ -384,3 +382,19 @@ export async function pollSigners(accounts: ViemClient[]): Promise<ViemClient> {
}
}
}

/**
* Returns the gas limit for a tx by applying the specified config
*/
export function getTxGas(config: BotConfig, gas: bigint): bigint {
if (config.txGas) {
if (config.txGas.endsWith("%")) {
const multiplier = BigInt(config.txGas.substring(0, config.txGas.length - 1));
return (gas * multiplier) / 100n;
} else {
return BigInt(config.txGas);
}
} else {
return gas;
}
}
4 changes: 2 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export type CliOptions = {
route?: string;
gasPriceMultiplier: number;
gasLimitMultiplier: number;
txGas?: bigint;
txGas?: string;
quoteGas: bigint;
rpOnly?: boolean;
};
Expand Down Expand Up @@ -193,7 +193,7 @@ export type BotConfig = {
rpcRecords: Record<string, RpcRecord>;
gasPriceMultiplier: number;
gasLimitMultiplier: number;
txGas?: bigint;
txGas?: string;
quoteGas: bigint;
rpOnly?: boolean;
onFetchRequest?: (request: Request) => void;
Expand Down
4 changes: 2 additions & 2 deletions test/cli.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,15 +212,15 @@ describe("Test cli", async function () {
},
gasPriceMultiplier: 120,
gasLimitMultiplier: 110,
txGas: 123456789n,
txGas: "123456789",
quoteGas: 7777n,
rpOnly: true,
},
options: {
botMinBalance: "0.123",
gasPriceMultiplier: 120,
gasLimitMultiplier: 110,
txGas: 123456789n,
txGas: "123456789",
quoteGas: 7777n,
rpOnly: true,
},
Expand Down
9 changes: 6 additions & 3 deletions test/e2e/e2e.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,17 @@ for (let i = 0; i < testData.length; i++) {
provider.register();
const tracer = provider.getTracer("arb-bot-tracer");

config.rpc = [rpc];
const dataFetcherPromise = getDataFetcher(config, liquidityProviders, false);

// run tests on each rp version
for (let j = 0; j < rpVersions.length; j++) {
const rpVersion = rpVersions[j];

it(`should clear orders successfully using route processor v${rpVersion}`, async function () {
config.rpc = [rpc];
const viemClient = await viem.getPublicClient();
const dataFetcher = await getDataFetcher(config, liquidityProviders, false);
const dataFetcher = await dataFetcherPromise;
const testSpan = tracer.startSpan("test-clearing");
const ctx = trace.setSpan(context.active(), testSpan);

Expand Down Expand Up @@ -342,7 +345,7 @@ for (let i = 0; i < testData.length; i++) {
it("should clear orders successfully using inter-orderbook", async function () {
config.rpc = [rpc];
const viemClient = await viem.getPublicClient();
const dataFetcher = await getDataFetcher(config, liquidityProviders, false);
const dataFetcher = await dataFetcherPromise;
const testSpan = tracer.startSpan("test-clearing");
const ctx = trace.setSpan(context.active(), testSpan);

Expand Down Expand Up @@ -690,7 +693,7 @@ for (let i = 0; i < testData.length; i++) {
it("should clear orders successfully using intra-orderbook", async function () {
config.rpc = [rpc];
const viemClient = await viem.getPublicClient();
const dataFetcher = await getDataFetcher(config, liquidityProviders, false);
const dataFetcher = await dataFetcherPromise;
const testSpan = tracer.startSpan("test-clearing");
const ctx = trace.setSpan(context.active(), testSpan);

Expand Down
24 changes: 24 additions & 0 deletions test/tx.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
handleReceipt,
sendTransaction,
handleTransaction,
getTxGas,
} from "../src/tx";

describe("Test tx", async function () {
Expand Down Expand Up @@ -423,4 +424,27 @@ describe("Test tx", async function () {
const result = await pollSigners(someMockedSigners);
assert.equal(result, someMockedSigners[2]);
});

it("should test getTxGas", async function () {
const gas = 500n;

// percentage
const config = {
txGas: "120%",
} as any;
let result = getTxGas(config, gas);
let expected = 600n;
assert.equal(result, expected);

// static
config.txGas = "900";
result = getTxGas(config, gas);
expected = 900n;
assert.equal(result, expected);

// none
config.txGas = undefined;
result = getTxGas(config, gas);
assert.equal(result, gas);
});
});

0 comments on commit 607ce9e

Please sign in to comment.