@aztec/end-to-end 0.0.1-commit.b1c78909e → 0.0.1-commit.b2a5d0dd1

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 (103) hide show
  1. package/README.md +27 -0
  2. package/dest/bench/client_flows/client_flows_benchmark.d.ts +1 -1
  3. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  4. package/dest/bench/client_flows/client_flows_benchmark.js +15 -30
  5. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +3 -2
  6. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  7. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +1 -1
  8. package/dest/e2e_epochs/epochs_test.d.ts +18 -1
  9. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  10. package/dest/e2e_epochs/epochs_test.js +59 -9
  11. package/dest/e2e_fees/fees_test.d.ts +1 -1
  12. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  13. package/dest/e2e_fees/fees_test.js +3 -3
  14. package/dest/e2e_p2p/inactivity_slash_test.js +3 -3
  15. package/dest/e2e_p2p/p2p_network.d.ts +10 -9
  16. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  17. package/dest/e2e_p2p/p2p_network.js +46 -27
  18. package/dest/e2e_p2p/reqresp/utils.js +1 -1
  19. package/dest/e2e_p2p/shared.d.ts +5 -7
  20. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  21. package/dest/e2e_p2p/shared.js +29 -44
  22. package/dest/fixtures/authwit_proxy.d.ts +1 -1
  23. package/dest/fixtures/authwit_proxy.d.ts.map +1 -1
  24. package/dest/fixtures/authwit_proxy.js +4 -0
  25. package/dest/fixtures/e2e_prover_test.d.ts +4 -3
  26. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  27. package/dest/fixtures/e2e_prover_test.js +7 -12
  28. package/dest/fixtures/fixtures.d.ts +12 -1
  29. package/dest/fixtures/fixtures.d.ts.map +1 -1
  30. package/dest/fixtures/fixtures.js +10 -0
  31. package/dest/fixtures/get_bb_config.d.ts +1 -1
  32. package/dest/fixtures/get_bb_config.d.ts.map +1 -1
  33. package/dest/fixtures/get_bb_config.js +5 -5
  34. package/dest/fixtures/ha_setup.d.ts +2 -2
  35. package/dest/fixtures/ha_setup.d.ts.map +1 -1
  36. package/dest/fixtures/ha_setup.js +1 -1
  37. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
  38. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
  39. package/dest/fixtures/schnorr_hardcoded_account_contract.js +39 -0
  40. package/dest/fixtures/setup.d.ts +17 -10
  41. package/dest/fixtures/setup.d.ts.map +1 -1
  42. package/dest/fixtures/setup.js +40 -21
  43. package/dest/fixtures/setup_p2p_test.d.ts +6 -6
  44. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  45. package/dest/fixtures/setup_p2p_test.js +8 -8
  46. package/dest/fixtures/token_utils.d.ts +1 -1
  47. package/dest/fixtures/token_utils.d.ts.map +1 -1
  48. package/dest/fixtures/token_utils.js +2 -5
  49. package/dest/forward-compatibility/wallet_rpc_client.d.ts +7 -0
  50. package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
  51. package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
  52. package/dest/forward-compatibility/wallet_service.d.ts +3 -0
  53. package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
  54. package/dest/forward-compatibility/wallet_service.js +109 -0
  55. package/dest/legacy-jest-resolver.d.cts +3 -0
  56. package/dest/legacy-jest-resolver.d.cts.map +1 -0
  57. package/dest/shared/gas_portal_test_harness.js +1 -1
  58. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  59. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  60. package/dest/shared/uniswap_l1_l2.js +9 -16
  61. package/dest/simulators/lending_simulator.d.ts +1 -1
  62. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  63. package/dest/simulators/lending_simulator.js +2 -2
  64. package/dest/simulators/token_simulator.js +1 -1
  65. package/dest/spartan/setup_test_wallets.d.ts +1 -1
  66. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  67. package/dest/spartan/setup_test_wallets.js +63 -45
  68. package/dest/test-wallet/test_wallet.d.ts +24 -23
  69. package/dest/test-wallet/test_wallet.d.ts.map +1 -1
  70. package/dest/test-wallet/test_wallet.js +118 -81
  71. package/dest/test-wallet/worker_wallet.d.ts +4 -4
  72. package/dest/test-wallet/worker_wallet.d.ts.map +1 -1
  73. package/dest/test-wallet/worker_wallet_schema.d.ts +9 -4
  74. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -1
  75. package/package.json +40 -40
  76. package/src/bench/client_flows/client_flows_benchmark.ts +33 -24
  77. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +3 -6
  78. package/src/e2e_epochs/epochs_test.ts +69 -9
  79. package/src/e2e_fees/fees_test.ts +4 -2
  80. package/src/e2e_p2p/inactivity_slash_test.ts +3 -3
  81. package/src/e2e_p2p/p2p_network.ts +57 -39
  82. package/src/e2e_p2p/reqresp/utils.ts +1 -1
  83. package/src/e2e_p2p/shared.ts +29 -59
  84. package/src/fixtures/authwit_proxy.ts +4 -0
  85. package/src/fixtures/e2e_prover_test.ts +12 -17
  86. package/src/fixtures/fixtures.ts +22 -0
  87. package/src/fixtures/get_bb_config.ts +7 -6
  88. package/src/fixtures/ha_setup.ts +4 -2
  89. package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
  90. package/src/fixtures/setup.ts +54 -25
  91. package/src/fixtures/setup_p2p_test.ts +9 -9
  92. package/src/fixtures/token_utils.ts +1 -4
  93. package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
  94. package/src/forward-compatibility/wallet_service.ts +104 -0
  95. package/src/guides/up_quick_start.sh +0 -2
  96. package/src/legacy-jest-resolver.cjs +135 -0
  97. package/src/shared/gas_portal_test_harness.ts +0 -1
  98. package/src/shared/uniswap_l1_l2.ts +29 -28
  99. package/src/simulators/lending_simulator.ts +4 -2
  100. package/src/simulators/token_simulator.ts +1 -1
  101. package/src/spartan/setup_test_wallets.ts +63 -39
  102. package/src/test-wallet/test_wallet.ts +147 -100
  103. package/src/test-wallet/worker_wallet.ts +3 -2
@@ -1,3 +1,4 @@
1
+ import { NO_FROM } from '@aztec/aztec.js/account';
1
2
  import { AztecAddress } from '@aztec/aztec.js/addresses';
2
3
  import { FeeJuicePaymentMethodWithClaim } from '@aztec/aztec.js/fee';
3
4
  import { type FeePaymentMethod, PrivateFeePaymentMethod, SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee';
@@ -27,7 +28,7 @@ import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
27
28
  import { GasSettings } from '@aztec/stdlib/gas';
28
29
  import { deriveSigningKey } from '@aztec/stdlib/keys';
29
30
 
30
- import { MNEMONIC } from '../../fixtures/fixtures.js';
31
+ import { MNEMONIC, getPaddedMaxFeesPerGas } from '../../fixtures/fixtures.js';
31
32
  import { type EndToEndContext, type SetupOptions, deployAccounts, setup, teardown } from '../../fixtures/setup.js';
32
33
  import { mintTokensToPrivate } from '../../fixtures/token_utils.js';
33
34
  import { setupSponsoredFPC } from '../../fixtures/utils.js';
@@ -249,11 +250,14 @@ export class ClientFlowsBenchmark {
249
250
 
250
251
  async applyDeployBananaToken() {
251
252
  this.logger.info('Applying banana token deployment');
252
- const {
253
- receipt: { contract: bananaCoin, instance: bananaCoinInstance },
254
- } = await BananaCoin.deploy(this.adminWallet, this.adminAddress, 'BC', 'BC', 18n).send({
253
+ const { contract: bananaCoin, instance: bananaCoinInstance } = await BananaCoin.deploy(
254
+ this.adminWallet,
255
+ this.adminAddress,
256
+ 'BC',
257
+ 'BC',
258
+ 18n,
259
+ ).send({
255
260
  from: this.adminAddress,
256
- wait: { returnReceipt: true },
257
261
  });
258
262
  this.logger.info(`BananaCoin deployed at ${bananaCoin.address}`);
259
263
  this.bananaCoin = bananaCoin;
@@ -262,11 +266,14 @@ export class ClientFlowsBenchmark {
262
266
 
263
267
  async applyDeployCandyBarToken() {
264
268
  this.logger.info('Applying candy bar token deployment');
265
- const {
266
- receipt: { contract: candyBarCoin, instance: candyBarCoinInstance },
267
- } = await TokenContract.deploy(this.adminWallet, this.adminAddress, 'CBC', 'CBC', 18n).send({
269
+ const { contract: candyBarCoin, instance: candyBarCoinInstance } = await TokenContract.deploy(
270
+ this.adminWallet,
271
+ this.adminAddress,
272
+ 'CBC',
273
+ 'CBC',
274
+ 18n,
275
+ ).send({
268
276
  from: this.adminAddress,
269
- wait: { returnReceipt: true },
270
277
  });
271
278
  this.logger.info(`CandyBarCoin deployed at ${candyBarCoin.address}`);
272
279
  this.candyBarCoin = candyBarCoin;
@@ -279,11 +286,12 @@ export class ClientFlowsBenchmark {
279
286
  expect((await this.context.wallet.getContractMetadata(feeJuiceContract.address)).isContractPublished).toBe(true);
280
287
 
281
288
  const bananaCoin = this.bananaCoin;
282
- const {
283
- receipt: { contract: bananaFPC, instance: bananaFPCInstance },
284
- } = await FPCContract.deploy(this.adminWallet, bananaCoin.address, this.adminAddress).send({
289
+ const { contract: bananaFPC, instance: bananaFPCInstance } = await FPCContract.deploy(
290
+ this.adminWallet,
291
+ bananaCoin.address,
292
+ this.adminAddress,
293
+ ).send({
285
294
  from: this.adminAddress,
286
- wait: { returnReceipt: true },
287
295
  });
288
296
 
289
297
  this.logger.info(`BananaPay deployed at ${bananaFPC.address}`);
@@ -333,7 +341,7 @@ export class ClientFlowsBenchmark {
333
341
  const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(benchysAddress);
334
342
  const behchysDeployMethod = await benchysAccountManager.getDeployMethod();
335
343
  await behchysDeployMethod.send({
336
- from: AztecAddress.ZERO,
344
+ from: NO_FROM,
337
345
  fee: { paymentMethod: new FeeJuicePaymentMethodWithClaim(benchysAddress, claim) },
338
346
  });
339
347
  // Register benchy on the user's Wallet, where we're going to be interacting from
@@ -347,20 +355,21 @@ export class ClientFlowsBenchmark {
347
355
 
348
356
  public async applyDeployAmm() {
349
357
  this.logger.info('Applying AMM deployment');
350
- const {
351
- receipt: { contract: liquidityToken, instance: liquidityTokenInstance },
352
- } = await TokenContract.deploy(this.adminWallet, this.adminAddress, 'LPT', 'LPT', 18n).send({
358
+ const { contract: liquidityToken, instance: liquidityTokenInstance } = await TokenContract.deploy(
359
+ this.adminWallet,
360
+ this.adminAddress,
361
+ 'LPT',
362
+ 'LPT',
363
+ 18n,
364
+ ).send({
353
365
  from: this.adminAddress,
354
- wait: { returnReceipt: true },
355
366
  });
356
- const {
357
- receipt: { contract: amm, instance: ammInstance },
358
- } = await AMMContract.deploy(
367
+ const { contract: amm, instance: ammInstance } = await AMMContract.deploy(
359
368
  this.adminWallet,
360
369
  this.bananaCoin.address,
361
370
  this.candyBarCoin.address,
362
371
  liquidityToken.address,
363
- ).send({ from: this.adminAddress, wait: { returnReceipt: true } });
372
+ ).send({ from: this.adminAddress });
364
373
  this.logger.info(`AMM deployed at ${amm.address}`);
365
374
  await liquidityToken.methods.set_minter(amm.address, true).send({ from: this.adminAddress });
366
375
  this.liquidityToken = liquidityToken;
@@ -377,8 +386,8 @@ export class ClientFlowsBenchmark {
377
386
  public async getPrivateFPCPaymentMethodForWallet(wallet: Wallet, sender: AztecAddress) {
378
387
  // The private fee paying method assembled on the app side requires knowledge of the maximum
379
388
  // fee the user is willing to pay
380
- const maxFeesPerGas = (await this.aztecNode.getCurrentMinFees()).mul(1.5);
381
- const gasSettings = GasSettings.default({ maxFeesPerGas });
389
+ const maxFeesPerGas = await getPaddedMaxFeesPerGas(this.aztecNode);
390
+ const gasSettings = GasSettings.fallback({ maxFeesPerGas });
382
391
  return new PrivateFeePaymentMethod(this.bananaFPC.address, sender, wallet, gasSettings);
383
392
  }
384
393
 
@@ -10,6 +10,7 @@ import { TokenBlacklistContract } from '@aztec/noir-contracts.js/TokenBlacklist'
10
10
  import { GenericProxyContract } from '@aztec/noir-test-contracts.js/GenericProxy';
11
11
  import { InvalidAccountContract } from '@aztec/noir-test-contracts.js/InvalidAccount';
12
12
  import type { SequencerClient } from '@aztec/sequencer-client';
13
+ import type { AztecNodeDebug } from '@aztec/stdlib/interfaces/client';
13
14
 
14
15
  import { jest } from '@jest/globals';
15
16
 
@@ -57,7 +58,7 @@ export class BlacklistTokenContractTest {
57
58
  authwitProxy!: GenericProxyContract;
58
59
  cheatCodes!: CheatCodes;
59
60
  sequencer!: SequencerClient;
60
- aztecNode!: AztecNode;
61
+ aztecNode!: AztecNode & AztecNodeDebug;
61
62
 
62
63
  adminAddress!: AztecAddress;
63
64
  otherAddress!: AztecAddress;
@@ -68,11 +69,7 @@ export class BlacklistTokenContractTest {
68
69
  }
69
70
 
70
71
  async crossTimestampOfChange() {
71
- await this.cheatCodes.warpL2TimeAtLeastBy(
72
- this.sequencer,
73
- this.aztecNode,
74
- BlacklistTokenContractTest.CHANGE_ROLES_DELAY,
75
- );
72
+ await this.cheatCodes.warpL2TimeAtLeastBy(this.aztecNode, BlacklistTokenContractTest.CHANGE_ROLES_DELAY);
76
73
  }
77
74
 
78
75
  /**
@@ -1,5 +1,7 @@
1
+ import type { InitialAccountData } from '@aztec/accounts/testing';
1
2
  import type { Archiver } from '@aztec/archiver';
2
3
  import { type AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
4
+ import { getAccountContractAddress } from '@aztec/aztec.js/account';
3
5
  import { getTimestampRangeForEpoch } from '@aztec/aztec.js/block';
4
6
  import { getContractInstanceFromInstantiationParams } from '@aztec/aztec.js/contracts';
5
7
  import { Fr } from '@aztec/aztec.js/fields';
@@ -28,11 +30,16 @@ import { type SequencerClient, type SequencerEvents, SequencerState } from '@azt
28
30
  import { type BlockParameter, EthAddress } from '@aztec/stdlib/block';
29
31
  import { type L1RollupConstants, getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
30
32
  import { tryStop } from '@aztec/stdlib/interfaces/server';
33
+ import type { SlashingProtectionDatabase } from '@aztec/validator-ha-signer/types';
31
34
 
32
35
  import { join } from 'path';
33
36
  import type { Hex } from 'viem';
34
37
  import { privateKeyToAccount } from 'viem/accounts';
35
38
 
39
+ import {
40
+ SCHNORR_HARDCODED_PRIVATE_KEY,
41
+ SchnorrHardcodedKeyAccountContract,
42
+ } from '../fixtures/schnorr_hardcoded_account_contract.js';
36
43
  import {
37
44
  type EndToEndContext,
38
45
  type SetupOptions,
@@ -40,6 +47,7 @@ import {
40
47
  getPrivateKeyFromIndex,
41
48
  setup,
42
49
  } from '../fixtures/utils.js';
50
+ import type { TestWallet } from '../test-wallet/test_wallet.js';
43
51
 
44
52
  export const WORLD_STATE_CHECKPOINT_HISTORY = 2;
45
53
  export const WORLD_STATE_BLOCK_CHECK_INTERVAL = 50;
@@ -50,6 +58,8 @@ export type EpochsTestOpts = Partial<SetupOptions> & {
50
58
  numberOfAccounts?: number;
51
59
  pxeOpts?: Partial<PXEConfig>;
52
60
  aztecSlotDurationInL1Slots?: number;
61
+ /** Skip creating/registering the hardcoded account during setup (for tests that handle accounts themselves). */
62
+ skipHardcodedAccount?: boolean;
53
63
  };
54
64
 
55
65
  export type TrackedSequencerEvent = {
@@ -120,10 +130,18 @@ export class EpochsTestContext {
120
130
  this.L1_BLOCK_TIME_IN_S = ethereumSlotDuration;
121
131
  this.L2_SLOT_DURATION_IN_S = aztecSlotDuration;
122
132
 
133
+ // When skipInitialSequencer is set, auto-create a hardcoded account funded via genesis.
134
+ // This avoids needing to deploy accounts on-chain (which would require a running sequencer).
135
+ const useHardcodedAccount = opts.skipInitialSequencer && !opts.skipHardcodedAccount;
136
+ let hardcodedAccountData: InitialAccountData | undefined;
137
+ if (useHardcodedAccount) {
138
+ hardcodedAccountData = await EpochsTestContext.getHardcodedAccountData(Fr.random(), Fr.random());
139
+ }
140
+
123
141
  // Set up system without any account nor protocol contracts
124
142
  // and with faster block times and shorter epochs.
125
143
  const context = await setup(
126
- opts.numberOfAccounts ?? 0,
144
+ useHardcodedAccount ? 0 : (opts.numberOfAccounts ?? 0),
127
145
  {
128
146
  automineL1Setup: true,
129
147
  checkIntervalMs: 50,
@@ -138,15 +156,13 @@ export class EpochsTestContext {
138
156
  realProofs: false,
139
157
  startProverNode: true,
140
158
  proverTestDelayMs: opts.proverTestDelayMs ?? 0,
141
- // We use numeric incremental prover ids for simplicity, but we can switch to
142
- // using the prover's eth address if the proverId is used for something in the rollup contract
143
- // Use numeric EthAddress for deterministic prover id
144
159
  proverId: EthAddress.fromNumber(1),
145
160
  worldStateCheckpointHistory: WORLD_STATE_CHECKPOINT_HISTORY,
146
161
  exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
147
- slasherFlavor: 'none',
162
+ slasherEnabled: false,
148
163
  l1PublishingTime,
149
164
  ...opts,
165
+ ...(hardcodedAccountData ? { initialFundedAccounts: [hardcodedAccountData], numberOfAccounts: 0 } : {}),
150
166
  },
151
167
  // Use checkpointed chain tip for PXE by default to avoid issues with blocks being dropped due to pruned anchor blocks.
152
168
  // Can be overridden via opts.pxeOpts.
@@ -154,6 +170,11 @@ export class EpochsTestContext {
154
170
  );
155
171
 
156
172
  this.context = context;
173
+
174
+ // Register the hardcoded account in PXE (local only, no on-chain deployment needed).
175
+ if (hardcodedAccountData) {
176
+ await this.registerHardcodedAccount(hardcodedAccountData);
177
+ }
157
178
  this.proverNodes = context.proverNode ? [context.proverNode] : [];
158
179
  this.nodes = context.aztecNode ? [context.aztecNode as AztecNodeService] : [];
159
180
  this.logger = context.logger;
@@ -196,6 +217,35 @@ export class EpochsTestContext {
196
217
  await this.context.teardown();
197
218
  }
198
219
 
220
+ /**
221
+ * Computes InitialAccountData for a SchnorrHardcodedKeyAccountContract.
222
+ * This contract has a hardcoded signing key and no initializer, so it can be used without
223
+ * on-chain deployment. Pass the returned data in `initialFundedAccounts` so the address
224
+ * gets funded with fee juice in genesis.
225
+ */
226
+ public static async getHardcodedAccountData(secret: Fr, salt: Fr): Promise<InitialAccountData> {
227
+ const contract = new SchnorrHardcodedKeyAccountContract();
228
+ const address = await getAccountContractAddress(contract, secret, salt);
229
+ const signingKey = SCHNORR_HARDCODED_PRIVATE_KEY;
230
+ return { secret, salt, signingKey, address };
231
+ }
232
+
233
+ /**
234
+ * Registers a SchnorrHardcodedKeyAccountContract in PXE. The account must have been funded
235
+ * at genesis (via getHardcodedAccountData). No on-chain deployment or block mining needed.
236
+ */
237
+ public async registerHardcodedAccount(accountData: InitialAccountData) {
238
+ const contract = new SchnorrHardcodedKeyAccountContract();
239
+ const wallet = this.context.wallet;
240
+ const accountManager = await (wallet as TestWallet).createAccount({
241
+ secret: accountData.secret,
242
+ salt: accountData.salt,
243
+ contract,
244
+ });
245
+ this.context.accounts = [accountManager.address];
246
+ return accountManager.address;
247
+ }
248
+
199
249
  public async createProverNode(opts: { dontStart?: boolean } & Partial<ProverNodeConfig> = {}) {
200
250
  this.logger.warn('Creating and syncing a simulated prover node...');
201
251
  const proverNodePrivateKey = this.getNextPrivateKey();
@@ -222,7 +272,7 @@ export class EpochsTestContext {
222
272
  },
223
273
  },
224
274
  {
225
- prefilledPublicData: this.context.prefilledPublicData ?? [],
275
+ genesis: this.context.genesis,
226
276
  dontStart: opts.dontStart,
227
277
  },
228
278
  ),
@@ -238,13 +288,21 @@ export class EpochsTestContext {
238
288
 
239
289
  public createValidatorNode(
240
290
  privateKeys: `0x${string}`[],
241
- opts: Partial<AztecNodeConfig> & { dontStartSequencer?: boolean } = {},
291
+ opts: Partial<AztecNodeConfig> & {
292
+ dontStartSequencer?: boolean;
293
+ slashingProtectionDb?: SlashingProtectionDatabase;
294
+ } = {},
242
295
  ) {
243
296
  this.logger.warn('Creating and syncing a validator node...');
244
297
  return this.createNode({ ...opts, disableValidator: false, validatorPrivateKeys: new SecretValue(privateKeys) });
245
298
  }
246
299
 
247
- private async createNode(opts: Partial<AztecNodeConfig> & { dontStartSequencer?: boolean } = {}) {
300
+ private async createNode(
301
+ opts: Partial<AztecNodeConfig> & {
302
+ dontStartSequencer?: boolean;
303
+ slashingProtectionDb?: SlashingProtectionDatabase;
304
+ } = {},
305
+ ) {
248
306
  const nodeIndex = this.nodes.length + 1;
249
307
  const actorPrefix = opts.disableValidator ? 'node' : 'validator';
250
308
  const { mockGossipSubNetwork } = this.context;
@@ -257,6 +315,7 @@ export class EpochsTestContext {
257
315
  ...resolvedConfig,
258
316
  dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
259
317
  validatorPrivateKeys: opts.validatorPrivateKeys ?? new SecretValue([]),
318
+ nodeId: resolvedConfig.nodeId || `${actorPrefix}-${nodeIndex}`,
260
319
  p2pEnabled,
261
320
  p2pIp,
262
321
  },
@@ -265,9 +324,10 @@ export class EpochsTestContext {
265
324
  p2pClientDeps: {
266
325
  p2pServiceFactory: mockGossipSubNetwork ? getMockPubSubP2PServiceFactory(mockGossipSubNetwork) : undefined,
267
326
  },
327
+ slashingProtectionDb: opts.slashingProtectionDb,
268
328
  },
269
329
  {
270
- prefilledPublicData: this.context.prefilledPublicData,
330
+ genesis: this.context.genesis,
271
331
  ...opts,
272
332
  },
273
333
  ),
@@ -23,7 +23,7 @@ import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
23
23
 
24
24
  import { getContract } from 'viem';
25
25
 
26
- import { MNEMONIC } from '../fixtures/fixtures.js';
26
+ import { MNEMONIC, getPaddedMaxFeesPerGas } from '../fixtures/fixtures.js';
27
27
  import {
28
28
  type EndToEndContext,
29
29
  type SetupOptions,
@@ -193,7 +193,9 @@ export class FeesTest {
193
193
  this.wallet = this.context.wallet;
194
194
  this.aztecNode = this.context.aztecNodeService;
195
195
  this.aztecNodeAdmin = this.context.aztecNodeService;
196
- this.gasSettings = GasSettings.default({ maxFeesPerGas: (await this.aztecNode.getCurrentMinFees()).mul(2) });
196
+ this.gasSettings = GasSettings.fallback({
197
+ maxFeesPerGas: await getPaddedMaxFeesPerGas(this.aztecNode),
198
+ });
197
199
  this.cheatCodes = this.context.cheatCodes;
198
200
  this.accounts = deployedAccounts.map(a => a.address);
199
201
  this.accounts.forEach((a, i) => this.logger.verbose(`Account ${i} address: ${a}`));
@@ -58,6 +58,7 @@ export class P2PInactivityTest {
58
58
  basePort: BOOT_NODE_UDP_PORT,
59
59
  startProverNode: true,
60
60
  initialConfig: {
61
+ anvilSlotsInAnEpoch: 4,
61
62
  proverNodeConfig: { proverNodeEpochProvingDelayMs: AZTEC_SLOT_DURATION * 1000 },
62
63
  aztecTargetCommitteeSize: COMMITTEE_SIZE,
63
64
  aztecSlotDuration: AZTEC_SLOT_DURATION,
@@ -66,7 +67,6 @@ export class P2PInactivityTest {
66
67
  listenAddress: '127.0.0.1',
67
68
  minTxsPerBlock: 0,
68
69
  aztecEpochDuration: EPOCH_DURATION,
69
- validatorReexecute: false,
70
70
  sentinelEnabled: true,
71
71
  slashingQuorum: SLASHING_QUORUM,
72
72
  slashingRoundSizeInEpochs: SLASHING_ROUND_SIZE_IN_EPOCHS,
@@ -108,7 +108,7 @@ export class P2PInactivityTest {
108
108
  this.test.bootstrapNodeEnr,
109
109
  NUM_NODES - this.inactiveNodeCount - Number(this.keepInitialNode),
110
110
  BOOT_NODE_UDP_PORT,
111
- this.test.prefilledPublicData,
111
+ this.test.genesis,
112
112
  this.dataDir,
113
113
  undefined,
114
114
  Number(this.keepInitialNode),
@@ -122,7 +122,7 @@ export class P2PInactivityTest {
122
122
  this.test.bootstrapNodeEnr,
123
123
  this.inactiveNodeCount,
124
124
  BOOT_NODE_UDP_PORT,
125
- this.test.prefilledPublicData,
125
+ this.test.genesis,
126
126
  this.dataDir,
127
127
  undefined,
128
128
  NUM_NODES - this.inactiveNodeCount,
@@ -1,14 +1,10 @@
1
- import type { InitialAccountData } from '@aztec/accounts/testing';
1
+ import { type InitialAccountData, generateSchnorrAccounts } from '@aztec/accounts/testing';
2
2
  import type { AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
3
+ import { getAccountContractAddress } from '@aztec/aztec.js/account';
3
4
  import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses';
4
5
  import { Fr } from '@aztec/aztec.js/fields';
5
6
  import { getL1ContractsConfigEnvVars } from '@aztec/ethereum/config';
6
- import {
7
- type EmpireSlashingProposerContract,
8
- GSEContract,
9
- RollupContract,
10
- type TallySlashingProposerContract,
11
- } from '@aztec/ethereum/contracts';
7
+ import { GSEContract, RollupContract, type SlashingProposerContract } from '@aztec/ethereum/contracts';
12
8
  import type { Operator } from '@aztec/ethereum/deploy-aztec-l1-contracts';
13
9
  import { deployL1Contract } from '@aztec/ethereum/deploy-l1-contract';
14
10
  import { MultiAdderArtifact } from '@aztec/ethereum/l1-artifacts';
@@ -24,9 +20,8 @@ import { SpamContract } from '@aztec/noir-test-contracts.js/Spam';
24
20
  import type { BootstrapNode } from '@aztec/p2p/bootstrap';
25
21
  import { createBootstrapNodeFromPrivateKey, getBootstrapNodeEnr } from '@aztec/p2p/test-helpers';
26
22
  import { tryStop } from '@aztec/stdlib/interfaces/server';
27
- import { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
28
23
  import { TopicType } from '@aztec/stdlib/p2p';
29
- import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
24
+ import type { GenesisData } from '@aztec/stdlib/world-state';
30
25
  import { ZkPassportProofParams } from '@aztec/stdlib/zkpassport';
31
26
  import { getGenesisValues } from '@aztec/world-state/testing';
32
27
 
@@ -34,10 +29,13 @@ import getPort from 'get-port';
34
29
  import { type GetContractReturnType, getAddress, getContract } from 'viem';
35
30
  import { privateKeyToAccount } from 'viem/accounts';
36
31
 
32
+ import {
33
+ SCHNORR_HARDCODED_PRIVATE_KEY,
34
+ SchnorrHardcodedKeyAccountContract,
35
+ } from '../fixtures/schnorr_hardcoded_account_contract.js';
37
36
  import {
38
37
  type EndToEndContext,
39
38
  type SetupOptions,
40
- deployAccounts,
41
39
  getPrivateKeyFromIndex,
42
40
  getSponsoredFPCAddress,
43
41
  setup,
@@ -76,8 +74,8 @@ export class P2PNetworkTest {
76
74
  public peerIdPrivateKeys: string[] = [];
77
75
  public validators: Operator[] = [];
78
76
 
79
- public deployedAccounts: InitialAccountData[] = [];
80
- public prefilledPublicData: PublicDataTreeLeaf[] = [];
77
+ public hardcodedAccountData!: InitialAccountData;
78
+ public genesis: GenesisData | undefined;
81
79
 
82
80
  // The re-execution test needs a wallet and a spam contract
83
81
  public wallet?: TestWallet;
@@ -124,12 +122,11 @@ export class P2PNetworkTest {
124
122
  initialValidatorConfig.aztecProofSubmissionEpochs ?? l1ContractsConfig.aztecProofSubmissionEpochs,
125
123
  slashingRoundSizeInEpochs:
126
124
  initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
127
- slasherFlavor: initialValidatorConfig.slasherFlavor ?? 'tally',
125
+ slasherEnabled: initialValidatorConfig.slasherEnabled ?? true,
128
126
  aztecTargetCommitteeSize: numberOfValidators,
129
127
  metricsPort: metricsPort,
130
128
  numberOfInitialFundedAccounts: 2,
131
129
  startProverNode,
132
- walletMinFeePadding: 2.0,
133
130
  };
134
131
 
135
132
  this.deployL1ContractsArgs = {
@@ -137,7 +134,7 @@ export class P2PNetworkTest {
137
134
  aztecEpochDuration: initialValidatorConfig.aztecEpochDuration ?? l1ContractsConfig.aztecEpochDuration,
138
135
  slashingRoundSizeInEpochs:
139
136
  initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
140
- slasherFlavor: initialValidatorConfig.slasherFlavor ?? 'tally',
137
+ slasherEnabled: initialValidatorConfig.slasherEnabled ?? true,
141
138
 
142
139
  ethereumSlotDuration: initialValidatorConfig.ethereumSlotDuration ?? l1ContractsConfig.ethereumSlotDuration,
143
140
  aztecSlotDuration: initialValidatorConfig.aztecSlotDuration ?? l1ContractsConfig.aztecSlotDuration,
@@ -192,10 +189,10 @@ export class P2PNetworkTest {
192
189
  }
193
190
 
194
191
  get fundedAccount() {
195
- if (!this.deployedAccounts[0]) {
196
- throw new Error('Call setupAccount to create a funded account.');
192
+ if (!this.hardcodedAccountData) {
193
+ throw new Error('Call setup to initialize the hardcoded account.');
197
194
  }
198
- return this.deployedAccounts[0];
195
+ return this.hardcodedAccountData;
199
196
  }
200
197
 
201
198
  async addBootstrapNode() {
@@ -303,17 +300,22 @@ export class P2PNetworkTest {
303
300
  await this._sendDummyTx(this.context.deployL1ContractsValues.l1Client);
304
301
  }
305
302
 
303
+ /** Points the wallet to a P2P-enabled node so transactions can propagate through the network. */
304
+ setupWalletOnNode(node: AztecNodeService) {
305
+ this.logger.info('Pointing wallet to a P2P-enabled node');
306
+ this.context.wallet.updateNode(node);
307
+ }
308
+
309
+ /** Registers the hardcoded account in PXE without on-chain deployment. No sequencer needed. */
306
310
  async setupAccount() {
307
- this.logger.info('Setting up account');
308
- const { deployedAccounts } = await deployAccounts(
309
- 1,
310
- this.logger,
311
- )({
312
- wallet: this.context.wallet,
313
- initialFundedAccounts: this.context.initialFundedAccounts,
311
+ this.logger.info('Registering hardcoded account (no deployment)');
312
+ const contract = new SchnorrHardcodedKeyAccountContract();
313
+ const accountManager = await (this.context.wallet as TestWallet).createAccount({
314
+ secret: this.hardcodedAccountData.secret,
315
+ salt: this.hardcodedAccountData.salt,
316
+ contract,
314
317
  });
315
- this.deployedAccounts = deployedAccounts;
316
- [{ address: this.defaultAccountAddress }] = deployedAccounts;
318
+ this.defaultAccountAddress = accountManager.address;
317
319
  this.wallet = this.context.wallet;
318
320
  }
319
321
 
@@ -354,13 +356,30 @@ export class P2PNetworkTest {
354
356
 
355
357
  async setup() {
356
358
  this.logger.info('Setting up subsystems from fresh');
359
+
360
+ // Pre-compute hardcoded account data so it gets funded in genesis.
361
+ const contract = new SchnorrHardcodedKeyAccountContract();
362
+ const secret = Fr.random();
363
+ const salt = Fr.random();
364
+ this.hardcodedAccountData = {
365
+ secret,
366
+ salt,
367
+ signingKey: SCHNORR_HARDCODED_PRIVATE_KEY,
368
+ address: await getAccountContractAddress(contract, secret, salt),
369
+ };
370
+
371
+ // Generate regular Schnorr accounts for tests that need deployable accounts (e.g. add_rollup).
372
+ const regularAccounts = await generateSchnorrAccounts(this.setupOptions.numberOfInitialFundedAccounts ?? 2);
373
+
357
374
  this.context = await setup(
358
375
  0,
359
376
  {
360
377
  ...this.setupOptions,
361
378
  fundSponsoredFPC: true,
362
379
  skipAccountDeployment: true,
363
- slasherFlavor: this.setupOptions.slasherFlavor ?? this.deployL1ContractsArgs.slasherFlavor ?? 'none',
380
+ skipInitialSequencer: true,
381
+ initialFundedAccounts: [...regularAccounts, this.hardcodedAccountData],
382
+ slasherEnabled: this.setupOptions.slasherEnabled ?? this.deployL1ContractsArgs.slasherEnabled ?? false,
364
383
  aztecTargetCommitteeSize: 0,
365
384
  l1ContractsArgs: this.deployL1ContractsArgs,
366
385
  },
@@ -372,8 +391,13 @@ export class P2PNetworkTest {
372
391
  const sponsoredFPCAddress = await getSponsoredFPCAddress();
373
392
  const initialFundedAccounts = [...this.context.initialFundedAccounts.map(a => a.address), sponsoredFPCAddress];
374
393
 
375
- const { prefilledPublicData } = await getGenesisValues(initialFundedAccounts);
376
- this.prefilledPublicData = prefilledPublicData;
394
+ const { genesis } = await getGenesisValues(
395
+ initialFundedAccounts,
396
+ undefined,
397
+ undefined,
398
+ this.context.genesis!.genesisTimestamp,
399
+ );
400
+ this.genesis = genesis;
377
401
 
378
402
  const rollupContract = RollupContract.getFromL1ContractsValues(this.context.deployL1ContractsValues);
379
403
  this.monitor = new ChainMonitor(rollupContract, this.context.dateProvider).start();
@@ -468,8 +492,7 @@ export class P2PNetworkTest {
468
492
  async getContracts(): Promise<{
469
493
  rollup: RollupContract;
470
494
  slasherContract: GetContractReturnType<typeof SlasherAbi, ViemClient>;
471
- slashingProposer: EmpireSlashingProposerContract | TallySlashingProposerContract | undefined;
472
- slashFactory: SlashFactoryContract;
495
+ slashingProposer: SlashingProposerContract | undefined;
473
496
  }> {
474
497
  if (!this.ctx.deployL1ContractsValues) {
475
498
  throw new Error('DeployAztecL1ContractsValues not set');
@@ -486,14 +509,9 @@ export class P2PNetworkTest {
486
509
  client: this.ctx.deployL1ContractsValues.l1Client,
487
510
  });
488
511
 
489
- // Get the actual slashing proposer from rollup (which handles both empire and tally)
512
+ // Get the actual slashing proposer from rollup
490
513
  const slashingProposer = await rollup.getSlashingProposer();
491
514
 
492
- const slashFactory = new SlashFactoryContract(
493
- this.ctx.deployL1ContractsValues.l1Client,
494
- getAddress(this.ctx.deployL1ContractsValues.l1ContractAddresses.slashFactoryAddress!.toString()),
495
- );
496
-
497
- return { rollup, slasherContract, slashingProposer, slashFactory };
515
+ return { rollup, slasherContract, slashingProposer };
498
516
  }
499
517
  }
@@ -91,7 +91,7 @@ export async function runReqrespTxTest(params: {
91
91
  t.bootstrapNodeEnr,
92
92
  NUM_VALIDATORS,
93
93
  BOOT_NODE_UDP_PORT,
94
- t.prefilledPublicData,
94
+ t.genesis,
95
95
  dataDir,
96
96
  shouldCollectMetrics(),
97
97
  );