@aztec/end-to-end 0.0.1-commit.934299a21 → 0.0.1-commit.949a33fd8

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 (149) 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 +21 -28
  5. package/dest/bench/utils.d.ts +1 -1
  6. package/dest/bench/utils.d.ts.map +1 -1
  7. package/dest/bench/utils.js +6 -3
  8. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +3 -2
  9. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  10. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +15 -15
  11. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +1 -1
  12. package/dest/e2e_epochs/epochs_test.d.ts +18 -1
  13. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  14. package/dest/e2e_epochs/epochs_test.js +61 -10
  15. package/dest/e2e_fees/fees_test.d.ts +1 -1
  16. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  17. package/dest/e2e_fees/fees_test.js +16 -9
  18. package/dest/e2e_nested_contract/nested_contract_test.d.ts +1 -1
  19. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  20. package/dest/e2e_nested_contract/nested_contract_test.js +4 -6
  21. package/dest/e2e_p2p/inactivity_slash_test.js +3 -3
  22. package/dest/e2e_p2p/p2p_network.d.ts +13 -11
  23. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  24. package/dest/e2e_p2p/p2p_network.js +65 -43
  25. package/dest/e2e_p2p/reqresp/utils.d.ts +1 -1
  26. package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
  27. package/dest/e2e_p2p/reqresp/utils.js +23 -7
  28. package/dest/e2e_p2p/shared.d.ts +25 -7
  29. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  30. package/dest/e2e_p2p/shared.js +69 -49
  31. package/dest/e2e_token_contract/token_contract_test.d.ts +1 -1
  32. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  33. package/dest/e2e_token_contract/token_contract_test.js +11 -11
  34. package/dest/fixtures/authwit_proxy.d.ts +3 -3
  35. package/dest/fixtures/authwit_proxy.d.ts.map +1 -1
  36. package/dest/fixtures/authwit_proxy.js +4 -0
  37. package/dest/fixtures/e2e_prover_test.d.ts +4 -3
  38. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  39. package/dest/fixtures/e2e_prover_test.js +11 -16
  40. package/dest/fixtures/fixtures.d.ts +12 -1
  41. package/dest/fixtures/fixtures.d.ts.map +1 -1
  42. package/dest/fixtures/fixtures.js +10 -0
  43. package/dest/fixtures/get_bb_config.d.ts +1 -1
  44. package/dest/fixtures/get_bb_config.d.ts.map +1 -1
  45. package/dest/fixtures/get_bb_config.js +5 -5
  46. package/dest/fixtures/ha_setup.d.ts +2 -2
  47. package/dest/fixtures/ha_setup.d.ts.map +1 -1
  48. package/dest/fixtures/ha_setup.js +1 -1
  49. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
  50. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
  51. package/dest/fixtures/schnorr_hardcoded_account_contract.js +39 -0
  52. package/dest/fixtures/setup.d.ts +24 -13
  53. package/dest/fixtures/setup.d.ts.map +1 -1
  54. package/dest/fixtures/setup.js +45 -25
  55. package/dest/fixtures/setup_p2p_test.d.ts +6 -6
  56. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  57. package/dest/fixtures/setup_p2p_test.js +8 -8
  58. package/dest/fixtures/token_utils.d.ts +1 -1
  59. package/dest/fixtures/token_utils.d.ts.map +1 -1
  60. package/dest/fixtures/token_utils.js +2 -5
  61. package/dest/forward-compatibility/wallet_rpc_client.d.ts +7 -0
  62. package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
  63. package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
  64. package/dest/forward-compatibility/wallet_service.d.ts +3 -0
  65. package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
  66. package/dest/forward-compatibility/wallet_service.js +109 -0
  67. package/dest/legacy-jest-resolver.d.cts +3 -0
  68. package/dest/legacy-jest-resolver.d.cts.map +1 -0
  69. package/dest/shared/cross_chain_test_harness.d.ts +1 -1
  70. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  71. package/dest/shared/cross_chain_test_harness.js +13 -13
  72. package/dest/shared/gas_portal_test_harness.js +3 -3
  73. package/dest/shared/jest_setup.js +32 -1
  74. package/dest/shared/submit-transactions.d.ts +1 -1
  75. package/dest/shared/submit-transactions.d.ts.map +1 -1
  76. package/dest/shared/submit-transactions.js +1 -1
  77. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  78. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  79. package/dest/shared/uniswap_l1_l2.js +14 -21
  80. package/dest/simulators/lending_simulator.d.ts +1 -1
  81. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  82. package/dest/simulators/lending_simulator.js +4 -4
  83. package/dest/simulators/token_simulator.d.ts +1 -1
  84. package/dest/simulators/token_simulator.d.ts.map +1 -1
  85. package/dest/simulators/token_simulator.js +2 -2
  86. package/dest/spartan/setup_test_wallets.d.ts +4 -2
  87. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  88. package/dest/spartan/setup_test_wallets.js +69 -38
  89. package/dest/spartan/tx_metrics.d.ts +1 -1
  90. package/dest/spartan/tx_metrics.d.ts.map +1 -1
  91. package/dest/spartan/tx_metrics.js +19 -3
  92. package/dest/spartan/utils/config.d.ts +7 -1
  93. package/dest/spartan/utils/config.d.ts.map +1 -1
  94. package/dest/spartan/utils/config.js +3 -1
  95. package/dest/spartan/utils/index.d.ts +3 -1
  96. package/dest/spartan/utils/index.d.ts.map +1 -1
  97. package/dest/spartan/utils/index.js +4 -0
  98. package/dest/spartan/utils/nodes.js +1 -1
  99. package/dest/spartan/utils/pod_logs.d.ts +25 -0
  100. package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
  101. package/dest/spartan/utils/pod_logs.js +74 -0
  102. package/dest/test-wallet/test_wallet.d.ts +24 -23
  103. package/dest/test-wallet/test_wallet.d.ts.map +1 -1
  104. package/dest/test-wallet/test_wallet.js +124 -83
  105. package/dest/test-wallet/worker_wallet.d.ts +4 -4
  106. package/dest/test-wallet/worker_wallet.d.ts.map +1 -1
  107. package/dest/test-wallet/worker_wallet_schema.d.ts +10 -5
  108. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -1
  109. package/package.json +43 -44
  110. package/src/bench/client_flows/client_flows_benchmark.ts +29 -12
  111. package/src/bench/utils.ts +7 -2
  112. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +21 -20
  113. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +1 -1
  114. package/src/e2e_epochs/epochs_test.ts +70 -9
  115. package/src/e2e_fees/fees_test.ts +17 -8
  116. package/src/e2e_nested_contract/nested_contract_test.ts +6 -4
  117. package/src/e2e_p2p/inactivity_slash_test.ts +3 -3
  118. package/src/e2e_p2p/p2p_network.ts +82 -60
  119. package/src/e2e_p2p/reqresp/utils.ts +29 -7
  120. package/src/e2e_p2p/shared.ts +88 -63
  121. package/src/e2e_token_contract/token_contract_test.ts +16 -8
  122. package/src/fixtures/authwit_proxy.ts +4 -0
  123. package/src/fixtures/e2e_prover_test.ts +19 -18
  124. package/src/fixtures/fixtures.ts +22 -0
  125. package/src/fixtures/get_bb_config.ts +7 -6
  126. package/src/fixtures/ha_setup.ts +4 -2
  127. package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
  128. package/src/fixtures/setup.ts +69 -33
  129. package/src/fixtures/setup_p2p_test.ts +9 -9
  130. package/src/fixtures/token_utils.ts +1 -2
  131. package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
  132. package/src/forward-compatibility/wallet_service.ts +104 -0
  133. package/src/guides/up_quick_start.sh +0 -2
  134. package/src/legacy-jest-resolver.cjs +135 -0
  135. package/src/shared/cross_chain_test_harness.ts +13 -9
  136. package/src/shared/gas_portal_test_harness.ts +1 -2
  137. package/src/shared/jest_setup.ts +36 -1
  138. package/src/shared/submit-transactions.ts +1 -4
  139. package/src/shared/uniswap_l1_l2.ts +35 -32
  140. package/src/simulators/lending_simulator.ts +8 -4
  141. package/src/simulators/token_simulator.ts +6 -2
  142. package/src/spartan/setup_test_wallets.ts +90 -35
  143. package/src/spartan/tx_metrics.ts +17 -5
  144. package/src/spartan/utils/config.ts +2 -0
  145. package/src/spartan/utils/index.ts +6 -0
  146. package/src/spartan/utils/nodes.ts +1 -1
  147. package/src/spartan/utils/pod_logs.ts +99 -0
  148. package/src/test-wallet/test_wallet.ts +152 -101
  149. package/src/test-wallet/worker_wallet.ts +3 -2
@@ -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;
@@ -181,6 +202,7 @@ export class EpochsTestContext {
181
202
  ethereumSlotDuration,
182
203
  proofSubmissionEpochs: Number(await this.rollup.getProofSubmissionEpochs()),
183
204
  targetCommitteeSize: await this.rollup.getTargetCommitteeSize(),
205
+ rollupManaLimit: Number(await this.rollup.getManaLimit()),
184
206
  };
185
207
 
186
208
  this.logger.info(
@@ -195,6 +217,35 @@ export class EpochsTestContext {
195
217
  await this.context.teardown();
196
218
  }
197
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
+
198
249
  public async createProverNode(opts: { dontStart?: boolean } & Partial<ProverNodeConfig> = {}) {
199
250
  this.logger.warn('Creating and syncing a simulated prover node...');
200
251
  const proverNodePrivateKey = this.getNextPrivateKey();
@@ -221,7 +272,7 @@ export class EpochsTestContext {
221
272
  },
222
273
  },
223
274
  {
224
- prefilledPublicData: this.context.prefilledPublicData ?? [],
275
+ genesis: this.context.genesis,
225
276
  dontStart: opts.dontStart,
226
277
  },
227
278
  ),
@@ -237,13 +288,21 @@ export class EpochsTestContext {
237
288
 
238
289
  public createValidatorNode(
239
290
  privateKeys: `0x${string}`[],
240
- opts: Partial<AztecNodeConfig> & { dontStartSequencer?: boolean } = {},
291
+ opts: Partial<AztecNodeConfig> & {
292
+ dontStartSequencer?: boolean;
293
+ slashingProtectionDb?: SlashingProtectionDatabase;
294
+ } = {},
241
295
  ) {
242
296
  this.logger.warn('Creating and syncing a validator node...');
243
297
  return this.createNode({ ...opts, disableValidator: false, validatorPrivateKeys: new SecretValue(privateKeys) });
244
298
  }
245
299
 
246
- private async createNode(opts: Partial<AztecNodeConfig> & { dontStartSequencer?: boolean } = {}) {
300
+ private async createNode(
301
+ opts: Partial<AztecNodeConfig> & {
302
+ dontStartSequencer?: boolean;
303
+ slashingProtectionDb?: SlashingProtectionDatabase;
304
+ } = {},
305
+ ) {
247
306
  const nodeIndex = this.nodes.length + 1;
248
307
  const actorPrefix = opts.disableValidator ? 'node' : 'validator';
249
308
  const { mockGossipSubNetwork } = this.context;
@@ -256,6 +315,7 @@ export class EpochsTestContext {
256
315
  ...resolvedConfig,
257
316
  dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
258
317
  validatorPrivateKeys: opts.validatorPrivateKeys ?? new SecretValue([]),
318
+ nodeId: resolvedConfig.nodeId || `${actorPrefix}-${nodeIndex}`,
259
319
  p2pEnabled,
260
320
  p2pIp,
261
321
  },
@@ -264,9 +324,10 @@ export class EpochsTestContext {
264
324
  p2pClientDeps: {
265
325
  p2pServiceFactory: mockGossipSubNetwork ? getMockPubSubP2PServiceFactory(mockGossipSubNetwork) : undefined,
266
326
  },
327
+ slashingProtectionDb: opts.slashingProtectionDb,
267
328
  },
268
329
  {
269
- prefilledPublicData: this.context.prefilledPublicData,
330
+ genesis: this.context.genesis,
270
331
  ...opts,
271
332
  },
272
333
  ),
@@ -1,7 +1,7 @@
1
1
  import type { 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
- import { CheatCodes } from '@aztec/aztec/testing';
4
+ import { CheatCodes, getTokenAllowedSetupFunctions } from '@aztec/aztec/testing';
5
5
  import { createExtendedL1Client } from '@aztec/ethereum/client';
6
6
  import { RollupContract } from '@aztec/ethereum/contracts';
7
7
  import type { DeployAztecL1ContractsArgs } from '@aztec/ethereum/deploy-aztec-l1-contracts';
@@ -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,
@@ -104,12 +104,15 @@ export class FeesTest {
104
104
 
105
105
  async setup() {
106
106
  this.logger.verbose('Setting up fresh context...');
107
+ // Token allowlist entries are test-only: FPC-based fee payment with custom tokens won't work on mainnet alpha.
108
+ const tokenAllowList = await getTokenAllowedSetupFunctions();
107
109
  this.context = await setup(0, {
108
110
  startProverNode: true,
109
111
  ...this.setupOptions,
110
112
  fundSponsoredFPC: true,
111
113
  skipAccountDeployment: true,
112
114
  l1ContractsArgs: { ...this.setupOptions },
115
+ txPublicSetupAllowListExtend: [...(this.setupOptions.txPublicSetupAllowListExtend ?? []), ...tokenAllowList],
113
116
  });
114
117
 
115
118
  this.rollupContract = RollupContract.getFromConfig(this.context.config);
@@ -131,7 +134,7 @@ export class FeesTest {
131
134
 
132
135
  async catchUpProvenChain() {
133
136
  const bn = await this.aztecNode.getBlockNumber();
134
- while ((await this.aztecNode.getProvenBlockNumber()) < bn) {
137
+ while ((await this.aztecNode.getBlockNumber('proven')) < bn) {
135
138
  await sleep(1000);
136
139
  }
137
140
  }
@@ -157,11 +160,15 @@ export class FeesTest {
157
160
 
158
161
  /** Alice mints bananaCoin tokens privately to the target address and redeems them. */
159
162
  async mintPrivateBananas(amount: bigint, address: AztecAddress) {
160
- const balanceBefore = await this.bananaCoin.methods.balance_of_private(address).simulate({ from: address });
163
+ const { result: balanceBefore } = await this.bananaCoin.methods
164
+ .balance_of_private(address)
165
+ .simulate({ from: address });
161
166
 
162
167
  await mintTokensToPrivate(this.bananaCoin, this.aliceAddress, address, amount);
163
168
 
164
- const balanceAfter = await this.bananaCoin.methods.balance_of_private(address).simulate({ from: address });
169
+ const { result: balanceAfter } = await this.bananaCoin.methods
170
+ .balance_of_private(address)
171
+ .simulate({ from: address });
165
172
  expect(balanceAfter).toEqual(balanceBefore + amount);
166
173
  }
167
174
 
@@ -186,7 +193,9 @@ export class FeesTest {
186
193
  this.wallet = this.context.wallet;
187
194
  this.aztecNode = this.context.aztecNodeService;
188
195
  this.aztecNodeAdmin = this.context.aztecNodeService;
189
- this.gasSettings = GasSettings.default({ maxFeesPerGas: (await this.aztecNode.getCurrentMinFees()).mul(2) });
196
+ this.gasSettings = GasSettings.fallback({
197
+ maxFeesPerGas: await getPaddedMaxFeesPerGas(this.aztecNode),
198
+ });
190
199
  this.cheatCodes = this.context.cheatCodes;
191
200
  this.accounts = deployedAccounts.map(a => a.address);
192
201
  this.accounts.forEach((a, i) => this.logger.verbose(`Account ${i} address: ${a}`));
@@ -223,7 +232,7 @@ export class FeesTest {
223
232
  async applyDeployBananaToken() {
224
233
  this.logger.info('Applying deploy banana token setup');
225
234
 
226
- const bananaCoin = await BananaCoin.deploy(this.wallet, this.aliceAddress, 'BC', 'BC', 18n).send({
235
+ const { contract: bananaCoin } = await BananaCoin.deploy(this.wallet, this.aliceAddress, 'BC', 'BC', 18n).send({
227
236
  from: this.aliceAddress,
228
237
  });
229
238
  this.logger.info(`BananaCoin deployed at ${bananaCoin.address}`);
@@ -244,7 +253,7 @@ export class FeesTest {
244
253
  expect((await this.wallet.getContractMetadata(feeJuiceContract.address)).isContractPublished).toBe(true);
245
254
 
246
255
  const bananaCoin = this.bananaCoin;
247
- const bananaFPC = await FPCContract.deploy(this.wallet, bananaCoin.address, this.fpcAdmin).send({
256
+ const { contract: bananaFPC } = await FPCContract.deploy(this.wallet, bananaCoin.address, this.fpcAdmin).send({
248
257
  from: this.aliceAddress,
249
258
  });
250
259
 
@@ -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
  }
@@ -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,
@@ -59,7 +57,7 @@ export const WAIT_FOR_TX_TIMEOUT = l1ContractsConfig.aztecSlotDuration * 3;
59
57
  export const SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES = {
60
58
  aztecSlotDuration: 12,
61
59
  ethereumSlotDuration: 4,
62
- aztecProofSubmissionWindow: 640,
60
+ aztecProofSubmissionEpochs: 640,
63
61
  };
64
62
 
65
63
  export class P2PNetworkTest {
@@ -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
 
@@ -323,8 +325,9 @@ export class P2PNetworkTest {
323
325
  throw new Error('Call setupAccount before deploying spam contract');
324
326
  }
325
327
 
326
- const spamContract = await SpamContract.deploy(this.wallet).send({ from: this.defaultAccountAddress! });
327
- this.spamContract = spamContract;
328
+ ({ contract: this.spamContract } = await SpamContract.deploy(this.wallet).send({
329
+ from: this.defaultAccountAddress!,
330
+ }));
328
331
  }
329
332
 
330
333
  async removeInitialNode() {
@@ -353,13 +356,30 @@ export class P2PNetworkTest {
353
356
 
354
357
  async setup() {
355
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
+
356
374
  this.context = await setup(
357
375
  0,
358
376
  {
359
377
  ...this.setupOptions,
360
378
  fundSponsoredFPC: true,
361
379
  skipAccountDeployment: true,
362
- 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,
363
383
  aztecTargetCommitteeSize: 0,
364
384
  l1ContractsArgs: this.deployL1ContractsArgs,
365
385
  },
@@ -371,8 +391,13 @@ export class P2PNetworkTest {
371
391
  const sponsoredFPCAddress = await getSponsoredFPCAddress();
372
392
  const initialFundedAccounts = [...this.context.initialFundedAccounts.map(a => a.address), sponsoredFPCAddress];
373
393
 
374
- const { prefilledPublicData } = await getGenesisValues(initialFundedAccounts);
375
- this.prefilledPublicData = prefilledPublicData;
394
+ const { genesis } = await getGenesisValues(
395
+ initialFundedAccounts,
396
+ undefined,
397
+ undefined,
398
+ this.context.genesis!.genesisTimestamp,
399
+ );
400
+ this.genesis = genesis;
376
401
 
377
402
  const rollupContract = RollupContract.getFromL1ContractsValues(this.context.deployL1ContractsValues);
378
403
  this.monitor = new ChainMonitor(rollupContract, this.context.dateProvider).start();
@@ -407,6 +432,7 @@ export class P2PNetworkTest {
407
432
  expectedNodeCount?: number,
408
433
  timeoutSeconds = 30,
409
434
  checkIntervalSeconds = 0.1,
435
+ topics: TopicType[] = [TopicType.tx],
410
436
  ) {
411
437
  const nodeCount = expectedNodeCount ?? nodes.length;
412
438
  const minPeerCount = nodeCount - 1;
@@ -433,26 +459,28 @@ export class P2PNetworkTest {
433
459
 
434
460
  this.logger.warn('All nodes connected to P2P mesh');
435
461
 
436
- // Wait for GossipSub mesh to form for the tx topic.
462
+ // Wait for GossipSub mesh to form for all specified topics.
437
463
  // We only require at least 1 mesh peer per node because GossipSub
438
464
  // stops grafting once it reaches Dlo peers and won't fill the mesh to all available peers.
439
- this.logger.warn('Waiting for GossipSub mesh to form for tx topic...');
440
- await Promise.all(
441
- nodes.map(async (node, index) => {
442
- const p2p = node.getP2P();
443
- await retryUntil(
444
- async () => {
445
- const meshPeers = await p2p.getGossipMeshPeerCount(TopicType.tx);
446
- this.logger.debug(`Node ${index} has ${meshPeers} gossip mesh peers for tx topic`);
447
- return meshPeers >= 1 ? true : undefined;
448
- },
449
- `Node ${index} to have gossip mesh peers for tx topic`,
450
- timeoutSeconds,
451
- checkIntervalSeconds,
452
- );
453
- }),
454
- );
455
- this.logger.warn('All nodes have gossip mesh peers for tx topic');
465
+ for (const topic of topics) {
466
+ this.logger.warn(`Waiting for GossipSub mesh to form for ${topic} topic...`);
467
+ await Promise.all(
468
+ nodes.map(async (node, index) => {
469
+ const p2p = node.getP2P();
470
+ await retryUntil(
471
+ async () => {
472
+ const meshPeers = await p2p.getGossipMeshPeerCount(topic);
473
+ this.logger.debug(`Node ${index} has ${meshPeers} gossip mesh peers for ${topic} topic`);
474
+ return meshPeers >= 1 ? true : undefined;
475
+ },
476
+ `Node ${index} to have gossip mesh peers for ${topic} topic`,
477
+ timeoutSeconds,
478
+ checkIntervalSeconds,
479
+ );
480
+ }),
481
+ );
482
+ this.logger.warn(`All nodes have gossip mesh peers for ${topic} topic`);
483
+ }
456
484
  }
457
485
 
458
486
  async teardown() {
@@ -464,8 +492,7 @@ export class P2PNetworkTest {
464
492
  async getContracts(): Promise<{
465
493
  rollup: RollupContract;
466
494
  slasherContract: GetContractReturnType<typeof SlasherAbi, ViemClient>;
467
- slashingProposer: EmpireSlashingProposerContract | TallySlashingProposerContract | undefined;
468
- slashFactory: SlashFactoryContract;
495
+ slashingProposer: SlashingProposerContract | undefined;
469
496
  }> {
470
497
  if (!this.ctx.deployL1ContractsValues) {
471
498
  throw new Error('DeployAztecL1ContractsValues not set');
@@ -482,14 +509,9 @@ export class P2PNetworkTest {
482
509
  client: this.ctx.deployL1ContractsValues.l1Client,
483
510
  });
484
511
 
485
- // Get the actual slashing proposer from rollup (which handles both empire and tally)
512
+ // Get the actual slashing proposer from rollup
486
513
  const slashingProposer = await rollup.getSlashingProposer();
487
514
 
488
- const slashFactory = new SlashFactoryContract(
489
- this.ctx.deployL1ContractsValues.l1Client,
490
- getAddress(this.ctx.deployL1ContractsValues.l1ContractAddresses.slashFactoryAddress!.toString()),
491
- );
492
-
493
- return { rollup, slasherContract, slashingProposer, slashFactory };
515
+ return { rollup, slasherContract, slashingProposer };
494
516
  }
495
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
  );
@@ -149,6 +149,13 @@ export async function runReqrespTxTest(params: {
149
149
  const submittedTxs = await Promise.all(
150
150
  txBatches.map(async (batch, batchIndex) => {
151
151
  const proposerNode = nodes[proposerIndexes[batchIndex]];
152
+ for (const tx of batch) {
153
+ t.logger.info(`Tx ${tx.getTxHash().toString()} base64: ${tx.toBuffer().toString('base64')}`);
154
+ }
155
+ const txHashes = batch.map(tx => tx.getTxHash().toString());
156
+ t.logger.info(
157
+ `Sending batch ${batchIndex} to proposer ${getNodePort(proposerIndexes[batchIndex])}: ${txHashes.join(', ')}`,
158
+ );
152
159
  await Promise.all(
153
160
  batch.map(async tx => {
154
161
  try {
@@ -163,6 +170,12 @@ export async function runReqrespTxTest(params: {
163
170
  }),
164
171
  );
165
172
 
173
+ // Log pool state per node after sending
174
+ for (let i = 0; i < NUM_VALIDATORS; i++) {
175
+ const count = await nodes[i].getPendingTxCount();
176
+ t.logger.info(`Node ${getNodePort(i)} pool has ${count} pending txs`);
177
+ }
178
+
166
179
  t.logger.info('Waiting for all transactions to be mined');
167
180
  await Promise.all(
168
181
  submittedTxs.flatMap((batch, batchIndex) =>
@@ -178,20 +191,29 @@ export async function runReqrespTxTest(params: {
178
191
 
179
192
  // Assert that multiple blocks were built for at least one slot
180
193
  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);
194
+ // Wait for L1 checkpoint sync, which may lag behind P2P block propagation.
195
+ const checkpoints = await retryUntil(
196
+ async () => {
197
+ const cps = await nodes[0].getCheckpoints(CheckpointNumber(1), 50, { includeBlocks: true });
198
+ return cps.length > 0 && cps.some(cp => (cp.blocks?.length ?? 0) >= 2) ? cps : undefined;
199
+ },
200
+ 'waiting for multi-block checkpoint to sync from L1',
201
+ 30,
202
+ 1,
203
+ );
183
204
 
184
205
  let mbpsFound = false;
185
- let expectedBlockNumber = checkpoints[0].checkpoint.blocks[0].number;
206
+ let expectedBlockNumber = checkpoints[0].blocks![0].number;
186
207
 
187
208
  for (const published of checkpoints) {
188
- const blockCount = published.checkpoint.blocks.length;
209
+ const blocks = published.blocks!;
210
+ const blockCount = blocks.length;
189
211
  mbpsFound = mbpsFound || blockCount >= 2;
190
212
 
191
213
  for (let i = 0; i < blockCount; i++) {
192
- const block = published.checkpoint.blocks[i];
214
+ const block = blocks[i];
193
215
  expect(block.indexWithinCheckpoint).toBe(i);
194
- expect(block.checkpointNumber).toBe(published.checkpoint.number);
216
+ expect(block.checkpointNumber).toBe(published.number);
195
217
  expect(block.number).toBe(expectedBlockNumber);
196
218
  expectedBlockNumber++;
197
219
  }