@aztec/end-to-end 0.0.1-commit.6b113946b → 0.0.1-commit.6bd18f1aa

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 (36) hide show
  1. package/dest/bench/client_flows/client_flows_benchmark.d.ts +1 -1
  2. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  3. package/dest/bench/client_flows/client_flows_benchmark.js +12 -27
  4. package/dest/e2e_p2p/inactivity_slash_test.js +1 -1
  5. package/dest/fixtures/e2e_prover_test.d.ts +4 -3
  6. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  7. package/dest/fixtures/e2e_prover_test.js +5 -10
  8. package/dest/fixtures/get_bb_config.d.ts +1 -1
  9. package/dest/fixtures/get_bb_config.d.ts.map +1 -1
  10. package/dest/fixtures/get_bb_config.js +5 -5
  11. package/dest/fixtures/setup.d.ts +1 -1
  12. package/dest/fixtures/setup.d.ts.map +1 -1
  13. package/dest/fixtures/setup.js +12 -9
  14. package/dest/fixtures/token_utils.d.ts +1 -1
  15. package/dest/fixtures/token_utils.d.ts.map +1 -1
  16. package/dest/fixtures/token_utils.js +2 -5
  17. package/dest/simulators/lending_simulator.d.ts +1 -1
  18. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  19. package/dest/simulators/lending_simulator.js +2 -2
  20. package/dest/spartan/setup_test_wallets.d.ts +1 -1
  21. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  22. package/dest/spartan/setup_test_wallets.js +60 -10
  23. package/dest/test-wallet/test_wallet.d.ts +1 -1
  24. package/dest/test-wallet/test_wallet.d.ts.map +1 -1
  25. package/dest/test-wallet/test_wallet.js +33 -34
  26. package/dest/test-wallet/worker_wallet_schema.d.ts +2 -2
  27. package/package.json +39 -39
  28. package/src/bench/client_flows/client_flows_benchmark.ts +30 -21
  29. package/src/e2e_p2p/inactivity_slash_test.ts +1 -1
  30. package/src/fixtures/e2e_prover_test.ts +7 -15
  31. package/src/fixtures/get_bb_config.ts +7 -6
  32. package/src/fixtures/setup.ts +11 -8
  33. package/src/fixtures/token_utils.ts +1 -4
  34. package/src/simulators/lending_simulator.ts +4 -2
  35. package/src/spartan/setup_test_wallets.ts +61 -11
  36. package/src/test-wallet/test_wallet.ts +44 -37
@@ -1,6 +1,7 @@
1
1
  import { SchnorrAccountContractArtifact } from '@aztec/accounts/schnorr';
2
2
  import { type InitialAccountData, generateSchnorrAccounts } from '@aztec/accounts/testing';
3
3
  import { type AztecNodeConfig, AztecNodeService, getConfigEnvVars } from '@aztec/aztec-node';
4
+ import { NO_FROM } from '@aztec/aztec.js/account';
4
5
  import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses';
5
6
  import {
6
7
  BatchCall,
@@ -302,6 +303,8 @@ export async function setup(
302
303
  config.dataDirectory = directoryToCleanup;
303
304
  }
304
305
 
306
+ const dateProvider = new TestDateProvider();
307
+
305
308
  if (!config.l1RpcUrls?.length) {
306
309
  if (!isAnvilTestChain(chain.id)) {
307
310
  throw new Error(`No ETHEREUM_HOSTS set but non anvil chain requested`);
@@ -311,6 +314,7 @@ export async function setup(
311
314
  accounts: opts.anvilAccounts,
312
315
  port: opts.anvilPort ?? (process.env.ANVIL_PORT ? parseInt(process.env.ANVIL_PORT) : undefined),
313
316
  slotsInAnEpoch: opts.anvilSlotsInAnEpoch,
317
+ dateProvider,
314
318
  });
315
319
  anvil = res.anvil;
316
320
  config.l1RpcUrls = [res.rpcUrl];
@@ -322,8 +326,6 @@ export async function setup(
322
326
  logger.info(`Logging metrics to ${filename}`);
323
327
  setupMetricsLogger(filename);
324
328
  }
325
-
326
- const dateProvider = new TestDateProvider();
327
329
  const ethCheatCodes = new EthCheatCodesWithState(config.l1RpcUrls, dateProvider);
328
330
 
329
331
  if (opts.stateLoad) {
@@ -419,11 +421,12 @@ export async function setup(
419
421
  await ethCheatCodes.setIntervalMining(config.ethereumSlotDuration);
420
422
  }
421
423
 
422
- // Always sync dateProvider to L1 time after deploying L1 contracts, regardless of mining mode.
423
- // In compose mode, L1 time may have drifted ahead of system time due to the local-network watcher
424
- // warping time forward on each filled slot. Without this sync, the sequencer computes the wrong
425
- // slot from its dateProvider and cannot propose blocks.
426
- dateProvider.setTime((await ethCheatCodes.timestamp()) * 1000);
424
+ // In compose mode (no local anvil), sync dateProvider to L1 time since it may have drifted
425
+ // ahead of system time due to the local-network watcher warping time forward on each filled slot.
426
+ // When running with a local anvil, the dateProvider is kept in sync via the stdout listener.
427
+ if (!anvil) {
428
+ dateProvider.setTime((await ethCheatCodes.lastBlockTimestamp()) * 1000);
429
+ }
427
430
 
428
431
  if (opts.l2StartTime) {
429
432
  await ethCheatCodes.warp(opts.l2StartTime, { resetBlockInterval: true });
@@ -847,7 +850,7 @@ export const deployAccounts =
847
850
  );
848
851
  const deployMethod = await accountManager.getDeployMethod();
849
852
  await deployMethod.send({
850
- from: AztecAddress.ZERO,
853
+ from: NO_FROM,
851
854
  skipClassPublication: i !== 0, // Publish the contract class at most once.
852
855
  });
853
856
  }
@@ -6,11 +6,8 @@ import { TokenContract } from '@aztec/noir-contracts.js/Token';
6
6
 
7
7
  export async function deployToken(wallet: Wallet, admin: AztecAddress, initialAdminBalance: bigint, logger: Logger) {
8
8
  logger.info(`Deploying Token contract...`);
9
- const {
10
- receipt: { contract, instance },
11
- } = await TokenContract.deploy(wallet, admin, 'TokenName', 'TokenSymbol', 18).send({
9
+ const { contract, instance } = await TokenContract.deploy(wallet, admin, 'TokenName', 'TokenSymbol', 18).send({
12
10
  from: admin,
13
- wait: { returnReceipt: true },
14
11
  });
15
12
 
16
13
  if (initialAdminBalance > 0n) {
@@ -94,7 +94,9 @@ export class LendingSimulator {
94
94
 
95
95
  async prepare() {
96
96
  this.accumulator = BASE;
97
- const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.timestamp()) + BigInt(this.ethereumSlotDuration));
97
+ const slot = await this.rollup.getSlotAt(
98
+ BigInt(await this.cc.eth.lastBlockTimestamp()) + BigInt(this.ethereumSlotDuration),
99
+ );
98
100
  this.time = Number(await this.rollup.getTimestampForSlot(slot));
99
101
  }
100
102
 
@@ -103,7 +105,7 @@ export class LendingSimulator {
103
105
  return;
104
106
  }
105
107
 
106
- const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.timestamp()));
108
+ const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.lastBlockTimestamp()));
107
109
  const targetSlot = SlotNumber(slot + diff);
108
110
  const ts = Number(await this.rollup.getTimestampForSlot(targetSlot));
109
111
  const timeDiff = ts - this.time;
@@ -1,4 +1,5 @@
1
1
  import { generateSchnorrAccounts } from '@aztec/accounts/testing';
2
+ import { NO_FROM } from '@aztec/aztec.js/account';
2
3
  import { AztecAddress } from '@aztec/aztec.js/addresses';
3
4
  import { NO_WAIT } from '@aztec/aztec.js/contracts';
4
5
  import { L1FeeJuicePortalManager } from '@aztec/aztec.js/ethereum';
@@ -10,7 +11,7 @@ import type { Wallet } from '@aztec/aztec.js/wallet';
10
11
  import { createEthereumChain } from '@aztec/ethereum/chain';
11
12
  import { createExtendedL1Client } from '@aztec/ethereum/client';
12
13
  import type { Logger } from '@aztec/foundation/log';
13
- import { retryUntil } from '@aztec/foundation/retry';
14
+ import { makeBackoff, retry, retryUntil } from '@aztec/foundation/retry';
14
15
  import { TokenContract } from '@aztec/noir-contracts.js/Token';
15
16
  import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
16
17
  import { registerInitialLocalNetworkAccountsInWallet } from '@aztec/wallets/testing';
@@ -89,7 +90,7 @@ export async function deploySponsoredTestAccountsWithTokens(
89
90
  const paymentMethod = new SponsoredFeePaymentMethod(await getSponsoredFPCAddress());
90
91
  const recipientDeployMethod = await recipientAccount.getDeployMethod();
91
92
  await recipientDeployMethod.send({
92
- from: AztecAddress.ZERO,
93
+ from: NO_FROM,
93
94
  fee: { paymentMethod },
94
95
  wait: { timeout: 2400 },
95
96
  });
@@ -97,7 +98,7 @@ export async function deploySponsoredTestAccountsWithTokens(
97
98
  fundedAccounts.map(async a => {
98
99
  const deployMethod = await a.getDeployMethod();
99
100
  await deployMethod.send({
100
- from: AztecAddress.ZERO,
101
+ from: NO_FROM,
101
102
  fee: { paymentMethod },
102
103
  wait: { timeout: 2400 },
103
104
  }); // increase timeout on purpose in order to account for two empty epochs
@@ -138,15 +139,15 @@ async function deployAccountWithDiagnostics(
138
139
  ): Promise<void> {
139
140
  const deployMethod = await account.getDeployMethod();
140
141
  let txHash;
142
+ let gasSettings: any;
141
143
  try {
142
- let gasSettings;
143
144
  if (estimateGas) {
144
- const sim = await deployMethod.simulate({ from: AztecAddress.ZERO, fee: { paymentMethod } });
145
+ const sim = await deployMethod.simulate({ from: NO_FROM, fee: { paymentMethod } });
145
146
  gasSettings = sim.estimatedGas;
146
147
  logger.info(`${accountLabel} estimated gas: DA=${gasSettings.gasLimits.daGas} L2=${gasSettings.gasLimits.l2Gas}`);
147
148
  }
148
149
  const deployResult = await deployMethod.send({
149
- from: AztecAddress.ZERO,
150
+ from: NO_FROM,
150
151
  fee: { paymentMethod, gasSettings },
151
152
  wait: NO_WAIT,
152
153
  });
@@ -169,6 +170,51 @@ async function deployAccountWithDiagnostics(
169
170
  });
170
171
  throw error;
171
172
  }
173
+
174
+ // Track the tx hash across retries so we don't re-send when the previous tx is still pending.
175
+ let sentTxHash: { txHash: any } | undefined;
176
+
177
+ await retry(
178
+ async () => {
179
+ // Check if already deployed (handles case where previous attempt succeeded but waitForTx timed out)
180
+ const existing = await aztecNode.getContract(account.address);
181
+ if (existing) {
182
+ logger.info(`${accountLabel} already deployed at ${account.address}, skipping`);
183
+ return;
184
+ }
185
+
186
+ // If we already sent a tx, check if it was dropped before deciding to re-send.
187
+ if (sentTxHash) {
188
+ const prevReceipt = await aztecNode.getTxReceipt(sentTxHash.txHash);
189
+ if (prevReceipt.isDropped()) {
190
+ logger.info(`${accountLabel} previous tx ${sentTxHash.txHash} was dropped, re-sending`);
191
+ sentTxHash = undefined;
192
+ } else {
193
+ logger.info(`${accountLabel} previous tx ${sentTxHash.txHash} still pending, waiting again...`);
194
+ }
195
+ }
196
+
197
+ if (!sentTxHash) {
198
+ const deployResult = await deployMethod.send({
199
+ from: AztecAddress.ZERO,
200
+ fee: { paymentMethod, gasSettings },
201
+ wait: NO_WAIT,
202
+ });
203
+ sentTxHash = { txHash: deployResult.txHash };
204
+ logger.info(`${accountLabel} tx sent`, { txHash: sentTxHash.txHash.toString() });
205
+ }
206
+
207
+ const receipt = await waitForTx(aztecNode, sentTxHash.txHash, { timeout: 600 });
208
+ if (receipt.isDropped()) {
209
+ sentTxHash = undefined;
210
+ throw new Error(`${accountLabel} tx was dropped, retrying...`);
211
+ }
212
+ logger.info(`${accountLabel} deployed at ${account.address}`);
213
+ },
214
+ `deploy ${accountLabel}`,
215
+ makeBackoff([1, 2, 4, 8, 16]),
216
+ logger,
217
+ );
172
218
  }
173
219
 
174
220
  async function deployAccountsInBatches(
@@ -269,7 +315,7 @@ export async function deployTestAccountsWithTokens(
269
315
  fundedAccounts.map(async (a, i) => {
270
316
  const paymentMethod = new FeeJuicePaymentMethodWithClaim(a.address, claims[i]);
271
317
  const deployMethod = await a.getDeployMethod();
272
- await deployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod } });
318
+ await deployMethod.send({ from: NO_FROM, fee: { paymentMethod } });
273
319
  logger.info(`Account deployed at ${a.address}`);
274
320
  }),
275
321
  );
@@ -345,14 +391,18 @@ async function deployTokenAndMint(
345
391
  logger: Logger,
346
392
  ) {
347
393
  logger.verbose(`Deploying TokenContract...`);
348
- const {
349
- receipt: { contract: tokenContract },
350
- } = await TokenContract.deploy(wallet, admin, TOKEN_NAME, TOKEN_SYMBOL, TOKEN_DECIMALS).send({
394
+ const { contract: tokenContract } = await TokenContract.deploy(
395
+ wallet,
396
+ admin,
397
+ TOKEN_NAME,
398
+ TOKEN_SYMBOL,
399
+ TOKEN_DECIMALS,
400
+ ).send({
351
401
  from: admin,
352
402
  fee: {
353
403
  paymentMethod,
354
404
  },
355
- wait: { timeout: 600, returnReceipt: true },
405
+ wait: { timeout: 600 },
356
406
  });
357
407
 
358
408
  const tokenAddress = tokenContract.address;
@@ -1,7 +1,7 @@
1
1
  import { EcdsaKAccountContract, EcdsaRAccountContract } from '@aztec/accounts/ecdsa';
2
2
  import { SchnorrAccountContract } from '@aztec/accounts/schnorr';
3
3
  import { StubAccountContractArtifact, createStubAccount } from '@aztec/accounts/stub';
4
- import { type Account, type AccountContract, SignerlessAccount } from '@aztec/aztec.js/account';
4
+ import { type Account, type AccountContract, NO_FROM } from '@aztec/aztec.js/account';
5
5
  import {
6
6
  type CallIntent,
7
7
  type ContractFunctionInteractionCallIntent,
@@ -14,6 +14,7 @@ import {
14
14
  import type { AztecNode } from '@aztec/aztec.js/node';
15
15
  import { AccountManager, type SendOptions } from '@aztec/aztec.js/wallet';
16
16
  import type { DefaultAccountEntrypointOptions } from '@aztec/entrypoints/account';
17
+ import { DefaultEntrypoint } from '@aztec/entrypoints/default';
17
18
  import { Fq, Fr } from '@aztec/foundation/curves/bn254';
18
19
  import { GrumpkinScalar } from '@aztec/foundation/curves/grumpkin';
19
20
  import type { NotesFilter } from '@aztec/pxe/client/lazy';
@@ -24,7 +25,14 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address';
24
25
  import { getContractInstanceFromInstantiationParams } from '@aztec/stdlib/contract';
25
26
  import { deriveSigningKey } from '@aztec/stdlib/keys';
26
27
  import type { NoteDao } from '@aztec/stdlib/note';
27
- import type { BlockHeader, SimulationOverrides, TxHash, TxReceipt, TxSimulationResult } from '@aztec/stdlib/tx';
28
+ import type {
29
+ BlockHeader,
30
+ SimulationOverrides,
31
+ TxExecutionRequest,
32
+ TxHash,
33
+ TxReceipt,
34
+ TxSimulationResult,
35
+ } from '@aztec/stdlib/tx';
28
36
  import { ExecutionPayload, mergeExecutionPayloads } from '@aztec/stdlib/tx';
29
37
  import { BaseWallet, type SimulateViaEntrypointOptions } from '@aztec/wallet-sdk/base-wallet';
30
38
 
@@ -104,10 +112,7 @@ export class TestWallet extends BaseWallet {
104
112
 
105
113
  async getFakeAccountDataFor(address: AztecAddress) {
106
114
  const originalAccount = await this.getAccountFromAddress(address);
107
- if (originalAccount instanceof SignerlessAccount) {
108
- throw new Error(`Cannot create fake account data for SignerlessAccount at address: ${address}`);
109
- }
110
- const originalAddress = (originalAccount as Account).getCompleteAddress();
115
+ const originalAddress = originalAccount.getCompleteAddress();
111
116
  const contractInstance = await this.pxe.getContractInstance(originalAddress.address);
112
117
  if (!contractInstance) {
113
118
  throw new Error(`No contract instance found for address: ${originalAddress.address}`);
@@ -141,12 +146,7 @@ export class TestWallet extends BaseWallet {
141
146
  }
142
147
 
143
148
  protected getAccountFromAddress(address: AztecAddress): Promise<Account> {
144
- let account: Account | undefined;
145
- if (address.equals(AztecAddress.ZERO)) {
146
- account = new SignerlessAccount();
147
- } else {
148
- account = this.accounts.get(address?.toString() ?? '');
149
- }
149
+ const account = this.accounts.get(address?.toString() ?? '');
150
150
 
151
151
  if (!account) {
152
152
  throw new Error(`Account not found in wallet for address: ${address}`);
@@ -220,36 +220,43 @@ export class TestWallet extends BaseWallet {
220
220
  ): Promise<TxSimulationResult> {
221
221
  const { from, feeOptions, scopes, skipTxValidation, skipFeeEnforcement } = opts;
222
222
  const skipKernels = this.simulationMode !== 'full';
223
- const useOverride = this.simulationMode === 'kernelless-override' && !from.equals(AztecAddress.ZERO);
224
-
225
- let overrides: SimulationOverrides | undefined;
226
- let fromAccount: Account;
227
- if (useOverride) {
228
- const { account, instance, artifact } = await this.getFakeAccountDataFor(from);
229
- fromAccount = account;
230
- overrides = {
231
- contracts: { [from.toString()]: { instance, artifact } },
232
- };
233
- } else {
234
- fromAccount = await this.getAccountFromAddress(from);
235
- }
236
-
237
223
  const feeExecutionPayload = await feeOptions.walletFeePaymentMethod?.getExecutionPayload();
238
- const executionOptions: DefaultAccountEntrypointOptions = {
239
- txNonce: Fr.random(),
240
- cancellable: this.cancellableTransactions,
241
- feePaymentMethodOptions: feeOptions.accountFeePaymentMethodOptions,
242
- };
243
224
  const finalExecutionPayload = feeExecutionPayload
244
225
  ? mergeExecutionPayloads([feeExecutionPayload, executionPayload])
245
226
  : executionPayload;
246
227
  const chainInfo = await this.getChainInfo();
247
- const txRequest = await fromAccount.createTxExecutionRequest(
248
- finalExecutionPayload,
249
- feeOptions.gasSettings,
250
- chainInfo,
251
- executionOptions,
252
- );
228
+
229
+ let overrides: SimulationOverrides | undefined;
230
+ let txRequest: TxExecutionRequest;
231
+ if (from === NO_FROM) {
232
+ const entrypoint = new DefaultEntrypoint();
233
+ txRequest = await entrypoint.createTxExecutionRequest(finalExecutionPayload, feeOptions.gasSettings, chainInfo);
234
+ } else {
235
+ const useOverride = this.simulationMode === 'kernelless-override';
236
+ let fromAccount: Account;
237
+ if (useOverride) {
238
+ const { account, instance, artifact } = await this.getFakeAccountDataFor(from);
239
+ fromAccount = account;
240
+ overrides = {
241
+ contracts: { [from.toString()]: { instance, artifact } },
242
+ };
243
+ } else {
244
+ fromAccount = await this.getAccountFromAddress(from);
245
+ }
246
+ const executionOptions: DefaultAccountEntrypointOptions = {
247
+ txNonce: Fr.random(),
248
+ cancellable: this.cancellableTransactions,
249
+ // If from is an address, feeOptions include the way the account contract should handle the fee payment
250
+ feePaymentMethodOptions: feeOptions.accountFeePaymentMethodOptions!,
251
+ };
252
+ txRequest = await fromAccount.createTxExecutionRequest(
253
+ finalExecutionPayload,
254
+ feeOptions.gasSettings,
255
+ chainInfo,
256
+ executionOptions,
257
+ );
258
+ }
259
+
253
260
  return this.pxe.simulateTx(txRequest, {
254
261
  simulatePublic: true,
255
262
  skipKernels,