@aztec/end-to-end 0.0.1-commit.f2ce05ee → 0.0.1-commit.f504929

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 (161) 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 +11 -10
  4. package/dest/bench/utils.d.ts +1 -1
  5. package/dest/bench/utils.d.ts.map +1 -1
  6. package/dest/bench/utils.js +6 -3
  7. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +4 -2
  8. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  9. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +22 -12
  10. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +2 -2
  11. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
  12. package/dest/e2e_deploy_contract/deploy_test.d.ts +2 -2
  13. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  14. package/dest/e2e_epochs/epochs_test.d.ts +9 -7
  15. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  16. package/dest/e2e_epochs/epochs_test.js +56 -32
  17. package/dest/e2e_fees/fees_test.d.ts +2 -2
  18. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  19. package/dest/e2e_fees/fees_test.js +10 -10
  20. package/dest/e2e_nested_contract/nested_contract_test.d.ts +1 -1
  21. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  22. package/dest/e2e_nested_contract/nested_contract_test.js +4 -6
  23. package/dest/e2e_p2p/p2p_network.d.ts +4 -3
  24. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  25. package/dest/e2e_p2p/p2p_network.js +23 -6
  26. package/dest/e2e_p2p/reqresp/utils.d.ts +3 -3
  27. package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
  28. package/dest/e2e_p2p/reqresp/utils.js +32 -8
  29. package/dest/e2e_p2p/shared.d.ts +16 -2
  30. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  31. package/dest/e2e_p2p/shared.js +27 -3
  32. package/dest/e2e_token_contract/token_contract_test.d.ts +4 -2
  33. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  34. package/dest/e2e_token_contract/token_contract_test.js +19 -9
  35. package/dest/fixtures/authwit_proxy.d.ts +15 -0
  36. package/dest/fixtures/authwit_proxy.d.ts.map +1 -0
  37. package/dest/fixtures/authwit_proxy.js +30 -0
  38. package/dest/fixtures/e2e_prover_test.d.ts +4 -4
  39. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  40. package/dest/fixtures/e2e_prover_test.js +33 -40
  41. package/dest/fixtures/elu_monitor.d.ts +21 -0
  42. package/dest/fixtures/elu_monitor.d.ts.map +1 -0
  43. package/dest/fixtures/elu_monitor.js +102 -0
  44. package/dest/fixtures/fixtures.d.ts +5 -1
  45. package/dest/fixtures/fixtures.d.ts.map +1 -1
  46. package/dest/fixtures/fixtures.js +6 -0
  47. package/dest/fixtures/ha_setup.d.ts +1 -1
  48. package/dest/fixtures/ha_setup.d.ts.map +1 -1
  49. package/dest/fixtures/ha_setup.js +3 -1
  50. package/dest/fixtures/setup.d.ts +39 -23
  51. package/dest/fixtures/setup.d.ts.map +1 -1
  52. package/dest/fixtures/setup.js +62 -152
  53. package/dest/fixtures/setup_p2p_test.d.ts +6 -3
  54. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  55. package/dest/fixtures/setup_p2p_test.js +12 -9
  56. package/dest/fixtures/token_utils.d.ts +2 -2
  57. package/dest/fixtures/token_utils.d.ts.map +1 -1
  58. package/dest/fixtures/token_utils.js +5 -4
  59. package/dest/shared/cross_chain_test_harness.d.ts +1 -1
  60. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  61. package/dest/shared/cross_chain_test_harness.js +13 -13
  62. package/dest/shared/gas_portal_test_harness.js +2 -2
  63. package/dest/shared/index.d.ts +2 -1
  64. package/dest/shared/index.d.ts.map +1 -1
  65. package/dest/shared/index.js +1 -0
  66. package/dest/shared/jest_setup.js +41 -1
  67. package/dest/shared/mock_state_view.d.ts +86 -0
  68. package/dest/shared/mock_state_view.d.ts.map +1 -0
  69. package/dest/shared/mock_state_view.js +186 -0
  70. package/dest/shared/submit-transactions.d.ts +2 -2
  71. package/dest/shared/submit-transactions.d.ts.map +1 -1
  72. package/dest/shared/submit-transactions.js +1 -1
  73. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  74. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  75. package/dest/shared/uniswap_l1_l2.js +6 -6
  76. package/dest/simulators/lending_simulator.d.ts +1 -1
  77. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  78. package/dest/simulators/lending_simulator.js +2 -2
  79. package/dest/simulators/token_simulator.d.ts +1 -1
  80. package/dest/simulators/token_simulator.d.ts.map +1 -1
  81. package/dest/simulators/token_simulator.js +3 -24
  82. package/dest/spartan/setup_test_wallets.d.ts +9 -2
  83. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  84. package/dest/spartan/setup_test_wallets.js +34 -3
  85. package/dest/spartan/tx_metrics.js +1 -1
  86. package/dest/spartan/utils/bot.d.ts +3 -2
  87. package/dest/spartan/utils/bot.d.ts.map +1 -1
  88. package/dest/spartan/utils/bot.js +2 -1
  89. package/dest/spartan/utils/config.d.ts +4 -1
  90. package/dest/spartan/utils/config.d.ts.map +1 -1
  91. package/dest/spartan/utils/config.js +2 -1
  92. package/dest/spartan/utils/index.d.ts +3 -2
  93. package/dest/spartan/utils/index.d.ts.map +1 -1
  94. package/dest/spartan/utils/index.js +3 -1
  95. package/dest/spartan/utils/k8s.d.ts +3 -1
  96. package/dest/spartan/utils/k8s.d.ts.map +1 -1
  97. package/dest/spartan/utils/k8s.js +6 -0
  98. package/dest/spartan/utils/nodes.d.ts +4 -5
  99. package/dest/spartan/utils/nodes.d.ts.map +1 -1
  100. package/dest/spartan/utils/nodes.js +9 -9
  101. package/dest/test-wallet/test_wallet.d.ts +83 -0
  102. package/dest/test-wallet/test_wallet.d.ts.map +1 -0
  103. package/dest/test-wallet/test_wallet.js +214 -0
  104. package/dest/test-wallet/utils.d.ts +41 -0
  105. package/dest/test-wallet/utils.d.ts.map +1 -0
  106. package/dest/test-wallet/utils.js +71 -0
  107. package/dest/test-wallet/wallet_worker_script.d.ts +2 -0
  108. package/dest/test-wallet/wallet_worker_script.d.ts.map +1 -0
  109. package/dest/test-wallet/wallet_worker_script.js +48 -0
  110. package/dest/test-wallet/worker_wallet.d.ts +52 -0
  111. package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
  112. package/dest/test-wallet/worker_wallet.js +151 -0
  113. package/dest/test-wallet/worker_wallet_schema.d.ts +274 -0
  114. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
  115. package/dest/test-wallet/worker_wallet_schema.js +10 -0
  116. package/package.json +43 -43
  117. package/src/bench/client_flows/client_flows_benchmark.ts +38 -37
  118. package/src/bench/utils.ts +8 -3
  119. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +28 -15
  120. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +4 -4
  121. package/src/e2e_deploy_contract/deploy_test.ts +3 -3
  122. package/src/e2e_epochs/epochs_test.ts +72 -63
  123. package/src/e2e_fees/bridging_race.notest.ts +1 -1
  124. package/src/e2e_fees/fees_test.ts +16 -27
  125. package/src/e2e_nested_contract/nested_contract_test.ts +7 -5
  126. package/src/e2e_p2p/inactivity_slash_test.ts +4 -4
  127. package/src/e2e_p2p/p2p_network.ts +35 -9
  128. package/src/e2e_p2p/reqresp/utils.ts +40 -12
  129. package/src/e2e_p2p/shared.ts +47 -3
  130. package/src/e2e_token_contract/token_contract_test.ts +26 -9
  131. package/src/fixtures/authwit_proxy.ts +50 -0
  132. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  133. package/src/fixtures/e2e_prover_test.ts +39 -43
  134. package/src/fixtures/elu_monitor.ts +126 -0
  135. package/src/fixtures/fixtures.ts +10 -0
  136. package/src/fixtures/ha_setup.ts +3 -1
  137. package/src/fixtures/setup.ts +94 -214
  138. package/src/fixtures/setup_p2p_test.ts +9 -17
  139. package/src/fixtures/token_utils.ts +6 -3
  140. package/src/guides/up_quick_start.sh +3 -3
  141. package/src/shared/cross_chain_test_harness.ts +13 -9
  142. package/src/shared/gas_portal_test_harness.ts +1 -1
  143. package/src/shared/index.ts +1 -0
  144. package/src/shared/jest_setup.ts +51 -1
  145. package/src/shared/mock_state_view.ts +188 -0
  146. package/src/shared/submit-transactions.ts +3 -2
  147. package/src/shared/uniswap_l1_l2.ts +8 -6
  148. package/src/simulators/lending_simulator.ts +4 -2
  149. package/src/simulators/token_simulator.ts +6 -30
  150. package/src/spartan/setup_test_wallets.ts +58 -11
  151. package/src/spartan/tx_metrics.ts +1 -1
  152. package/src/spartan/utils/bot.ts +4 -1
  153. package/src/spartan/utils/config.ts +1 -0
  154. package/src/spartan/utils/index.ts +4 -0
  155. package/src/spartan/utils/k8s.ts +8 -0
  156. package/src/spartan/utils/nodes.ts +15 -10
  157. package/src/test-wallet/test_wallet.ts +306 -0
  158. package/src/test-wallet/utils.ts +112 -0
  159. package/src/test-wallet/wallet_worker_script.ts +60 -0
  160. package/src/test-wallet/worker_wallet.ts +213 -0
  161. package/src/test-wallet/worker_wallet_schema.ts +13 -0
@@ -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:
@@ -113,7 +113,7 @@ export class FeesTest {
113
113
  });
114
114
 
115
115
  this.rollupContract = RollupContract.getFromConfig(this.context.config);
116
- this.chainMonitor = new ChainMonitor(this.rollupContract, this.context.dateProvider!, this.logger, 200).start();
116
+ this.chainMonitor = new ChainMonitor(this.rollupContract, this.context.dateProvider, this.logger, 200).start();
117
117
 
118
118
  await this.applyBaseSetup();
119
119
 
@@ -126,7 +126,7 @@ export class FeesTest {
126
126
  }
127
127
 
128
128
  setIsMarkingAsProven(b: boolean) {
129
- this.context.watcher!.setIsMarkingAsProven(b);
129
+ this.context.watcher.setIsMarkingAsProven(b);
130
130
  }
131
131
 
132
132
  async catchUpProvenChain() {
@@ -157,15 +157,15 @@ 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
160
+ const { result: balanceBefore } = await this.bananaCoin.methods
161
161
  .balance_of_private(address)
162
- .simulate({ from: this.aliceAddress });
162
+ .simulate({ from: address });
163
163
 
164
164
  await mintTokensToPrivate(this.bananaCoin, this.aliceAddress, address, amount);
165
165
 
166
- const balanceAfter = await this.bananaCoin.methods
166
+ const { result: balanceAfter } = await this.bananaCoin.methods
167
167
  .balance_of_private(address)
168
- .simulate({ from: this.aliceAddress });
168
+ .simulate({ from: address });
169
169
  expect(balanceAfter).toEqual(balanceBefore + amount);
170
170
  }
171
171
 
@@ -188,8 +188,8 @@ export class FeesTest {
188
188
  });
189
189
 
190
190
  this.wallet = this.context.wallet;
191
- this.aztecNode = this.context.aztecNodeService!;
192
- this.aztecNodeAdmin = this.context.aztecNodeService!;
191
+ this.aztecNode = this.context.aztecNodeService;
192
+ this.aztecNodeAdmin = this.context.aztecNodeService;
193
193
  this.gasSettings = GasSettings.default({ maxFeesPerGas: (await this.aztecNode.getCurrentMinFees()).mul(2) });
194
194
  this.cheatCodes = this.context.cheatCodes;
195
195
  this.accounts = deployedAccounts.map(a => a.address);
@@ -213,16 +213,11 @@ export class FeesTest {
213
213
 
214
214
  this.feeJuiceContract = FeeJuiceContract.at(ProtocolContractAddress.FeeJuice, this.wallet);
215
215
 
216
- this.getGasBalanceFn = getBalancesFn(
217
- '⛽',
218
- this.feeJuiceContract.methods.balance_of_public,
219
- this.aliceAddress,
220
- this.logger,
221
- );
216
+ this.getGasBalanceFn = getBalancesFn('⛽', this.feeJuiceContract.methods.balance_of_public, this.logger);
222
217
 
223
218
  this.feeJuiceBridgeTestHarness = await FeeJuicePortalTestingHarnessFactory.create({
224
- aztecNode: this.context.aztecNodeService!,
225
- aztecNodeAdmin: this.context.aztecNodeService!,
219
+ aztecNode: this.context.aztecNodeService,
220
+ aztecNodeAdmin: this.context.aztecNodeService,
226
221
  l1Client: this.context.deployL1ContractsValues.l1Client,
227
222
  wallet: this.wallet,
228
223
  logger: this.logger,
@@ -232,22 +227,16 @@ export class FeesTest {
232
227
  async applyDeployBananaToken() {
233
228
  this.logger.info('Applying deploy banana token setup');
234
229
 
235
- const bananaCoin = await BananaCoin.deploy(this.wallet, this.aliceAddress, 'BC', 'BC', 18n).send({
230
+ const { contract: bananaCoin } = await BananaCoin.deploy(this.wallet, this.aliceAddress, 'BC', 'BC', 18n).send({
236
231
  from: this.aliceAddress,
237
232
  });
238
233
  this.logger.info(`BananaCoin deployed at ${bananaCoin.address}`);
239
234
 
240
235
  this.bananaCoin = bananaCoin;
241
- this.getBananaPublicBalanceFn = getBalancesFn(
242
- '🍌.public',
243
- this.bananaCoin.methods.balance_of_public,
244
- this.aliceAddress,
245
- this.logger,
246
- );
236
+ this.getBananaPublicBalanceFn = getBalancesFn('🍌.public', this.bananaCoin.methods.balance_of_public, this.logger);
247
237
  this.getBananaPrivateBalanceFn = getBalancesFn(
248
238
  '🍌.private',
249
239
  this.bananaCoin.methods.balance_of_private,
250
- this.aliceAddress,
251
240
  this.logger,
252
241
  );
253
242
  }
@@ -259,7 +248,7 @@ export class FeesTest {
259
248
  expect((await this.wallet.getContractMetadata(feeJuiceContract.address)).isContractPublished).toBe(true);
260
249
 
261
250
  const bananaCoin = this.bananaCoin;
262
- const bananaFPC = await FPCContract.deploy(this.wallet, bananaCoin.address, this.fpcAdmin).send({
251
+ const { contract: bananaFPC } = await FPCContract.deploy(this.wallet, bananaCoin.address, this.fpcAdmin).send({
263
252
  from: this.aliceAddress,
264
253
  });
265
254
 
@@ -290,7 +279,7 @@ export class FeesTest {
290
279
 
291
280
  // @todo @lherskind As we deal with #13601
292
281
  // Right now the value is from `FeeLib.sol`
293
- const L1_GAS_PER_EPOCH_VERIFIED = 1000000n;
282
+ const L1_GAS_PER_EPOCH_VERIFIED = 3600000n;
294
283
 
295
284
  // We round up
296
285
  const mulDiv = (a: bigint, b: bigint, c: bigint) => (a * b) / c + ((a * b) % c > 0n ? 1n : 0n);
@@ -44,7 +44,7 @@ export class NestedContractTest {
44
44
  });
45
45
  this.wallet = this.context.wallet;
46
46
  [{ address: this.defaultAccountAddress }] = deployedAccounts;
47
- this.aztecNode = this.context.aztecNodeService!;
47
+ this.aztecNode = this.context.aztecNodeService;
48
48
 
49
49
  this.logger.info('Public deploy accounts');
50
50
  await publicDeployAccounts(this.wallet, [this.defaultAccountAddress]);
@@ -65,9 +65,11 @@ export class NestedContractTest {
65
65
 
66
66
  async applyManual() {
67
67
  this.logger.info('Deploying parent and child contracts');
68
- const parentContract = await ParentContract.deploy(this.wallet).send({ from: this.defaultAccountAddress });
69
- const childContract = await ChildContract.deploy(this.wallet).send({ from: this.defaultAccountAddress });
70
- this.parentContract = parentContract;
71
- this.childContract = childContract;
68
+ ({ contract: this.parentContract } = await ParentContract.deploy(this.wallet).send({
69
+ from: this.defaultAccountAddress,
70
+ }));
71
+ ({ contract: this.childContract } = await ChildContract.deploy(this.wallet).send({
72
+ from: this.defaultAccountAddress,
73
+ }));
72
74
  }
73
75
  }
@@ -98,13 +98,13 @@ export class P2PInactivityTest {
98
98
  this.rollup = rollup;
99
99
 
100
100
  if (!this.keepInitialNode) {
101
- await this.test.ctx.aztecNodeService!.stop();
101
+ await this.test.ctx.aztecNodeService.stop();
102
102
  }
103
103
 
104
104
  // Create all active nodes
105
105
  this.activeNodes = await createNodes(
106
106
  this.test.ctx.aztecNodeConfig,
107
- this.test.ctx.dateProvider!,
107
+ this.test.ctx.dateProvider,
108
108
  this.test.bootstrapNodeEnr,
109
109
  NUM_NODES - this.inactiveNodeCount - Number(this.keepInitialNode),
110
110
  BOOT_NODE_UDP_PORT,
@@ -118,7 +118,7 @@ export class P2PInactivityTest {
118
118
  const inactiveConfig = { ...this.test.ctx.aztecNodeConfig, dontStartSequencer: true };
119
119
  this.inactiveNodes = await createNodes(
120
120
  inactiveConfig,
121
- this.test.ctx.dateProvider!,
121
+ this.test.ctx.dateProvider,
122
122
  this.test.bootstrapNodeEnr,
123
123
  this.inactiveNodeCount,
124
124
  BOOT_NODE_UDP_PORT,
@@ -129,7 +129,7 @@ export class P2PInactivityTest {
129
129
  );
130
130
 
131
131
  this.nodes = [
132
- ...(this.keepInitialNode ? [this.test.ctx.aztecNodeService!] : []),
132
+ ...(this.keepInitialNode ? [this.test.ctx.aztecNodeService] : []),
133
133
  ...this.activeNodes,
134
134
  ...this.inactiveNodes,
135
135
  ];
@@ -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';
@@ -25,9 +25,9 @@ import type { BootstrapNode } from '@aztec/p2p/bootstrap';
25
25
  import { createBootstrapNodeFromPrivateKey, getBootstrapNodeEnr } from '@aztec/p2p/test-helpers';
26
26
  import { tryStop } from '@aztec/stdlib/interfaces/server';
27
27
  import { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
28
+ import { TopicType } from '@aztec/stdlib/p2p';
28
29
  import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
29
30
  import { ZkPassportProofParams } from '@aztec/stdlib/zkpassport';
30
- import type { TestWallet } from '@aztec/test-wallet/server';
31
31
  import { getGenesisValues } from '@aztec/world-state/testing';
32
32
 
33
33
  import getPort from 'get-port';
@@ -49,6 +49,7 @@ import {
49
49
  generatePrivateKeys,
50
50
  } from '../fixtures/setup_p2p_test.js';
51
51
  import { getEndToEndTestTelemetryClient } from '../fixtures/with_telemetry_utils.js';
52
+ import type { TestWallet } from '../test-wallet/test_wallet.js';
52
53
 
53
54
  // Use a fixed bootstrap node private key so that we can re-use the same snapshot and the nodes can find each other
54
55
  const BOOTSTRAP_NODE_PRIVATE_KEY = '080212208f988fc0899e4a73a5aee4d271a5f20670603a756ad8d84f2c94263a6427c591';
@@ -322,8 +323,9 @@ export class P2PNetworkTest {
322
323
  throw new Error('Call setupAccount before deploying spam contract');
323
324
  }
324
325
 
325
- const spamContract = await SpamContract.deploy(this.wallet).send({ from: this.defaultAccountAddress! });
326
- this.spamContract = spamContract;
326
+ ({ contract: this.spamContract } = await SpamContract.deploy(this.wallet).send({
327
+ from: this.defaultAccountAddress!,
328
+ }));
327
329
  }
328
330
 
329
331
  async removeInitialNode() {
@@ -333,9 +335,9 @@ export class P2PNetworkTest {
333
335
  const block = await this.context.deployL1ContractsValues.l1Client.getBlock({
334
336
  blockNumber: receipt.blockNumber,
335
337
  });
336
- this.context.dateProvider!.setTime(Number(block.timestamp) * 1000);
338
+ this.context.dateProvider.setTime(Number(block.timestamp) * 1000);
337
339
 
338
- await this.context.aztecNodeService!.stop();
340
+ await this.context.aztecNodeService.stop();
339
341
  }
340
342
 
341
343
  async sendDummyTx() {
@@ -343,7 +345,7 @@ export class P2PNetworkTest {
343
345
  }
344
346
 
345
347
  private async _sendDummyTx(l1Client: ExtendedViemWalletClient) {
346
- const l1TxUtils = createL1TxUtilsFromViemWallet(l1Client);
348
+ const l1TxUtils = createL1TxUtils(l1Client);
347
349
  return await l1TxUtils.sendAndMonitorTransaction({
348
350
  to: l1Client.account!.address,
349
351
  value: 1n,
@@ -374,8 +376,8 @@ export class P2PNetworkTest {
374
376
  this.prefilledPublicData = prefilledPublicData;
375
377
 
376
378
  const rollupContract = RollupContract.getFromL1ContractsValues(this.context.deployL1ContractsValues);
377
- this.monitor = new ChainMonitor(rollupContract, this.context.dateProvider!).start();
378
- this.monitor.on('l1-block', ({ timestamp }) => this.context.dateProvider!.setTime(Number(timestamp) * 1000));
379
+ this.monitor = new ChainMonitor(rollupContract, this.context.dateProvider).start();
380
+ this.monitor.on('l1-block', ({ timestamp }) => this.context.dateProvider.setTime(Number(timestamp) * 1000));
379
381
  }
380
382
 
381
383
  async stopNodes(nodes: AztecNodeService[]) {
@@ -406,6 +408,7 @@ export class P2PNetworkTest {
406
408
  expectedNodeCount?: number,
407
409
  timeoutSeconds = 30,
408
410
  checkIntervalSeconds = 0.1,
411
+ topics: TopicType[] = [TopicType.tx],
409
412
  ) {
410
413
  const nodeCount = expectedNodeCount ?? nodes.length;
411
414
  const minPeerCount = nodeCount - 1;
@@ -431,6 +434,29 @@ export class P2PNetworkTest {
431
434
  );
432
435
 
433
436
  this.logger.warn('All nodes connected to P2P mesh');
437
+
438
+ // Wait for GossipSub mesh to form for all specified topics.
439
+ // We only require at least 1 mesh peer per node because GossipSub
440
+ // stops grafting once it reaches Dlo peers and won't fill the mesh to all available peers.
441
+ for (const topic of topics) {
442
+ this.logger.warn(`Waiting for GossipSub mesh to form for ${topic} topic...`);
443
+ await Promise.all(
444
+ nodes.map(async (node, index) => {
445
+ const p2p = node.getP2P();
446
+ await retryUntil(
447
+ async () => {
448
+ const meshPeers = await p2p.getGossipMeshPeerCount(topic);
449
+ this.logger.debug(`Node ${index} has ${meshPeers} gossip mesh peers for ${topic} topic`);
450
+ return meshPeers >= 1 ? true : undefined;
451
+ },
452
+ `Node ${index} to have gossip mesh peers for ${topic} topic`,
453
+ timeoutSeconds,
454
+ checkIntervalSeconds,
455
+ );
456
+ }),
457
+ );
458
+ this.logger.warn(`All nodes have gossip mesh peers for ${topic} topic`);
459
+ }
434
460
  }
435
461
 
436
462
  async teardown() {
@@ -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
@@ -81,7 +87,7 @@ export async function runReqrespTxTest(params: {
81
87
 
82
88
  const nodes = await createNodes(
83
89
  aztecNodeConfig,
84
- t.ctx.dateProvider!,
90
+ t.ctx.dateProvider,
85
91
  t.bootstrapNodeEnr,
86
92
  NUM_VALIDATORS,
87
93
  BOOT_NODE_UDP_PORT,
@@ -95,7 +101,7 @@ export async function runReqrespTxTest(params: {
95
101
 
96
102
  await t.setupAccount();
97
103
 
98
- const targetBlockNumber = await t.ctx.aztecNodeService!.getBlockNumber();
104
+ const targetBlockNumber = await t.ctx.aztecNodeService.getBlockNumber();
99
105
  await retryUntil(
100
106
  async () => {
101
107
  const blockNumbers = await Promise.all(nodes.map(node => node.getBlockNumber()));
@@ -108,7 +114,7 @@ export async function runReqrespTxTest(params: {
108
114
 
109
115
  t.logger.info('Preparing transactions to send');
110
116
  const txBatches = await timesAsync(2, () =>
111
- prepareTransactions(t.logger, t.ctx.aztecNodeService!, NUM_TXS_PER_NODE, t.fundedAccount),
117
+ prepareTransactions(t.logger, t.ctx.aztecNodeService, NUM_TXS_PER_NODE, t.fundedAccount),
112
118
  );
113
119
 
114
120
  t.logger.info('Removing initial node');
@@ -116,7 +122,7 @@ export async function runReqrespTxTest(params: {
116
122
 
117
123
  t.logger.info('Starting fresh slot');
118
124
  const [timestamp] = await t.ctx.cheatCodes.rollup.advanceToNextSlot();
119
- t.ctx.dateProvider!.setTime(Number(timestamp) * 1000);
125
+ t.ctx.dateProvider.setTime(Number(timestamp) * 1000);
120
126
  const startSlotTimestamp = BigInt(timestamp);
121
127
 
122
128
  const { proposerIndexes, nodesToTurnOffTxGossip } = await getProposerIndexes(t, startSlotTimestamp);
@@ -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
 
@@ -6,12 +6,13 @@ import { Fr } from '@aztec/aztec.js/fields';
6
6
  import type { Logger } from '@aztec/aztec.js/log';
7
7
  import { TxHash } from '@aztec/aztec.js/tx';
8
8
  import type { RollupCheatCodes } from '@aztec/aztec/testing';
9
+ import type { EpochCacheInterface } from '@aztec/epoch-cache';
9
10
  import type {
10
11
  EmpireSlashingProposerContract,
11
12
  RollupContract,
12
13
  TallySlashingProposerContract,
13
14
  } from '@aztec/ethereum/contracts';
14
- import { EpochNumber } from '@aztec/foundation/branded-types';
15
+ import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
15
16
  import { timesAsync, unique } from '@aztec/foundation/collection';
16
17
  import { EthAddress } from '@aztec/foundation/eth-address';
17
18
  import { retryUntil } from '@aztec/foundation/retry';
@@ -22,9 +23,10 @@ import { getPXEConfig, getPXEConfig as getRpcConfig } from '@aztec/pxe/server';
22
23
  import { getRoundForOffense } from '@aztec/slasher';
23
24
  import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
24
25
  import type { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
25
- import { type ProvenTx, TestWallet, proveInteraction } from '@aztec/test-wallet/server';
26
26
 
27
27
  import { submitTxsTo } from '../shared/submit-transactions.js';
28
+ import { TestWallet } from '../test-wallet/test_wallet.js';
29
+ import { type ProvenTx, proveInteraction } from '../test-wallet/utils.js';
28
30
 
29
31
  // submits a set of transactions to the provided Private eXecution Environment (PXE)
30
32
  export const submitComplexTxsTo = async (
@@ -40,7 +42,7 @@ export const submitComplexTxsTo = async (
40
42
  const spamCount = 15;
41
43
  for (let i = 0; i < numTxs; i++) {
42
44
  const method = spamContract.methods.spam(seed + BigInt(i * spamCount), spamCount, !!opts.callPublic);
43
- const txHash = await method.send({ from, wait: NO_WAIT });
45
+ const { txHash } = await method.send({ from, wait: NO_WAIT });
44
46
  logger.info(`Tx sent with hash ${txHash.toString()}`);
45
47
  txs.push(txHash);
46
48
  }
@@ -149,6 +151,48 @@ export async function awaitCommitteeExists({
149
151
  return committee!.map(c => c.toString() as `0x${string}`);
150
152
  }
151
153
 
154
+ /**
155
+ * Advance epochs until we find one where the target proposer is selected for at least one slot.
156
+ * With N validators and M slots per epoch, a specific proposer may not be selected in any given epoch.
157
+ * For example, with 4 validators and 2 slots/epoch, there is about a 44% chance per epoch.
158
+ */
159
+ export async function awaitEpochWithProposer({
160
+ epochCache,
161
+ cheatCodes,
162
+ targetProposer,
163
+ logger,
164
+ maxAttempts = 20,
165
+ }: {
166
+ epochCache: EpochCacheInterface;
167
+ cheatCodes: RollupCheatCodes;
168
+ targetProposer: EthAddress;
169
+ logger: Logger;
170
+ maxAttempts?: number;
171
+ }): Promise<void> {
172
+ const { epochDuration } = await cheatCodes.getConfig();
173
+
174
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
175
+ const currentEpoch = await cheatCodes.getEpoch();
176
+ const startSlot = Number(currentEpoch) * Number(epochDuration);
177
+ const endSlot = startSlot + Number(epochDuration);
178
+
179
+ logger.info(`Checking epoch ${currentEpoch} (slots ${startSlot}-${endSlot - 1}) for proposer ${targetProposer}`);
180
+
181
+ for (let s = startSlot; s < endSlot; s++) {
182
+ const proposer = await epochCache.getProposerAttesterAddressInSlot(SlotNumber(s));
183
+ if (proposer && proposer.equals(targetProposer)) {
184
+ logger.warn(`Found target proposer ${targetProposer} in slot ${s} of epoch ${currentEpoch}`);
185
+ return;
186
+ }
187
+ }
188
+
189
+ logger.info(`Target proposer not found in epoch ${currentEpoch}, advancing to next epoch`);
190
+ await cheatCodes.advanceToNextEpoch();
191
+ }
192
+
193
+ throw new Error(`Target proposer ${targetProposer} not found in any slot after ${maxAttempts} epoch attempts`);
194
+ }
195
+
152
196
  export async function awaitOffenseDetected({
153
197
  logger,
154
198
  nodeAdmin,
@@ -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;
@@ -70,7 +72,7 @@ export class TokenContractTest {
70
72
  initialFundedAccounts: this.context.initialFundedAccounts,
71
73
  });
72
74
 
73
- this.node = this.context.aztecNodeService!;
75
+ this.node = this.context.aztecNodeService;
74
76
  this.wallet = this.context.wallet;
75
77
  [this.adminAddress, this.account1Address, this.account2Address] = deployedAccounts.map(acc => acc.address);
76
78
 
@@ -79,25 +81,36 @@ export class TokenContractTest {
79
81
  await publicDeployAccounts(this.wallet, [this.adminAddress, this.account1Address]);
80
82
 
81
83
  this.logger.verbose(`Deploying TokenContract...`);
82
- this.asset = await TokenContract.deploy(
84
+ ({ contract: this.asset } = await TokenContract.deploy(
83
85
  this.wallet,
84
86
  this.adminAddress,
85
87
  TokenContractTest.TOKEN_NAME,
86
88
  TokenContractTest.TOKEN_SYMBOL,
87
89
  TokenContractTest.TOKEN_DECIMALS,
88
- ).send({ from: this.adminAddress });
90
+ ).send({ from: this.adminAddress }));
89
91
  this.logger.verbose(`Token deployed to ${this.asset.address}`);
90
92
 
91
93
  this.logger.verbose(`Deploying bad account...`);
92
- this.badAccount = await InvalidAccountContract.deploy(this.wallet).send({ from: this.adminAddress });
94
+ ({ contract: this.badAccount } = await InvalidAccountContract.deploy(this.wallet).send({
95
+ from: this.adminAddress,
96
+ }));
93
97
  this.logger.verbose(`Deployed to ${this.badAccount.address}.`);
94
98
 
99
+ // Deploy a proxy contract for "on behalf of other" tests. The note owner must be the tx sender
100
+ // (so their notes are in scope), but msg_sender in the target must differ from the note owner
101
+ // to trigger authwit validation. The proxy forwards calls so that msg_sender != tx sender.
102
+ this.logger.verbose(`Deploying generic proxy...`);
103
+ ({ contract: this.authwitProxy } = await GenericProxyContract.deploy(this.wallet).send({
104
+ from: this.adminAddress,
105
+ }));
106
+ this.logger.verbose(`Deployed to ${this.authwitProxy.address}.`);
107
+
95
108
  this.tokenSim = new TokenSimulator(this.asset, this.wallet, this.adminAddress, this.logger, [
96
109
  this.adminAddress,
97
110
  this.account1Address,
98
111
  ]);
99
112
 
100
- expect(await this.asset.methods.get_admin().simulate({ from: this.adminAddress })).toBe(
113
+ expect((await this.asset.methods.get_admin().simulate({ from: this.adminAddress })).result).toBe(
101
114
  this.adminAddress.toBigInt(),
102
115
  );
103
116
  }
@@ -131,7 +144,9 @@ export class TokenContractTest {
131
144
  await asset.methods.mint_to_public(adminAddress, amount).send({ from: adminAddress });
132
145
  tokenSim.mintPublic(adminAddress, amount);
133
146
 
134
- const publicBalance = await asset.methods.balance_of_public(adminAddress).simulate({ from: adminAddress });
147
+ const { result: publicBalance } = await asset.methods
148
+ .balance_of_public(adminAddress)
149
+ .simulate({ from: adminAddress });
135
150
  this.logger.verbose(`Public balance of wallet 0: ${publicBalance}`);
136
151
  expect(publicBalance).toEqual(this.tokenSim.balanceOfPublic(adminAddress));
137
152
 
@@ -139,11 +154,13 @@ export class TokenContractTest {
139
154
  await mintTokensToPrivate(asset, adminAddress, adminAddress, amount);
140
155
  tokenSim.mintPrivate(adminAddress, amount);
141
156
 
142
- const privateBalance = await asset.methods.balance_of_private(adminAddress).simulate({ from: adminAddress });
157
+ const { result: privateBalance } = await asset.methods
158
+ .balance_of_private(adminAddress)
159
+ .simulate({ from: adminAddress });
143
160
  this.logger.verbose(`Private balance of wallet 0: ${privateBalance}`);
144
161
  expect(privateBalance).toEqual(tokenSim.balanceOfPrivate(adminAddress));
145
162
 
146
- const totalSupply = await asset.methods.total_supply().simulate({ from: adminAddress });
163
+ const { result: totalSupply } = await asset.methods.total_supply().simulate({ from: adminAddress });
147
164
  this.logger.verbose(`Total supply: ${totalSupply}`);
148
165
  expect(totalSupply).toEqual(tokenSim.totalSupply);
149
166
 
@@ -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
+ }