Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Handle exceptions in bot runner #7679

Merged
merged 2 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions yarn-project/aztec/terraform/bot/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ resource "aws_ecs_task_definition" "aztec-bot" {
{ name = "BOT_NO_START", value = "true" },
{ name = "BOT_PXE_URL", value = "http://${var.DEPLOY_TAG}-aztec-pxe-1.local/${var.DEPLOY_TAG}/aztec-pxe-1/${var.API_KEY}" },
{ name = "BOT_TX_INTERVAL_SECONDS", value = 300 },
{ name = "LOG_LEVEL", value = var.LOG_LEVEL },
{ name = "AZTEC_PORT", value = "80" },
{ name = "API_PREFIX", value = local.api_prefix },
]
Expand Down
5 changes: 5 additions & 0 deletions yarn-project/aztec/terraform/bot/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,8 @@ variable "BOT_API_KEY" {
variable "BOT_PRIVATE_KEY" {
type = string
}

variable "LOG_LEVEL" {
type = string
default = "verbose"
}
23 changes: 19 additions & 4 deletions yarn-project/bot/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ export class Bot {
}

public async run() {
const logCtx = { runId: Date.now() * 1000 + Math.floor(Math.random() * 1000) };
const { privateTransfersPerTx, publicTransfersPerTx, feePaymentMethod } = this.config;
const { token, recipient, wallet } = this;
const sender = wallet.getAddress();

this.log.verbose(
`Sending tx with ${feePaymentMethod} fee with ${privateTransfersPerTx} private and ${publicTransfersPerTx} public transfers`,
logCtx,
);

const calls: FunctionCall[] = [
Expand All @@ -52,11 +54,24 @@ export class Bot {
const paymentMethod = feePaymentMethod === 'native' ? new NativeFeePaymentMethod(sender) : new NoFeePaymentMethod();
const gasSettings = GasSettings.default();
const opts: SendMethodOptions = { estimateGas: true, fee: { paymentMethod, gasSettings } };
const tx = new BatchCall(wallet, calls).send(opts);
this.log.verbose(`Sent tx ${tx.getTxHash()}`);

const receipt = await tx.wait();
this.log.info(`Tx ${receipt.txHash} mined in block ${receipt.blockNumber}`);
const batch = new BatchCall(wallet, calls);
this.log.verbose(`Creating batch execution request with ${calls.length} calls`, logCtx);
await batch.create(opts);

this.log.verbose(`Simulating transaction`, logCtx);
await batch.simulate();

this.log.verbose(`Proving transaction`, logCtx);
await batch.prove(opts);

this.log.verbose(`Sending tx`, logCtx);
const tx = batch.send(opts);

this.log.verbose(`Awaiting tx ${tx.getTxHash()} to be mined (timeout ${this.config.txMinedWaitSeconds}s)`, logCtx);
const receipt = await tx.wait({ timeout: this.config.txMinedWaitSeconds });

this.log.info(`Tx ${receipt.txHash} mined in block ${receipt.blockNumber}`, logCtx);
}

public async getBalances() {
Expand Down
5 changes: 5 additions & 0 deletions yarn-project/bot/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export type BotConfig = {
feePaymentMethod: 'native' | 'none';
/** True to not automatically setup or start the bot on initialization. */
noStart: boolean;
/** How long to wait for a tx to be mined before reporting an error. */
txMinedWaitSeconds: number;
};

export function getBotConfigFromEnv(): BotConfig {
Expand All @@ -32,6 +34,7 @@ export function getBotConfigFromEnv(): BotConfig {
BOT_PRIVATE_TRANSFERS_PER_TX,
BOT_PUBLIC_TRANSFERS_PER_TX,
BOT_NO_START,
BOT_TX_MINED_WAIT_SECONDS,
} = process.env;
if (BOT_FEE_PAYMENT_METHOD && !['native', 'none'].includes(BOT_FEE_PAYMENT_METHOD)) {
throw new Error(`Invalid bot fee payment method: ${BOT_FEE_PAYMENT_METHOD}`);
Expand All @@ -49,6 +52,7 @@ export function getBotConfigFromEnv(): BotConfig {
publicTransfersPerTx: BOT_PUBLIC_TRANSFERS_PER_TX ? parseInt(BOT_PUBLIC_TRANSFERS_PER_TX) : undefined,
feePaymentMethod: BOT_FEE_PAYMENT_METHOD ? (BOT_FEE_PAYMENT_METHOD as 'native' | 'none') : undefined,
noStart: BOT_NO_START ? ['1', 'true'].includes(BOT_NO_START) : undefined,
txMinedWaitSeconds: BOT_TX_MINED_WAIT_SECONDS ? parseInt(BOT_TX_MINED_WAIT_SECONDS) : undefined,
});
}

Expand All @@ -63,6 +67,7 @@ export function getBotDefaultConfig(overrides: Partial<BotConfig> = {}): BotConf
publicTransfersPerTx: 1,
feePaymentMethod: 'none',
noStart: false,
txMinedWaitSeconds: 180,
...compact(overrides),
};
}
48 changes: 39 additions & 9 deletions yarn-project/bot/src/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class BotRunner {
await this.setup();
if (!this.interval) {
this.log.info(`Starting bot with interval of ${this.config.txIntervalSeconds}s`);
this.interval = setInterval(() => this.run(), this.config.txIntervalSeconds * 1000);
this.interval = setInterval(() => this.#safeRun(), this.config.txIntervalSeconds * 1000);
}
}

Expand Down Expand Up @@ -80,14 +80,31 @@ export class BotRunner {
*/
public async run() {
if (!this.bot) {
this.log.error(`Trying to run with uninitialized bot`);
throw new Error(`Bot is not initialized`);
}
this.log.verbose(`Manually triggered bot run`);
const bot = await this.bot;
const promise = bot.run();
this.running.add(promise);
await promise;
this.running.delete(promise);

let bot;
try {
bot = await this.bot;
} catch (err) {
this.log.error(`Error awaiting bot set up: ${err}`);
throw err;
}

let promise;
try {
promise = bot.run();
this.running.add(promise);
await promise;
} catch (err) {
this.log.error(`Error running bot: ${err}`);
throw err;
} finally {
if (promise) {
this.running.delete(promise);
}
}
}

/** Returns the current configuration for the bot. */
Expand All @@ -96,7 +113,20 @@ export class BotRunner {
}

async #createBot() {
this.bot = Bot.create(this.config, { pxe: this.pxe });
await this.bot;
try {
this.bot = Bot.create(this.config, { pxe: this.pxe });
await this.bot;
} catch (err) {
this.log.error(`Error setting up bot: ${err}`);
throw err;
}
}

async #safeRun() {
try {
await this.run();
} catch (err) {
// Already logged in run()
}
}
}
Loading