diff --git a/spartan/aztec-bot/templates/env.configmap.yaml b/spartan/aztec-bot/templates/env.configmap.yaml index 4e7b71230178..da4414c48818 100644 --- a/spartan/aztec-bot/templates/env.configmap.yaml +++ b/spartan/aztec-bot/templates/env.configmap.yaml @@ -9,6 +9,7 @@ data: BOT_PRIVATE_TRANSFERS_PER_TX: {{ .Values.bot.privateTransfersPerTx | quote }} BOT_PUBLIC_TRANSFERS_PER_TX: {{ .Values.bot.publicTransfersPerTx | quote }} BOT_FOLLOW_CHAIN: {{ .Values.bot.followChain | quote }} + PXE_SYNC_CHAIN_TIP: {{ .Values.bot.pxeSyncChainTip | quote }} BOT_NO_START: {{ .Values.bot.botNoStart | quote }} BOT_FEE_PAYMENT_METHOD: {{ .Values.bot.feePaymentMethod | quote }} BOT_AMM_TXS: {{ .Values.bot.ammTxs | quote }} diff --git a/spartan/aztec-bot/values.yaml b/spartan/aztec-bot/values.yaml index d310e507ed8e..10fecf8ed417 100644 --- a/spartan/aztec-bot/values.yaml +++ b/spartan/aztec-bot/values.yaml @@ -12,6 +12,7 @@ bot: publicTransfersPerTx: 1 # Do not wait for transactions followChain: "NONE" + pxeSyncChainTip: "checkpointed" botNoStart: false feePaymentMethod: "fee_juice" ammTxs: false diff --git a/spartan/scripts/deploy_network.sh b/spartan/scripts/deploy_network.sh index e6007c3fd3f4..beab348a291c 100755 --- a/spartan/scripts/deploy_network.sh +++ b/spartan/scripts/deploy_network.sh @@ -115,6 +115,8 @@ BOT_TRANSFERS_TX_INTERVAL_SECONDS=${BOT_TRANSFERS_TX_INTERVAL_SECONDS:-60} BOT_SWAPS_TX_INTERVAL_SECONDS=${BOT_SWAPS_TX_INTERVAL_SECONDS:-60} BOT_TRANSFERS_FOLLOW_CHAIN=${BOT_TRANSFERS_FOLLOW_CHAIN:-NONE} BOT_SWAPS_FOLLOW_CHAIN=${BOT_SWAPS_FOLLOW_CHAIN:-NONE} +BOT_TRANSFERS_PXE_SYNC_CHAIN_TIP=${BOT_TRANSFERS_PXE_SYNC_CHAIN_TIP:-checkpointed} +BOT_SWAPS_PXE_SYNC_CHAIN_TIP=${BOT_SWAPS_PXE_SYNC_CHAIN_TIP:-checkpointed} RPC_INGRESS_ENABLED=${RPC_INGRESS_ENABLED:-false} RPC_INGRESS_HOSTS=${RPC_INGRESS_HOSTS:-[]} @@ -506,6 +508,8 @@ BOT_SWAPS_MNEMONIC_START_INDEX = ${BOT_SWAPS_MNEMONIC_START_INDEX} BOT_SWAPS_REPLICAS = ${BOT_SWAPS_REPLICAS} BOT_SWAPS_TX_INTERVAL_SECONDS = ${BOT_SWAPS_TX_INTERVAL_SECONDS} BOT_SWAPS_FOLLOW_CHAIN = "${BOT_SWAPS_FOLLOW_CHAIN}" +BOT_TRANSFERS_PXE_SYNC_CHAIN_TIP = "${BOT_TRANSFERS_PXE_SYNC_CHAIN_TIP}" +BOT_SWAPS_PXE_SYNC_CHAIN_TIP = "${BOT_SWAPS_PXE_SYNC_CHAIN_TIP}" BOT_TRANSFERS_L2_PRIVATE_KEY = "${BOT_TRANSFERS_L2_PRIVATE_KEY:-0xcafe01}" BOT_SWAPS_L2_PRIVATE_KEY = "${BOT_SWAPS_L2_PRIVATE_KEY:-0xcafe02}" diff --git a/spartan/terraform/deploy-aztec-infra/main.tf b/spartan/terraform/deploy-aztec-infra/main.tf index 1222f613773f..d4518fc09787 100644 --- a/spartan/terraform/deploy-aztec-infra/main.tf +++ b/spartan/terraform/deploy-aztec-infra/main.tf @@ -576,6 +576,7 @@ locals { "bot.replicaCount" = var.BOT_TRANSFERS_REPLICAS "bot.txIntervalSeconds" = var.BOT_TRANSFERS_TX_INTERVAL_SECONDS "bot.followChain" = var.BOT_TRANSFERS_FOLLOW_CHAIN + "bot.pxeSyncChainTip" = var.BOT_TRANSFERS_PXE_SYNC_CHAIN_TIP "bot.botPrivateKey" = var.BOT_TRANSFERS_L2_PRIVATE_KEY "bot.nodeUrl" = local.internal_rpc_url "bot.mnemonic" = var.BOT_MNEMONIC @@ -599,6 +600,7 @@ locals { "bot.replicaCount" = var.BOT_SWAPS_REPLICAS "bot.txIntervalSeconds" = var.BOT_SWAPS_TX_INTERVAL_SECONDS "bot.followChain" = var.BOT_SWAPS_FOLLOW_CHAIN + "bot.pxeSyncChainTip" = var.BOT_SWAPS_PXE_SYNC_CHAIN_TIP "bot.botPrivateKey" = var.BOT_SWAPS_L2_PRIVATE_KEY "bot.nodeUrl" = local.internal_rpc_url "bot.mnemonic" = var.BOT_MNEMONIC diff --git a/spartan/terraform/deploy-aztec-infra/variables.tf b/spartan/terraform/deploy-aztec-infra/variables.tf index d5d412557818..798f88005737 100644 --- a/spartan/terraform/deploy-aztec-infra/variables.tf +++ b/spartan/terraform/deploy-aztec-infra/variables.tf @@ -519,6 +519,12 @@ variable "BOT_TRANSFERS_FOLLOW_CHAIN" { default = "PENDING" } +variable "BOT_TRANSFERS_PXE_SYNC_CHAIN_TIP" { + description = "Transfers bot PXE sync chain tip mode (e.g., checkpointed)" + type = string + default = "checkpointed" +} + variable "BOT_TRANSFERS_L2_PRIVATE_KEY" { description = "Private key for the transfers bot (hex string starting with 0x)" nullable = true @@ -549,6 +555,12 @@ variable "BOT_SWAPS_FOLLOW_CHAIN" { default = "PENDING" } +variable "BOT_SWAPS_PXE_SYNC_CHAIN_TIP" { + description = "AMM swaps bot PXE sync chain tip mode (e.g., checkpointed)" + type = string + default = "checkpointed" +} + variable "BOT_SWAPS_L2_PRIVATE_KEY" { description = "Private key for the AMM swaps bot (hex string starting with 0x)" type = string diff --git a/yarn-project/aztec/src/cli/cmds/start_bot.ts b/yarn-project/aztec/src/cli/cmds/start_bot.ts index 3d23797ed400..6263177786dc 100644 --- a/yarn-project/aztec/src/cli/cmds/start_bot.ts +++ b/yarn-project/aztec/src/cli/cmds/start_bot.ts @@ -12,7 +12,7 @@ import { } from '@aztec/telemetry-client'; import { TestWallet } from '@aztec/test-wallet/server'; -import { extractRelevantOptions } from '../util.js'; +import { extractRelevantOptions, stringifyConfig } from '../util.js'; import { getVersions } from '../versioning.js'; export async function startBot( @@ -38,10 +38,11 @@ export async function startBot( const aztecNode = createAztecNodeClient(config.nodeUrl, getVersions(), fetch); const pxeConfig = extractRelevantOptions(options, allPxeConfigMappings, 'pxe'); + userLog(`Creating bot test wallet with config ${stringifyConfig(pxeConfig)}`); const wallet = await TestWallet.create(aztecNode, pxeConfig); const telemetry = await initTelemetryClient(getTelemetryClientConfig()); - await addBot(options, signalHandlers, services, wallet, aztecNode, telemetry, undefined); + await addBot(options, signalHandlers, services, wallet, aztecNode, telemetry, undefined, userLog); } export async function addBot( @@ -52,8 +53,10 @@ export async function addBot( aztecNode: AztecNode, telemetry: TelemetryClient, aztecNodeAdmin?: AztecNodeAdmin, + userLog?: LogFn, ) { const config = extractRelevantOptions(options, botConfigMappings, 'bot'); + userLog?.(`Starting bot with config ${stringifyConfig(config)}`); const db = await (config.dataDirectory ? createStore('bot', BotStore.SCHEMA_VERSION, config) diff --git a/yarn-project/aztec/src/cli/util.ts b/yarn-project/aztec/src/cli/util.ts index d5063ba24de9..fe90d7f4b445 100644 --- a/yarn-project/aztec/src/cli/util.ts +++ b/yarn-project/aztec/src/cli/util.ts @@ -4,6 +4,7 @@ import type { ViemClient } from '@aztec/ethereum/types'; import type { ConfigMappingsType } from '@aztec/foundation/config'; import { Fr } from '@aztec/foundation/curves/bn254'; import { EthAddress } from '@aztec/foundation/eth-address'; +import { jsonStringify } from '@aztec/foundation/json-rpc'; import { type LogFn, createLogger } from '@aztec/foundation/log'; import type { SharedNodeConfig } from '@aztec/node-lib/config'; import type { ProverConfig } from '@aztec/stdlib/interfaces/server'; @@ -388,3 +389,9 @@ export async function setupUpdateMonitor( checker.start(); } + +export function stringifyConfig(config: object): string { + return Object.entries(config) + .map(([key, value]) => `${key}=${jsonStringify(value)}`) + .join(' '); +} diff --git a/yarn-project/bot/src/base_bot.ts b/yarn-project/bot/src/base_bot.ts index 74184a072fc1..2ec0397f5902 100644 --- a/yarn-project/bot/src/base_bot.ts +++ b/yarn-project/bot/src/base_bot.ts @@ -1,13 +1,8 @@ import { AztecAddress } from '@aztec/aztec.js/addresses'; -import { - BatchCall, - ContractFunctionInteraction, - type SendInteractionOptions, - waitForProven, -} from '@aztec/aztec.js/contracts'; +import { BatchCall, ContractFunctionInteraction, type SendInteractionOptions } from '@aztec/aztec.js/contracts'; import { createLogger } from '@aztec/aztec.js/log'; import { waitForTx } from '@aztec/aztec.js/node'; -import { TxHash, TxReceipt } from '@aztec/aztec.js/tx'; +import { TxHash, TxReceipt, TxStatus } from '@aztec/aztec.js/tx'; import { Gas } from '@aztec/stdlib/gas'; import type { AztecNode } from '@aztec/stdlib/interfaces/client'; import type { TestWallet } from '@aztec/test-wallet/server'; @@ -29,8 +24,8 @@ export abstract class BaseBot { public async run(): Promise { this.attempts++; - const logCtx = { runId: Date.now() * 1000 + Math.floor(Math.random() * 1000) }; const { followChain, txMinedWaitSeconds } = this.config; + const logCtx = { runId: Date.now() * 1000 + Math.floor(Math.random() * 1000), followChain, txMinedWaitSeconds }; this.log.verbose(`Creating tx`, logCtx); const txHash = await this.createAndSendTx(logCtx); @@ -40,14 +35,9 @@ export abstract class BaseBot { return txHash; } - this.log.verbose( - `Awaiting tx ${txHash.toString()} to be on the ${followChain} chain (timeout ${txMinedWaitSeconds}s)`, - logCtx, - ); - const receipt = await waitForTx(this.node, txHash, { timeout: txMinedWaitSeconds }); - if (followChain === 'PROVEN') { - await waitForProven(this.node, receipt, { provenTimeout: txMinedWaitSeconds }); - } + const waitForStatus = TxStatus[followChain]; + this.log.verbose(`Awaiting tx ${txHash.toString()} to be on the ${followChain} chain`, logCtx); + const receipt = await waitForTx(this.node, txHash, { timeout: txMinedWaitSeconds, waitForStatus }); this.successes++; this.log.info( `Tx #${this.attempts} ${receipt.txHash} successfully mined in block ${receipt.blockNumber} (stats: ${this.successes}/${this.attempts} success)`, diff --git a/yarn-project/bot/src/config.ts b/yarn-project/bot/src/config.ts index ae73ce1f0f01..d02ef5ebb401 100644 --- a/yarn-project/bot/src/config.ts +++ b/yarn-project/bot/src/config.ts @@ -19,7 +19,7 @@ import type { ComponentsVersions } from '@aztec/stdlib/versioning'; import { z } from 'zod'; -const BotFollowChain = ['NONE', 'PENDING', 'PROVEN'] as const; +const BotFollowChain = ['NONE', 'PROPOSED', 'CHECKPOINTED', 'PROVEN'] as const; type BotFollowChain = (typeof BotFollowChain)[number]; export enum SupportedTokenContracts { @@ -213,10 +213,14 @@ export const botConfigMappings: ConfigMappingsType = { description: 'Which chain the bot follows', defaultValue: 'NONE', parseEnv(val) { - if (!(BotFollowChain as readonly string[]).includes(val.toUpperCase())) { + const upper = val.toUpperCase(); + if (upper === 'PENDING') { + return 'CHECKPOINTED'; + } + if (!(BotFollowChain as readonly string[]).includes(upper)) { throw new Error(`Invalid value for BOT_FOLLOW_CHAIN: ${val}`); } - return val as BotFollowChain; + return upper as BotFollowChain; }, }, maxPendingTxs: { diff --git a/yarn-project/end-to-end/src/e2e_bot.test.ts b/yarn-project/end-to-end/src/e2e_bot.test.ts index ffcef16930db..6648e886349b 100644 --- a/yarn-project/end-to-end/src/e2e_bot.test.ts +++ b/yarn-project/end-to-end/src/e2e_bot.test.ts @@ -44,7 +44,7 @@ describe('e2e_bot', () => { beforeAll(async () => { config = { ...getBotDefaultConfig(), - followChain: 'PENDING', + followChain: 'CHECKPOINTED', ammTxs: false, }; bot = await Bot.create(config, wallet, aztecNode, undefined, new BotStore(await openTmpStore('bot'))); @@ -109,7 +109,7 @@ describe('e2e_bot', () => { const config: BotConfig = { ...getBotDefaultConfig(), - followChain: 'PENDING', + followChain: 'CHECKPOINTED', ammTxs: false, // this bot has a well defined private key and salt @@ -147,7 +147,7 @@ describe('e2e_bot', () => { const config: BotConfig = { ...getBotDefaultConfig(), - followChain: 'PENDING', + followChain: 'CHECKPOINTED', ammTxs: false, // this bot has a well defined private key and salt @@ -185,7 +185,7 @@ describe('e2e_bot', () => { beforeAll(async () => { config = { ...getBotDefaultConfig(), - followChain: 'PENDING', + followChain: 'CHECKPOINTED', ammTxs: true, }; bot = await AmmBot.create(config, wallet, aztecNode, undefined, new BotStore(await openTmpStore('bot'))); @@ -215,7 +215,7 @@ describe('e2e_bot', () => { beforeAll(() => { config = { ...getBotDefaultConfig(), - followChain: 'PENDING', + followChain: 'CHECKPOINTED', ammTxs: false, senderPrivateKey: new SecretValue(Fr.random()), l1PrivateKey: new SecretValue(bufferToHex(getPrivateKeyFromIndex(8)!)), diff --git a/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts b/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts index 98258d0e5b10..f1ac27f7712a 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer_config.test.ts @@ -39,7 +39,7 @@ describe('e2e_sequencer_config', () => { })); config = { ...getBotDefaultConfig(), - followChain: 'PENDING', + followChain: 'CHECKPOINTED', ammTxs: false, txMinedWaitSeconds: 12, }; diff --git a/yarn-project/end-to-end/src/spartan/gating-passive.test.ts b/yarn-project/end-to-end/src/spartan/gating-passive.test.ts index a122f1af5e11..4a8bf19ae4a7 100644 --- a/yarn-project/end-to-end/src/spartan/gating-passive.test.ts +++ b/yarn-project/end-to-end/src/spartan/gating-passive.test.ts @@ -112,7 +112,7 @@ describe('a test that passively observes the network in the presence of network logger: debugLogger, replicas: 1, txIntervalSeconds: 10, - followChain: 'PENDING', + followChain: 'CHECKPOINTED', }); }); diff --git a/yarn-project/end-to-end/src/spartan/utils/bot.ts b/yarn-project/end-to-end/src/spartan/utils/bot.ts index c841cad5a429..6314d2850292 100644 --- a/yarn-project/end-to-end/src/spartan/utils/bot.ts +++ b/yarn-project/end-to-end/src/spartan/utils/bot.ts @@ -34,7 +34,7 @@ export async function installTransferBot({ logger: log, replicas = 1, txIntervalSeconds = 10, - followChain = 'PENDING', + followChain = 'CHECKPOINTED', mnemonic = process.env.LABS_INFRA_MNEMONIC ?? 'test test test test test test test test test test test junk', mnemonicStartIndex, botPrivateKey = process.env.BOT_TRANSFERS_L2_PRIVATE_KEY ?? '0xcafe01',