Skip to content
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ docs/.yarn/install-state.gz
docs/docs/protocol-specs/public-vm/gen/

__pycache__

*.local.md
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got tired of needing to avoid docs that I had created in the course of planning.

2 changes: 1 addition & 1 deletion spartan/aztec-bot/templates/env.configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ data:
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 }}
BOT_MODE: {{ .Values.bot.botMode | quote }}
BOT_MAX_CONSECUTIVE_ERRORS: {{ .Values.bot.maxErrors | quote }}
BOT_STOP_WHEN_UNHEALTHY: {{ .Values.bot.stopIfUnhealthy | quote }}
AZTEC_NODE_URL: {{ .Values.bot.nodeUrl | quote }}
Expand Down
2 changes: 1 addition & 1 deletion spartan/aztec-bot/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ bot:
pxeSyncChainTip: "checkpointed"
botNoStart: false
feePaymentMethod: "fee_juice"
ammTxs: false
botMode: "transfer"
maxErrors: 3
stopIfUnhealthy: true
nodeUrl: ""
Expand Down
5 changes: 5 additions & 0 deletions spartan/environments/mbps-net.env
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ BOT_SWAPS_TX_INTERVAL_SECONDS=4
BOT_SWAPS_FOLLOW_CHAIN=PROPOSED
BOT_SWAPS_PXE_SYNC_CHAIN_TIP=proposed

BOT_CROSS_CHAIN_REPLICAS=1
BOT_CROSS_CHAIN_TX_INTERVAL_SECONDS=8
BOT_CROSS_CHAIN_FOLLOW_CHAIN=PROPOSED
BOT_CROSS_CHAIN_PXE_SYNC_CHAIN_TIP=proposed

REDEPLOY_ROLLUP_CONTRACTS=true

DEBUG_P2P_INSTRUMENT_MESSAGES=true
Expand Down
8 changes: 6 additions & 2 deletions spartan/environments/staging-public.env
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,12 @@ PROVER_PUBLISHER_MNEMONIC_START_INDEX=8000

BOT_TRANSFERS_REPLICAS=1
BOT_TRANSFERS_TX_INTERVAL_SECONDS=250
BOT_TRANSFERS_FOLLOW_CHAIN=PENDING
BOT_TRANSFERS_FOLLOW_CHAIN=PROPOSED

BOT_SWAPS_REPLICAS=1
BOT_SWAPS_FOLLOW_CHAIN=PENDING
BOT_SWAPS_FOLLOW_CHAIN=PROPOSED
BOT_SWAPS_TX_INTERVAL_SECONDS=350

BOT_CROSS_CHAIN_REPLICAS=1
BOT_CROSS_CHAIN_TX_INTERVAL_SECONDS=250
BOT_CROSS_CHAIN_FOLLOW_CHAIN=PROPOSED
17 changes: 17 additions & 0 deletions spartan/scripts/calculate_publisher_indices.sh
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ if (( BOT_SWAPS_REPLICAS > 0 )); then
BOT_SWAPS_INDICES=$(seq "$BOT_SWAPS_MNEMONIC_START_INDEX" $((BOT_SWAPS_MNEMONIC_START_INDEX + BOT_SWAPS_REPLICAS - 1)) | tr '\n' ',' | sed 's/,$//')
fi

# Calculate cross-chain bot indices
BOT_CROSS_CHAIN_REPLICAS=${BOT_CROSS_CHAIN_REPLICAS:-0}
BOT_CROSS_CHAIN_MNEMONIC_START_INDEX=${BOT_CROSS_CHAIN_MNEMONIC_START_INDEX:-7200}

BOT_CROSS_CHAIN_INDICES=""
if (( BOT_CROSS_CHAIN_REPLICAS > 0 )); then
BOT_CROSS_CHAIN_INDICES=$(seq "$BOT_CROSS_CHAIN_MNEMONIC_START_INDEX" $((BOT_CROSS_CHAIN_MNEMONIC_START_INDEX + BOT_CROSS_CHAIN_REPLICAS - 1)) | tr '\n' ',' | sed 's/,$//')
fi

# Combine all publisher indices
ALL_PUBLISHER_INDICES=""
if [ -n "$VALIDATOR_PUBLISHER_INDICES" ]; then
Expand Down Expand Up @@ -100,5 +109,13 @@ if [ -n "$BOT_SWAPS_INDICES" ]; then
fi
fi

if [ -n "$BOT_CROSS_CHAIN_INDICES" ]; then
if [ -n "$ALL_PUBLISHER_INDICES" ]; then
ALL_PUBLISHER_INDICES="${ALL_PUBLISHER_INDICES},${BOT_CROSS_CHAIN_INDICES}"
else
ALL_PUBLISHER_INDICES="$BOT_CROSS_CHAIN_INDICES"
fi
fi

# Output the comma-separated list of indices
echo "$ALL_PUBLISHER_INDICES"
27 changes: 27 additions & 0 deletions spartan/scripts/deploy_network.sh
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,19 @@ DEPLOY_ARCHIVAL_NODE=${DEPLOY_ARCHIVAL_NODE:-false}
BOT_RESOURCE_PROFILE=${BOT_RESOURCE_PROFILE:-${RESOURCE_PROFILE}}
BOT_TRANSFERS_MNEMONIC_START_INDEX=${BOT_TRANSFERS_MNEMONIC_START_INDEX:-7000}
BOT_SWAPS_MNEMONIC_START_INDEX=${BOT_SWAPS_MNEMONIC_START_INDEX:-7100}
BOT_CROSS_CHAIN_MNEMONIC_START_INDEX=${BOT_CROSS_CHAIN_MNEMONIC_START_INDEX:-7200}
BOT_TRANSFERS_REPLICAS=${BOT_TRANSFERS_REPLICAS:-0}
BOT_SWAPS_REPLICAS=${BOT_SWAPS_REPLICAS:-0}
BOT_CROSS_CHAIN_REPLICAS=${BOT_CROSS_CHAIN_REPLICAS:-0}
BOT_TRANSFERS_TX_INTERVAL_SECONDS=${BOT_TRANSFERS_TX_INTERVAL_SECONDS:-60}
BOT_SWAPS_TX_INTERVAL_SECONDS=${BOT_SWAPS_TX_INTERVAL_SECONDS:-60}
BOT_CROSS_CHAIN_TX_INTERVAL_SECONDS=${BOT_CROSS_CHAIN_TX_INTERVAL_SECONDS:-10}
BOT_TRANSFERS_FOLLOW_CHAIN=${BOT_TRANSFERS_FOLLOW_CHAIN:-NONE}
BOT_SWAPS_FOLLOW_CHAIN=${BOT_SWAPS_FOLLOW_CHAIN:-NONE}
BOT_CROSS_CHAIN_FOLLOW_CHAIN=${BOT_CROSS_CHAIN_FOLLOW_CHAIN:-PENDING}
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}
BOT_CROSS_CHAIN_PXE_SYNC_CHAIN_TIP=${BOT_CROSS_CHAIN_PXE_SYNC_CHAIN_TIP:-checkpointed}

RPC_INGRESS_ENABLED=${RPC_INGRESS_ENABLED:-false}
RPC_INGRESS_HOSTS=${RPC_INGRESS_HOSTS:-[]}
Expand Down Expand Up @@ -209,6 +214,22 @@ if (( TOTAL_PROVER_PUBLISHERS > 0 )); then
LABS_INFRA_INDICES="${LABS_INFRA_INDICES},${PROVER_PUBLISHER_RANGE}"
fi

# Add bot L1 accounts to prefunding list
if (( BOT_TRANSFERS_REPLICAS > 0 )); then
BOT_TRANSFERS_RANGE=$(seq "$BOT_TRANSFERS_MNEMONIC_START_INDEX" $((BOT_TRANSFERS_MNEMONIC_START_INDEX + BOT_TRANSFERS_REPLICAS - 1)) | tr '\n' ',' | sed 's/,$//')
LABS_INFRA_INDICES="${LABS_INFRA_INDICES},${BOT_TRANSFERS_RANGE}"
fi

if (( BOT_SWAPS_REPLICAS > 0 )); then
BOT_SWAPS_RANGE=$(seq "$BOT_SWAPS_MNEMONIC_START_INDEX" $((BOT_SWAPS_MNEMONIC_START_INDEX + BOT_SWAPS_REPLICAS - 1)) | tr '\n' ',' | sed 's/,$//')
LABS_INFRA_INDICES="${LABS_INFRA_INDICES},${BOT_SWAPS_RANGE}"
fi

if (( BOT_CROSS_CHAIN_REPLICAS > 0 )); then
BOT_CROSS_CHAIN_RANGE=$(seq "$BOT_CROSS_CHAIN_MNEMONIC_START_INDEX" $((BOT_CROSS_CHAIN_MNEMONIC_START_INDEX + BOT_CROSS_CHAIN_REPLICAS - 1)) | tr '\n' ',' | sed 's/,$//')
LABS_INFRA_INDICES="${LABS_INFRA_INDICES},${BOT_CROSS_CHAIN_RANGE}"
fi

# Ensure docker image provided (not needed for pure teardowns)
if [[ -z "${AZTEC_DOCKER_IMAGE:-}" && ("${CREATE_AZTEC_INFRA:-}" == "true" || "${CREATE_ROLLUP_CONTRACTS:-}" == "true") ]]; then
die "AZTEC_DOCKER_IMAGE is not set"
Expand Down Expand Up @@ -519,10 +540,16 @@ 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_CROSS_CHAIN_MNEMONIC_START_INDEX = ${BOT_CROSS_CHAIN_MNEMONIC_START_INDEX}
BOT_CROSS_CHAIN_REPLICAS = ${BOT_CROSS_CHAIN_REPLICAS}
BOT_CROSS_CHAIN_TX_INTERVAL_SECONDS = ${BOT_CROSS_CHAIN_TX_INTERVAL_SECONDS}
BOT_CROSS_CHAIN_FOLLOW_CHAIN = "${BOT_CROSS_CHAIN_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_CROSS_CHAIN_PXE_SYNC_CHAIN_TIP = "${BOT_CROSS_CHAIN_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}"
BOT_CROSS_CHAIN_L2_PRIVATE_KEY = "${BOT_CROSS_CHAIN_L2_PRIVATE_KEY:-0xcafe03}"

PROVER_AGENTS_PER_PROVER = ${PROVER_AGENTS_PER_PROVER}
PROVER_AGENT_POLL_INTERVAL_MS = ${PROVER_AGENT_POLL_INTERVAL_MS}
Expand Down
24 changes: 24 additions & 0 deletions spartan/terraform/deploy-aztec-infra/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,30 @@ locals {
bootstrap_nodes_path = ""
wait = false
} : null

# Optional: cross-chain message bots
bot_cross_chain = var.BOT_CROSS_CHAIN_REPLICAS > 0 ? {
name = "${var.RELEASE_PREFIX}-bot-cross-chain"
chart = "aztec-bot"
values = [
"common.yaml",
"bot-cross-chain.yaml",
"bot-resources-${var.BOT_RESOURCE_PROFILE}.yaml",
]
custom_settings = {
"bot.replicaCount" = var.BOT_CROSS_CHAIN_REPLICAS
"bot.txIntervalSeconds" = var.BOT_CROSS_CHAIN_TX_INTERVAL_SECONDS
"bot.followChain" = var.BOT_CROSS_CHAIN_FOLLOW_CHAIN
"bot.pxeSyncChainTip" = var.BOT_CROSS_CHAIN_PXE_SYNC_CHAIN_TIP
"bot.botPrivateKey" = var.BOT_CROSS_CHAIN_L2_PRIVATE_KEY
"bot.nodeUrl" = local.internal_rpc_url
"bot.mnemonic" = var.BOT_MNEMONIC
"bot.mnemonicStartIndex" = var.BOT_CROSS_CHAIN_MNEMONIC_START_INDEX
}
boot_node_host_path = ""
bootstrap_nodes_path = ""
wait = false
} : null
}, local.validator_releases)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
bot:
replicaCount: 1
txIntervalSeconds: 10
ammTxs: true
followChain: "PENDING"
botMode: "amm"
followChain: "PROPOSED"
feePaymentMethod: "fee_juice"
maxErrors: 3
stopIfUnhealthy: true
Expand Down
25 changes: 25 additions & 0 deletions spartan/terraform/deploy-aztec-infra/values/bot-cross-chain.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
bot:
replicaCount: 1
botMode: "crosschain"
txIntervalSeconds: 10
followChain: "PROPOSED"
feePaymentMethod: "fee_juice"
maxErrors: 3
stopIfUnhealthy: true
botPrivateKey: "0xcafe03"

persistence:
enabled: true
statefulSet:
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 2Gi

service:
headless:
enabled: true
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
bot:
replicaCount: 1
ammTxs: false
botMode: "transfer"
txIntervalSeconds: 10
privateTransfersPerTx: 0
publicTransfersPerTx: 1
Expand Down
37 changes: 37 additions & 0 deletions spartan/terraform/deploy-aztec-infra/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,43 @@ variable "BOT_SWAPS_L2_PRIVATE_KEY" {
default = null
}

variable "BOT_CROSS_CHAIN_MNEMONIC_START_INDEX" {
description = "The cross-chain bot mnemonic start index"
type = string
default = ""
}

variable "BOT_CROSS_CHAIN_REPLICAS" {
description = "Number of cross-chain bot replicas to deploy (0 to disable)"
type = number
default = 0
}

variable "BOT_CROSS_CHAIN_TX_INTERVAL_SECONDS" {
description = "Interval in seconds between cross-chain bot transactions"
type = number
default = 10
}

variable "BOT_CROSS_CHAIN_FOLLOW_CHAIN" {
description = "Cross-chain bot follow-chain mode"
type = string
default = "PENDING"
}

variable "BOT_CROSS_CHAIN_L2_PRIVATE_KEY" {
description = "Private key for the cross-chain bot (hex string starting with 0x)"
type = string
nullable = true
default = null
}
Comment on lines +577 to +606
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heads up we're missing a BOT_CROSS_CHAIN_PXE_SYNC_CHAIN_TIP (see #20392)


variable "BOT_CROSS_CHAIN_PXE_SYNC_CHAIN_TIP" {
description = "Cross-chain bot PXE sync chain tip mode (e.g., checkpointed)"
type = string
default = "checkpointed"
}

# RPC ingress configuration (GKE-specific)
variable "RPC_INGRESS_ENABLED" {
description = "Enable GKE ingress for RPC nodes"
Expand Down
3 changes: 3 additions & 0 deletions yarn-project/bot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,17 @@
"@aztec/ethereum": "workspace:^",
"@aztec/foundation": "workspace:^",
"@aztec/kv-store": "workspace:^",
"@aztec/l1-artifacts": "workspace:^",
"@aztec/noir-contracts.js": "workspace:^",
"@aztec/noir-protocol-circuits-types": "workspace:^",
"@aztec/noir-test-contracts.js": "workspace:^",
"@aztec/protocol-contracts": "workspace:^",
"@aztec/stdlib": "workspace:^",
"@aztec/telemetry-client": "workspace:^",
"@aztec/wallets": "workspace:^",
"source-map-support": "^0.5.21",
"tslib": "^2.4.0",
"viem": "npm:@aztec/viem@2.38.2",
"zod": "^3.23.8"
},
"devDependencies": {
Expand Down
39 changes: 32 additions & 7 deletions yarn-project/bot/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import { z } from 'zod';
const BotFollowChain = ['NONE', 'PROPOSED', 'CHECKPOINTED', 'PROVEN'] as const;
type BotFollowChain = (typeof BotFollowChain)[number];

const BotMode = ['transfer', 'amm', 'crosschain'] as const;
type BotMode = (typeof BotMode)[number];

export enum SupportedTokenContracts {
TokenContract = 'TokenContract',
PrivateTokenContract = 'PrivateTokenContract',
Expand Down Expand Up @@ -76,8 +79,12 @@ export type BotConfig = {
maxConsecutiveErrors: number;
/** Stops the bot if service becomes unhealthy */
stopWhenUnhealthy: boolean;
/** Deploy an AMM contract and do swaps instead of transfers */
ammTxs: boolean;
/** Bot mode: transfer, amm, or crosschain. */
botMode: BotMode;
/** Number of L2→L1 messages per tx (crosschain mode). */
l2ToL1MessagesPerTx: number;
/** Max L1→L2 messages to keep in-flight (crosschain mode). */
l1ToL2SeedCount: number;
} & Pick<DataStoreConfig, 'dataDirectory' | 'dataStoreMapSizeKb'>;

export const BotConfigSchema = zodFor<BotConfig>()(
Expand Down Expand Up @@ -107,7 +114,9 @@ export const BotConfigSchema = zodFor<BotConfig>()(
contract: z.nativeEnum(SupportedTokenContracts),
maxConsecutiveErrors: z.number().int().nonnegative(),
stopWhenUnhealthy: z.boolean(),
ammTxs: z.boolean().default(false),
botMode: z.enum(BotMode).default('transfer'),
l2ToL1MessagesPerTx: z.number().int().nonnegative().default(1),
l1ToL2SeedCount: z.number().int().nonnegative().default(1),
dataDirectory: z.string().optional(),
dataStoreMapSizeKb: z.number().optional(),
})
Expand Down Expand Up @@ -268,10 +277,26 @@ export const botConfigMappings: ConfigMappingsType<BotConfig> = {
description: 'Stops the bot if service becomes unhealthy',
...booleanConfigHelper(false),
},
ammTxs: {
env: 'BOT_AMM_TXS',
description: 'Deploy an AMM and send swaps to it',
...booleanConfigHelper(false),
botMode: {
env: 'BOT_MODE',
description: 'Bot mode: transfer, amm, or crosschain',
defaultValue: 'transfer' as BotMode,
parseEnv(val: string) {
if (!(BotMode as readonly string[]).includes(val)) {
throw new Error(`Invalid value for BOT_MODE: ${val}`);
}
return val as BotMode;
},
},
l2ToL1MessagesPerTx: {
env: 'BOT_L2_TO_L1_MESSAGES_PER_TX',
description: 'Number of L2→L1 messages per tx (crosschain mode)',
...numberConfigHelper(1),
},
l1ToL2SeedCount: {
env: 'BOT_L1_TO_L2_SEED_COUNT',
description: 'Max L1→L2 messages to keep in-flight (crosschain mode)',
...numberConfigHelper(1),
},
...pickConfigMappings(dataConfigMappings, ['dataStoreMapSizeKb', 'dataDirectory']),
};
Expand Down
15 changes: 15 additions & 0 deletions yarn-project/bot/src/cross_chain_bot.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
import type { EmbeddedWallet } from '@aztec/wallets/embedded';

import { type BotConfig, getBotDefaultConfig } from './config.js';
import { CrossChainBot } from './cross_chain_bot.js';
import type { BotStore } from './store/index.js';

describe('CrossChainBot', () => {
it('rejects followChain=NONE', async () => {
const config: BotConfig = { ...getBotDefaultConfig(), botMode: 'crosschain', followChain: 'NONE' };
await expect(
CrossChainBot.create(config, {} as EmbeddedWallet, {} as AztecNode, {} as AztecNodeAdmin, {} as BotStore),
).rejects.toThrow(/followChain/);
});
});
Loading
Loading