@aztec/end-to-end 4.0.0-devnet.1-patch.0 → 4.0.0-devnet.2-patch.0

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 (120) hide show
  1. package/dest/bench/client_flows/client_flows_benchmark.d.ts +2 -2
  2. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  3. package/dest/bench/client_flows/client_flows_benchmark.js +3 -3
  4. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +4 -2
  5. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  6. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +10 -0
  7. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +2 -2
  8. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
  9. package/dest/e2e_deploy_contract/deploy_test.d.ts +2 -2
  10. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  11. package/dest/e2e_epochs/epochs_test.d.ts +9 -7
  12. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  13. package/dest/e2e_epochs/epochs_test.js +53 -34
  14. package/dest/e2e_fees/fees_test.d.ts +2 -2
  15. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  16. package/dest/e2e_fees/fees_test.js +5 -5
  17. package/dest/e2e_p2p/p2p_network.d.ts +2 -2
  18. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  19. package/dest/e2e_p2p/p2p_network.js +2 -2
  20. package/dest/e2e_p2p/reqresp/utils.d.ts +3 -3
  21. package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
  22. package/dest/e2e_p2p/reqresp/utils.js +32 -8
  23. package/dest/e2e_p2p/shared.d.ts +2 -2
  24. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  25. package/dest/e2e_p2p/shared.js +2 -1
  26. package/dest/e2e_token_contract/token_contract_test.d.ts +4 -2
  27. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  28. package/dest/e2e_token_contract/token_contract_test.js +10 -0
  29. package/dest/fixtures/authwit_proxy.d.ts +15 -0
  30. package/dest/fixtures/authwit_proxy.d.ts.map +1 -0
  31. package/dest/fixtures/authwit_proxy.js +30 -0
  32. package/dest/fixtures/e2e_prover_test.d.ts +4 -4
  33. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  34. package/dest/fixtures/e2e_prover_test.js +27 -34
  35. package/dest/fixtures/fixtures.d.ts +5 -1
  36. package/dest/fixtures/fixtures.d.ts.map +1 -1
  37. package/dest/fixtures/fixtures.js +6 -0
  38. package/dest/fixtures/ha_setup.d.ts +1 -1
  39. package/dest/fixtures/ha_setup.d.ts.map +1 -1
  40. package/dest/fixtures/ha_setup.js +3 -1
  41. package/dest/fixtures/setup.d.ts +27 -10
  42. package/dest/fixtures/setup.d.ts.map +1 -1
  43. package/dest/fixtures/setup.js +56 -81
  44. package/dest/fixtures/setup_p2p_test.d.ts +6 -3
  45. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  46. package/dest/fixtures/setup_p2p_test.js +12 -9
  47. package/dest/shared/index.d.ts +2 -1
  48. package/dest/shared/index.d.ts.map +1 -1
  49. package/dest/shared/index.js +1 -0
  50. package/dest/shared/mock_state_view.d.ts +86 -0
  51. package/dest/shared/mock_state_view.d.ts.map +1 -0
  52. package/dest/shared/mock_state_view.js +186 -0
  53. package/dest/shared/submit-transactions.d.ts +2 -2
  54. package/dest/shared/submit-transactions.d.ts.map +1 -1
  55. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  56. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  57. package/dest/simulators/token_simulator.d.ts +1 -1
  58. package/dest/simulators/token_simulator.d.ts.map +1 -1
  59. package/dest/simulators/token_simulator.js +2 -23
  60. package/dest/spartan/setup_test_wallets.d.ts +9 -2
  61. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  62. package/dest/spartan/setup_test_wallets.js +31 -1
  63. package/dest/spartan/utils/bot.d.ts +3 -2
  64. package/dest/spartan/utils/bot.d.ts.map +1 -1
  65. package/dest/spartan/utils/bot.js +2 -1
  66. package/dest/spartan/utils/index.d.ts +2 -2
  67. package/dest/spartan/utils/index.d.ts.map +1 -1
  68. package/dest/spartan/utils/index.js +1 -1
  69. package/dest/spartan/utils/k8s.d.ts +3 -1
  70. package/dest/spartan/utils/k8s.d.ts.map +1 -1
  71. package/dest/spartan/utils/k8s.js +6 -0
  72. package/dest/test-wallet/test_wallet.d.ts +83 -0
  73. package/dest/test-wallet/test_wallet.d.ts.map +1 -0
  74. package/dest/test-wallet/test_wallet.js +214 -0
  75. package/dest/test-wallet/utils.d.ts +41 -0
  76. package/dest/test-wallet/utils.d.ts.map +1 -0
  77. package/dest/test-wallet/utils.js +71 -0
  78. package/dest/test-wallet/wallet_worker_script.d.ts +2 -0
  79. package/dest/test-wallet/wallet_worker_script.d.ts.map +1 -0
  80. package/dest/test-wallet/wallet_worker_script.js +40 -0
  81. package/dest/test-wallet/worker_wallet.d.ts +52 -0
  82. package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
  83. package/dest/test-wallet/worker_wallet.js +103 -0
  84. package/dest/test-wallet/worker_wallet_schema.d.ts +271 -0
  85. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
  86. package/dest/test-wallet/worker_wallet_schema.js +10 -0
  87. package/package.json +40 -39
  88. package/src/bench/client_flows/client_flows_benchmark.ts +3 -7
  89. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +10 -1
  90. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +1 -1
  91. package/src/e2e_deploy_contract/deploy_test.ts +1 -1
  92. package/src/e2e_epochs/epochs_test.ts +66 -66
  93. package/src/e2e_fees/bridging_race.notest.ts +1 -1
  94. package/src/e2e_fees/fees_test.ts +5 -20
  95. package/src/e2e_p2p/p2p_network.ts +3 -3
  96. package/src/e2e_p2p/reqresp/utils.ts +36 -8
  97. package/src/e2e_p2p/shared.ts +2 -1
  98. package/src/e2e_token_contract/token_contract_test.ts +10 -1
  99. package/src/fixtures/authwit_proxy.ts +50 -0
  100. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  101. package/src/fixtures/e2e_prover_test.ts +26 -36
  102. package/src/fixtures/fixtures.ts +10 -0
  103. package/src/fixtures/ha_setup.ts +3 -1
  104. package/src/fixtures/setup.ts +73 -109
  105. package/src/fixtures/setup_p2p_test.ts +9 -17
  106. package/src/guides/up_quick_start.sh +3 -3
  107. package/src/shared/index.ts +1 -0
  108. package/src/shared/mock_state_view.ts +188 -0
  109. package/src/shared/submit-transactions.ts +2 -1
  110. package/src/shared/uniswap_l1_l2.ts +1 -1
  111. package/src/simulators/token_simulator.ts +1 -29
  112. package/src/spartan/setup_test_wallets.ts +43 -1
  113. package/src/spartan/utils/bot.ts +4 -1
  114. package/src/spartan/utils/index.ts +1 -0
  115. package/src/spartan/utils/k8s.ts +8 -0
  116. package/src/test-wallet/test_wallet.ts +306 -0
  117. package/src/test-wallet/utils.ts +112 -0
  118. package/src/test-wallet/wallet_worker_script.ts +43 -0
  119. package/src/test-wallet/worker_wallet.ts +165 -0
  120. package/src/test-wallet/worker_wallet_schema.ts +13 -0
@@ -1,3 +1,4 @@
1
+ import type { Archiver } from '@aztec/archiver';
1
2
  import { type AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
2
3
  import { getTimestampRangeForEpoch } from '@aztec/aztec.js/block';
3
4
  import { getContractInstanceFromInstantiationParams } from '@aztec/aztec.js/contracts';
@@ -9,7 +10,8 @@ import { EpochCache } from '@aztec/epoch-cache';
9
10
  import { createExtendedL1Client } from '@aztec/ethereum/client';
10
11
  import { DefaultL1ContractsConfig } from '@aztec/ethereum/config';
11
12
  import { RollupContract } from '@aztec/ethereum/contracts';
12
- import { ChainMonitor, DelayedTxUtils, type Delayer, waitUntilL1Timestamp, withDelayer } from '@aztec/ethereum/test';
13
+ import { Delayer, createDelayer, waitUntilL1Timestamp, wrapClientWithDelayer } from '@aztec/ethereum/l1-tx-utils';
14
+ import { ChainMonitor } from '@aztec/ethereum/test';
13
15
  import type { ExtendedViemWalletClient } from '@aztec/ethereum/types';
14
16
  import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
15
17
  import { SecretValue } from '@aztec/foundation/config';
@@ -20,16 +22,9 @@ import { sleep } from '@aztec/foundation/sleep';
20
22
  import { SpamContract } from '@aztec/noir-test-contracts.js/Spam';
21
23
  import { TestContract } from '@aztec/noir-test-contracts.js/Test';
22
24
  import { getMockPubSubP2PServiceFactory } from '@aztec/p2p/test-helpers';
23
- import { ProverNode, type ProverNodeConfig, ProverNodePublisher } from '@aztec/prover-node';
24
- import type { TestProverNode } from '@aztec/prover-node/test';
25
+ import type { ProverNodeConfig } from '@aztec/prover-node';
25
26
  import type { PXEConfig } from '@aztec/pxe/config';
26
- import {
27
- type SequencerClient,
28
- type SequencerEvents,
29
- type SequencerPublisher,
30
- SequencerState,
31
- } from '@aztec/sequencer-client';
32
- import type { TestSequencerClient } from '@aztec/sequencer-client/test';
27
+ import { type SequencerClient, type SequencerEvents, SequencerState } from '@aztec/sequencer-client';
33
28
  import { type BlockParameter, EthAddress } from '@aztec/stdlib/block';
34
29
  import { type L1RollupConstants, getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
35
30
  import { tryStop } from '@aztec/stdlib/interfaces/server';
@@ -46,7 +41,7 @@ import {
46
41
  setup,
47
42
  } from '../fixtures/utils.js';
48
43
 
49
- export const WORLD_STATE_BLOCK_HISTORY = 2;
44
+ export const WORLD_STATE_CHECKPOINT_HISTORY = 2;
50
45
  export const WORLD_STATE_BLOCK_CHECK_INTERVAL = 50;
51
46
  export const ARCHIVER_POLL_INTERVAL = 50;
52
47
  export const DEFAULT_L1_BLOCK_TIME = process.env.CI ? 12 : 8;
@@ -81,7 +76,7 @@ export class EpochsTestContext {
81
76
  public proverDelayer!: Delayer;
82
77
  public sequencerDelayer!: Delayer;
83
78
 
84
- public proverNodes: ProverNode[] = [];
79
+ public proverNodes: AztecNodeService[] = [];
85
80
  public nodes: AztecNodeService[] = [];
86
81
 
87
82
  public epochDuration!: number;
@@ -147,7 +142,7 @@ export class EpochsTestContext {
147
142
  // using the prover's eth address if the proverId is used for something in the rollup contract
148
143
  // Use numeric EthAddress for deterministic prover id
149
144
  proverId: EthAddress.fromNumber(1),
150
- worldStateBlockHistory: WORLD_STATE_BLOCK_HISTORY,
145
+ worldStateCheckpointHistory: WORLD_STATE_CHECKPOINT_HISTORY,
151
146
  exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
152
147
  slasherFlavor: 'none',
153
148
  l1PublishingTime,
@@ -169,17 +164,8 @@ export class EpochsTestContext {
169
164
  // Loop that tracks L1 and L2 block numbers and logs whenever there's a new one.
170
165
  this.monitor = new ChainMonitor(this.rollup, context.dateProvider, this.logger).start();
171
166
 
172
- // This is hideous.
173
- // We ought to have a definite reference to the l1TxUtils that we're using in both places, provided by the test context.
174
- this.proverDelayer = context.proverNode
175
- ? (((context.proverNode as TestProverNode).publisher as ProverNodePublisher).l1TxUtils as DelayedTxUtils).delayer!
176
- : undefined!;
177
- this.sequencerDelayer = context.sequencer
178
- ? (
179
- ((context.sequencer as TestSequencerClient).sequencer.publisher as SequencerPublisher)
180
- .l1TxUtils as DelayedTxUtils
181
- ).delayer!
182
- : undefined!;
167
+ this.proverDelayer = context.proverDelayer!;
168
+ this.sequencerDelayer = context.sequencerDelayer!;
183
169
 
184
170
  if ((context.proverNode && !this.proverDelayer) || (context.sequencer && !this.sequencerDelayer)) {
185
171
  throw new Error(`Could not find prover or sequencer delayer`);
@@ -214,26 +200,29 @@ export class EpochsTestContext {
214
200
  const proverNodePrivateKey = this.getNextPrivateKey();
215
201
  const proverIndex = this.proverNodes.length + 1;
216
202
  const { mockGossipSubNetwork } = this.context;
217
- const proverNode = await withLoggerBindings({ actor: `prover-${proverIndex}` }, () =>
203
+ const { proverNode } = await withLoggerBindings({ actor: `prover-${proverIndex}` }, () =>
218
204
  createAndSyncProverNode(
219
205
  proverNodePrivateKey,
220
206
  {
221
207
  ...this.context.config,
222
208
  p2pEnabled: this.context.config.p2pEnabled || mockGossipSubNetwork !== undefined,
223
- },
224
- {
225
- dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
226
209
  proverId: EthAddress.fromNumber(proverIndex),
227
210
  dontStart: opts.dontStart,
228
211
  ...opts,
229
212
  },
230
- this.context.aztecNode,
231
- this.context.prefilledPublicData ?? [],
213
+ {
214
+ dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
215
+ },
232
216
  {
233
217
  dateProvider: this.context.dateProvider,
234
- p2pClientDeps: mockGossipSubNetwork
235
- ? { p2pServiceFactory: getMockPubSubP2PServiceFactory(mockGossipSubNetwork) }
236
- : undefined,
218
+ p2pClientDeps: {
219
+ p2pServiceFactory: mockGossipSubNetwork ? getMockPubSubP2PServiceFactory(mockGossipSubNetwork) : undefined,
220
+ rpcTxProviders: [this.context.aztecNode],
221
+ },
222
+ },
223
+ {
224
+ prefilledPublicData: this.context.prefilledPublicData ?? [],
225
+ dontStart: opts.dontStart,
237
226
  },
238
227
  ),
239
228
  );
@@ -248,15 +237,13 @@ export class EpochsTestContext {
248
237
 
249
238
  public createValidatorNode(
250
239
  privateKeys: `0x${string}`[],
251
- opts: Partial<AztecNodeConfig> & { txDelayerMaxInclusionTimeIntoSlot?: number; dontStartSequencer?: boolean } = {},
240
+ opts: Partial<AztecNodeConfig> & { dontStartSequencer?: boolean } = {},
252
241
  ) {
253
242
  this.logger.warn('Creating and syncing a validator node...');
254
243
  return this.createNode({ ...opts, disableValidator: false, validatorPrivateKeys: new SecretValue(privateKeys) });
255
244
  }
256
245
 
257
- private async createNode(
258
- opts: Partial<AztecNodeConfig> & { txDelayerMaxInclusionTimeIntoSlot?: number; dontStartSequencer?: boolean } = {},
259
- ) {
246
+ private async createNode(opts: Partial<AztecNodeConfig> & { dontStartSequencer?: boolean } = {}) {
260
247
  const nodeIndex = this.nodes.length + 1;
261
248
  const actorPrefix = opts.disableValidator ? 'node' : 'validator';
262
249
  const { mockGossipSubNetwork } = this.context;
@@ -285,26 +272,6 @@ export class EpochsTestContext {
285
272
  ),
286
273
  );
287
274
 
288
- // REFACTOR: We're getting too much into the internals of the sequencer here.
289
- // We should have a single method for constructing an aztec node that returns a TestAztecNodeService
290
- // which directly exposes the delayer and sets any test config.
291
- if (opts.txDelayerMaxInclusionTimeIntoSlot !== undefined) {
292
- this.logger.info(
293
- `Setting tx delayer max inclusion time into slot to ${opts.txDelayerMaxInclusionTimeIntoSlot} seconds`,
294
- );
295
- // Here we reach into the sequencer and hook in a tx delayer. The problem is that the sequencer's l1 utils only uses a public client, not a wallet.
296
- // The delayer needs a wallet (a client that can sign), so we have to create one here.
297
- const l1Client = createExtendedL1Client(
298
- resolvedConfig.l1RpcUrls!,
299
- resolvedConfig.publisherPrivateKeys![0]!.getValue(),
300
- );
301
- const sequencer = node.getSequencer() as TestSequencerClient;
302
- const publisher = sequencer.sequencer.publisher;
303
- const delayed = DelayedTxUtils.fromL1TxUtils(publisher.l1TxUtils, this.L1_BLOCK_TIME_IN_S, l1Client);
304
- delayed.delayer!.setMaxInclusionTimeIntoSlot(opts.txDelayerMaxInclusionTimeIntoSlot);
305
- publisher.l1TxUtils = delayed;
306
- }
307
-
308
275
  this.nodes.push(node);
309
276
  return node;
310
277
  }
@@ -356,7 +323,10 @@ export class EpochsTestContext {
356
323
  this.logger.info(`Waiting until last slot of submission window for epoch ${epochNumber} at ${date}`, {
357
324
  oneSlotBefore,
358
325
  });
359
- await waitUntilL1Timestamp(this.l1Client, oneSlotBefore);
326
+ // Use a timeout that accounts for the full proof submission window
327
+ const proofSubmissionWindowDuration =
328
+ this.constants.proofSubmissionEpochs * this.epochDuration * this.L2_SLOT_DURATION_IN_S;
329
+ await waitUntilL1Timestamp(this.l1Client, oneSlotBefore, undefined, proofSubmissionWindowDuration * 2);
360
330
  }
361
331
 
362
332
  /** Waits for the aztec node to sync to the target block number. */
@@ -408,15 +378,13 @@ export class EpochsTestContext {
408
378
 
409
379
  /** Creates an L1 client using a fresh account with funds from anvil, with a tx delayer already set up. */
410
380
  public async createL1Client() {
411
- const { client, delayer } = withDelayer(
412
- createExtendedL1Client(
413
- [...this.l1Client.chain.rpcUrls.default.http],
414
- privateKeyToAccount(this.getNextPrivateKey()),
415
- this.l1Client.chain,
416
- ),
417
- this.context.dateProvider,
418
- { ethereumSlotDuration: this.L1_BLOCK_TIME_IN_S },
381
+ const rawClient = createExtendedL1Client(
382
+ [...this.l1Client.chain.rpcUrls.default.http],
383
+ privateKeyToAccount(this.getNextPrivateKey()),
384
+ this.l1Client.chain,
419
385
  );
386
+ const delayer = createDelayer(this.context.dateProvider, { ethereumSlotDuration: this.L1_BLOCK_TIME_IN_S }, {});
387
+ const client = wrapClientWithDelayer(rawClient, delayer);
420
388
  expect(await client.getBalance({ address: client.account.address })).toBeGreaterThan(0n);
421
389
  return { client, delayer };
422
390
  }
@@ -433,6 +401,38 @@ export class EpochsTestContext {
433
401
  expect(result).toBe(expectedSuccess);
434
402
  }
435
403
 
404
+ /** Verifies at least one checkpoint has the target number of blocks (for MBPS validation). */
405
+ public async assertMultipleBlocksPerSlot(targetBlockCount: number) {
406
+ const archiver = (this.context.aztecNode as AztecNodeService).getBlockSource() as Archiver;
407
+ const checkpoints = await archiver.getCheckpoints(CheckpointNumber(1), 50);
408
+
409
+ this.logger.warn(`Retrieved ${checkpoints.length} checkpoints from archiver`, {
410
+ checkpoints: checkpoints.map(pc => pc.checkpoint.getStats()),
411
+ });
412
+
413
+ let expectedBlockNumber = checkpoints[0].checkpoint.blocks[0].number;
414
+ let targetFound = false;
415
+
416
+ for (const checkpoint of checkpoints) {
417
+ const blockCount = checkpoint.checkpoint.blocks.length;
418
+ targetFound = targetFound || blockCount >= targetBlockCount;
419
+
420
+ this.logger.verbose(`Checkpoint ${checkpoint.checkpoint.number} has ${blockCount} blocks`, {
421
+ checkpoint: checkpoint.checkpoint.getStats(),
422
+ });
423
+
424
+ for (let i = 0; i < blockCount; i++) {
425
+ const block = checkpoint.checkpoint.blocks[i];
426
+ expect(block.indexWithinCheckpoint).toBe(i);
427
+ expect(block.checkpointNumber).toBe(checkpoint.checkpoint.number);
428
+ expect(block.number).toBe(expectedBlockNumber);
429
+ expectedBlockNumber++;
430
+ }
431
+ }
432
+
433
+ expect(targetFound).toBe(true);
434
+ }
435
+
436
436
  public watchSequencerEvents(
437
437
  sequencers: SequencerClient[],
438
438
  getMetadata: (i: number) => Record<string, any> = () => ({}),
@@ -4,11 +4,11 @@ import type { Logger } from '@aztec/aztec.js/log';
4
4
  import { Fq } from '@aztec/foundation/curves/bn254';
5
5
  import { sleep } from '@aztec/foundation/sleep';
6
6
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
7
- import type { TestWallet } from '@aztec/test-wallet/server';
8
7
 
9
8
  import { jest } from '@jest/globals';
10
9
  import type { Hex } from 'viem';
11
10
 
11
+ import type { TestWallet } from '../test-wallet/test_wallet.js';
12
12
  import { FeesTest } from './fees_test.js';
13
13
 
14
14
  jest.setTimeout(300_000);
@@ -20,7 +20,6 @@ import { ProtocolContractAddress } from '@aztec/protocol-contracts';
20
20
  import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice';
21
21
  import { GasSettings } from '@aztec/stdlib/gas';
22
22
  import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
23
- import { TestWallet } from '@aztec/test-wallet/server';
24
23
 
25
24
  import { getContract } from 'viem';
26
25
 
@@ -36,6 +35,7 @@ import {
36
35
  import { mintTokensToPrivate } from '../fixtures/token_utils.js';
37
36
  import { type BalancesFn, getBalancesFn, setupSponsoredFPC } from '../fixtures/utils.js';
38
37
  import { FeeJuicePortalTestingHarnessFactory, type GasBridgingTestHarness } from '../shared/gas_portal_test_harness.js';
38
+ import { TestWallet } from '../test-wallet/test_wallet.js';
39
39
 
40
40
  /**
41
41
  * Test fixture for testing fees. Provides the following setup steps:
@@ -157,15 +157,11 @@ export class FeesTest {
157
157
 
158
158
  /** Alice mints bananaCoin tokens privately to the target address and redeems them. */
159
159
  async mintPrivateBananas(amount: bigint, address: AztecAddress) {
160
- const balanceBefore = await this.bananaCoin.methods
161
- .balance_of_private(address)
162
- .simulate({ from: this.aliceAddress });
160
+ const balanceBefore = await this.bananaCoin.methods.balance_of_private(address).simulate({ from: address });
163
161
 
164
162
  await mintTokensToPrivate(this.bananaCoin, this.aliceAddress, address, amount);
165
163
 
166
- const balanceAfter = await this.bananaCoin.methods
167
- .balance_of_private(address)
168
- .simulate({ from: this.aliceAddress });
164
+ const balanceAfter = await this.bananaCoin.methods.balance_of_private(address).simulate({ from: address });
169
165
  expect(balanceAfter).toEqual(balanceBefore + amount);
170
166
  }
171
167
 
@@ -213,12 +209,7 @@ export class FeesTest {
213
209
 
214
210
  this.feeJuiceContract = FeeJuiceContract.at(ProtocolContractAddress.FeeJuice, this.wallet);
215
211
 
216
- this.getGasBalanceFn = getBalancesFn(
217
- '⛽',
218
- this.feeJuiceContract.methods.balance_of_public,
219
- this.aliceAddress,
220
- this.logger,
221
- );
212
+ this.getGasBalanceFn = getBalancesFn('⛽', this.feeJuiceContract.methods.balance_of_public, this.logger);
222
213
 
223
214
  this.feeJuiceBridgeTestHarness = await FeeJuicePortalTestingHarnessFactory.create({
224
215
  aztecNode: this.context.aztecNodeService,
@@ -238,16 +229,10 @@ export class FeesTest {
238
229
  this.logger.info(`BananaCoin deployed at ${bananaCoin.address}`);
239
230
 
240
231
  this.bananaCoin = bananaCoin;
241
- this.getBananaPublicBalanceFn = getBalancesFn(
242
- '🍌.public',
243
- this.bananaCoin.methods.balance_of_public,
244
- this.aliceAddress,
245
- this.logger,
246
- );
232
+ this.getBananaPublicBalanceFn = getBalancesFn('🍌.public', this.bananaCoin.methods.balance_of_public, this.logger);
247
233
  this.getBananaPrivateBalanceFn = getBalancesFn(
248
234
  '🍌.private',
249
235
  this.bananaCoin.methods.balance_of_private,
250
- this.aliceAddress,
251
236
  this.logger,
252
237
  );
253
238
  }
@@ -12,7 +12,7 @@ import {
12
12
  import type { Operator } from '@aztec/ethereum/deploy-aztec-l1-contracts';
13
13
  import { deployL1Contract } from '@aztec/ethereum/deploy-l1-contract';
14
14
  import { MultiAdderArtifact } from '@aztec/ethereum/l1-artifacts';
15
- import { createL1TxUtilsFromViemWallet } from '@aztec/ethereum/l1-tx-utils';
15
+ import { createL1TxUtils } from '@aztec/ethereum/l1-tx-utils';
16
16
  import { ChainMonitor } from '@aztec/ethereum/test';
17
17
  import type { ExtendedViemWalletClient, ViemClient } from '@aztec/ethereum/types';
18
18
  import { EpochNumber } from '@aztec/foundation/branded-types';
@@ -27,7 +27,6 @@ import { tryStop } from '@aztec/stdlib/interfaces/server';
27
27
  import { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
28
28
  import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
29
29
  import { ZkPassportProofParams } from '@aztec/stdlib/zkpassport';
30
- import type { TestWallet } from '@aztec/test-wallet/server';
31
30
  import { getGenesisValues } from '@aztec/world-state/testing';
32
31
 
33
32
  import getPort from 'get-port';
@@ -49,6 +48,7 @@ import {
49
48
  generatePrivateKeys,
50
49
  } from '../fixtures/setup_p2p_test.js';
51
50
  import { getEndToEndTestTelemetryClient } from '../fixtures/with_telemetry_utils.js';
51
+ import type { TestWallet } from '../test-wallet/test_wallet.js';
52
52
 
53
53
  // Use a fixed bootstrap node private key so that we can re-use the same snapshot and the nodes can find each other
54
54
  const BOOTSTRAP_NODE_PRIVATE_KEY = '080212208f988fc0899e4a73a5aee4d271a5f20670603a756ad8d84f2c94263a6427c591';
@@ -343,7 +343,7 @@ export class P2PNetworkTest {
343
343
  }
344
344
 
345
345
  private async _sendDummyTx(l1Client: ExtendedViemWalletClient) {
346
- const l1TxUtils = createL1TxUtilsFromViemWallet(l1Client);
346
+ const l1TxUtils = createL1TxUtils(l1Client);
347
347
  return await l1TxUtils.sendAndMonitorTransaction({
348
348
  to: l1Client.account!.address,
349
349
  value: 1n,
@@ -3,24 +3,24 @@ import { createLogger } from '@aztec/aztec.js/log';
3
3
  import { waitForTx } from '@aztec/aztec.js/node';
4
4
  import { Tx } from '@aztec/aztec.js/tx';
5
5
  import { RollupContract } from '@aztec/ethereum/contracts';
6
- import { SlotNumber } from '@aztec/foundation/branded-types';
6
+ import { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
7
7
  import { timesAsync } from '@aztec/foundation/collection';
8
8
  import { retryUntil } from '@aztec/foundation/retry';
9
9
 
10
- import { jest } from '@jest/globals';
10
+ import { expect, jest } from '@jest/globals';
11
11
  import fs from 'fs';
12
12
  import os from 'os';
13
13
  import path from 'path';
14
14
 
15
- import { shouldCollectMetrics } from '../../fixtures/fixtures.js';
15
+ import { getBootNodeUdpPort, shouldCollectMetrics } from '../../fixtures/fixtures.js';
16
16
  import { createNodes } from '../../fixtures/setup_p2p_test.js';
17
- import { P2PNetworkTest, SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES, WAIT_FOR_TX_TIMEOUT } from '../p2p_network.js';
17
+ import { P2PNetworkTest, WAIT_FOR_TX_TIMEOUT } from '../p2p_network.js';
18
18
  import { prepareTransactions } from '../shared.js';
19
19
 
20
20
  // Don't set this to a higher value than 9 because each node will use a different L1 publisher account and anvil seeds
21
21
  export const NUM_VALIDATORS = 6;
22
- export const NUM_TXS_PER_NODE = 2;
23
- export const BOOT_NODE_UDP_PORT = 4500;
22
+ export const NUM_TXS_PER_NODE = 4;
23
+ export const BOOT_NODE_UDP_PORT = getBootNodeUdpPort();
24
24
 
25
25
  export const createReqrespDataDir = () => fs.mkdtempSync(path.join(os.tmpdir(), 'reqresp-'));
26
26
 
@@ -38,8 +38,14 @@ export async function createReqrespTest(options: ReqrespOptions = {}): Promise<P
38
38
  // To collect metrics - run in aztec-packages `docker compose --profile metrics up`
39
39
  metricsPort: shouldCollectMetrics(),
40
40
  initialConfig: {
41
- ...SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES,
42
- aztecSlotDuration: 24,
41
+ ethereumSlotDuration: 8,
42
+ aztecSlotDuration: 36,
43
+ blockDurationMs: 6000,
44
+ l1PublishingTime: 8,
45
+ minTxsPerBlock: 1,
46
+ maxTxsPerBlock: 2,
47
+ enforceTimeTable: true,
48
+ aztecProofSubmissionEpochs: 1024, // effectively do not reorg
43
49
  ...(disableStatusHandshake ? { p2pDisableStatusHandshake: true } : {}),
44
50
  listenAddress: '127.0.0.1',
45
51
  aztecEpochDuration: 64, // stable committee
@@ -170,6 +176,28 @@ export async function runReqrespTxTest(params: {
170
176
 
171
177
  t.logger.info('All transactions mined');
172
178
 
179
+ // Assert that multiple blocks were built for at least one slot
180
+ t.logger.info('Verifying multiple blocks for at least one checkpoint');
181
+ const checkpoints = await nodes[0].getCheckpoints(CheckpointNumber(1), 50);
182
+ expect(checkpoints.length).toBeGreaterThan(0);
183
+
184
+ let mbpsFound = false;
185
+ let expectedBlockNumber = checkpoints[0].checkpoint.blocks[0].number;
186
+
187
+ for (const published of checkpoints) {
188
+ const blockCount = published.checkpoint.blocks.length;
189
+ mbpsFound = mbpsFound || blockCount >= 2;
190
+
191
+ for (let i = 0; i < blockCount; i++) {
192
+ const block = published.checkpoint.blocks[i];
193
+ expect(block.indexWithinCheckpoint).toBe(i);
194
+ expect(block.checkpointNumber).toBe(published.checkpoint.number);
195
+ expect(block.number).toBe(expectedBlockNumber);
196
+ expectedBlockNumber++;
197
+ }
198
+ }
199
+
200
+ expect(mbpsFound).toBe(true);
173
201
  return nodes;
174
202
  }
175
203
 
@@ -22,9 +22,10 @@ import { getPXEConfig, getPXEConfig as getRpcConfig } from '@aztec/pxe/server';
22
22
  import { getRoundForOffense } from '@aztec/slasher';
23
23
  import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
24
24
  import type { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
25
- import { type ProvenTx, TestWallet, proveInteraction } from '@aztec/test-wallet/server';
26
25
 
27
26
  import { submitTxsTo } from '../shared/submit-transactions.js';
27
+ import { TestWallet } from '../test-wallet/test_wallet.js';
28
+ import { type ProvenTx, proveInteraction } from '../test-wallet/utils.js';
28
29
 
29
30
  // submits a set of transactions to the provided Private eXecution Environment (PXE)
30
31
  export const submitComplexTxsTo = async (
@@ -2,14 +2,15 @@ import { AztecAddress } from '@aztec/aztec.js/addresses';
2
2
  import { type Logger, createLogger } from '@aztec/aztec.js/log';
3
3
  import type { AztecNode } from '@aztec/aztec.js/node';
4
4
  import { TokenContract } from '@aztec/noir-contracts.js/Token';
5
+ import { GenericProxyContract } from '@aztec/noir-test-contracts.js/GenericProxy';
5
6
  import { InvalidAccountContract } from '@aztec/noir-test-contracts.js/InvalidAccount';
6
- import type { TestWallet } from '@aztec/test-wallet/server';
7
7
 
8
8
  import { jest } from '@jest/globals';
9
9
 
10
10
  import { type EndToEndContext, deployAccounts, publicDeployAccounts, setup, teardown } from '../fixtures/setup.js';
11
11
  import { mintTokensToPrivate } from '../fixtures/token_utils.js';
12
12
  import { TokenSimulator } from '../simulators/token_simulator.js';
13
+ import type { TestWallet } from '../test-wallet/test_wallet.js';
13
14
 
14
15
  const { METRICS_PORT: metricsPort } = process.env;
15
16
 
@@ -25,6 +26,7 @@ export class TokenContractTest {
25
26
  node!: AztecNode;
26
27
 
27
28
  badAccount!: InvalidAccountContract;
29
+ authwitProxy!: GenericProxyContract;
28
30
  wallet!: TestWallet;
29
31
  adminAddress!: AztecAddress;
30
32
  account1Address!: AztecAddress;
@@ -92,6 +94,13 @@ export class TokenContractTest {
92
94
  this.badAccount = await InvalidAccountContract.deploy(this.wallet).send({ from: this.adminAddress });
93
95
  this.logger.verbose(`Deployed to ${this.badAccount.address}.`);
94
96
 
97
+ // Deploy a proxy contract for "on behalf of other" tests. The note owner must be the tx sender
98
+ // (so their notes are in scope), but msg_sender in the target must differ from the note owner
99
+ // to trigger authwit validation. The proxy forwards calls so that msg_sender != tx sender.
100
+ this.logger.verbose(`Deploying generic proxy...`);
101
+ this.authwitProxy = await GenericProxyContract.deploy(this.wallet).send({ from: this.adminAddress });
102
+ this.logger.verbose(`Deployed to ${this.authwitProxy.address}.`);
103
+
95
104
  this.tokenSim = new TokenSimulator(this.asset, this.wallet, this.adminAddress, this.logger, [
96
105
  this.adminAddress,
97
106
  this.account1Address,
@@ -0,0 +1,50 @@
1
+ import type {
2
+ ContractFunctionInteraction,
3
+ SendInteractionOptions,
4
+ SimulateInteractionOptions,
5
+ } from '@aztec/aztec.js/contracts';
6
+ import type { GenericProxyContract } from '@aztec/noir-test-contracts.js/GenericProxy';
7
+
8
+ /**
9
+ * Builds a proxy forwarding call from an action, selecting the right forward_private_N method.
10
+ */
11
+ async function buildProxyCall(proxy: GenericProxyContract, action: ContractFunctionInteraction) {
12
+ const call = await action.getFunctionCall();
13
+ const argCount = call.args.length;
14
+ if (argCount === 2) {
15
+ return proxy.methods.forward_private_2(call.to, call.selector, call.args);
16
+ } else if (argCount === 3) {
17
+ return proxy.methods.forward_private_3(call.to, call.selector, call.args);
18
+ } else if (argCount === 4) {
19
+ return proxy.methods.forward_private_4(call.to, call.selector, call.args);
20
+ }
21
+ throw new Error(`No forward_private_${argCount} method on proxy`);
22
+ }
23
+
24
+ /**
25
+ * Sends a contract call through the authwit proxy.
26
+ * The proxy becomes msg_sender in the target (triggering authwit validation),
27
+ * while the actual tx sender retains their keys in scope.
28
+ */
29
+ export async function sendThroughAuthwitProxy(
30
+ proxy: GenericProxyContract,
31
+ action: ContractFunctionInteraction,
32
+ options: SendInteractionOptions,
33
+ ) {
34
+ const proxyCall = await buildProxyCall(proxy, action);
35
+ return proxyCall.send(options);
36
+ }
37
+
38
+ /**
39
+ * Simulates a contract call through the authwit proxy.
40
+ * The proxy becomes msg_sender in the target (triggering authwit validation),
41
+ * while the actual tx sender retains their keys in scope.
42
+ */
43
+ export async function simulateThroughAuthwitProxy(
44
+ proxy: GenericProxyContract,
45
+ action: ContractFunctionInteraction,
46
+ options: SimulateInteractionOptions,
47
+ ) {
48
+ const proxyCall = await buildProxyCall(proxy, action);
49
+ return proxyCall.simulate(options);
50
+ }