@aztec/end-to-end 0.0.0-test.1 → 0.0.1-fake-ceab37513c

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 (156) hide show
  1. package/dest/bench/client_flows/benchmark.d.ts +60 -0
  2. package/dest/bench/client_flows/benchmark.d.ts.map +1 -0
  3. package/dest/bench/client_flows/benchmark.js +261 -0
  4. package/dest/bench/client_flows/client_flows_benchmark.d.ts +69 -0
  5. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -0
  6. package/dest/bench/client_flows/client_flows_benchmark.js +315 -0
  7. package/dest/bench/client_flows/config.d.ts +14 -0
  8. package/dest/bench/client_flows/config.d.ts.map +1 -0
  9. package/dest/bench/client_flows/config.js +106 -0
  10. package/dest/bench/client_flows/data_extractor.d.ts +2 -0
  11. package/dest/bench/client_flows/data_extractor.d.ts.map +1 -0
  12. package/dest/bench/client_flows/data_extractor.js +99 -0
  13. package/dest/bench/utils.d.ts +10 -27
  14. package/dest/bench/utils.d.ts.map +1 -1
  15. package/dest/bench/utils.js +27 -43
  16. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +15 -7
  17. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  18. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +66 -38
  19. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +10 -18
  20. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
  21. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +34 -53
  22. package/dest/e2e_deploy_contract/deploy_test.d.ts +4 -2
  23. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  24. package/dest/e2e_deploy_contract/deploy_test.js +9 -6
  25. package/dest/e2e_epochs/epochs_test.d.ts +56 -17
  26. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  27. package/dest/e2e_epochs/epochs_test.js +222 -42
  28. package/dest/e2e_fees/bridging_race.notest.d.ts +2 -0
  29. package/dest/e2e_fees/bridging_race.notest.d.ts.map +1 -0
  30. package/dest/e2e_fees/bridging_race.notest.js +60 -0
  31. package/dest/e2e_fees/fees_test.d.ts +16 -5
  32. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  33. package/dest/e2e_fees/fees_test.js +87 -88
  34. package/dest/e2e_l1_publisher/write_json.d.ts +8 -0
  35. package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -0
  36. package/dest/e2e_l1_publisher/write_json.js +57 -0
  37. package/dest/e2e_multi_validator/utils.d.ts +12 -0
  38. package/dest/e2e_multi_validator/utils.d.ts.map +1 -0
  39. package/dest/e2e_multi_validator/utils.js +214 -0
  40. package/dest/e2e_nested_contract/nested_contract_test.d.ts +5 -5
  41. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  42. package/dest/e2e_nested_contract/nested_contract_test.js +19 -14
  43. package/dest/e2e_p2p/inactivity_slash_test.d.ts +31 -0
  44. package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -0
  45. package/dest/e2e_p2p/inactivity_slash_test.js +132 -0
  46. package/dest/e2e_p2p/p2p_network.d.ts +56 -21
  47. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  48. package/dest/e2e_p2p/p2p_network.js +154 -125
  49. package/dest/e2e_p2p/shared.d.ts +41 -3
  50. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  51. package/dest/e2e_p2p/shared.js +146 -6
  52. package/dest/e2e_token_contract/token_contract_test.d.ts +10 -5
  53. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  54. package/dest/e2e_token_contract/token_contract_test.js +51 -24
  55. package/dest/{e2e_prover → fixtures}/e2e_prover_test.d.ts +7 -4
  56. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -0
  57. package/dest/{e2e_prover → fixtures}/e2e_prover_test.js +67 -62
  58. package/dest/fixtures/fixtures.d.ts +5 -6
  59. package/dest/fixtures/fixtures.d.ts.map +1 -1
  60. package/dest/fixtures/fixtures.js +4 -3
  61. package/dest/fixtures/get_acvm_config.d.ts.map +1 -1
  62. package/dest/fixtures/get_acvm_config.js +2 -14
  63. package/dest/fixtures/get_bb_config.d.ts.map +1 -1
  64. package/dest/fixtures/get_bb_config.js +8 -15
  65. package/dest/fixtures/l1_to_l2_messaging.d.ts +8 -5
  66. package/dest/fixtures/l1_to_l2_messaging.d.ts.map +1 -1
  67. package/dest/fixtures/l1_to_l2_messaging.js +44 -18
  68. package/dest/fixtures/setup_l1_contracts.d.ts +3 -3
  69. package/dest/fixtures/setup_l1_contracts.d.ts.map +1 -1
  70. package/dest/fixtures/setup_l1_contracts.js +3 -3
  71. package/dest/fixtures/setup_p2p_test.d.ts +14 -6
  72. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  73. package/dest/fixtures/setup_p2p_test.js +73 -21
  74. package/dest/fixtures/snapshot_manager.d.ts +8 -3
  75. package/dest/fixtures/snapshot_manager.d.ts.map +1 -1
  76. package/dest/fixtures/snapshot_manager.js +120 -104
  77. package/dest/fixtures/token_utils.d.ts +4 -3
  78. package/dest/fixtures/token_utils.d.ts.map +1 -1
  79. package/dest/fixtures/token_utils.js +24 -7
  80. package/dest/fixtures/utils.d.ts +65 -22
  81. package/dest/fixtures/utils.d.ts.map +1 -1
  82. package/dest/fixtures/utils.js +439 -318
  83. package/dest/fixtures/web3signer.d.ts +5 -0
  84. package/dest/fixtures/web3signer.d.ts.map +1 -0
  85. package/dest/fixtures/web3signer.js +42 -0
  86. package/dest/shared/cross_chain_test_harness.d.ts +28 -18
  87. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  88. package/dest/shared/cross_chain_test_harness.js +97 -41
  89. package/dest/shared/gas_portal_test_harness.d.ts +23 -18
  90. package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
  91. package/dest/shared/gas_portal_test_harness.js +43 -25
  92. package/dest/shared/submit-transactions.d.ts.map +1 -1
  93. package/dest/shared/uniswap_l1_l2.d.ts +5 -6
  94. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  95. package/dest/shared/uniswap_l1_l2.js +136 -90
  96. package/dest/simulators/lending_simulator.d.ts +5 -6
  97. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  98. package/dest/simulators/lending_simulator.js +11 -15
  99. package/dest/simulators/token_simulator.d.ts +2 -1
  100. package/dest/simulators/token_simulator.d.ts.map +1 -1
  101. package/dest/simulators/token_simulator.js +16 -13
  102. package/dest/spartan/setup_test_wallets.d.ts +8 -1
  103. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  104. package/dest/spartan/setup_test_wallets.js +108 -22
  105. package/dest/spartan/utils.d.ts +60 -307
  106. package/dest/spartan/utils.d.ts.map +1 -1
  107. package/dest/spartan/utils.js +200 -115
  108. package/package.json +60 -56
  109. package/src/bench/client_flows/benchmark.ts +341 -0
  110. package/src/bench/client_flows/client_flows_benchmark.ts +422 -0
  111. package/src/bench/client_flows/config.ts +61 -0
  112. package/src/bench/client_flows/data_extractor.ts +111 -0
  113. package/src/bench/utils.ts +26 -52
  114. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +60 -40
  115. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +47 -75
  116. package/src/e2e_deploy_contract/deploy_test.ts +11 -8
  117. package/src/e2e_epochs/epochs_test.ts +276 -54
  118. package/src/e2e_fees/bridging_race.notest.ts +75 -0
  119. package/src/e2e_fees/fees_test.ts +121 -108
  120. package/src/e2e_l1_publisher/write_json.ts +74 -0
  121. package/src/e2e_multi_validator/utils.ts +258 -0
  122. package/src/e2e_nested_contract/nested_contract_test.ts +22 -14
  123. package/src/e2e_p2p/inactivity_slash_test.ts +174 -0
  124. package/src/e2e_p2p/p2p_network.ts +212 -144
  125. package/src/e2e_p2p/shared.ts +234 -14
  126. package/src/e2e_token_contract/token_contract_test.ts +42 -38
  127. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  128. package/src/{e2e_prover → fixtures}/e2e_prover_test.ts +62 -69
  129. package/src/fixtures/fixtures.ts +4 -3
  130. package/src/fixtures/get_acvm_config.ts +2 -10
  131. package/src/fixtures/get_bb_config.ts +15 -11
  132. package/src/fixtures/l1_to_l2_messaging.ts +53 -23
  133. package/src/fixtures/setup_l1_contracts.ts +5 -6
  134. package/src/fixtures/setup_p2p_test.ts +112 -30
  135. package/src/fixtures/snapshot_manager.ts +150 -102
  136. package/src/fixtures/token_utils.ts +33 -8
  137. package/src/fixtures/utils.ts +530 -352
  138. package/src/fixtures/web3signer.ts +46 -0
  139. package/src/guides/up_quick_start.sh +4 -4
  140. package/src/shared/cross_chain_test_harness.ts +92 -52
  141. package/src/shared/gas_portal_test_harness.ts +47 -31
  142. package/src/shared/uniswap_l1_l2.ts +127 -124
  143. package/src/simulators/lending_simulator.ts +11 -15
  144. package/src/simulators/token_simulator.ts +17 -12
  145. package/src/spartan/DEVELOP.md +116 -0
  146. package/src/spartan/setup_test_wallets.ts +144 -29
  147. package/src/spartan/utils.ts +194 -116
  148. package/dest/e2e_prover/e2e_prover_test.d.ts.map +0 -1
  149. package/dest/sample-dapp/connect.js +0 -12
  150. package/dest/sample-dapp/contracts.js +0 -10
  151. package/dest/sample-dapp/deploy.js +0 -35
  152. package/dest/sample-dapp/index.js +0 -98
  153. package/src/sample-dapp/connect.mjs +0 -16
  154. package/src/sample-dapp/contracts.mjs +0 -14
  155. package/src/sample-dapp/deploy.mjs +0 -40
  156. package/src/sample-dapp/index.mjs +0 -128
@@ -1,14 +1,15 @@
1
1
  import { getSchnorrWallet } from '@aztec/accounts/schnorr';
2
- import { Fr, createLogger, getContractInstanceFromDeployParams } from '@aztec/aztec.js';
2
+ import { Fr, createLogger, getContractInstanceFromInstantiationParams } from '@aztec/aztec.js';
3
3
  import { createSnapshotManager, deployAccounts } from '../fixtures/snapshot_manager.js';
4
4
  const { E2E_DATA_PATH: dataPath } = process.env;
5
5
  export class DeployTest {
6
6
  snapshotManager;
7
- wallets = [];
8
7
  logger;
9
8
  pxe;
10
9
  wallet;
10
+ defaultAccountAddress;
11
11
  aztecNode;
12
+ aztecNodeAdmin;
12
13
  constructor(testName){
13
14
  this.logger = createLogger(`e2e:e2e_deploy_contract:${testName}`);
14
15
  this.snapshotManager = createSnapshotManager(`e2e_deploy_contract/${testName}`, dataPath);
@@ -17,6 +18,7 @@ export class DeployTest {
17
18
  await this.applyInitialAccountSnapshot();
18
19
  const context = await this.snapshotManager.setup();
19
20
  ({ pxe: this.pxe, aztecNode: this.aztecNode } = context);
21
+ this.aztecNodeAdmin = context.aztecNode;
20
22
  return this;
21
23
  }
22
24
  async teardown() {
@@ -24,14 +26,15 @@ export class DeployTest {
24
26
  }
25
27
  async applyInitialAccountSnapshot() {
26
28
  await this.snapshotManager.snapshot('initial_account', deployAccounts(1, this.logger), async ({ deployedAccounts }, { pxe })=>{
27
- this.wallets = await Promise.all(deployedAccounts.map((a)=>getSchnorrWallet(pxe, a.address, a.signingKey)));
28
- this.wallets.forEach((w, i)=>this.logger.verbose(`Wallet ${i} address: ${w.getAddress()}`));
29
- this.wallet = this.wallets[0];
29
+ const wallets = await Promise.all(deployedAccounts.map((a)=>getSchnorrWallet(pxe, a.address, a.signingKey)));
30
+ wallets.forEach((w, i)=>this.logger.verbose(`Wallet ${i} address: ${w.getAddress()}`));
31
+ this.wallet = wallets[0];
32
+ this.defaultAccountAddress = this.wallet.getAddress();
30
33
  });
31
34
  }
32
35
  async registerContract(wallet, contractArtifact, opts = {}) {
33
36
  const { salt, publicKeys, initArgs, constructorName, deployer } = opts;
34
- const instance = await getContractInstanceFromDeployParams(contractArtifact.artifact, {
37
+ const instance = await getContractInstanceFromInstantiationParams(contractArtifact.artifact, {
35
38
  constructorArgs: initArgs ?? [],
36
39
  constructorArtifact: constructorName,
37
40
  salt,
@@ -1,20 +1,29 @@
1
- import { AztecNodeService } from '@aztec/aztec-node';
2
- import { type Logger } from '@aztec/aztec.js';
3
- import { ChainMonitor } from '@aztec/aztec.js/ethereum';
1
+ import { type AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
2
+ import { Fr, type Logger, type Wallet } from '@aztec/aztec.js';
3
+ import { EpochCache } from '@aztec/epoch-cache';
4
+ import { type ExtendedViemWalletClient } from '@aztec/ethereum';
4
5
  import { RollupContract } from '@aztec/ethereum/contracts';
5
- import { type Delayer } from '@aztec/ethereum/test';
6
- import { ProverNode } from '@aztec/prover-node';
7
- import type { L2BlockNumber } from '@aztec/stdlib/block';
8
- import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
9
- import type { PublicClient } from 'viem';
6
+ import { ChainMonitor, type Delayer } from '@aztec/ethereum/test';
7
+ import { SpamContract } from '@aztec/noir-test-contracts.js/Spam';
8
+ import { ProverNode, type ProverNodeConfig } from '@aztec/prover-node';
9
+ import { type SequencerClient, type SequencerEvents } from '@aztec/sequencer-client';
10
+ import { EthAddress, type L2BlockNumber } from '@aztec/stdlib/block';
11
+ import { type L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
10
12
  import { type EndToEndContext, type SetupOptions } from '../fixtures/utils.js';
11
- export declare const L1_BLOCK_TIME_IN_S: number;
12
- export declare const EPOCH_DURATION_IN_L2_SLOTS = 4;
13
- export declare const L2_SLOT_DURATION_IN_L1_SLOTS = 2;
14
13
  export declare const WORLD_STATE_BLOCK_HISTORY = 2;
15
14
  export declare const WORLD_STATE_BLOCK_CHECK_INTERVAL = 50;
16
15
  export declare const ARCHIVER_POLL_INTERVAL = 50;
17
- export type EpochsTestOpts = Partial<Pick<SetupOptions, 'startProverNode'>>;
16
+ export declare const DEFAULT_L1_BLOCK_TIME: number;
17
+ export type EpochsTestOpts = Partial<SetupOptions> & {
18
+ numberOfAccounts?: number;
19
+ };
20
+ export type TrackedSequencerEvent = {
21
+ [K in keyof SequencerEvents]: Parameters<SequencerEvents[K]>[0] & {
22
+ type: K;
23
+ sequencerIndex: number;
24
+ validator: EthAddress;
25
+ };
26
+ }[keyof SequencerEvents];
18
27
  /**
19
28
  * Tests building of epochs using fast block times and short epochs.
20
29
  * Spawns an aztec node and a prover node with fake proofs.
@@ -22,30 +31,60 @@ export type EpochsTestOpts = Partial<Pick<SetupOptions, 'startProverNode'>>;
22
31
  */
23
32
  export declare class EpochsTestContext {
24
33
  context: EndToEndContext;
25
- l1Client: PublicClient;
34
+ l1Client: ExtendedViemWalletClient;
26
35
  rollup: RollupContract;
27
36
  constants: L1RollupConstants;
28
37
  logger: Logger;
29
38
  monitor: ChainMonitor;
39
+ epochCache: EpochCache;
30
40
  proverDelayer: Delayer;
31
41
  sequencerDelayer: Delayer;
32
42
  proverNodes: ProverNode[];
33
43
  nodes: AztecNodeService[];
44
+ epochDuration: number;
45
+ L1_BLOCK_TIME_IN_S: number;
46
+ L2_SLOT_DURATION_IN_S: number;
34
47
  static setup(opts?: EpochsTestOpts): Promise<EpochsTestContext>;
48
+ static getSlotDurations(opts?: EpochsTestOpts): {
49
+ ethereumSlotDuration: number;
50
+ aztecSlotDuration: number;
51
+ aztecEpochDuration: number;
52
+ aztecProofSubmissionEpochs: number;
53
+ };
35
54
  setup(opts?: EpochsTestOpts): Promise<void>;
36
55
  teardown(): Promise<void>;
37
- createProverNode(): Promise<ProverNode>;
38
- createNonValidatorNode(): Promise<AztecNodeService>;
56
+ createProverNode(opts?: {
57
+ dontStart?: boolean;
58
+ } & Partial<ProverNodeConfig>): Promise<ProverNode>;
59
+ createNonValidatorNode(opts?: Partial<AztecNodeConfig>): Promise<AztecNodeService>;
60
+ createValidatorNode(privateKeys: `0x${string}`[], opts?: Partial<AztecNodeConfig> & {
61
+ txDelayerMaxInclusionTimeIntoSlot?: number;
62
+ dontStartSequencer?: boolean;
63
+ }): Promise<AztecNodeService>;
64
+ private createNode;
39
65
  private getNextPrivateKey;
40
66
  /** Waits until the epoch begins (ie until the immediately previous L1 block is mined). */
41
67
  waitUntilEpochStarts(epoch: number): Promise<bigint>;
42
68
  /** Waits until the given L2 block number is mined. */
43
69
  waitUntilL2BlockNumber(target: number, timeout?: number): Promise<void>;
44
70
  /** Waits until the given L2 block number is marked as proven. */
45
- waitUntilProvenL2BlockNumber(t: number, timeout?: number): Promise<void>;
71
+ waitUntilProvenL2BlockNumber(t: number, timeout?: number): Promise<number>;
72
+ /** Waits until the last slot of the proof submission window for a given epoch. */
73
+ waitUntilLastSlotOfProofSubmissionWindow(epochNumber: number | bigint): Promise<void>;
46
74
  /** Waits for the aztec node to sync to the target block number. */
47
- waitForNodeToSync(blockNumber: number, type: 'finalised' | 'historic'): Promise<void>;
75
+ waitForNodeToSync(blockNumber: number, type: 'proven' | 'finalized' | 'historic'): Promise<void>;
76
+ /** Registers the SpamContract on the given wallet. */
77
+ registerSpamContract(wallet: Wallet, salt?: Fr): Promise<SpamContract>;
78
+ /** Creates an L1 client using a fresh account with funds from anvil, with a tx delayer already set up. */
79
+ createL1Client(): Promise<{
80
+ client: ExtendedViemWalletClient;
81
+ delayer: Delayer;
82
+ }>;
48
83
  /** Verifies whether the given block number is found on the aztec node. */
49
84
  verifyHistoricBlock(blockNumber: L2BlockNumber, expectedSuccess: boolean): Promise<void>;
85
+ watchSequencerEvents(sequencers: SequencerClient[], getMetadata?: (i: number) => Record<string, any>): {
86
+ failEvents: TrackedSequencerEvent[];
87
+ stateChanges: TrackedSequencerEvent[];
88
+ };
50
89
  }
51
90
  //# sourceMappingURL=epochs_test.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"epochs_test.d.ts","sourceRoot":"","sources":["../../src/e2e_epochs/epochs_test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAM,KAAK,MAAM,EAAgD,MAAM,iBAAiB,CAAC;AAChG,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAkB,KAAK,OAAO,EAAwB,MAAM,sBAAsB,CAAC;AAG1F,OAAO,EAAE,UAAU,EAAuB,MAAM,oBAAoB,CAAC;AAIrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAIrE,OAAO,KAAK,EAAO,YAAY,EAAE,MAAM,MAAM,CAAC;AAE9C,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,YAAY,EAIlB,MAAM,sBAAsB,CAAC;AAG9B,eAAO,MAAM,kBAAkB,QAAsE,CAAC;AACtG,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAC5C,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAC9C,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAC3C,eAAO,MAAM,gCAAgC,KAAK,CAAC;AACnD,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAE5E;;;;GAIG;AACH,qBAAa,iBAAiB;IACrB,OAAO,EAAG,eAAe,CAAC;IAC1B,QAAQ,EAAG,YAAY,CAAC;IACxB,MAAM,EAAG,cAAc,CAAC;IACxB,SAAS,EAAG,iBAAiB,CAAC;IAC9B,MAAM,EAAG,MAAM,CAAC;IAChB,OAAO,EAAG,YAAY,CAAC;IACvB,aAAa,EAAG,OAAO,CAAC;IACxB,gBAAgB,EAAG,OAAO,CAAC;IAE3B,WAAW,EAAE,UAAU,EAAE,CAAM;IAC/B,KAAK,EAAE,gBAAgB,EAAE,CAAM;WAElB,KAAK,CAAC,IAAI,GAAE,cAAmB;IAMtC,KAAK,CAAC,IAAI,GAAE,cAAmB;IA+D/B,QAAQ;IAOR,gBAAgB;IAgBhB,sBAAsB;IAcnC,OAAO,CAAC,iBAAiB;IAKzB,0FAA0F;IAC7E,oBAAoB,CAAC,KAAK,EAAE,MAAM;IAO/C,sDAAsD;IACzC,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,SAAK;IAShE,iEAAiE;IACpD,4BAA4B,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,SAAK;IASjE,mEAAmE;IACtD,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU;IAclF,0EAA0E;IAC7D,mBAAmB,CAAC,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,OAAO;CAOtF"}
1
+ {"version":3,"file":"epochs_test.d.ts","sourceRoot":"","sources":["../../src/e2e_epochs/epochs_test.ts"],"names":[],"mappings":"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"}
@@ -1,20 +1,25 @@
1
1
  import { AztecNodeService } from '@aztec/aztec-node';
2
- import { Fr, getTimestampRangeForEpoch, retryUntil, sleep } from '@aztec/aztec.js';
3
- import { ChainMonitor } from '@aztec/aztec.js/ethereum';
2
+ import { Fr, MerkleTreeId, getContractInstanceFromInstantiationParams, getTimestampRangeForEpoch, retryUntil, sleep } from '@aztec/aztec.js';
3
+ import { EpochCache } from '@aztec/epoch-cache';
4
+ import { DefaultL1ContractsConfig, createExtendedL1Client } from '@aztec/ethereum';
4
5
  import { RollupContract } from '@aztec/ethereum/contracts';
5
- import { waitUntilL1Timestamp } from '@aztec/ethereum/test';
6
+ import { ChainMonitor, DelayedTxUtils, waitUntilL1Timestamp, withDelayer } from '@aztec/ethereum/test';
7
+ import { SecretValue } from '@aztec/foundation/config';
6
8
  import { randomBytes } from '@aztec/foundation/crypto';
7
9
  import { withLogNameSuffix } from '@aztec/foundation/log';
8
- import { MerkleTreeId } from '@aztec/stdlib/trees';
10
+ import { SpamContract } from '@aztec/noir-test-contracts.js/Spam';
11
+ import { getMockPubSubP2PServiceFactory } from '@aztec/p2p/test-helpers';
12
+ import { SequencerState } from '@aztec/sequencer-client';
13
+ import { EthAddress } from '@aztec/stdlib/block';
14
+ import { getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
15
+ import { tryStop } from '@aztec/stdlib/interfaces/server';
9
16
  import { join } from 'path';
17
+ import { privateKeyToAccount } from 'viem/accounts';
10
18
  import { createAndSyncProverNode, getPrivateKeyFromIndex, setup } from '../fixtures/utils.js';
11
- // This can be lowered to as much as 2s in non-CI
12
- export const L1_BLOCK_TIME_IN_S = process.env.L1_BLOCK_TIME ? parseInt(process.env.L1_BLOCK_TIME) : 8;
13
- export const EPOCH_DURATION_IN_L2_SLOTS = 4;
14
- export const L2_SLOT_DURATION_IN_L1_SLOTS = 2;
15
19
  export const WORLD_STATE_BLOCK_HISTORY = 2;
16
20
  export const WORLD_STATE_BLOCK_CHECK_INTERVAL = 50;
17
21
  export const ARCHIVER_POLL_INTERVAL = 50;
22
+ export const DEFAULT_L1_BLOCK_TIME = process.env.CI ? 12 : 8;
18
23
  /**
19
24
  * Tests building of epochs using fast block times and short epochs.
20
25
  * Spawns an aztec node and a prover node with fake proofs.
@@ -26,38 +31,61 @@ export const ARCHIVER_POLL_INTERVAL = 50;
26
31
  constants;
27
32
  logger;
28
33
  monitor;
34
+ epochCache;
29
35
  proverDelayer;
30
36
  sequencerDelayer;
31
37
  proverNodes = [];
32
38
  nodes = [];
39
+ epochDuration;
40
+ L1_BLOCK_TIME_IN_S;
41
+ L2_SLOT_DURATION_IN_S;
33
42
  static async setup(opts = {}) {
34
43
  const test = new EpochsTestContext();
35
44
  await test.setup(opts);
36
45
  return test;
37
46
  }
47
+ static getSlotDurations(opts = {}) {
48
+ const envEthereumSlotDuration = process.env.L1_BLOCK_TIME ? parseInt(process.env.L1_BLOCK_TIME) : DEFAULT_L1_BLOCK_TIME;
49
+ const ethereumSlotDuration = opts.ethereumSlotDuration ?? envEthereumSlotDuration;
50
+ const aztecSlotDuration = opts.aztecSlotDuration ?? ethereumSlotDuration * 2;
51
+ const aztecEpochDuration = opts.aztecEpochDuration ?? 6;
52
+ const aztecProofSubmissionEpochs = opts.aztecProofSubmissionEpochs ?? 1;
53
+ return {
54
+ ethereumSlotDuration,
55
+ aztecSlotDuration,
56
+ aztecEpochDuration,
57
+ aztecProofSubmissionEpochs
58
+ };
59
+ }
38
60
  async setup(opts = {}) {
61
+ const { ethereumSlotDuration, aztecSlotDuration, aztecEpochDuration, aztecProofSubmissionEpochs } = EpochsTestContext.getSlotDurations(opts);
62
+ this.L1_BLOCK_TIME_IN_S = ethereumSlotDuration;
63
+ this.L2_SLOT_DURATION_IN_S = aztecSlotDuration;
39
64
  // Set up system without any account nor protocol contracts
40
65
  // and with faster block times and shorter epochs.
41
- const context = await setup(0, {
66
+ const context = await setup(opts.numberOfAccounts ?? 0, {
67
+ automineL1Setup: true,
42
68
  checkIntervalMs: 50,
43
69
  archiverPollingIntervalMS: ARCHIVER_POLL_INTERVAL,
44
70
  worldStateBlockCheckIntervalMS: WORLD_STATE_BLOCK_CHECK_INTERVAL,
45
71
  skipProtocolContracts: true,
46
72
  salt: 1,
47
- aztecEpochDuration: EPOCH_DURATION_IN_L2_SLOTS,
48
- aztecSlotDuration: L1_BLOCK_TIME_IN_S * L2_SLOT_DURATION_IN_L1_SLOTS,
49
- ethereumSlotDuration: L1_BLOCK_TIME_IN_S,
50
- aztecProofSubmissionWindow: EPOCH_DURATION_IN_L2_SLOTS * 2 - 1,
73
+ aztecEpochDuration,
74
+ aztecSlotDuration,
75
+ ethereumSlotDuration,
76
+ aztecProofSubmissionEpochs,
77
+ aztecTargetCommitteeSize: opts.initialValidators?.length ?? 0,
51
78
  minTxsPerBlock: 0,
52
79
  realProofs: false,
53
80
  startProverNode: true,
81
+ proverTestDelayMs: opts.proverTestDelayMs ?? 0,
54
82
  // We use numeric incremental prover ids for simplicity, but we can switch to
55
83
  // using the prover's eth address if the proverId is used for something in the rollup contract
56
- proverId: Fr.fromString('1'),
57
- // This must be enough so that the tx from the prover is delayed properly,
58
- // but not so much to hang the sequencer and timeout the teardown
59
- txPropagationMaxQueryAttempts: 12,
84
+ // Use numeric EthAddress for deterministic prover id
85
+ proverId: EthAddress.fromNumber(1),
60
86
  worldStateBlockHistory: WORLD_STATE_BLOCK_HISTORY,
87
+ exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
88
+ slasherFlavor: 'none',
61
89
  ...opts
62
90
  });
63
91
  this.context = context;
@@ -68,52 +96,109 @@ export const ARCHIVER_POLL_INTERVAL = 50;
68
96
  context.aztecNode
69
97
  ] : [];
70
98
  this.logger = context.logger;
71
- this.l1Client = context.deployL1ContractsValues.publicClient;
99
+ this.l1Client = context.deployL1ContractsValues.l1Client;
72
100
  this.rollup = RollupContract.getFromConfig(context.config);
101
+ this.epochCache = await EpochCache.create(this.rollup, context.config, {
102
+ dateProvider: context.dateProvider
103
+ });
73
104
  // Loop that tracks L1 and L2 block numbers and logs whenever there's a new one.
74
- this.monitor = new ChainMonitor(this.rollup, this.logger).start();
105
+ this.monitor = new ChainMonitor(this.rollup, context.dateProvider, this.logger).start();
75
106
  // This is hideous.
76
107
  // We ought to have a definite reference to the l1TxUtils that we're using in both places, provided by the test context.
77
108
  this.proverDelayer = context.proverNode ? context.proverNode.publisher.l1TxUtils.delayer : undefined;
78
- this.sequencerDelayer = context.sequencer.sequencer.publisher.l1TxUtils.delayer;
79
- if (context.proverNode && !this.proverDelayer || !this.sequencerDelayer) {
109
+ this.sequencerDelayer = context.sequencer ? context.sequencer.sequencer.publisher.l1TxUtils.delayer : undefined;
110
+ if (context.proverNode && !this.proverDelayer || context.sequencer && !this.sequencerDelayer) {
80
111
  throw new Error(`Could not find prover or sequencer delayer`);
81
112
  }
82
113
  // Constants used for time calculation
114
+ this.epochDuration = aztecEpochDuration;
83
115
  this.constants = {
84
- epochDuration: EPOCH_DURATION_IN_L2_SLOTS,
85
- slotDuration: L1_BLOCK_TIME_IN_S * L2_SLOT_DURATION_IN_L1_SLOTS,
116
+ epochDuration: aztecEpochDuration,
117
+ slotDuration: aztecSlotDuration,
86
118
  l1StartBlock: await this.rollup.getL1StartBlock(),
87
119
  l1GenesisTime: await this.rollup.getL1GenesisTime(),
88
- ethereumSlotDuration: L1_BLOCK_TIME_IN_S
120
+ ethereumSlotDuration,
121
+ proofSubmissionEpochs: Number(await this.rollup.getProofSubmissionEpochs())
89
122
  };
90
123
  this.logger.info(`L2 genesis at L1 block ${this.constants.l1StartBlock} (timestamp ${this.constants.l1GenesisTime})`);
91
124
  }
92
125
  async teardown() {
93
- this.monitor.stop();
94
- await Promise.all(this.proverNodes.map((node)=>node.stop()));
95
- await Promise.all(this.nodes.map((node)=>node.stop()));
126
+ await this.monitor.stop();
127
+ await Promise.all(this.proverNodes.map((node)=>tryStop(node, this.logger)));
128
+ await Promise.all(this.nodes.map((node)=>tryStop(node, this.logger)));
96
129
  await this.context.teardown();
97
130
  }
98
- async createProverNode() {
131
+ async createProverNode(opts = {}) {
99
132
  this.logger.warn('Creating and syncing a simulated prover node...');
100
133
  const proverNodePrivateKey = this.getNextPrivateKey();
101
134
  const suffix = (this.proverNodes.length + 1).toString();
135
+ const proverId = EthAddress.fromNumber(parseInt(suffix, 10));
102
136
  const proverNode = await withLogNameSuffix(suffix, ()=>createAndSyncProverNode(proverNodePrivateKey, {
103
137
  ...this.context.config,
104
- proverId: Fr.fromString(suffix)
105
- }, this.context.aztecNode, join(this.context.config.dataDirectory, randomBytes(8).toString('hex'))));
138
+ proverId
139
+ }, {
140
+ dataDirectory: join(this.context.config.dataDirectory, randomBytes(8).toString('hex')),
141
+ proverId,
142
+ ...opts
143
+ }, this.context.aztecNode, undefined, {
144
+ dateProvider: this.context.dateProvider
145
+ }));
106
146
  this.proverNodes.push(proverNode);
107
147
  return proverNode;
108
148
  }
109
- async createNonValidatorNode() {
149
+ createNonValidatorNode(opts = {}) {
110
150
  this.logger.warn('Creating and syncing a node without a validator...');
151
+ return this.createNode({
152
+ ...opts,
153
+ disableValidator: true
154
+ });
155
+ }
156
+ createValidatorNode(privateKeys, opts = {}) {
157
+ this.logger.warn('Creating and syncing a validator node...');
158
+ return this.createNode({
159
+ ...opts,
160
+ disableValidator: false,
161
+ validatorPrivateKeys: new SecretValue(privateKeys)
162
+ });
163
+ }
164
+ async createNode(opts = {}) {
111
165
  const suffix = (this.nodes.length + 1).toString();
166
+ const { mockGossipSubNetwork } = this.context;
167
+ const resolvedConfig = {
168
+ ...this.context.config,
169
+ ...opts
170
+ };
171
+ const p2pEnabled = resolvedConfig.p2pEnabled || mockGossipSubNetwork !== undefined;
172
+ const p2pIp = resolvedConfig.p2pIp ?? (p2pEnabled ? '127.0.0.1' : undefined);
112
173
  const node = await withLogNameSuffix(suffix, ()=>AztecNodeService.createAndSync({
113
- ...this.context.config,
114
- disableValidator: true,
115
- dataDirectory: join(this.context.config.dataDirectory, randomBytes(8).toString('hex'))
174
+ ...resolvedConfig,
175
+ dataDirectory: join(this.context.config.dataDirectory, randomBytes(8).toString('hex')),
176
+ validatorPrivateKeys: opts.validatorPrivateKeys ?? new SecretValue([]),
177
+ p2pEnabled,
178
+ p2pIp
179
+ }, {
180
+ dateProvider: this.context.dateProvider,
181
+ p2pClientDeps: {
182
+ p2pServiceFactory: mockGossipSubNetwork ? getMockPubSubP2PServiceFactory(mockGossipSubNetwork) : undefined
183
+ }
184
+ }, {
185
+ prefilledPublicData: this.context.prefilledPublicData,
186
+ ...opts
116
187
  }));
188
+ // REFACTOR: We're getting too much into the internals of the sequencer here.
189
+ // We should have a single method for constructing an aztec node that returns a TestAztecNodeService
190
+ // which directly exposes the delayer and sets any test config.
191
+ if (opts.txDelayerMaxInclusionTimeIntoSlot !== undefined) {
192
+ this.logger.info(`Setting tx delayer max inclusion time into slot to ${opts.txDelayerMaxInclusionTimeIntoSlot} seconds`);
193
+ // Here we reach into the sequencer and hook in a tx delayer. The problem is that the sequencer's l1 utils only uses a public client, not a wallet.
194
+ // The delayer needs a wallet (a client that can sign), so we have to create one here.
195
+ const l1Client = createExtendedL1Client(resolvedConfig.l1RpcUrls, resolvedConfig.publisherPrivateKeys[0].getValue());
196
+ const sequencer = node.getSequencer();
197
+ const publisher = sequencer.sequencer.publisher;
198
+ const delayed = DelayedTxUtils.fromL1TxUtils(publisher.l1TxUtils, this.L1_BLOCK_TIME_IN_S, l1Client);
199
+ delayed.delayer.setMaxInclusionTimeIntoSlot(opts.txDelayerMaxInclusionTimeIntoSlot);
200
+ publisher.l1TxUtils = delayed;
201
+ }
117
202
  this.nodes.push(node);
118
203
  return node;
119
204
  }
@@ -124,32 +209,127 @@ export const ARCHIVER_POLL_INTERVAL = 50;
124
209
  /** Waits until the epoch begins (ie until the immediately previous L1 block is mined). */ async waitUntilEpochStarts(epoch) {
125
210
  const [start] = getTimestampRangeForEpoch(BigInt(epoch), this.constants);
126
211
  this.logger.info(`Waiting until L1 timestamp ${start} is reached as the start of epoch ${epoch}`);
127
- await waitUntilL1Timestamp(this.l1Client, start - BigInt(L1_BLOCK_TIME_IN_S));
212
+ await waitUntilL1Timestamp(this.l1Client, start - BigInt(this.L1_BLOCK_TIME_IN_S), undefined, 30 * this.epochDuration);
128
213
  return start;
129
214
  }
130
215
  /** Waits until the given L2 block number is mined. */ async waitUntilL2BlockNumber(target, timeout = 60) {
131
- await retryUntil(()=>Promise.resolve(target === this.monitor.l2BlockNumber), `Wait until L2 block ${target}`, timeout, 0.1);
216
+ await retryUntil(()=>Promise.resolve(target <= this.monitor.l2BlockNumber), `Wait until L2 block ${target}`, timeout, 0.1);
132
217
  }
133
218
  /** Waits until the given L2 block number is marked as proven. */ async waitUntilProvenL2BlockNumber(t, timeout = 60) {
134
- await retryUntil(()=>Promise.resolve(t === this.monitor.l2ProvenBlockNumber), `Wait proven L2 block ${t}`, timeout, 0.1);
219
+ await retryUntil(()=>Promise.resolve(t <= this.monitor.l2ProvenBlockNumber), `Wait proven L2 block ${t}`, timeout, 0.1);
220
+ return this.monitor.l2ProvenBlockNumber;
221
+ }
222
+ /** Waits until the last slot of the proof submission window for a given epoch. */ async waitUntilLastSlotOfProofSubmissionWindow(epochNumber) {
223
+ const deadline = getProofSubmissionDeadlineTimestamp(BigInt(epochNumber), this.constants);
224
+ const oneSlotBefore = deadline - BigInt(this.constants.slotDuration);
225
+ const date = new Date(Number(oneSlotBefore) * 1000);
226
+ this.logger.info(`Waiting until last slot of submission window for epoch ${epochNumber} at ${date}`, {
227
+ oneSlotBefore
228
+ });
229
+ await waitUntilL1Timestamp(this.l1Client, oneSlotBefore);
135
230
  }
136
231
  /** Waits for the aztec node to sync to the target block number. */ async waitForNodeToSync(blockNumber, type) {
137
232
  const waitTime = ARCHIVER_POLL_INTERVAL + WORLD_STATE_BLOCK_CHECK_INTERVAL;
138
233
  let synched = false;
139
234
  while(!synched){
140
235
  await sleep(waitTime);
141
- const syncState = await this.context.aztecNode.getWorldStateSyncStatus();
142
- if (type === 'finalised') {
143
- synched = syncState.finalisedBlockNumber >= blockNumber;
236
+ const [syncState, tips] = await Promise.all([
237
+ this.context.aztecNode.getWorldStateSyncStatus(),
238
+ await this.context.aztecNode.getL2Tips()
239
+ ]);
240
+ this.logger.info(`Wait for node synch ${blockNumber} ${type}`, {
241
+ blockNumber,
242
+ type,
243
+ syncState,
244
+ tips
245
+ });
246
+ if (type === 'proven') {
247
+ synched = tips.proven.number >= blockNumber && syncState.latestBlockNumber >= blockNumber;
248
+ } else if (type === 'finalized') {
249
+ synched = syncState.finalizedBlockNumber >= blockNumber;
144
250
  } else {
145
251
  synched = syncState.oldestHistoricBlockNumber >= blockNumber;
146
252
  }
147
253
  }
148
254
  }
255
+ /** Registers the SpamContract on the given wallet. */ async registerSpamContract(wallet, salt = Fr.ZERO) {
256
+ const instance = await getContractInstanceFromInstantiationParams(SpamContract.artifact, {
257
+ constructorArgs: [],
258
+ constructorArtifact: undefined,
259
+ salt,
260
+ publicKeys: undefined,
261
+ deployer: undefined
262
+ });
263
+ await wallet.registerContract({
264
+ artifact: SpamContract.artifact,
265
+ instance
266
+ });
267
+ return SpamContract.at(instance.address, wallet);
268
+ }
269
+ /** Creates an L1 client using a fresh account with funds from anvil, with a tx delayer already set up. */ async createL1Client() {
270
+ const { client, delayer } = withDelayer(createExtendedL1Client([
271
+ ...this.l1Client.chain.rpcUrls.default.http
272
+ ], privateKeyToAccount(this.getNextPrivateKey()), this.l1Client.chain), this.context.dateProvider, {
273
+ ethereumSlotDuration: this.L1_BLOCK_TIME_IN_S
274
+ });
275
+ expect(await client.getBalance({
276
+ address: client.account.address
277
+ })).toBeGreaterThan(0n);
278
+ return {
279
+ client,
280
+ delayer
281
+ };
282
+ }
149
283
  /** Verifies whether the given block number is found on the aztec node. */ async verifyHistoricBlock(blockNumber, expectedSuccess) {
150
- const result = await this.context.aztecNode.findBlockNumbersForIndexes(blockNumber, MerkleTreeId.NULLIFIER_TREE, [
151
- 0n
284
+ // We use `findLeavesIndexes` here, but could use any function that queries the world-state
285
+ // at a particular block, so we know whether that historic block is available or has been
286
+ // pruned. Note that `getBlock` would not work here, since it only hits the archiver.
287
+ const result = await this.context.aztecNode.findLeavesIndexes(blockNumber, MerkleTreeId.NULLIFIER_TREE, [
288
+ Fr.ZERO
152
289
  ]).then((_)=>true).catch((_)=>false);
153
290
  expect(result).toBe(expectedSuccess);
154
291
  }
292
+ watchSequencerEvents(sequencers, getMetadata = ()=>({})) {
293
+ const stateChanges = [];
294
+ const failEvents = [];
295
+ // Note we do not include the 'tx-count-check-failed' event here, since it is fine if we dont build
296
+ // due to lack of txs available.
297
+ const failEventsKeys = [
298
+ 'block-build-failed',
299
+ 'block-publish-failed',
300
+ 'proposer-rollup-check-failed'
301
+ ];
302
+ const makeEvent = (i, eventName, args)=>({
303
+ ...args,
304
+ type: eventName,
305
+ sequencerIndex: i + 2,
306
+ ...getMetadata(i)
307
+ });
308
+ sequencers.forEach((sequencer, i)=>{
309
+ const sequencerIndex = i + 2;
310
+ sequencer.getSequencer().on('state-changed', (args)=>{
311
+ const noisyStates = [
312
+ SequencerState.IDLE,
313
+ SequencerState.PROPOSER_CHECK,
314
+ SequencerState.SYNCHRONIZING
315
+ ];
316
+ if (!noisyStates.includes(args.newState)) {
317
+ const evt = makeEvent(i, 'state-changed', args);
318
+ stateChanges.push(evt);
319
+ this.logger.verbose(`Sequencer ${sequencerIndex} transitioned from state ${args.oldState} to state ${args.newState}`, evt);
320
+ }
321
+ });
322
+ failEventsKeys.forEach((eventName)=>{
323
+ sequencer.getSequencer().on(eventName, (args)=>{
324
+ const evt = makeEvent(i, eventName, args);
325
+ failEvents.push(evt);
326
+ this.logger.error(`Failed event ${eventName} from sequencer ${sequencerIndex}`, undefined, evt);
327
+ });
328
+ });
329
+ });
330
+ return {
331
+ failEvents,
332
+ stateChanges
333
+ };
334
+ }
155
335
  }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bridging_race.notest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridging_race.notest.d.ts","sourceRoot":"","sources":["../../src/e2e_fees/bridging_race.notest.ts"],"names":[],"mappings":""}
@@ -0,0 +1,60 @@
1
+ import { getSchnorrAccount } from '@aztec/accounts/schnorr';
2
+ import { Fr, sleep } from '@aztec/aztec.js';
3
+ import { Fq } from '@aztec/foundation/fields';
4
+ import { jest } from '@jest/globals';
5
+ import { FeesTest } from './fees_test.js';
6
+ jest.setTimeout(300_000);
7
+ // Regression for https://github.com/AztecProtocol/aztec-packages/issues/12366
8
+ // Similar to e2e_fees/account_init but with no automine
9
+ describe('e2e_fees bridging_race', ()=>{
10
+ const ETHEREUM_SLOT_DURATION = 4;
11
+ const AZTEC_SLOT_DURATION = ETHEREUM_SLOT_DURATION * 2;
12
+ const t = new FeesTest('bridging_race', 1, {
13
+ ethereumSlotDuration: ETHEREUM_SLOT_DURATION,
14
+ aztecSlotDuration: AZTEC_SLOT_DURATION,
15
+ minTxsPerBlock: 0
16
+ });
17
+ beforeAll(async ()=>{
18
+ await t.applyInitialAccountsSnapshot();
19
+ await t.applyPublicDeployAccountsSnapshot();
20
+ await t.applySetupFeeJuiceSnapshot();
21
+ ({ pxe, logger } = await t.setup());
22
+ });
23
+ afterAll(async ()=>{
24
+ await t.teardown();
25
+ });
26
+ let logger;
27
+ let pxe;
28
+ let bobsAddress;
29
+ beforeEach(async ()=>{
30
+ const bobsSecretKey = Fr.random();
31
+ const bobsPrivateSigningKey = Fq.random();
32
+ const bobsAccountManager = await getSchnorrAccount(pxe, bobsSecretKey, bobsPrivateSigningKey, Fr.random());
33
+ const bobsCompleteAddress = await bobsAccountManager.getCompleteAddress();
34
+ bobsAddress = bobsCompleteAddress.address;
35
+ await bobsAccountManager.getWallet();
36
+ await bobsAccountManager.register();
37
+ });
38
+ it('Alice bridges funds to Bob', async ()=>{
39
+ // Tweak the token manager so the bridging happens immediately before the end of the current L2 slot
40
+ // This caused the message to be "not in state" when tried to be used
41
+ const l1TokenManager = t.feeJuiceBridgeTestHarness.l1TokenManager;
42
+ const origApprove = l1TokenManager.approve.bind(l1TokenManager);
43
+ l1TokenManager.approve = async (amount, address, addressName = '')=>{
44
+ await origApprove(amount, address, addressName);
45
+ const sleepTime = (Number(t.chainMonitor.l2BlockTimestamp) + AZTEC_SLOT_DURATION) * 1000 - Date.now() - 500;
46
+ logger.info(`Sleeping for ${sleepTime}ms until near end of L2 slot before sending L1 fee juice to L2 inbox`);
47
+ await sleep(sleepTime);
48
+ };
49
+ // Waiting for the archiver to sync the message _before_ waiting for the mandatory 2 L2 blocks to pass fixed it
50
+ // This was added everywhere we wait for two blocks, which is spread across three different places in the codebase
51
+ // Yes, we need to REFACTOR it at some point
52
+ const claim = await t.feeJuiceBridgeTestHarness.prepareTokensOnL1(bobsAddress);
53
+ const { claimSecret: secret, messageLeafIndex: index } = claim;
54
+ await t.feeJuiceContract.methods.claim(bobsAddress, claim.claimAmount, secret, index).send({
55
+ from: bobsAddress
56
+ }).wait();
57
+ const [balance] = await t.getGasBalanceFn(bobsAddress);
58
+ expect(balance).toEqual(claim.claimAmount);
59
+ });
60
+ });