@aztec/end-to-end 0.0.1-commit.d3ec352c → 0.0.1-commit.f295ac2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bench/client_flows/benchmark.d.ts +3 -2
- package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/benchmark.js +21 -1
- package/dest/bench/client_flows/client_flows_benchmark.d.ts +14 -15
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +110 -138
- package/dest/bench/client_flows/data_extractor.js +3 -1
- package/dest/bench/utils.d.ts +6 -6
- package/dest/bench/utils.d.ts.map +1 -1
- package/dest/bench/utils.js +18 -11
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +6 -7
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
- package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +98 -113
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +19 -13
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
- package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +91 -71
- package/dest/e2e_deploy_contract/deploy_test.d.ts +4 -3
- package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
- package/dest/e2e_deploy_contract/deploy_test.js +18 -13
- package/dest/e2e_epochs/epochs_test.d.ts +3 -2
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +13 -11
- package/dest/e2e_fees/bridging_race.notest.js +3 -5
- package/dest/e2e_fees/fees_test.d.ts +18 -15
- package/dest/e2e_fees/fees_test.d.ts.map +1 -1
- package/dest/e2e_fees/fees_test.js +126 -141
- package/dest/e2e_l1_publisher/write_json.d.ts +3 -3
- package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -1
- package/dest/e2e_l1_publisher/write_json.js +19 -15
- package/dest/e2e_multi_validator/utils.js +1 -1
- package/dest/e2e_nested_contract/nested_contract_test.d.ts +6 -9
- package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
- package/dest/e2e_nested_contract/nested_contract_test.js +32 -40
- package/dest/e2e_p2p/inactivity_slash_test.d.ts +4 -4
- package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -1
- package/dest/e2e_p2p/inactivity_slash_test.js +6 -9
- package/dest/e2e_p2p/p2p_network.d.ts +13 -11
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +116 -111
- package/dest/e2e_p2p/shared.d.ts +2 -2
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +4 -4
- package/dest/e2e_token_contract/token_contract_test.d.ts +16 -9
- package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
- package/dest/e2e_token_contract/token_contract_test.js +90 -92
- package/dest/fixtures/e2e_prover_test.d.ts +10 -18
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
- package/dest/fixtures/e2e_prover_test.js +88 -103
- package/dest/fixtures/fixtures.d.ts +2 -3
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +1 -2
- package/dest/fixtures/get_acvm_config.js +1 -1
- package/dest/fixtures/l1_to_l2_messaging.d.ts +4 -3
- package/dest/fixtures/l1_to_l2_messaging.d.ts.map +1 -1
- package/dest/fixtures/l1_to_l2_messaging.js +2 -2
- package/dest/fixtures/setup.d.ts +216 -0
- package/dest/fixtures/setup.d.ts.map +1 -0
- package/dest/fixtures/setup.js +684 -0
- package/dest/fixtures/setup_p2p_test.js +3 -3
- package/dest/fixtures/utils.d.ts +5 -638
- package/dest/fixtures/utils.d.ts.map +1 -1
- package/dest/fixtures/utils.js +4 -647
- package/dest/fixtures/web3signer.js +1 -1
- package/dest/fixtures/with_telemetry_utils.d.ts +2 -2
- package/dest/fixtures/with_telemetry_utils.d.ts.map +1 -1
- package/dest/fixtures/with_telemetry_utils.js +2 -2
- package/dest/quality_of_service/grafana_client.d.ts +41 -0
- package/dest/quality_of_service/grafana_client.d.ts.map +1 -0
- package/dest/quality_of_service/{alert_checker.js → grafana_client.js} +1 -1
- package/dest/quality_of_service/prometheus_client.d.ts +38 -0
- package/dest/quality_of_service/prometheus_client.d.ts.map +1 -0
- package/dest/quality_of_service/prometheus_client.js +67 -0
- package/dest/shared/cross_chain_test_harness.d.ts +16 -4
- package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
- package/dest/shared/cross_chain_test_harness.js +3 -3
- package/dest/shared/gas_portal_test_harness.d.ts +12 -2
- package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
- package/dest/shared/index.d.ts +2 -2
- package/dest/shared/index.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.d.ts +3 -27
- package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.js +43 -23
- package/dest/simulators/lending_simulator.d.ts +6 -2
- package/dest/simulators/lending_simulator.d.ts.map +1 -1
- package/dest/simulators/lending_simulator.js +1 -1
- package/dest/spartan/setup_test_wallets.d.ts +4 -3
- package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
- package/dest/spartan/setup_test_wallets.js +2 -1
- package/dest/spartan/tx_metrics.d.ts +42 -0
- package/dest/spartan/tx_metrics.d.ts.map +1 -0
- package/dest/spartan/tx_metrics.js +118 -0
- package/dest/spartan/utils.d.ts +51 -12
- package/dest/spartan/utils.d.ts.map +1 -1
- package/dest/spartan/utils.js +262 -102
- package/package.json +40 -39
- package/src/bench/client_flows/benchmark.ts +24 -2
- package/src/bench/client_flows/client_flows_benchmark.ts +150 -200
- package/src/bench/client_flows/data_extractor.ts +1 -1
- package/src/bench/utils.ts +22 -14
- package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +107 -142
- package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +140 -125
- package/src/e2e_deploy_contract/deploy_test.ts +21 -14
- package/src/e2e_epochs/epochs_test.ts +26 -13
- package/src/e2e_fees/bridging_race.notest.ts +3 -6
- package/src/e2e_fees/fees_test.ts +177 -216
- package/src/e2e_l1_publisher/write_json.ts +22 -17
- package/src/e2e_multi_validator/utils.ts +1 -1
- package/src/e2e_nested_contract/nested_contract_test.ts +35 -56
- package/src/e2e_p2p/inactivity_slash_test.ts +9 -12
- package/src/e2e_p2p/p2p_network.ts +174 -183
- package/src/e2e_p2p/shared.ts +11 -6
- package/src/e2e_token_contract/token_contract_test.ts +105 -118
- package/src/fixtures/e2e_prover_test.ts +112 -144
- package/src/fixtures/fixtures.ts +1 -3
- package/src/fixtures/get_acvm_config.ts +1 -1
- package/src/fixtures/l1_to_l2_messaging.ts +4 -2
- package/src/fixtures/setup.ts +1010 -0
- package/src/fixtures/setup_p2p_test.ts +3 -3
- package/src/fixtures/utils.ts +27 -966
- package/src/fixtures/web3signer.ts +1 -1
- package/src/fixtures/with_telemetry_utils.ts +2 -2
- package/src/quality_of_service/{alert_checker.ts → grafana_client.ts} +1 -1
- package/src/quality_of_service/prometheus_client.ts +113 -0
- package/src/shared/cross_chain_test_harness.ts +6 -10
- package/src/shared/gas_portal_test_harness.ts +1 -1
- package/src/shared/index.ts +1 -1
- package/src/shared/uniswap_l1_l2.ts +53 -67
- package/src/simulators/lending_simulator.ts +2 -2
- package/src/spartan/setup_test_wallets.ts +9 -2
- package/src/spartan/tx_metrics.ts +153 -0
- package/src/spartan/utils.ts +308 -45
- package/dest/fixtures/setup_l1_contracts.d.ts +0 -477
- package/dest/fixtures/setup_l1_contracts.d.ts.map +0 -1
- package/dest/fixtures/setup_l1_contracts.js +0 -17
- package/dest/fixtures/snapshot_manager.d.ts +0 -95
- package/dest/fixtures/snapshot_manager.d.ts.map +0 -1
- package/dest/fixtures/snapshot_manager.js +0 -505
- package/dest/quality_of_service/alert_checker.d.ts +0 -41
- package/dest/quality_of_service/alert_checker.d.ts.map +0 -1
- package/src/fixtures/setup_l1_contracts.ts +0 -26
- package/src/fixtures/snapshot_manager.ts +0 -665
package/dest/spartan/utils.js
CHANGED
|
@@ -18,7 +18,9 @@ const testConfigSchema = z.object({
|
|
|
18
18
|
L1_RPC_URLS_JSON: z.string().optional(),
|
|
19
19
|
L1_ACCOUNT_MNEMONIC: z.string().optional(),
|
|
20
20
|
AZTEC_SLOT_DURATION: z.coerce.number().optional().default(24),
|
|
21
|
-
|
|
21
|
+
AZTEC_EPOCH_DURATION: z.coerce.number().optional().default(32),
|
|
22
|
+
AZTEC_PROOF_SUBMISSION_WINDOW: z.coerce.number().optional().default(5),
|
|
23
|
+
AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET: z.coerce.number().optional().default(2)
|
|
22
24
|
});
|
|
23
25
|
export function setupEnvironment(env) {
|
|
24
26
|
const config = testConfigSchema.parse(env);
|
|
@@ -91,7 +93,7 @@ export async function startPortForward({ resource, namespace, containerPort, hos
|
|
|
91
93
|
]
|
|
92
94
|
});
|
|
93
95
|
let isResolved = false;
|
|
94
|
-
const connected = new Promise((resolve)=>{
|
|
96
|
+
const connected = new Promise((resolve, reject)=>{
|
|
95
97
|
process1.stdout?.on('data', (data)=>{
|
|
96
98
|
const str = data.toString();
|
|
97
99
|
if (!isResolved && str.includes('Forwarding from')) {
|
|
@@ -99,7 +101,8 @@ export async function startPortForward({ resource, namespace, containerPort, hos
|
|
|
99
101
|
logger.debug(`Port forward for ${resource}: ${str}`);
|
|
100
102
|
const port = str.search(/:\d+/);
|
|
101
103
|
if (port === -1) {
|
|
102
|
-
|
|
104
|
+
reject(new Error('Port not found in port forward output'));
|
|
105
|
+
return;
|
|
103
106
|
}
|
|
104
107
|
const portNumber = parseInt(str.slice(port + 1));
|
|
105
108
|
logger.verbose(`Port forwarded for ${resource} at ${portNumber}:${containerPort}`);
|
|
@@ -119,17 +122,26 @@ export async function startPortForward({ resource, namespace, containerPort, hos
|
|
|
119
122
|
process1.on('close', ()=>{
|
|
120
123
|
if (!isResolved) {
|
|
121
124
|
isResolved = true;
|
|
122
|
-
|
|
123
|
-
|
|
125
|
+
const msg = `Port forward for ${resource} closed before connection established`;
|
|
126
|
+
logger.warn(msg);
|
|
127
|
+
reject(new Error(msg));
|
|
124
128
|
}
|
|
125
129
|
});
|
|
126
130
|
process1.on('error', (error)=>{
|
|
127
|
-
|
|
128
|
-
|
|
131
|
+
if (!isResolved) {
|
|
132
|
+
isResolved = true;
|
|
133
|
+
const msg = `Port forward for ${resource} error: ${error}`;
|
|
134
|
+
logger.error(msg);
|
|
135
|
+
reject(new Error(msg));
|
|
136
|
+
}
|
|
129
137
|
});
|
|
130
138
|
process1.on('exit', (code)=>{
|
|
131
|
-
|
|
132
|
-
|
|
139
|
+
if (!isResolved) {
|
|
140
|
+
isResolved = true;
|
|
141
|
+
const msg = `Port forward for ${resource} exited with code ${code}`;
|
|
142
|
+
logger.verbose(msg);
|
|
143
|
+
reject(new Error(msg));
|
|
144
|
+
}
|
|
133
145
|
});
|
|
134
146
|
});
|
|
135
147
|
const port = await connected;
|
|
@@ -164,6 +176,13 @@ export function getExternalIP(namespace, serviceName) {
|
|
|
164
176
|
});
|
|
165
177
|
return promise;
|
|
166
178
|
}
|
|
179
|
+
export function startPortForwardForPrometeheus(namespace) {
|
|
180
|
+
return startPortForward({
|
|
181
|
+
resource: `svc/${namespace}-prometheus-server`,
|
|
182
|
+
namespace,
|
|
183
|
+
containerPort: 80
|
|
184
|
+
});
|
|
185
|
+
}
|
|
167
186
|
export function startPortForwardForRPC(namespace, index = 0) {
|
|
168
187
|
return startPortForward({
|
|
169
188
|
resource: `pod/${namespace}-rpc-aztec-node-${index}`,
|
|
@@ -185,9 +204,11 @@ export async function deleteResourceByName({ resource, namespace, name, force =
|
|
|
185
204
|
return stdout;
|
|
186
205
|
}
|
|
187
206
|
export async function deleteResourceByLabel({ resource, namespace, label, timeout = '5m', force = false }) {
|
|
188
|
-
// Check if the resource type exists before attempting to delete
|
|
189
207
|
try {
|
|
190
|
-
|
|
208
|
+
// Match both plain and group-qualified names (e.g., "podchaos" or "podchaos.chaos-mesh.org")
|
|
209
|
+
const escaped = resource.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
210
|
+
const regex = `(^|\\.)${escaped}(\\.|$)`;
|
|
211
|
+
await execAsync(`kubectl api-resources --no-headers -o name | grep -Eq '${regex}'`);
|
|
191
212
|
} catch (error) {
|
|
192
213
|
logger.warn(`Resource type '${resource}' not found in cluster, skipping deletion ${error}`);
|
|
193
214
|
return '';
|
|
@@ -203,6 +224,31 @@ export async function waitForResourceByLabel({ resource, label, namespace, condi
|
|
|
203
224
|
const { stdout } = await execAsync(command);
|
|
204
225
|
return stdout;
|
|
205
226
|
}
|
|
227
|
+
export async function waitForResourceByName({ resource, name, namespace, condition = 'Ready', timeout = '10m' }) {
|
|
228
|
+
const command = `kubectl wait ${resource}/${name} --for=condition=${condition} -n ${namespace} --timeout=${timeout}`;
|
|
229
|
+
logger.info(`command: ${command}`);
|
|
230
|
+
const { stdout } = await execAsync(command);
|
|
231
|
+
return stdout;
|
|
232
|
+
}
|
|
233
|
+
export async function waitForResourcesByName({ resource, names, namespace, condition = 'Ready', timeout = '10m' }) {
|
|
234
|
+
if (!names.length) {
|
|
235
|
+
throw new Error(`No ${resource} names provided to waitForResourcesByName`);
|
|
236
|
+
}
|
|
237
|
+
// Wait all in parallel; if any fails, surface which one.
|
|
238
|
+
await Promise.all(names.map(async (name)=>{
|
|
239
|
+
try {
|
|
240
|
+
await waitForResourceByName({
|
|
241
|
+
resource,
|
|
242
|
+
name,
|
|
243
|
+
namespace,
|
|
244
|
+
condition,
|
|
245
|
+
timeout
|
|
246
|
+
});
|
|
247
|
+
} catch (err) {
|
|
248
|
+
throw new Error(`Failed waiting for ${resource}/${name} condition=${condition} timeout=${timeout} namespace=${namespace}: ${String(err)}`);
|
|
249
|
+
}
|
|
250
|
+
}));
|
|
251
|
+
}
|
|
206
252
|
export function getChartDir(spartanDir, chartName) {
|
|
207
253
|
return path.join(spartanDir.trim(), chartName);
|
|
208
254
|
}
|
|
@@ -224,7 +270,31 @@ async function execHelmCommand(args) {
|
|
|
224
270
|
const { stdout } = await execAsync(helmCommand);
|
|
225
271
|
return stdout;
|
|
226
272
|
}
|
|
227
|
-
|
|
273
|
+
async function getHelmReleaseStatus(instanceName, namespace) {
|
|
274
|
+
try {
|
|
275
|
+
const { stdout } = await execAsync(`helm list --namespace ${namespace} --all --filter '^${instanceName}$' --output json | cat`);
|
|
276
|
+
const parsed = JSON.parse(stdout);
|
|
277
|
+
const row = parsed.find((r)=>r.name === instanceName);
|
|
278
|
+
return row?.status;
|
|
279
|
+
} catch {
|
|
280
|
+
return undefined;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
async function forceDeleteHelmReleaseRecord(instanceName, namespace, logger) {
|
|
284
|
+
const labelSelector = `owner=helm,name=${instanceName}`;
|
|
285
|
+
const cmd = `kubectl delete secret -n ${namespace} -l ${labelSelector} --ignore-not-found=true`;
|
|
286
|
+
logger.warn(`Force deleting Helm release record: ${cmd}`);
|
|
287
|
+
await execAsync(cmd).catch(()=>undefined);
|
|
288
|
+
}
|
|
289
|
+
async function hasDeployedHelmRelease(instanceName, namespace) {
|
|
290
|
+
try {
|
|
291
|
+
const status = await getHelmReleaseStatus(instanceName, namespace);
|
|
292
|
+
return status?.toLowerCase() === 'deployed';
|
|
293
|
+
} catch {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
export async function uninstallChaosMesh(instanceName, namespace, logger) {
|
|
228
298
|
// uninstall the helm chart if it exists
|
|
229
299
|
logger.info(`Uninstalling helm chart ${instanceName}`);
|
|
230
300
|
await execAsync(`helm uninstall ${instanceName} --namespace ${namespace} --wait --ignore-not-found`);
|
|
@@ -269,7 +339,7 @@ export async function cleanHelm(instanceName, namespace, logger) {
|
|
|
269
339
|
* ```
|
|
270
340
|
*/ export async function installChaosMeshChart({ instanceName, targetNamespace, valuesFile, helmChartDir, timeout = '10m', clean = true, values = {}, logger }) {
|
|
271
341
|
if (clean) {
|
|
272
|
-
await
|
|
342
|
+
await uninstallChaosMesh(instanceName, targetNamespace, logger);
|
|
273
343
|
}
|
|
274
344
|
return execHelmCommand({
|
|
275
345
|
instanceName,
|
|
@@ -295,51 +365,66 @@ export function applyProverFailure({ namespace, spartanDir, durationSeconds, log
|
|
|
295
365
|
logger
|
|
296
366
|
});
|
|
297
367
|
}
|
|
298
|
-
export function
|
|
368
|
+
export function applyValidatorFailure({ namespace, spartanDir, logger, values, instanceName }) {
|
|
369
|
+
return installChaosMeshChart({
|
|
370
|
+
instanceName: instanceName ?? 'validator-failure',
|
|
371
|
+
targetNamespace: namespace,
|
|
372
|
+
valuesFile: 'validator-failure.yaml',
|
|
373
|
+
helmChartDir: getChartDir(spartanDir, 'aztec-chaos-scenarios'),
|
|
374
|
+
values,
|
|
375
|
+
logger
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
export function applyProverKill({ namespace, spartanDir, logger, values }) {
|
|
299
379
|
return installChaosMeshChart({
|
|
300
380
|
instanceName: 'prover-kill',
|
|
301
381
|
targetNamespace: namespace,
|
|
302
382
|
valuesFile: 'prover-kill.yaml',
|
|
303
383
|
helmChartDir: getChartDir(spartanDir, 'aztec-chaos-scenarios'),
|
|
384
|
+
chaosMeshNamespace: namespace,
|
|
304
385
|
clean: true,
|
|
305
|
-
logger
|
|
386
|
+
logger,
|
|
387
|
+
values
|
|
306
388
|
});
|
|
307
389
|
}
|
|
308
|
-
export function applyProverBrokerKill({ namespace, spartanDir, logger }) {
|
|
390
|
+
export function applyProverBrokerKill({ namespace, spartanDir, logger, values }) {
|
|
309
391
|
return installChaosMeshChart({
|
|
310
392
|
instanceName: 'prover-broker-kill',
|
|
311
393
|
targetNamespace: namespace,
|
|
312
394
|
valuesFile: 'prover-broker-kill.yaml',
|
|
313
395
|
helmChartDir: getChartDir(spartanDir, 'aztec-chaos-scenarios'),
|
|
314
396
|
clean: true,
|
|
315
|
-
logger
|
|
397
|
+
logger,
|
|
398
|
+
values
|
|
316
399
|
});
|
|
317
400
|
}
|
|
318
|
-
export function applyBootNodeFailure({ namespace, spartanDir, durationSeconds, logger }) {
|
|
401
|
+
export function applyBootNodeFailure({ instanceName = 'boot-node-failure', namespace, spartanDir, durationSeconds, logger, values }) {
|
|
319
402
|
return installChaosMeshChart({
|
|
320
|
-
instanceName
|
|
403
|
+
instanceName,
|
|
321
404
|
targetNamespace: namespace,
|
|
322
405
|
valuesFile: 'boot-node-failure.yaml',
|
|
323
406
|
helmChartDir: getChartDir(spartanDir, 'aztec-chaos-scenarios'),
|
|
324
407
|
values: {
|
|
325
|
-
'bootNodeFailure.duration': `${durationSeconds}s
|
|
408
|
+
'bootNodeFailure.duration': `${durationSeconds}s`,
|
|
409
|
+
...values ?? {}
|
|
326
410
|
},
|
|
327
411
|
logger
|
|
328
412
|
});
|
|
329
413
|
}
|
|
330
|
-
export function applyValidatorKill({ namespace, spartanDir, logger, values }) {
|
|
414
|
+
export function applyValidatorKill({ instanceName = 'validator-kill', namespace, spartanDir, logger, values, clean = true }) {
|
|
331
415
|
return installChaosMeshChart({
|
|
332
|
-
instanceName: 'validator-kill',
|
|
416
|
+
instanceName: instanceName ?? 'validator-kill',
|
|
333
417
|
targetNamespace: namespace,
|
|
334
418
|
valuesFile: 'validator-kill.yaml',
|
|
335
419
|
helmChartDir: getChartDir(spartanDir, 'aztec-chaos-scenarios'),
|
|
420
|
+
clean,
|
|
336
421
|
logger,
|
|
337
422
|
values
|
|
338
423
|
});
|
|
339
424
|
}
|
|
340
|
-
export function applyNetworkShaping({ valuesFile, namespace, spartanDir, logger }) {
|
|
425
|
+
export function applyNetworkShaping({ instanceName = 'network-shaping', valuesFile, namespace, spartanDir, logger }) {
|
|
341
426
|
return installChaosMeshChart({
|
|
342
|
-
instanceName
|
|
427
|
+
instanceName,
|
|
343
428
|
targetNamespace: namespace,
|
|
344
429
|
valuesFile,
|
|
345
430
|
helmChartDir: getChartDir(spartanDir, 'aztec-chaos-scenarios'),
|
|
@@ -402,7 +487,12 @@ export async function restartBot(namespace, logger) {
|
|
|
402
487
|
// Provide L1 execution RPC for bridging fee juice
|
|
403
488
|
'bot.node.env.ETHEREUM_HOSTS': `http://${namespace}-eth-execution.${namespace}.svc.cluster.local:8545`,
|
|
404
489
|
// Provide L1 mnemonic for bridging (falls back to labs mnemonic)
|
|
405
|
-
'bot.node.env.BOT_L1_MNEMONIC': mnemonic
|
|
490
|
+
'bot.node.env.BOT_L1_MNEMONIC': mnemonic,
|
|
491
|
+
// The bot does not need Kubernetes API access. Disable RBAC + ServiceAccount creation so the chart
|
|
492
|
+
// can be installed by users without cluster-scoped RBAC permissions.
|
|
493
|
+
'bot.rbac.create': false,
|
|
494
|
+
'bot.serviceAccount.create': false,
|
|
495
|
+
'bot.serviceAccount.name': 'default'
|
|
406
496
|
};
|
|
407
497
|
// Ensure we derive a funded L1 key (index 0 is funded on anvil default mnemonic)
|
|
408
498
|
if (mnemonicStartIndex === undefined) {
|
|
@@ -425,7 +515,7 @@ export async function restartBot(namespace, logger) {
|
|
|
425
515
|
let tag = tagFromEnv;
|
|
426
516
|
if (!repository || !tag) {
|
|
427
517
|
try {
|
|
428
|
-
const { stdout } = await execAsync(`kubectl get pods -l app.kubernetes.io/
|
|
518
|
+
const { stdout } = await execAsync(`kubectl get pods -l app.kubernetes.io/name=validator -n ${namespace} -o jsonpath='{.items[0].spec.containers[?(@.name=="aztec")].image}' | cat`);
|
|
429
519
|
const image = stdout.trim().replace(/^'|'$/g, '');
|
|
430
520
|
if (image && image.includes(':')) {
|
|
431
521
|
const lastColon = image.lastIndexOf(':');
|
|
@@ -443,6 +533,22 @@ export async function restartBot(namespace, logger) {
|
|
|
443
533
|
if (mnemonicStartIndex !== undefined) {
|
|
444
534
|
values['bot.mnemonicStartIndex'] = typeof mnemonicStartIndex === 'string' ? mnemonicStartIndex : Number(mnemonicStartIndex);
|
|
445
535
|
}
|
|
536
|
+
// If a previous install attempt left the release in a non-deployed state (e.g. FAILED),
|
|
537
|
+
// `helm upgrade --install` can error with "has no deployed releases".
|
|
538
|
+
// In that case, clear the release record and do a clean install.
|
|
539
|
+
const existingStatus = await getHelmReleaseStatus(instanceName, namespace);
|
|
540
|
+
if (existingStatus && existingStatus.toLowerCase() !== 'deployed') {
|
|
541
|
+
logger.warn(`Transfer bot release ${instanceName} is in status '${existingStatus}'. Reinstalling cleanly.`);
|
|
542
|
+
await execAsync(`helm uninstall ${instanceName} --namespace ${namespace} --wait --ignore-not-found`).catch(()=>undefined);
|
|
543
|
+
// If helm left the release in `uninstalling`, force-delete the record so we can reinstall.
|
|
544
|
+
const afterUninstallStatus = await getHelmReleaseStatus(instanceName, namespace);
|
|
545
|
+
if (afterUninstallStatus?.toLowerCase() === 'uninstalling') {
|
|
546
|
+
await forceDeleteHelmReleaseRecord(instanceName, namespace, logger);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
// `--reuse-values` fails if the release has never successfully deployed (e.g. first install, or a previous failed install).
|
|
550
|
+
// Only reuse values when we have a deployed release to reuse from.
|
|
551
|
+
const effectiveReuseValues = reuseValues && await hasDeployedHelmRelease(instanceName, namespace);
|
|
446
552
|
await execHelmCommand({
|
|
447
553
|
instanceName,
|
|
448
554
|
helmChartDir,
|
|
@@ -450,7 +556,7 @@ export async function restartBot(namespace, logger) {
|
|
|
450
556
|
valuesFile: undefined,
|
|
451
557
|
timeout,
|
|
452
558
|
values: values,
|
|
453
|
-
reuseValues
|
|
559
|
+
reuseValues: effectiveReuseValues
|
|
454
560
|
});
|
|
455
561
|
if (replicas > 0) {
|
|
456
562
|
await waitForResourceByLabel({
|
|
@@ -482,8 +588,9 @@ export async function restartBot(namespace, logger) {
|
|
|
482
588
|
const drop = enabled ? 'true' : 'false';
|
|
483
589
|
const prob = String(probability);
|
|
484
590
|
const selectors = [
|
|
485
|
-
'app=validator',
|
|
486
|
-
'app.kubernetes.io/component=validator'
|
|
591
|
+
'app.kubernetes.io/name=validator',
|
|
592
|
+
'app.kubernetes.io/component=validator',
|
|
593
|
+
'app=validator'
|
|
487
594
|
];
|
|
488
595
|
let updated = false;
|
|
489
596
|
for (const selector of selectors){
|
|
@@ -510,8 +617,9 @@ export async function restartBot(namespace, logger) {
|
|
|
510
617
|
}
|
|
511
618
|
export async function restartValidators(namespace, logger) {
|
|
512
619
|
const selectors = [
|
|
513
|
-
'app=validator',
|
|
514
|
-
'app.kubernetes.io/component=validator'
|
|
620
|
+
'app.kubernetes.io/name=validator',
|
|
621
|
+
'app.kubernetes.io/component=validator',
|
|
622
|
+
'app=validator'
|
|
515
623
|
];
|
|
516
624
|
let any = false;
|
|
517
625
|
for (const selector of selectors){
|
|
@@ -565,11 +673,27 @@ export async function enableValidatorDynamicBootNode(instanceName, namespace, sp
|
|
|
565
673
|
logger.info(`Validator dynamic boot node enabled`);
|
|
566
674
|
}
|
|
567
675
|
export async function getSequencers(namespace) {
|
|
568
|
-
const
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
676
|
+
const selectors = [
|
|
677
|
+
'app.kubernetes.io/name=validator',
|
|
678
|
+
'app.kubernetes.io/component=validator',
|
|
679
|
+
'app.kubernetes.io/component=sequencer-node',
|
|
680
|
+
'app=validator'
|
|
681
|
+
];
|
|
682
|
+
for (const selector of selectors){
|
|
683
|
+
try {
|
|
684
|
+
const command = `kubectl get pods -l ${selector} -n ${namespace} -o jsonpath='{.items[*].metadata.name}'`;
|
|
685
|
+
const { stdout } = await execAsync(command);
|
|
686
|
+
const sequencers = stdout.split(' ').map((s)=>s.trim()).filter(Boolean);
|
|
687
|
+
if (sequencers.length > 0) {
|
|
688
|
+
logger.verbose(`Found sequencer pods ${sequencers.join(', ')} (selector=${selector})`);
|
|
689
|
+
return sequencers;
|
|
690
|
+
}
|
|
691
|
+
} catch {
|
|
692
|
+
// try next selector
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
// Fail fast instead of returning [''] which leads to attempts to port-forward `pod/`.
|
|
696
|
+
throw new Error(`No sequencer/validator pods found in namespace ${namespace}. Tried selectors: ${selectors.join(', ')}`);
|
|
573
697
|
}
|
|
574
698
|
export function updateSequencersConfig(env, config) {
|
|
575
699
|
return withSequencersAdmin(env, async (client)=>{
|
|
@@ -619,7 +743,9 @@ export async function withSequencersAdmin(env, fn) {
|
|
|
619
743
|
const url = `http://127.0.0.1:${port}`;
|
|
620
744
|
const client = createPublicClient({
|
|
621
745
|
transport: fallback([
|
|
622
|
-
http(url
|
|
746
|
+
http(url, {
|
|
747
|
+
batch: false
|
|
748
|
+
})
|
|
623
749
|
])
|
|
624
750
|
});
|
|
625
751
|
if (processes) {
|
|
@@ -637,7 +763,9 @@ export async function withSequencersAdmin(env, fn) {
|
|
|
637
763
|
}
|
|
638
764
|
const client = createPublicClient({
|
|
639
765
|
transport: fallback([
|
|
640
|
-
http(L1_RPC_URLS_JSON
|
|
766
|
+
http(L1_RPC_URLS_JSON, {
|
|
767
|
+
batch: false
|
|
768
|
+
})
|
|
641
769
|
])
|
|
642
770
|
});
|
|
643
771
|
return {
|
|
@@ -670,71 +798,103 @@ export async function withSequencersAdmin(env, fn) {
|
|
|
670
798
|
/**
|
|
671
799
|
* Rolls the Aztec pods in the given namespace.
|
|
672
800
|
* @param namespace - The namespace to roll the Aztec pods in.
|
|
673
|
-
* @
|
|
674
|
-
* This
|
|
675
|
-
*
|
|
676
|
-
*/ export async function rollAztecPods(namespace) {
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
801
|
+
* @param clearState - If true, also deletes the underlying PVCs to clear persistent storage.
|
|
802
|
+
* This is required for rollup upgrades where the old state is incompatible with the new rollup.
|
|
803
|
+
* Defaults to false, which preserves the existing storage.
|
|
804
|
+
*/ export async function rollAztecPods(namespace, clearState = false) {
|
|
805
|
+
// Pod components use 'validator', but StatefulSets and PVCs use 'sequencer-node' for validators
|
|
806
|
+
const podComponents = [
|
|
807
|
+
'p2p-bootstrap',
|
|
808
|
+
'prover-node',
|
|
809
|
+
'prover-broker',
|
|
810
|
+
'prover-agent',
|
|
811
|
+
'sequencer-node',
|
|
812
|
+
'rpc'
|
|
813
|
+
];
|
|
814
|
+
const pvcComponents = [
|
|
815
|
+
'p2p-bootstrap',
|
|
816
|
+
'prover-node',
|
|
817
|
+
'prover-broker',
|
|
818
|
+
'sequencer-node',
|
|
819
|
+
'rpc'
|
|
820
|
+
];
|
|
821
|
+
// StatefulSet components that need to be scaled down before PVC deletion
|
|
822
|
+
// Note: validators use 'sequencer-node' as component label, not 'validator'
|
|
823
|
+
const statefulSetComponents = [
|
|
824
|
+
'p2p-bootstrap',
|
|
825
|
+
'prover-node',
|
|
826
|
+
'prover-broker',
|
|
827
|
+
'sequencer-node',
|
|
828
|
+
'rpc'
|
|
829
|
+
];
|
|
830
|
+
if (clearState) {
|
|
831
|
+
// To delete PVCs, we must first scale down StatefulSets so pods release the volumes
|
|
832
|
+
// Otherwise PVC deletion will hang waiting for pods to terminate
|
|
833
|
+
// First, save original replica counts
|
|
834
|
+
const originalReplicas = new Map();
|
|
835
|
+
for (const component of statefulSetComponents){
|
|
836
|
+
try {
|
|
837
|
+
const getCmd = `kubectl get statefulset -l app.kubernetes.io/component=${component} -n ${namespace} -o jsonpath='{.items[0].spec.replicas}'`;
|
|
838
|
+
const { stdout } = await execAsync(getCmd);
|
|
839
|
+
const replicas = parseInt(stdout.replace(/'/g, '').trim(), 10);
|
|
840
|
+
if (!isNaN(replicas) && replicas > 0) {
|
|
841
|
+
originalReplicas.set(component, replicas);
|
|
842
|
+
}
|
|
843
|
+
} catch {
|
|
844
|
+
// Component might not exist, continue
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
// Scale down to 0
|
|
848
|
+
for (const component of statefulSetComponents){
|
|
849
|
+
try {
|
|
850
|
+
const scaleCmd = `kubectl scale statefulset -l app.kubernetes.io/component=${component} -n ${namespace} --replicas=0 --timeout=2m`;
|
|
851
|
+
logger.info(`command: ${scaleCmd}`);
|
|
852
|
+
await execAsync(scaleCmd);
|
|
853
|
+
} catch (e) {
|
|
854
|
+
// Component might not exist or might be a Deployment, continue
|
|
855
|
+
logger.verbose(`Scale down ${component} skipped: ${e}`);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
// Wait for pods to terminate
|
|
859
|
+
await sleep(15 * 1000);
|
|
860
|
+
// Now delete PVCs (they should no longer be in use)
|
|
861
|
+
for (const component of pvcComponents){
|
|
862
|
+
await deleteResourceByLabel({
|
|
863
|
+
resource: 'persistentvolumeclaims',
|
|
864
|
+
namespace: namespace,
|
|
865
|
+
label: `app.kubernetes.io/component=${component}`
|
|
866
|
+
});
|
|
867
|
+
}
|
|
868
|
+
// Scale StatefulSets back up to original replica counts
|
|
869
|
+
for (const component of statefulSetComponents){
|
|
870
|
+
const replicas = originalReplicas.get(component) ?? 1;
|
|
871
|
+
try {
|
|
872
|
+
const scaleCmd = `kubectl scale statefulset -l app.kubernetes.io/component=${component} -n ${namespace} --replicas=${replicas} --timeout=2m`;
|
|
873
|
+
logger.info(`command: ${scaleCmd}`);
|
|
874
|
+
await execAsync(scaleCmd);
|
|
875
|
+
} catch (e) {
|
|
876
|
+
logger.verbose(`Scale up ${component} skipped: ${e}`);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
} else {
|
|
880
|
+
// Just delete pods (no state clearing)
|
|
881
|
+
for (const component of podComponents){
|
|
882
|
+
await deleteResourceByLabel({
|
|
883
|
+
resource: 'pods',
|
|
884
|
+
namespace: namespace,
|
|
885
|
+
label: `app.kubernetes.io/component=${component}`
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
}
|
|
707
889
|
await sleep(10 * 1000);
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
label: 'app=prover-node'
|
|
717
|
-
});
|
|
718
|
-
await waitForResourceByLabel({
|
|
719
|
-
resource: 'pods',
|
|
720
|
-
namespace: namespace,
|
|
721
|
-
label: 'app=prover-broker'
|
|
722
|
-
});
|
|
723
|
-
await waitForResourceByLabel({
|
|
724
|
-
resource: 'pods',
|
|
725
|
-
namespace: namespace,
|
|
726
|
-
label: 'app=prover-agent'
|
|
727
|
-
});
|
|
728
|
-
await waitForResourceByLabel({
|
|
729
|
-
resource: 'pods',
|
|
730
|
-
namespace: namespace,
|
|
731
|
-
label: 'app=validator'
|
|
732
|
-
});
|
|
733
|
-
await waitForResourceByLabel({
|
|
734
|
-
resource: 'pods',
|
|
735
|
-
namespace: namespace,
|
|
736
|
-
label: 'app=pxe'
|
|
737
|
-
});
|
|
890
|
+
// Wait for pods to come back
|
|
891
|
+
for (const component of podComponents){
|
|
892
|
+
await waitForResourceByLabel({
|
|
893
|
+
resource: 'pods',
|
|
894
|
+
namespace: namespace,
|
|
895
|
+
label: `app.kubernetes.io/component=${component}`
|
|
896
|
+
});
|
|
897
|
+
}
|
|
738
898
|
}
|
|
739
899
|
/**
|
|
740
900
|
* Returns the absolute path to the git repository root
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/end-to-end",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.f295ac2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dest/index.js",
|
|
6
6
|
"inherits": [
|
|
@@ -25,43 +25,44 @@
|
|
|
25
25
|
"formatting": "run -T prettier --check ./src && run -T eslint ./src"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@aztec/accounts": "0.0.1-commit.
|
|
29
|
-
"@aztec/archiver": "0.0.1-commit.
|
|
30
|
-
"@aztec/aztec": "0.0.1-commit.
|
|
31
|
-
"@aztec/aztec-node": "0.0.1-commit.
|
|
32
|
-
"@aztec/aztec.js": "0.0.1-commit.
|
|
33
|
-
"@aztec/bb-prover": "0.0.1-commit.
|
|
34
|
-
"@aztec/bb.js": "0.0.1-commit.
|
|
35
|
-
"@aztec/blob-
|
|
36
|
-
"@aztec/blob-
|
|
37
|
-
"@aztec/bot": "0.0.1-commit.
|
|
38
|
-
"@aztec/cli": "0.0.1-commit.
|
|
39
|
-
"@aztec/constants": "0.0.1-commit.
|
|
40
|
-
"@aztec/entrypoints": "0.0.1-commit.
|
|
41
|
-
"@aztec/epoch-cache": "0.0.1-commit.
|
|
42
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
43
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
44
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
45
|
-
"@aztec/l1-artifacts": "0.0.1-commit.
|
|
46
|
-
"@aztec/merkle-tree": "0.0.1-commit.
|
|
47
|
-
"@aztec/node-keystore": "0.0.1-commit.
|
|
48
|
-
"@aztec/noir-contracts.js": "0.0.1-commit.
|
|
49
|
-
"@aztec/noir-noirc_abi": "0.0.1-commit.
|
|
50
|
-
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.
|
|
51
|
-
"@aztec/noir-test-contracts.js": "0.0.1-commit.
|
|
52
|
-
"@aztec/p2p": "0.0.1-commit.
|
|
53
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
54
|
-
"@aztec/prover-client": "0.0.1-commit.
|
|
55
|
-
"@aztec/prover-node": "0.0.1-commit.
|
|
56
|
-
"@aztec/pxe": "0.0.1-commit.
|
|
57
|
-
"@aztec/sequencer-client": "0.0.1-commit.
|
|
58
|
-
"@aztec/simulator": "0.0.1-commit.
|
|
59
|
-
"@aztec/slasher": "0.0.1-commit.
|
|
60
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
61
|
-
"@aztec/telemetry-client": "0.0.1-commit.
|
|
62
|
-
"@aztec/test-wallet": "0.0.1-commit.
|
|
63
|
-
"@aztec/validator-client": "0.0.1-commit.
|
|
64
|
-
"@aztec/
|
|
28
|
+
"@aztec/accounts": "0.0.1-commit.f295ac2",
|
|
29
|
+
"@aztec/archiver": "0.0.1-commit.f295ac2",
|
|
30
|
+
"@aztec/aztec": "0.0.1-commit.f295ac2",
|
|
31
|
+
"@aztec/aztec-node": "0.0.1-commit.f295ac2",
|
|
32
|
+
"@aztec/aztec.js": "0.0.1-commit.f295ac2",
|
|
33
|
+
"@aztec/bb-prover": "0.0.1-commit.f295ac2",
|
|
34
|
+
"@aztec/bb.js": "0.0.1-commit.f295ac2",
|
|
35
|
+
"@aztec/blob-client": "0.0.1-commit.f295ac2",
|
|
36
|
+
"@aztec/blob-lib": "0.0.1-commit.f295ac2",
|
|
37
|
+
"@aztec/bot": "0.0.1-commit.f295ac2",
|
|
38
|
+
"@aztec/cli": "0.0.1-commit.f295ac2",
|
|
39
|
+
"@aztec/constants": "0.0.1-commit.f295ac2",
|
|
40
|
+
"@aztec/entrypoints": "0.0.1-commit.f295ac2",
|
|
41
|
+
"@aztec/epoch-cache": "0.0.1-commit.f295ac2",
|
|
42
|
+
"@aztec/ethereum": "0.0.1-commit.f295ac2",
|
|
43
|
+
"@aztec/foundation": "0.0.1-commit.f295ac2",
|
|
44
|
+
"@aztec/kv-store": "0.0.1-commit.f295ac2",
|
|
45
|
+
"@aztec/l1-artifacts": "0.0.1-commit.f295ac2",
|
|
46
|
+
"@aztec/merkle-tree": "0.0.1-commit.f295ac2",
|
|
47
|
+
"@aztec/node-keystore": "0.0.1-commit.f295ac2",
|
|
48
|
+
"@aztec/noir-contracts.js": "0.0.1-commit.f295ac2",
|
|
49
|
+
"@aztec/noir-noirc_abi": "0.0.1-commit.f295ac2",
|
|
50
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.f295ac2",
|
|
51
|
+
"@aztec/noir-test-contracts.js": "0.0.1-commit.f295ac2",
|
|
52
|
+
"@aztec/p2p": "0.0.1-commit.f295ac2",
|
|
53
|
+
"@aztec/protocol-contracts": "0.0.1-commit.f295ac2",
|
|
54
|
+
"@aztec/prover-client": "0.0.1-commit.f295ac2",
|
|
55
|
+
"@aztec/prover-node": "0.0.1-commit.f295ac2",
|
|
56
|
+
"@aztec/pxe": "0.0.1-commit.f295ac2",
|
|
57
|
+
"@aztec/sequencer-client": "0.0.1-commit.f295ac2",
|
|
58
|
+
"@aztec/simulator": "0.0.1-commit.f295ac2",
|
|
59
|
+
"@aztec/slasher": "0.0.1-commit.f295ac2",
|
|
60
|
+
"@aztec/stdlib": "0.0.1-commit.f295ac2",
|
|
61
|
+
"@aztec/telemetry-client": "0.0.1-commit.f295ac2",
|
|
62
|
+
"@aztec/test-wallet": "0.0.1-commit.f295ac2",
|
|
63
|
+
"@aztec/validator-client": "0.0.1-commit.f295ac2",
|
|
64
|
+
"@aztec/validator-ha-signer": "0.0.1-commit.f295ac2",
|
|
65
|
+
"@aztec/world-state": "0.0.1-commit.f295ac2",
|
|
65
66
|
"@iarna/toml": "^2.2.5",
|
|
66
67
|
"@jest/globals": "^30.0.0",
|
|
67
68
|
"@noble/curves": "=1.0.0",
|
|
@@ -107,7 +108,7 @@
|
|
|
107
108
|
"@types/jest": "^30.0.0",
|
|
108
109
|
"@types/js-yaml": "^4.0.9",
|
|
109
110
|
"@types/lodash.chunk": "^4.2.9",
|
|
110
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
111
|
+
"@typescript/native-preview": "7.0.0-dev.20260113.1",
|
|
111
112
|
"concurrently": "^7.6.0",
|
|
112
113
|
"jest": "^30.0.0",
|
|
113
114
|
"jest-extended": "^6.0.0",
|