@aztec/end-to-end 2.1.0-rc.9 → 3.0.0-devnet.2

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.
Files changed (135) hide show
  1. package/dest/bench/client_flows/benchmark.d.ts +3 -2
  2. package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
  3. package/dest/bench/client_flows/client_flows_benchmark.d.ts +16 -12
  4. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  5. package/dest/bench/client_flows/client_flows_benchmark.js +54 -58
  6. package/dest/bench/utils.d.ts +2 -11
  7. package/dest/bench/utils.d.ts.map +1 -1
  8. package/dest/bench/utils.js +10 -34
  9. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +7 -7
  10. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  11. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +42 -42
  12. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +10 -8
  13. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
  14. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +31 -33
  15. package/dest/e2e_deploy_contract/deploy_test.d.ts +10 -4
  16. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  17. package/dest/e2e_deploy_contract/deploy_test.js +9 -18
  18. package/dest/e2e_epochs/epochs_test.d.ts +3 -1
  19. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  20. package/dest/e2e_epochs/epochs_test.js +10 -9
  21. package/dest/e2e_fees/bridging_race.notest.js +12 -9
  22. package/dest/e2e_fees/fees_test.d.ts +5 -5
  23. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  24. package/dest/e2e_fees/fees_test.js +23 -31
  25. package/dest/e2e_l1_publisher/write_json.d.ts +3 -1
  26. package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -1
  27. package/dest/e2e_l1_publisher/write_json.js +5 -5
  28. package/dest/e2e_multi_validator/utils.d.ts +1 -1
  29. package/dest/e2e_multi_validator/utils.d.ts.map +1 -1
  30. package/dest/e2e_nested_contract/nested_contract_test.d.ts +6 -3
  31. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  32. package/dest/e2e_nested_contract/nested_contract_test.js +7 -9
  33. package/dest/e2e_p2p/inactivity_slash_test.d.ts +2 -2
  34. package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -1
  35. package/dest/e2e_p2p/inactivity_slash_test.js +5 -2
  36. package/dest/e2e_p2p/p2p_network.d.ts +16 -4
  37. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  38. package/dest/e2e_p2p/p2p_network.js +32 -10
  39. package/dest/e2e_p2p/shared.d.ts +11 -13
  40. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  41. package/dest/e2e_p2p/shared.js +49 -45
  42. package/dest/e2e_token_contract/token_contract_test.d.ts +5 -4
  43. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  44. package/dest/e2e_token_contract/token_contract_test.js +14 -17
  45. package/dest/fixtures/e2e_prover_test.d.ts +8 -6
  46. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  47. package/dest/fixtures/e2e_prover_test.js +40 -50
  48. package/dest/fixtures/get_acvm_config.d.ts +1 -1
  49. package/dest/fixtures/get_acvm_config.d.ts.map +1 -1
  50. package/dest/fixtures/get_bb_config.d.ts +1 -1
  51. package/dest/fixtures/get_bb_config.d.ts.map +1 -1
  52. package/dest/fixtures/get_bb_config.js +2 -2
  53. package/dest/fixtures/setup_l1_contracts.d.ts +1 -1
  54. package/dest/fixtures/setup_l1_contracts.d.ts.map +1 -1
  55. package/dest/fixtures/setup_l1_contracts.js +2 -2
  56. package/dest/fixtures/setup_p2p_test.d.ts +0 -7
  57. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  58. package/dest/fixtures/snapshot_manager.d.ts +10 -7
  59. package/dest/fixtures/snapshot_manager.d.ts.map +1 -1
  60. package/dest/fixtures/snapshot_manager.js +44 -34
  61. package/dest/fixtures/token_utils.d.ts +6 -4
  62. package/dest/fixtures/token_utils.d.ts.map +1 -1
  63. package/dest/fixtures/token_utils.js +11 -15
  64. package/dest/fixtures/utils.d.ts +23 -27
  65. package/dest/fixtures/utils.d.ts.map +1 -1
  66. package/dest/fixtures/utils.js +76 -101
  67. package/dest/fixtures/web3signer.d.ts +1 -1
  68. package/dest/fixtures/web3signer.d.ts.map +1 -1
  69. package/dest/fixtures/web3signer.js +16 -5
  70. package/dest/quality_of_service/alert_checker.d.ts +1 -1
  71. package/dest/quality_of_service/alert_checker.d.ts.map +1 -1
  72. package/dest/shared/cross_chain_test_harness.d.ts +16 -10
  73. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  74. package/dest/shared/cross_chain_test_harness.js +13 -15
  75. package/dest/shared/gas_portal_test_harness.d.ts +9 -6
  76. package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
  77. package/dest/shared/gas_portal_test_harness.js +10 -7
  78. package/dest/shared/jest_setup.js +1 -1
  79. package/dest/shared/submit-transactions.d.ts +5 -3
  80. package/dest/shared/submit-transactions.d.ts.map +1 -1
  81. package/dest/shared/submit-transactions.js +8 -7
  82. package/dest/shared/uniswap_l1_l2.d.ts +9 -6
  83. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  84. package/dest/shared/uniswap_l1_l2.js +29 -45
  85. package/dest/simulators/lending_simulator.d.ts +2 -1
  86. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  87. package/dest/simulators/lending_simulator.js +3 -2
  88. package/dest/simulators/token_simulator.d.ts +3 -1
  89. package/dest/simulators/token_simulator.d.ts.map +1 -1
  90. package/dest/simulators/token_simulator.js +2 -2
  91. package/dest/spartan/setup_test_wallets.d.ts +19 -13
  92. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  93. package/dest/spartan/setup_test_wallets.js +108 -85
  94. package/dest/spartan/utils.d.ts +44 -0
  95. package/dest/spartan/utils.d.ts.map +1 -1
  96. package/dest/spartan/utils.js +212 -20
  97. package/package.json +38 -37
  98. package/src/bench/client_flows/benchmark.ts +6 -6
  99. package/src/bench/client_flows/client_flows_benchmark.ts +62 -82
  100. package/src/bench/client_flows/data_extractor.ts +1 -1
  101. package/src/bench/utils.ts +9 -37
  102. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +46 -63
  103. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +33 -47
  104. package/src/e2e_deploy_contract/deploy_test.ts +17 -35
  105. package/src/e2e_epochs/epochs_test.ts +12 -14
  106. package/src/e2e_fees/bridging_race.notest.ts +14 -9
  107. package/src/e2e_fees/fees_test.ts +26 -38
  108. package/src/e2e_l1_publisher/write_json.ts +8 -6
  109. package/src/e2e_multi_validator/utils.ts +1 -1
  110. package/src/e2e_nested_contract/nested_contract_test.ts +11 -10
  111. package/src/e2e_p2p/inactivity_slash_test.ts +7 -3
  112. package/src/e2e_p2p/p2p_network.ts +105 -67
  113. package/src/e2e_p2p/shared.ts +50 -55
  114. package/src/e2e_token_contract/token_contract_test.ts +17 -17
  115. package/src/fixtures/e2e_prover_test.ts +51 -88
  116. package/src/fixtures/get_acvm_config.ts +1 -1
  117. package/src/fixtures/get_bb_config.ts +3 -2
  118. package/src/fixtures/setup_l1_contracts.ts +3 -3
  119. package/src/fixtures/setup_p2p_test.ts +0 -8
  120. package/src/fixtures/snapshot_manager.ts +61 -61
  121. package/src/fixtures/token_utils.ts +13 -21
  122. package/src/fixtures/utils.ts +87 -138
  123. package/src/fixtures/web3signer.ts +22 -5
  124. package/src/guides/up_quick_start.sh +2 -10
  125. package/src/quality_of_service/alert_checker.ts +1 -1
  126. package/src/shared/cross_chain_test_harness.ts +18 -29
  127. package/src/shared/gas_portal_test_harness.ts +12 -19
  128. package/src/shared/jest_setup.ts +1 -1
  129. package/src/shared/submit-transactions.ts +12 -8
  130. package/src/shared/uniswap_l1_l2.ts +61 -67
  131. package/src/simulators/lending_simulator.ts +3 -2
  132. package/src/simulators/token_simulator.ts +5 -2
  133. package/src/spartan/DEVELOP.md +8 -3
  134. package/src/spartan/setup_test_wallets.ts +133 -126
  135. package/src/spartan/utils.ts +268 -18
@@ -1,5 +1,5 @@
1
1
  import type { AztecNodeService } from '@aztec/aztec-node';
2
- import { EthAddress } from '@aztec/aztec.js';
2
+ import { EthAddress } from '@aztec/aztec.js/addresses';
3
3
  import { RollupContract } from '@aztec/ethereum';
4
4
 
5
5
  import fs from 'fs';
@@ -17,8 +17,8 @@ const SLASHING_QUORUM = 3;
17
17
  const EPOCH_DURATION = 2;
18
18
  const SLASHING_ROUND_SIZE_IN_EPOCHS = 2;
19
19
  const BOOT_NODE_UDP_PORT = 4500;
20
- const ETHEREUM_SLOT_DURATION = 4;
21
- const AZTEC_SLOT_DURATION = 8;
20
+ const ETHEREUM_SLOT_DURATION = process.env.CI ? 8 : 4;
21
+ const AZTEC_SLOT_DURATION = ETHEREUM_SLOT_DURATION * 2;
22
22
  const SLASHING_UNIT = BigInt(1e18);
23
23
  const SLASHING_AMOUNT = SLASHING_UNIT * 3n;
24
24
 
@@ -146,6 +146,10 @@ export class P2PInactivityTest {
146
146
  offlineValidators: this.offlineValidators,
147
147
  });
148
148
 
149
+ // Wait for P2P mesh to be fully formed before starting slashing period
150
+ // This prevents race conditions where validators propose blocks before the network is ready
151
+ await this.test.waitForP2PMeshConnectivity(this.nodes, NUM_NODES);
152
+
149
153
  this.test.logger.warn(`Advancing to epoch ${SETUP_EPOCH_DURATION + 1} to start slashing`);
150
154
  await this.test.ctx.cheatCodes.rollup.advanceToEpoch(SETUP_EPOCH_DURATION + 1);
151
155
 
@@ -1,7 +1,7 @@
1
- import { getSchnorrWalletWithSecretKey } from '@aztec/accounts/schnorr';
2
1
  import type { InitialAccountData } from '@aztec/accounts/testing';
3
2
  import type { AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
4
- import { type AccountWalletWithSecretKey, AztecAddress, EthAddress, Fr } from '@aztec/aztec.js';
3
+ import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses';
4
+ import { Fr } from '@aztec/aztec.js/fields';
5
5
  import {
6
6
  type EmpireSlashingProposerContract,
7
7
  type ExtendedViemWalletClient,
@@ -18,6 +18,7 @@ import {
18
18
  import { ChainMonitor } from '@aztec/ethereum/test';
19
19
  import { SecretValue } from '@aztec/foundation/config';
20
20
  import { type Logger, createLogger } from '@aztec/foundation/log';
21
+ import { retryUntil } from '@aztec/foundation/retry';
21
22
  import { RollupAbi, SlasherAbi, TestERC20Abi } from '@aztec/l1-artifacts';
22
23
  import { SpamContract } from '@aztec/noir-test-contracts.js/Spam';
23
24
  import type { BootstrapNode } from '@aztec/p2p/bootstrap';
@@ -26,6 +27,7 @@ import { tryStop } from '@aztec/stdlib/interfaces/server';
26
27
  import { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
27
28
  import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
28
29
  import { ZkPassportProofParams } from '@aztec/stdlib/zkpassport';
30
+ import type { TestWallet } from '@aztec/test-wallet/server';
29
31
  import { getGenesisValues } from '@aztec/world-state/testing';
30
32
 
31
33
  import getPort from 'get-port';
@@ -75,7 +77,7 @@ export class P2PNetworkTest {
75
77
  public prefilledPublicData: PublicDataTreeLeaf[] = [];
76
78
 
77
79
  // The re-execution test needs a wallet and a spam contract
78
- public wallet?: AccountWalletWithSecretKey;
80
+ public wallet?: TestWallet;
79
81
  public defaultAccountAddress?: AztecAddress;
80
82
  public spamContract?: SpamContract;
81
83
 
@@ -230,89 +232,83 @@ export class P2PNetworkTest {
230
232
 
231
233
  async applyBaseSnapshots() {
232
234
  await this.addBootstrapNode();
233
- await this.snapshotManager.snapshot(
234
- 'add-validators',
235
- async ({ deployL1ContractsValues, dateProvider, cheatCodes }) => {
236
- const rollup = getContract({
237
- address: deployL1ContractsValues.l1ContractAddresses.rollupAddress.toString(),
238
- abi: RollupAbi,
239
- client: deployL1ContractsValues.l1Client,
240
- });
235
+ await this.snapshotManager.snapshot('add-validators', async ({ deployL1ContractsValues, cheatCodes }) => {
236
+ const rollup = getContract({
237
+ address: deployL1ContractsValues.l1ContractAddresses.rollupAddress.toString(),
238
+ abi: RollupAbi,
239
+ client: deployL1ContractsValues.l1Client,
240
+ });
241
241
 
242
- this.logger.info(`Adding ${this.numberOfValidators} validators`);
242
+ this.logger.info(`Adding ${this.numberOfValidators} validators`);
243
243
 
244
- const stakingAsset = getContract({
245
- address: deployL1ContractsValues.l1ContractAddresses.stakingAssetAddress.toString(),
246
- abi: TestERC20Abi,
247
- client: deployL1ContractsValues.l1Client,
248
- });
244
+ const stakingAsset = getContract({
245
+ address: deployL1ContractsValues.l1ContractAddresses.stakingAssetAddress.toString(),
246
+ abi: TestERC20Abi,
247
+ client: deployL1ContractsValues.l1Client,
248
+ });
249
249
 
250
- const { address: multiAdderAddress } = await deployL1Contract(
251
- deployL1ContractsValues.l1Client,
252
- MultiAdderArtifact.contractAbi,
253
- MultiAdderArtifact.contractBytecode,
254
- [rollup.address, deployL1ContractsValues.l1Client.account.address],
255
- );
250
+ const { address: multiAdderAddress } = await deployL1Contract(
251
+ deployL1ContractsValues.l1Client,
252
+ MultiAdderArtifact.contractAbi,
253
+ MultiAdderArtifact.contractBytecode,
254
+ [rollup.address, deployL1ContractsValues.l1Client.account.address],
255
+ );
256
256
 
257
- const multiAdder = getContract({
258
- address: multiAdderAddress.toString(),
259
- abi: MultiAdderArtifact.contractAbi,
260
- client: deployL1ContractsValues.l1Client,
261
- });
257
+ const multiAdder = getContract({
258
+ address: multiAdderAddress.toString(),
259
+ abi: MultiAdderArtifact.contractAbi,
260
+ client: deployL1ContractsValues.l1Client,
261
+ });
262
262
 
263
- const stakeNeeded = (await rollup.read.getActivationThreshold()) * BigInt(this.numberOfValidators);
264
- await Promise.all(
265
- [await stakingAsset.write.mint([multiAdder.address, stakeNeeded], {} as any)].map(txHash =>
266
- deployL1ContractsValues.l1Client.waitForTransactionReceipt({ hash: txHash }),
267
- ),
268
- );
263
+ const stakeNeeded = (await rollup.read.getActivationThreshold()) * BigInt(this.numberOfValidators);
264
+ await Promise.all(
265
+ [await stakingAsset.write.mint([multiAdder.address, stakeNeeded], {} as any)].map(txHash =>
266
+ deployL1ContractsValues.l1Client.waitForTransactionReceipt({ hash: txHash }),
267
+ ),
268
+ );
269
269
 
270
- const { validators } = this.getValidators();
271
- this.validators = validators;
270
+ const { validators } = this.getValidators();
271
+ this.validators = validators;
272
272
 
273
- const gseAddress = deployL1ContractsValues.l1ContractAddresses.gseAddress!;
274
- if (!gseAddress) {
275
- throw new Error('GSE contract not deployed');
276
- }
273
+ const gseAddress = deployL1ContractsValues.l1ContractAddresses.gseAddress!;
274
+ if (!gseAddress) {
275
+ throw new Error('GSE contract not deployed');
276
+ }
277
277
 
278
- const gseContract = new GSEContract(deployL1ContractsValues.l1Client, gseAddress.toString());
278
+ const gseContract = new GSEContract(deployL1ContractsValues.l1Client, gseAddress.toString());
279
279
 
280
- const makeValidatorTuples = async (validator: Operator) => {
281
- const registrationTuple = await gseContract.makeRegistrationTuple(validator.bn254SecretKey.getValue());
282
- return {
283
- attester: validator.attester.toString() as `0x${string}`,
284
- withdrawer: validator.withdrawer.toString() as `0x${string}`,
285
- ...registrationTuple,
286
- };
280
+ const makeValidatorTuples = async (validator: Operator) => {
281
+ const registrationTuple = await gseContract.makeRegistrationTuple(validator.bn254SecretKey.getValue());
282
+ return {
283
+ attester: validator.attester.toString() as `0x${string}`,
284
+ withdrawer: validator.withdrawer.toString() as `0x${string}`,
285
+ ...registrationTuple,
287
286
  };
288
- const validatorTuples = await Promise.all(validators.map(makeValidatorTuples));
287
+ };
288
+ const validatorTuples = await Promise.all(validators.map(makeValidatorTuples));
289
289
 
290
- await deployL1ContractsValues.l1Client.waitForTransactionReceipt({
291
- hash: await multiAdder.write.addValidators([validatorTuples]),
292
- });
290
+ await deployL1ContractsValues.l1Client.waitForTransactionReceipt({
291
+ hash: await multiAdder.write.addValidators([validatorTuples]),
292
+ });
293
293
 
294
- await cheatCodes.rollup.advanceToEpoch(
295
- (await cheatCodes.rollup.getEpoch()) + (await rollup.read.getLagInEpochs()) + 1n,
296
- {
297
- updateDateProvider: dateProvider,
298
- },
299
- );
294
+ await cheatCodes.rollup.advanceToEpoch(
295
+ (await cheatCodes.rollup.getEpoch()) + (await rollup.read.getLagInEpochs()) + 1n,
296
+ );
300
297
 
301
- // Send and await a tx to make sure we mine a block for the warp to correctly progress.
302
- await this._sendDummyTx(deployL1ContractsValues.l1Client);
303
- },
304
- );
298
+ // Send and await a tx to make sure we mine a block for the warp to correctly progress.
299
+ await this._sendDummyTx(deployL1ContractsValues.l1Client);
300
+ });
305
301
  }
306
302
 
307
303
  async setupAccount() {
308
304
  await this.snapshotManager.snapshot(
309
305
  'setup-account',
310
- deployAccounts(1, this.logger, false),
311
- async ({ deployedAccounts }, { pxe }) => {
306
+ deployAccounts(1, this.logger),
307
+ ({ deployedAccounts }, { wallet }) => {
312
308
  this.deployedAccounts = deployedAccounts;
313
- const [account] = deployedAccounts;
314
- this.wallet = await getSchnorrWalletWithSecretKey(pxe, account.secret, account.signingKey, account.salt);
315
- this.defaultAccountAddress = this.wallet.getAddress();
309
+ [{ address: this.defaultAccountAddress }] = deployedAccounts;
310
+ this.wallet = wallet;
311
+ return Promise.resolve();
316
312
  },
317
313
  );
318
314
  }
@@ -394,6 +390,48 @@ export class P2PNetworkTest {
394
390
  this.logger.info('Nodes stopped');
395
391
  }
396
392
 
393
+ /**
394
+ * Wait for P2P mesh to be fully formed across all nodes.
395
+ * This ensures that all nodes are connected to each other before proceeding,
396
+ * preventing race conditions where validators propose blocks before the network is ready.
397
+ *
398
+ * @param nodes - Array of nodes to check for P2P connectivity
399
+ * @param expectedNodeCount - Expected number of nodes in the network (defaults to nodes.length)
400
+ * @param timeoutSeconds - Maximum time to wait for connections (default: 30 seconds)
401
+ * @param checkIntervalSeconds - How often to check connectivity (default: 0.1 seconds)
402
+ */
403
+ async waitForP2PMeshConnectivity(
404
+ nodes: AztecNodeService[],
405
+ expectedNodeCount?: number,
406
+ timeoutSeconds = 30,
407
+ checkIntervalSeconds = 0.1,
408
+ ) {
409
+ const nodeCount = expectedNodeCount ?? nodes.length;
410
+ const minPeerCount = nodeCount - 1;
411
+
412
+ this.logger.warn(
413
+ `Waiting for all ${nodeCount} nodes to connect to P2P mesh (at least ${minPeerCount} peers each)...`,
414
+ );
415
+
416
+ await Promise.all(
417
+ nodes.map(async (node, index) => {
418
+ const p2p = node.getP2P();
419
+ await retryUntil(
420
+ async () => {
421
+ const peers = await p2p.getPeers();
422
+ // Each node should be connected to at least N-1 other nodes
423
+ return peers.length >= minPeerCount ? true : undefined;
424
+ },
425
+ `Node ${index} to connect to at least ${minPeerCount} peers`,
426
+ timeoutSeconds,
427
+ checkIntervalSeconds,
428
+ );
429
+ }),
430
+ );
431
+
432
+ this.logger.warn('All nodes connected to P2P mesh');
433
+ }
434
+
397
435
  async teardown() {
398
436
  await this.monitor.stop();
399
437
  await tryStop(this.bootstrapNode, this.logger);
@@ -1,29 +1,23 @@
1
- import { getSchnorrAccount } from '@aztec/accounts/schnorr';
2
1
  import type { InitialAccountData } from '@aztec/accounts/testing';
3
2
  import type { AztecNodeService } from '@aztec/aztec-node';
4
- import {
5
- AztecAddress,
6
- Fr,
7
- type Logger,
8
- ProvenTx,
9
- type SentTx,
10
- TxStatus,
11
- getContractInstanceFromInstantiationParams,
12
- retryUntil,
13
- } from '@aztec/aztec.js';
3
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
4
+ import { type SentTx, getContractInstanceFromInstantiationParams } from '@aztec/aztec.js/contracts';
5
+ import { Fr } from '@aztec/aztec.js/fields';
6
+ import type { Logger } from '@aztec/aztec.js/log';
7
+ import { Tx, TxStatus } from '@aztec/aztec.js/tx';
14
8
  import type { RollupCheatCodes } from '@aztec/aztec/testing';
15
9
  import type { EmpireSlashingProposerContract, RollupContract, TallySlashingProposerContract } from '@aztec/ethereum';
16
10
  import { timesAsync, unique } from '@aztec/foundation/collection';
11
+ import { retryUntil } from '@aztec/foundation/retry';
17
12
  import { pluralize } from '@aztec/foundation/string';
18
- import type { TestDateProvider } from '@aztec/foundation/timer';
19
13
  import type { SpamContract } from '@aztec/noir-test-contracts.js/Spam';
20
14
  import { TestContract, TestContractArtifact } from '@aztec/noir-test-contracts.js/Test';
21
- import { PXEService, createPXEService, getPXEServiceConfig as getRpcConfig } from '@aztec/pxe/server';
15
+ import { getPXEConfig, getPXEConfig as getRpcConfig } from '@aztec/pxe/server';
22
16
  import { getRoundForOffense } from '@aztec/slasher';
23
17
  import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
24
18
  import type { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
19
+ import { TestWallet, proveInteraction } from '@aztec/test-wallet/server';
25
20
 
26
- import type { NodeContext } from '../fixtures/setup_p2p_test.js';
27
21
  import { submitTxsTo } from '../shared/submit-transactions.js';
28
22
 
29
23
  // submits a set of transactions to the provided Private eXecution Environment (PXE)
@@ -56,56 +50,46 @@ export const submitComplexTxsTo = async (
56
50
  return txs;
57
51
  };
58
52
 
59
- // creates an instance of the PXE and submit a given number of transactions to it.
60
- export const createPXEServiceAndSubmitTransactions = async (
53
+ // creates a wallet and submit a given number of transactions through it.
54
+ export const submitTransactions = async (
61
55
  logger: Logger,
62
56
  node: AztecNodeService,
63
57
  numTxs: number,
64
58
  fundedAccount: InitialAccountData,
65
- ): Promise<NodeContext> => {
59
+ ): Promise<SentTx[]> => {
66
60
  const rpcConfig = getRpcConfig();
67
61
  rpcConfig.proverEnabled = false;
68
- const pxeService = await createPXEService(node, rpcConfig, { useLogSuffix: true });
69
-
70
- const account = await getSchnorrAccount(
71
- pxeService,
72
- fundedAccount.secret,
73
- fundedAccount.signingKey,
74
- fundedAccount.salt,
75
- );
76
- await account.register();
77
- const wallet = await account.getWallet();
78
-
79
- const txs = await submitTxsTo(pxeService, numTxs, wallet, logger);
80
- return { txs, pxeService, node };
62
+ const wallet = await TestWallet.create(node, { ...getPXEConfig(), proverEnabled: false }, { useLogSuffix: true });
63
+ const fundedAccountManager = await wallet.createSchnorrAccount(fundedAccount.secret, fundedAccount.salt);
64
+ return submitTxsTo(wallet, fundedAccountManager.address, numTxs, logger);
81
65
  };
82
66
 
83
- export async function createPXEServiceAndPrepareTransactions(
67
+ export async function prepareTransactions(
84
68
  logger: Logger,
85
69
  node: AztecNodeService,
86
70
  numTxs: number,
87
71
  fundedAccount: InitialAccountData,
88
- ): Promise<{ pxeService: PXEService; txs: ProvenTx[]; node: AztecNodeService }> {
72
+ ): Promise<Tx[]> {
89
73
  const rpcConfig = getRpcConfig();
90
74
  rpcConfig.proverEnabled = false;
91
- const pxe = await createPXEService(node, rpcConfig, { useLogSuffix: true });
92
75
 
93
- const account = await getSchnorrAccount(pxe, fundedAccount.secret, fundedAccount.signingKey, fundedAccount.salt);
94
- await account.register();
95
- const wallet = await account.getWallet();
76
+ const wallet = await TestWallet.create(node, { ...getPXEConfig(), proverEnabled: false }, { useLogSuffix: true });
77
+ const fundedAccountManager = await wallet.createSchnorrAccount(fundedAccount.secret, fundedAccount.salt);
96
78
 
97
- const testContractInstance = await getContractInstanceFromInstantiationParams(TestContractArtifact, {});
98
- await wallet.registerContract({ instance: testContractInstance, artifact: TestContractArtifact });
79
+ const testContractInstance = await getContractInstanceFromInstantiationParams(TestContractArtifact, {
80
+ salt: Fr.random(),
81
+ });
82
+ await wallet.registerContract(testContractInstance, TestContractArtifact);
99
83
  const contract = await TestContract.at(testContractInstance.address, wallet);
100
84
 
101
- const txs = await timesAsync(numTxs, async () => {
102
- const tx = await contract.methods.emit_nullifier(Fr.random()).prove({ from: account.getAddress() });
85
+ return timesAsync(numTxs, async () => {
86
+ const tx = await proveInteraction(wallet, contract.methods.emit_nullifier(Fr.random()), {
87
+ from: fundedAccountManager.address,
88
+ });
103
89
  const txHash = tx.getTxHash();
104
90
  logger.info(`Tx prepared with hash ${txHash}`);
105
91
  return tx;
106
92
  });
107
-
108
- return { txs, pxeService: pxe, node };
109
93
  }
110
94
 
111
95
  export function awaitProposalExecution(
@@ -166,12 +150,14 @@ export async function awaitOffenseDetected({
166
150
  slashingRoundSize,
167
151
  epochDuration,
168
152
  waitUntilOffenseCount,
153
+ timeoutSeconds = 120,
169
154
  }: {
170
155
  nodeAdmin: AztecNodeAdmin;
171
156
  logger: Logger;
172
157
  slashingRoundSize: number;
173
158
  epochDuration: number;
174
159
  waitUntilOffenseCount?: number;
160
+ timeoutSeconds?: number;
175
161
  }) {
176
162
  const targetOffenseCount = waitUntilOffenseCount ?? 1;
177
163
  logger.warn(`Waiting for ${pluralize('offense', targetOffenseCount)} to be detected`);
@@ -183,11 +169,11 @@ export async function awaitOffenseDetected({
183
169
  }
184
170
  },
185
171
  'non-empty offenses',
186
- 60,
172
+ timeoutSeconds,
187
173
  );
188
174
  logger.info(
189
175
  `Hit ${offenses.length} offenses on rounds ${unique(offenses.map(o => getRoundForOffense(o, { slashingRoundSize, epochDuration })))}`,
190
- offenses,
176
+ { offenses },
191
177
  );
192
178
  return offenses;
193
179
  }
@@ -204,8 +190,9 @@ export async function awaitCommitteeKicked({
204
190
  slashingProposer,
205
191
  slashingRoundSize,
206
192
  aztecSlotDuration,
193
+ aztecEpochDuration,
207
194
  logger,
208
- dateProvider,
195
+ offenseEpoch,
209
196
  }: {
210
197
  rollup: RollupContract;
211
198
  cheatCodes: RollupCheatCodes;
@@ -214,21 +201,22 @@ export async function awaitCommitteeKicked({
214
201
  slashingProposer: EmpireSlashingProposerContract | TallySlashingProposerContract | undefined;
215
202
  slashingRoundSize: number;
216
203
  aztecSlotDuration: number;
217
- dateProvider: TestDateProvider;
204
+ aztecEpochDuration: number;
218
205
  logger: Logger;
206
+ offenseEpoch: number;
219
207
  }) {
220
208
  if (!slashingProposer) {
221
209
  throw new Error('No slashing proposer configured. Cannot test slashing.');
222
210
  }
223
211
 
224
- logger.info(`Advancing epochs so we start slashing`);
225
212
  await cheatCodes.debugRollup();
226
- await cheatCodes.advanceToEpoch((await cheatCodes.getEpoch()) + (await rollup.getLagInEpochs()) + 1n, {
227
- updateDateProvider: dateProvider,
228
- });
229
213
 
230
- // Await for the slash payload to be created if empire (no payload is created on tally until execution time)
231
214
  if (slashingProposer.type === 'empire') {
215
+ // Await for the slash payload to be created if empire (no payload is created on tally until execution time)
216
+ const targetEpoch = (await cheatCodes.getEpoch()) + (await rollup.getLagInEpochs()) + 1n;
217
+ logger.info(`Advancing to epoch ${targetEpoch} so we start slashing`);
218
+ await cheatCodes.advanceToEpoch(targetEpoch);
219
+
232
220
  const slashPayloadEvents = await retryUntil(
233
221
  async () => {
234
222
  const events = await slashFactory.getSlashPayloadCreatedEvents();
@@ -243,6 +231,15 @@ export async function awaitCommitteeKicked({
243
231
  expect(unique(slashPayloadEvents[0].slashes.map(slash => slash.validator.toString()))).toHaveLength(
244
232
  committee.length,
245
233
  );
234
+ } else {
235
+ // Use the slash offset to ensure we are in the right epoch for tally
236
+ const slashOffsetInRounds = await slashingProposer.getSlashOffsetInRounds();
237
+ const slashingRoundSizeInEpochs = slashingRoundSize / aztecEpochDuration;
238
+ const slashingOffsetInEpochs = Number(slashOffsetInRounds) * slashingRoundSizeInEpochs;
239
+ const firstEpochInOffenseRound = offenseEpoch - (offenseEpoch % slashingRoundSizeInEpochs);
240
+ const targetEpoch = firstEpochInOffenseRound + slashingOffsetInEpochs;
241
+ logger.info(`Advancing to epoch ${targetEpoch} so we start slashing`);
242
+ await cheatCodes.advanceToEpoch(targetEpoch, { offset: -aztecSlotDuration / 2 });
246
243
  }
247
244
 
248
245
  const attestersPre = await rollup.getAttesters();
@@ -253,7 +250,7 @@ export async function awaitCommitteeKicked({
253
250
  expect(attesterInfo.status).toEqual(1); // Validating
254
251
  }
255
252
 
256
- const timeout = slashingRoundSize * 2 * aztecSlotDuration;
253
+ const timeout = slashingRoundSize * 2 * aztecSlotDuration + 30;
257
254
  logger.info(`Waiting for slash to be executed (timeout ${timeout}s)`);
258
255
  await awaitProposalExecution(slashingProposer, timeout, logger);
259
256
 
@@ -272,9 +269,7 @@ export async function awaitCommitteeKicked({
272
269
 
273
270
  logger.info(`Advancing to check current committee`);
274
271
  await cheatCodes.debugRollup();
275
- await cheatCodes.advanceToEpoch((await cheatCodes.getEpoch()) + (await rollup.getLagInEpochs()) + 1n, {
276
- updateDateProvider: dateProvider,
277
- });
272
+ await cheatCodes.advanceToEpoch((await cheatCodes.getEpoch()) + (await rollup.getLagInEpochs()) + 1n);
278
273
  await cheatCodes.debugRollup();
279
274
 
280
275
  const committeeNextEpoch = await rollup.getCurrentEpochCommittee();
@@ -1,7 +1,9 @@
1
- import { getSchnorrWallet } from '@aztec/accounts/schnorr';
2
- import { type AccountWallet, AztecAddress, type AztecNode, type Logger, createLogger } from '@aztec/aztec.js';
1
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
2
+ import { type Logger, createLogger } from '@aztec/aztec.js/log';
3
+ import type { AztecNode } from '@aztec/aztec.js/node';
3
4
  import { TokenContract } from '@aztec/noir-contracts.js/Token';
4
5
  import { InvalidAccountContract } from '@aztec/noir-test-contracts.js/InvalidAccount';
6
+ import type { TestWallet } from '@aztec/test-wallet/server';
5
7
 
6
8
  import { jest } from '@jest/globals';
7
9
 
@@ -28,11 +30,9 @@ export class TokenContractTest {
28
30
  node!: AztecNode;
29
31
 
30
32
  badAccount!: InvalidAccountContract;
31
- admin!: AccountWallet;
33
+ wallet!: TestWallet;
32
34
  adminAddress!: AztecAddress;
33
- account1!: AccountWallet;
34
35
  account1Address!: AztecAddress;
35
- account2!: AccountWallet;
36
36
  account2Address!: AztecAddress;
37
37
 
38
38
  constructor(testName: string) {
@@ -54,11 +54,11 @@ export class TokenContractTest {
54
54
  await this.snapshotManager.snapshot(
55
55
  '3_accounts',
56
56
  deployAccounts(3, this.logger),
57
- async ({ deployedAccounts }, { pxe, aztecNode }) => {
57
+ ({ deployedAccounts }, { wallet, aztecNode }) => {
58
58
  this.node = aztecNode;
59
- const wallets = await Promise.all(deployedAccounts.map(a => getSchnorrWallet(pxe, a.address, a.signingKey)));
60
- [this.admin, this.account1, this.account2] = wallets;
61
- [this.adminAddress, this.account1Address, this.account2Address] = wallets.map(w => w.getAddress());
59
+ this.wallet = wallet;
60
+ [this.adminAddress, this.account1Address, this.account2Address] = deployedAccounts.map(acc => acc.address);
61
+ return Promise.resolve();
62
62
  },
63
63
  );
64
64
 
@@ -68,11 +68,11 @@ export class TokenContractTest {
68
68
  // Create the token contract state.
69
69
  // Move this account thing to addAccounts above?
70
70
  this.logger.verbose(`Public deploy accounts...`);
71
- await publicDeployAccounts(this.admin, [this.adminAddress, this.account1Address]);
71
+ await publicDeployAccounts(this.wallet, [this.adminAddress, this.account1Address]);
72
72
 
73
73
  this.logger.verbose(`Deploying TokenContract...`);
74
74
  const asset = await TokenContract.deploy(
75
- this.admin,
75
+ this.wallet,
76
76
  this.adminAddress,
77
77
  TokenContractTest.TOKEN_NAME,
78
78
  TokenContractTest.TOKEN_SYMBOL,
@@ -83,22 +83,22 @@ export class TokenContractTest {
83
83
  this.logger.verbose(`Token deployed to ${asset.address}`);
84
84
 
85
85
  this.logger.verbose(`Deploying bad account...`);
86
- this.badAccount = await InvalidAccountContract.deploy(this.admin).send({ from: this.adminAddress }).deployed();
86
+ this.badAccount = await InvalidAccountContract.deploy(this.wallet).send({ from: this.adminAddress }).deployed();
87
87
  this.logger.verbose(`Deployed to ${this.badAccount.address}.`);
88
88
 
89
89
  return { tokenContractAddress: asset.address, badAccountAddress: this.badAccount.address };
90
90
  },
91
91
  async ({ tokenContractAddress, badAccountAddress }) => {
92
92
  // Restore the token contract state.
93
- this.asset = await TokenContract.at(tokenContractAddress, this.admin);
93
+ this.asset = await TokenContract.at(tokenContractAddress, this.wallet);
94
94
  this.logger.verbose(`Token contract address: ${this.asset.address}`);
95
95
 
96
- this.tokenSim = new TokenSimulator(this.asset, this.admin, this.adminAddress, this.logger, [
96
+ this.tokenSim = new TokenSimulator(this.asset, this.wallet, this.adminAddress, this.logger, [
97
97
  this.adminAddress,
98
98
  this.account1Address,
99
99
  ]);
100
100
 
101
- this.badAccount = await InvalidAccountContract.at(badAccountAddress, this.admin);
101
+ this.badAccount = await InvalidAccountContract.at(badAccountAddress, this.wallet);
102
102
  this.logger.verbose(`Bad account address: ${this.badAccount.address}`);
103
103
 
104
104
  expect(await this.asset.methods.get_admin().simulate({ from: this.adminAddress })).toBe(
@@ -131,14 +131,14 @@ export class TokenContractTest {
131
131
  await this.snapshotManager.snapshot(
132
132
  'mint',
133
133
  async () => {
134
- const { asset, admin, adminAddress } = this;
134
+ const { asset, adminAddress } = this;
135
135
  const amount = 10000n;
136
136
 
137
137
  this.logger.verbose(`Minting ${amount} publicly...`);
138
138
  await asset.methods.mint_to_public(adminAddress, amount).send({ from: adminAddress }).wait();
139
139
 
140
140
  this.logger.verbose(`Minting ${amount} privately...`);
141
- await mintTokensToPrivate(asset, adminAddress, admin, adminAddress, amount);
141
+ await mintTokensToPrivate(asset, adminAddress, adminAddress, amount);
142
142
  this.logger.verbose(`Minting complete.`);
143
143
 
144
144
  return { amount };