Skip to content

Commit

Permalink
feat: Add max pending txs to bot (#8046)
Browse files Browse the repository at this point in the history
Adds a config to txs bot so it does not send more txs if there are more
than N pending txs. Adds a requirement for an AZTEC_NODE_URL to be
passed into the bot runner.

Co-authored-by: PhilWindle <[email protected]>
  • Loading branch information
spalladino and PhilWindle authored Aug 19, 2024
1 parent d7edd24 commit 7f5517e
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 8 deletions.
4 changes: 4 additions & 0 deletions yarn-project/aztec-node/src/aztec-node/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,10 @@ export class AztecNodeService implements AztecNode {
return Promise.resolve(this.p2pClient!.getTxs('pending'));
}

public getPendingTxCount() {
return Promise.resolve(this.p2pClient!.getTxs('pending').length);
}

/**
* Method to retrieve a single tx from the mempool or unfinalised chain.
* @param txHash - The transaction hash to return.
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/aztec/src/cli/cmds/start_bot.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type BotConfig, BotRunner, botConfigMappings, createBotRunnerRpcServer } from '@aztec/bot';
import { type PXE } from '@aztec/circuit-types';
import { type AztecNode, type PXE } from '@aztec/circuit-types';
import { type ServerList } from '@aztec/foundation/json-rpc/server';
import { type LogFn } from '@aztec/foundation/log';

Expand Down Expand Up @@ -35,11 +35,11 @@ export function addBot(
options: any,
services: ServerList,
signalHandlers: (() => Promise<void>)[],
deps: { pxe?: PXE } = {},
deps: { pxe?: PXE; node?: AztecNode } = {},
) {
const config = extractRelevantOptions<BotConfig>(options, botConfigMappings);

const botRunner = new BotRunner(config, { pxe: deps.pxe });
const botRunner = new BotRunner(config, deps);
const botServer = createBotRunnerRpcServer(botRunner);
if (!config.noStart) {
void botRunner.start(); // Do not block since bot setup takes time
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/aztec/src/cli/cmds/start_node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export const startNode = async (
// Add a txs bot if requested
if (options.bot) {
const { addBot } = await import('./start_bot.js');
await addBot(options, services, signalHandlers, { pxe });
await addBot(options, services, signalHandlers, { pxe, node });
}

return services;
Expand Down
14 changes: 14 additions & 0 deletions yarn-project/bot/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ const botFollowChain = ['NONE', 'PENDING', 'PROVEN'] as const;
type BotFollowChain = (typeof botFollowChain)[number];

export type BotConfig = {
/** The URL to the Aztec node to check for tx pool status. */
nodeUrl: string | undefined;
/** URL to the PXE for sending txs, or undefined if an in-proc PXE is used. */
pxeUrl: string | undefined;
/** Signing private key for the sender account. */
Expand All @@ -31,10 +33,17 @@ export type BotConfig = {
noStart: boolean;
/** How long to wait for a tx to be mined before reporting an error. */
txMinedWaitSeconds: number;
/** Whether to wait for txs to be proven, to be mined, or no wait at all. */
followChain: BotFollowChain;
/** Do not send a tx if the node's tx pool already has this many pending txs. */
maxPendingTxs: number;
};

export const botConfigMappings: ConfigMappingsType<BotConfig> = {
nodeUrl: {
env: 'AZTEC_NODE_URL',
description: 'The URL to the Aztec node to check for tx pool status.',
},
pxeUrl: {
env: 'BOT_PXE_URL',
description: 'URL to the PXE for sending txs, or undefined if an in-proc PXE is used.',
Expand Down Expand Up @@ -99,6 +108,11 @@ export const botConfigMappings: ConfigMappingsType<BotConfig> = {
return val as BotFollowChain;
},
},
maxPendingTxs: {
env: 'BOT_MAX_PENDING_TXS',
description: "Do not send a tx if the node's tx pool already has this many pending txs.",
...numberConfigHelper(128),
},
};

export function getBotConfigFromEnv(): BotConfig {
Expand Down
21 changes: 17 additions & 4 deletions yarn-project/bot/src/runner.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type PXE, createDebugLogger } from '@aztec/aztec.js';
import { type AztecNode, type PXE, createAztecNodeClient, createDebugLogger } from '@aztec/aztec.js';
import { RunningPromise } from '@aztec/foundation/running-promise';

import { Bot } from './bot.js';
Expand All @@ -8,11 +8,16 @@ export class BotRunner {
private log = createDebugLogger('aztec:bot');
private bot?: Promise<Bot>;
private pxe?: PXE;
private node: AztecNode;
private runningPromise: RunningPromise;

public constructor(private config: BotConfig, dependencies: { pxe?: PXE } = {}) {
public constructor(private config: BotConfig, dependencies: { pxe?: PXE; node?: AztecNode }) {
this.pxe = dependencies.pxe;
this.runningPromise = new RunningPromise(() => this.#safeRun(), config.txIntervalSeconds * 1000);
if (!dependencies.node && !config.nodeUrl) {
throw new Error(`Missing node URL in config or dependencies`);
}
this.node = dependencies.node ?? createAztecNodeClient(config.nodeUrl!);
this.runningPromise = new RunningPromise(() => this.#work(), config.txIntervalSeconds * 1000);
}

/** Initializes the bot if needed. Blocks until the bot setup is finished. */
Expand Down Expand Up @@ -112,7 +117,15 @@ export class BotRunner {
}
}

async #safeRun() {
async #work() {
if (this.config.maxPendingTxs > 0) {
const pendingTxs = await this.node.getPendingTxs();
if (pendingTxs.length >= this.config.maxPendingTxs) {
this.log.verbose(`Not sending bot tx since node has ${pendingTxs.length} pending txs`);
return;
}
}

try {
await this.run();
} catch (err) {
Expand Down
6 changes: 6 additions & 0 deletions yarn-project/circuit-types/src/interfaces/aztec-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,12 @@ export interface AztecNode {
*/
getPendingTxs(): Promise<Tx[]>;

/**
* Retrieves the number of pending txs
* @returns The number of pending txs.
*/
getPendingTxCount(): Promise<number>;

/**
* Method to retrieve a single pending tx.
* @param txHash - The transaction hash to return.
Expand Down
1 change: 1 addition & 0 deletions yarn-project/foundation/src/config/env_var.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export type EnvVar =
| 'BOT_NO_START'
| 'BOT_TX_MINED_WAIT_SECONDS'
| 'BOT_NO_WAIT_FOR_TRANSFERS'
| 'BOT_MAX_PENDING_TXS'
| 'PXE_BLOCK_POLLING_INTERVAL_MS'
| 'PXE_L2_STARTING_BLOCK'
| 'PXE_DATA_DIRECTORY'
Expand Down

0 comments on commit 7f5517e

Please sign in to comment.