@aztec/end-to-end 0.0.1-commit.7d4e6cd → 0.0.1-commit.858058eac

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 (193) hide show
  1. package/dest/bench/client_flows/benchmark.d.ts +3 -2
  2. package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
  3. package/dest/bench/client_flows/benchmark.js +21 -1
  4. package/dest/bench/client_flows/client_flows_benchmark.d.ts +13 -14
  5. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  6. package/dest/bench/client_flows/client_flows_benchmark.js +118 -133
  7. package/dest/bench/client_flows/config.d.ts +2 -2
  8. package/dest/bench/client_flows/config.d.ts.map +1 -1
  9. package/dest/bench/client_flows/config.js +18 -0
  10. package/dest/bench/utils.d.ts +6 -5
  11. package/dest/bench/utils.d.ts.map +1 -1
  12. package/dest/bench/utils.js +9 -7
  13. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +7 -8
  14. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  15. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +96 -112
  16. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +7 -8
  17. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
  18. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +68 -64
  19. package/dest/e2e_deploy_contract/deploy_test.d.ts +5 -4
  20. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  21. package/dest/e2e_deploy_contract/deploy_test.js +18 -13
  22. package/dest/e2e_epochs/epochs_test.d.ts +7 -1
  23. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  24. package/dest/e2e_epochs/epochs_test.js +39 -11
  25. package/dest/e2e_fees/bridging_race.notest.js +3 -5
  26. package/dest/e2e_fees/fees_test.d.ts +14 -14
  27. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  28. package/dest/e2e_fees/fees_test.js +122 -140
  29. package/dest/e2e_l1_publisher/write_json.d.ts +4 -3
  30. package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -1
  31. package/dest/e2e_l1_publisher/write_json.js +14 -13
  32. package/dest/e2e_nested_contract/nested_contract_test.d.ts +6 -9
  33. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  34. package/dest/e2e_nested_contract/nested_contract_test.js +31 -39
  35. package/dest/e2e_p2p/inactivity_slash_test.d.ts +3 -3
  36. package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -1
  37. package/dest/e2e_p2p/inactivity_slash_test.js +3 -3
  38. package/dest/e2e_p2p/p2p_network.d.ts +8 -7
  39. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  40. package/dest/e2e_p2p/p2p_network.js +110 -103
  41. package/dest/e2e_p2p/reqresp/utils.d.ts +22 -0
  42. package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -0
  43. package/dest/e2e_p2p/reqresp/utils.js +153 -0
  44. package/dest/e2e_p2p/shared.d.ts +6 -6
  45. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  46. package/dest/e2e_p2p/shared.js +14 -17
  47. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts +2 -0
  48. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts.map +1 -0
  49. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.js +184 -0
  50. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts +18 -0
  51. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts.map +1 -0
  52. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.js +120 -0
  53. package/dest/e2e_token_contract/token_contract_test.d.ts +17 -10
  54. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  55. package/dest/e2e_token_contract/token_contract_test.js +89 -91
  56. package/dest/fixtures/e2e_prover_test.d.ts +9 -15
  57. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  58. package/dest/fixtures/e2e_prover_test.js +85 -93
  59. package/dest/fixtures/ha_setup.d.ts +71 -0
  60. package/dest/fixtures/ha_setup.d.ts.map +1 -0
  61. package/dest/fixtures/ha_setup.js +114 -0
  62. package/dest/fixtures/index.d.ts +2 -1
  63. package/dest/fixtures/index.d.ts.map +1 -1
  64. package/dest/fixtures/index.js +1 -0
  65. package/dest/fixtures/setup.d.ts +218 -0
  66. package/dest/fixtures/setup.d.ts.map +1 -0
  67. package/dest/fixtures/setup.js +631 -0
  68. package/dest/fixtures/setup_p2p_test.d.ts +12 -8
  69. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  70. package/dest/fixtures/setup_p2p_test.js +29 -21
  71. package/dest/fixtures/token_utils.d.ts +1 -1
  72. package/dest/fixtures/token_utils.d.ts.map +1 -1
  73. package/dest/fixtures/token_utils.js +7 -4
  74. package/dest/fixtures/utils.d.ts +5 -191
  75. package/dest/fixtures/utils.d.ts.map +1 -1
  76. package/dest/fixtures/utils.js +4 -615
  77. package/dest/quality_of_service/prometheus_client.d.ts +38 -0
  78. package/dest/quality_of_service/prometheus_client.d.ts.map +1 -0
  79. package/dest/quality_of_service/prometheus_client.js +67 -0
  80. package/dest/shared/cross_chain_test_harness.d.ts +14 -4
  81. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  82. package/dest/shared/cross_chain_test_harness.js +11 -11
  83. package/dest/shared/gas_portal_test_harness.d.ts +11 -1
  84. package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
  85. package/dest/shared/gas_portal_test_harness.js +1 -1
  86. package/dest/shared/submit-transactions.d.ts +4 -4
  87. package/dest/shared/submit-transactions.d.ts.map +1 -1
  88. package/dest/shared/submit-transactions.js +9 -11
  89. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  90. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  91. package/dest/shared/uniswap_l1_l2.js +20 -18
  92. package/dest/simulators/lending_simulator.d.ts +5 -1
  93. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  94. package/dest/simulators/lending_simulator.js +2 -2
  95. package/dest/spartan/setup_test_wallets.d.ts +2 -2
  96. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  97. package/dest/spartan/setup_test_wallets.js +64 -35
  98. package/dest/spartan/tx_metrics.d.ts +51 -2
  99. package/dest/spartan/tx_metrics.d.ts.map +1 -1
  100. package/dest/spartan/tx_metrics.js +333 -6
  101. package/dest/spartan/utils/bot.d.ts +27 -0
  102. package/dest/spartan/utils/bot.d.ts.map +1 -0
  103. package/dest/spartan/utils/bot.js +141 -0
  104. package/dest/spartan/utils/chaos.d.ts +79 -0
  105. package/dest/spartan/utils/chaos.d.ts.map +1 -0
  106. package/dest/spartan/utils/chaos.js +142 -0
  107. package/dest/spartan/utils/clients.d.ts +39 -0
  108. package/dest/spartan/utils/clients.d.ts.map +1 -0
  109. package/dest/spartan/utils/clients.js +90 -0
  110. package/dest/spartan/utils/config.d.ts +39 -0
  111. package/dest/spartan/utils/config.d.ts.map +1 -0
  112. package/dest/spartan/utils/config.js +21 -0
  113. package/dest/spartan/utils/health.d.ts +63 -0
  114. package/dest/spartan/utils/health.d.ts.map +1 -0
  115. package/dest/spartan/utils/health.js +202 -0
  116. package/dest/spartan/utils/helm.d.ts +15 -0
  117. package/dest/spartan/utils/helm.d.ts.map +1 -0
  118. package/dest/spartan/utils/helm.js +47 -0
  119. package/dest/spartan/utils/index.d.ts +9 -0
  120. package/dest/spartan/utils/index.d.ts.map +1 -0
  121. package/dest/spartan/utils/index.js +18 -0
  122. package/dest/spartan/utils/k8s.d.ts +126 -0
  123. package/dest/spartan/utils/k8s.d.ts.map +1 -0
  124. package/dest/spartan/utils/k8s.js +375 -0
  125. package/dest/spartan/utils/nodes.d.ts +41 -0
  126. package/dest/spartan/utils/nodes.d.ts.map +1 -0
  127. package/dest/spartan/utils/nodes.js +461 -0
  128. package/dest/spartan/utils/scripts.d.ts +30 -0
  129. package/dest/spartan/utils/scripts.d.ts.map +1 -0
  130. package/dest/spartan/utils/scripts.js +81 -0
  131. package/dest/spartan/utils.d.ts +2 -253
  132. package/dest/spartan/utils.d.ts.map +1 -1
  133. package/dest/spartan/utils.js +1 -892
  134. package/dest/test-wallet/test_wallet.d.ts +82 -0
  135. package/dest/test-wallet/test_wallet.d.ts.map +1 -0
  136. package/dest/test-wallet/test_wallet.js +213 -0
  137. package/dest/test-wallet/utils.d.ts +41 -0
  138. package/dest/test-wallet/utils.d.ts.map +1 -0
  139. package/dest/test-wallet/utils.js +71 -0
  140. package/package.json +44 -39
  141. package/src/bench/client_flows/benchmark.ts +24 -2
  142. package/src/bench/client_flows/client_flows_benchmark.ts +138 -204
  143. package/src/bench/client_flows/config.ts +9 -1
  144. package/src/bench/utils.ts +10 -8
  145. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +105 -143
  146. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +103 -111
  147. package/src/e2e_deploy_contract/deploy_test.ts +22 -15
  148. package/src/e2e_epochs/epochs_test.ts +72 -36
  149. package/src/e2e_fees/bridging_race.notest.ts +4 -10
  150. package/src/e2e_fees/fees_test.ts +171 -217
  151. package/src/e2e_l1_publisher/write_json.ts +16 -13
  152. package/src/e2e_nested_contract/nested_contract_test.ts +33 -56
  153. package/src/e2e_p2p/inactivity_slash_test.ts +3 -3
  154. package/src/e2e_p2p/p2p_network.ts +172 -168
  155. package/src/e2e_p2p/reqresp/utils.ts +207 -0
  156. package/src/e2e_p2p/shared.ts +22 -22
  157. package/src/e2e_storage_proof/fixtures/storage_proof.json +915 -0
  158. package/src/e2e_storage_proof/fixtures/storage_proof_fetcher.ts +190 -0
  159. package/src/e2e_storage_proof/fixtures/storage_proof_fixture.ts +173 -0
  160. package/src/e2e_token_contract/token_contract_test.ts +104 -119
  161. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  162. package/src/fixtures/e2e_prover_test.ts +98 -132
  163. package/src/fixtures/ha_setup.ts +184 -0
  164. package/src/fixtures/index.ts +1 -0
  165. package/src/fixtures/setup.ts +933 -0
  166. package/src/fixtures/setup_p2p_test.ts +31 -27
  167. package/src/fixtures/token_utils.ts +6 -5
  168. package/src/fixtures/utils.ts +27 -901
  169. package/src/quality_of_service/prometheus_client.ts +113 -0
  170. package/src/shared/cross_chain_test_harness.ts +13 -27
  171. package/src/shared/gas_portal_test_harness.ts +1 -1
  172. package/src/shared/submit-transactions.ts +11 -16
  173. package/src/shared/uniswap_l1_l2.ts +21 -30
  174. package/src/simulators/lending_simulator.ts +2 -2
  175. package/src/spartan/setup_test_wallets.ts +75 -25
  176. package/src/spartan/tx_metrics.ts +255 -9
  177. package/src/spartan/utils/bot.ts +185 -0
  178. package/src/spartan/utils/chaos.ts +253 -0
  179. package/src/spartan/utils/clients.ts +100 -0
  180. package/src/spartan/utils/config.ts +27 -0
  181. package/src/spartan/utils/health.ts +255 -0
  182. package/src/spartan/utils/helm.ts +84 -0
  183. package/src/spartan/utils/index.ts +64 -0
  184. package/src/spartan/utils/k8s.ts +527 -0
  185. package/src/spartan/utils/nodes.ts +538 -0
  186. package/src/spartan/utils/scripts.ts +99 -0
  187. package/src/spartan/utils.ts +1 -1158
  188. package/src/test-wallet/test_wallet.ts +296 -0
  189. package/src/test-wallet/utils.ts +112 -0
  190. package/dest/fixtures/snapshot_manager.d.ts +0 -93
  191. package/dest/fixtures/snapshot_manager.d.ts.map +0 -1
  192. package/dest/fixtures/snapshot_manager.js +0 -488
  193. package/src/fixtures/snapshot_manager.ts +0 -646
@@ -82,8 +82,8 @@ export class P2PInactivityTest {
82
82
  }
83
83
 
84
84
  public async setup() {
85
- await this.test.applyBaseSnapshots();
86
85
  await this.test.setup();
86
+ await this.test.applyBaseSetup();
87
87
 
88
88
  // Set slashing penalties for inactivity
89
89
  const { rollup } = await this.test.getContracts();
@@ -98,7 +98,7 @@ export class P2PInactivityTest {
98
98
  this.rollup = rollup;
99
99
 
100
100
  if (!this.keepInitialNode) {
101
- await this.test.ctx.aztecNode.stop();
101
+ await this.test.ctx.aztecNodeService.stop();
102
102
  }
103
103
 
104
104
  // Create all active nodes
@@ -129,7 +129,7 @@ export class P2PInactivityTest {
129
129
  );
130
130
 
131
131
  this.nodes = [
132
- ...(this.keepInitialNode ? [this.test.ctx.aztecNode] : []),
132
+ ...(this.keepInitialNode ? [this.test.ctx.aztecNodeService] : []),
133
133
  ...this.activeNodes,
134
134
  ...this.inactiveNodes,
135
135
  ];
@@ -27,26 +27,28 @@ import { tryStop } from '@aztec/stdlib/interfaces/server';
27
27
  import { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
28
28
  import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
29
29
  import { ZkPassportProofParams } from '@aztec/stdlib/zkpassport';
30
- import type { TestWallet } from '@aztec/test-wallet/server';
31
30
  import { getGenesisValues } from '@aztec/world-state/testing';
32
31
 
33
32
  import getPort from 'get-port';
34
33
  import { type GetContractReturnType, getAddress, getContract } from 'viem';
35
34
  import { privateKeyToAccount } from 'viem/accounts';
36
35
 
36
+ import {
37
+ type EndToEndContext,
38
+ type SetupOptions,
39
+ deployAccounts,
40
+ getPrivateKeyFromIndex,
41
+ getSponsoredFPCAddress,
42
+ setup,
43
+ teardown,
44
+ } from '../fixtures/setup.js';
37
45
  import {
38
46
  ATTESTER_PRIVATE_KEYS_START_INDEX,
39
47
  createValidatorConfig,
40
48
  generatePrivateKeys,
41
49
  } from '../fixtures/setup_p2p_test.js';
42
- import {
43
- type ISnapshotManager,
44
- type SubsystemsContext,
45
- createSnapshotManager,
46
- deployAccounts,
47
- } from '../fixtures/snapshot_manager.js';
48
- import { type SetupOptions, getPrivateKeyFromIndex, getSponsoredFPCAddress } from '../fixtures/utils.js';
49
50
  import { getEndToEndTestTelemetryClient } from '../fixtures/with_telemetry_utils.js';
51
+ import type { TestWallet } from '../test-wallet/test_wallet.js';
50
52
 
51
53
  // Use a fixed bootstrap node private key so that we can re-use the same snapshot and the nodes can find each other
52
54
  const BOOTSTRAP_NODE_PRIVATE_KEY = '080212208f988fc0899e4a73a5aee4d271a5f20670603a756ad8d84f2c94263a6427c591';
@@ -60,14 +62,14 @@ export const SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES = {
60
62
  };
61
63
 
62
64
  export class P2PNetworkTest {
63
- private snapshotManager: ISnapshotManager;
65
+ public context!: EndToEndContext;
64
66
  public baseAccountPrivateKey: `0x${string}`;
65
67
  public baseAccount;
66
68
 
67
69
  public logger: Logger;
68
70
  public monitor!: ChainMonitor;
69
71
 
70
- public ctx!: SubsystemsContext;
72
+ public ctx!: EndToEndContext;
71
73
  public attesterPrivateKeys: `0x${string}`[] = [];
72
74
  public attesterPublicKeys: string[] = [];
73
75
  public peerIdPrivateKeys: string[] = [];
@@ -83,6 +85,10 @@ export class P2PNetworkTest {
83
85
 
84
86
  public bootstrapNode?: BootstrapNode;
85
87
 
88
+ // Store setup options for use in setup()
89
+ private setupOptions: SetupOptions;
90
+ private deployL1ContractsArgs: any;
91
+
86
92
  constructor(
87
93
  public readonly testName: string,
88
94
  public bootstrapNodeEnr: string,
@@ -107,43 +113,42 @@ export class P2PNetworkTest {
107
113
 
108
114
  const zkPassportParams = ZkPassportProofParams.random();
109
115
 
110
- this.snapshotManager = createSnapshotManager(
111
- `e2e_p2p_network/${testName}`,
112
- process.env.E2E_DATA_PATH,
113
- {
114
- ...initialValidatorConfig,
115
- ethereumSlotDuration: initialValidatorConfig.ethereumSlotDuration ?? l1ContractsConfig.ethereumSlotDuration,
116
- aztecEpochDuration: initialValidatorConfig.aztecEpochDuration ?? l1ContractsConfig.aztecEpochDuration,
117
- aztecSlotDuration: initialValidatorConfig.aztecSlotDuration ?? l1ContractsConfig.aztecSlotDuration,
118
- aztecProofSubmissionEpochs:
119
- initialValidatorConfig.aztecProofSubmissionEpochs ?? l1ContractsConfig.aztecProofSubmissionEpochs,
120
- slashingRoundSizeInEpochs:
121
- initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
122
- slasherFlavor: initialValidatorConfig.slasherFlavor ?? 'tally',
123
- aztecTargetCommitteeSize: numberOfValidators,
124
- metricsPort: metricsPort,
125
- numberOfInitialFundedAccounts: 2,
126
- startProverNode,
127
- },
128
- {
129
- ...initialValidatorConfig,
130
- aztecEpochDuration: initialValidatorConfig.aztecEpochDuration ?? l1ContractsConfig.aztecEpochDuration,
131
- slashingRoundSizeInEpochs:
132
- initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
133
- slasherFlavor: initialValidatorConfig.slasherFlavor ?? 'tally',
134
-
135
- ethereumSlotDuration: initialValidatorConfig.ethereumSlotDuration ?? l1ContractsConfig.ethereumSlotDuration,
136
- aztecSlotDuration: initialValidatorConfig.aztecSlotDuration ?? l1ContractsConfig.aztecSlotDuration,
137
- aztecProofSubmissionEpochs:
138
- initialValidatorConfig.aztecProofSubmissionEpochs ?? l1ContractsConfig.aztecProofSubmissionEpochs,
139
- aztecTargetCommitteeSize: numberOfValidators,
140
- initialValidators: [],
141
- zkPassportArgs: {
142
- zkPassportDomain: zkPassportParams.domain,
143
- zkPassportScope: zkPassportParams.scope,
144
- },
116
+ // Store setup options for later use
117
+ this.setupOptions = {
118
+ ...initialValidatorConfig,
119
+ ethereumSlotDuration: initialValidatorConfig.ethereumSlotDuration ?? l1ContractsConfig.ethereumSlotDuration,
120
+ aztecEpochDuration: initialValidatorConfig.aztecEpochDuration ?? l1ContractsConfig.aztecEpochDuration,
121
+ aztecSlotDuration: initialValidatorConfig.aztecSlotDuration ?? l1ContractsConfig.aztecSlotDuration,
122
+ aztecProofSubmissionEpochs:
123
+ initialValidatorConfig.aztecProofSubmissionEpochs ?? l1ContractsConfig.aztecProofSubmissionEpochs,
124
+ slashingRoundSizeInEpochs:
125
+ initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
126
+ slasherFlavor: initialValidatorConfig.slasherFlavor ?? 'tally',
127
+ aztecTargetCommitteeSize: numberOfValidators,
128
+ metricsPort: metricsPort,
129
+ numberOfInitialFundedAccounts: 2,
130
+ startProverNode,
131
+ walletMinFeePadding: 2.0,
132
+ };
133
+
134
+ this.deployL1ContractsArgs = {
135
+ ...initialValidatorConfig,
136
+ aztecEpochDuration: initialValidatorConfig.aztecEpochDuration ?? l1ContractsConfig.aztecEpochDuration,
137
+ slashingRoundSizeInEpochs:
138
+ initialValidatorConfig.slashingRoundSizeInEpochs ?? l1ContractsConfig.slashingRoundSizeInEpochs,
139
+ slasherFlavor: initialValidatorConfig.slasherFlavor ?? 'tally',
140
+
141
+ ethereumSlotDuration: initialValidatorConfig.ethereumSlotDuration ?? l1ContractsConfig.ethereumSlotDuration,
142
+ aztecSlotDuration: initialValidatorConfig.aztecSlotDuration ?? l1ContractsConfig.aztecSlotDuration,
143
+ aztecProofSubmissionEpochs:
144
+ initialValidatorConfig.aztecProofSubmissionEpochs ?? l1ContractsConfig.aztecProofSubmissionEpochs,
145
+ aztecTargetCommitteeSize: numberOfValidators,
146
+ initialValidators: [],
147
+ zkPassportArgs: {
148
+ zkPassportDomain: zkPassportParams.domain,
149
+ zkPassportScope: zkPassportParams.scope,
145
150
  },
146
- );
151
+ };
147
152
  }
148
153
 
149
154
  static async create({
@@ -187,23 +192,22 @@ export class P2PNetworkTest {
187
192
 
188
193
  get fundedAccount() {
189
194
  if (!this.deployedAccounts[0]) {
190
- throw new Error('Call snapshot t.setupAccount to create a funded account.');
195
+ throw new Error('Call setupAccount to create a funded account.');
191
196
  }
192
197
  return this.deployedAccounts[0];
193
198
  }
194
199
 
195
200
  async addBootstrapNode() {
196
- await this.snapshotManager.snapshot('add-bootstrap-node', async ({ aztecNodeConfig }) => {
197
- const telemetry = await getEndToEndTestTelemetryClient(this.metricsPort);
198
- this.bootstrapNode = await createBootstrapNodeFromPrivateKey(
199
- BOOTSTRAP_NODE_PRIVATE_KEY,
200
- this.bootNodePort,
201
- telemetry,
202
- aztecNodeConfig,
203
- );
204
- // Overwrite enr with updated info
205
- this.bootstrapNodeEnr = this.bootstrapNode.getENR().encodeTxt();
206
- });
201
+ this.logger.info('Adding bootstrap node');
202
+ const telemetry = await getEndToEndTestTelemetryClient(this.metricsPort);
203
+ this.bootstrapNode = await createBootstrapNodeFromPrivateKey(
204
+ BOOTSTRAP_NODE_PRIVATE_KEY,
205
+ this.bootNodePort,
206
+ telemetry,
207
+ this.context.config,
208
+ );
209
+ // Overwrite enr with updated info
210
+ this.bootstrapNodeEnr = this.bootstrapNode.getENR().encodeTxt();
207
211
  }
208
212
 
209
213
  getValidators() {
@@ -224,128 +228,114 @@ export class P2PNetworkTest {
224
228
  return { validators };
225
229
  }
226
230
 
227
- async applyBaseSnapshots() {
231
+ async applyBaseSetup() {
228
232
  await this.addBootstrapNode();
229
- await this.snapshotManager.snapshot('add-validators', async ({ deployL1ContractsValues, cheatCodes }) => {
230
- const rollup = getContract({
231
- address: deployL1ContractsValues.l1ContractAddresses.rollupAddress.toString(),
232
- abi: RollupAbi,
233
- client: deployL1ContractsValues.l1Client,
234
- });
235
233
 
236
- this.logger.info(`Adding ${this.numberOfValidators} validators`);
234
+ this.logger.info('Adding validators');
235
+ const rollup = getContract({
236
+ address: this.context.deployL1ContractsValues.l1ContractAddresses.rollupAddress.toString(),
237
+ abi: RollupAbi,
238
+ client: this.context.deployL1ContractsValues.l1Client,
239
+ });
237
240
 
238
- const stakingAsset = getContract({
239
- address: deployL1ContractsValues.l1ContractAddresses.stakingAssetAddress.toString(),
240
- abi: TestERC20Abi,
241
- client: deployL1ContractsValues.l1Client,
242
- });
241
+ this.logger.info(`Adding ${this.numberOfValidators} validators`);
243
242
 
244
- const { address: multiAdderAddress } = await deployL1Contract(
245
- deployL1ContractsValues.l1Client,
246
- MultiAdderArtifact.contractAbi,
247
- MultiAdderArtifact.contractBytecode,
248
- [rollup.address, deployL1ContractsValues.l1Client.account.address],
249
- );
250
-
251
- const multiAdder = getContract({
252
- address: multiAdderAddress.toString(),
253
- abi: MultiAdderArtifact.contractAbi,
254
- client: deployL1ContractsValues.l1Client,
255
- });
243
+ const stakingAsset = getContract({
244
+ address: this.context.deployL1ContractsValues.l1ContractAddresses.stakingAssetAddress.toString(),
245
+ abi: TestERC20Abi,
246
+ client: this.context.deployL1ContractsValues.l1Client,
247
+ });
256
248
 
257
- const stakeNeeded = (await rollup.read.getActivationThreshold()) * BigInt(this.numberOfValidators);
258
- await Promise.all(
259
- [await stakingAsset.write.mint([multiAdder.address, stakeNeeded], {} as any)].map(txHash =>
260
- deployL1ContractsValues.l1Client.waitForTransactionReceipt({ hash: txHash }),
261
- ),
262
- );
263
-
264
- const { validators } = this.getValidators();
265
- this.validators = validators;
266
-
267
- const gseAddress = deployL1ContractsValues.l1ContractAddresses.gseAddress!;
268
- if (!gseAddress) {
269
- throw new Error('GSE contract not deployed');
270
- }
271
-
272
- const gseContract = new GSEContract(deployL1ContractsValues.l1Client, gseAddress.toString());
273
-
274
- const makeValidatorTuples = async (validator: Operator) => {
275
- const registrationTuple = await gseContract.makeRegistrationTuple(validator.bn254SecretKey.getValue());
276
- return {
277
- attester: validator.attester.toString() as `0x${string}`,
278
- withdrawer: validator.withdrawer.toString() as `0x${string}`,
279
- ...registrationTuple,
280
- };
281
- };
282
- const validatorTuples = await Promise.all(validators.map(makeValidatorTuples));
249
+ const { address: multiAdderAddress } = await deployL1Contract(
250
+ this.context.deployL1ContractsValues.l1Client,
251
+ MultiAdderArtifact.contractAbi,
252
+ MultiAdderArtifact.contractBytecode,
253
+ [rollup.address, this.context.deployL1ContractsValues.l1Client.account.address],
254
+ );
283
255
 
284
- await deployL1ContractsValues.l1Client.waitForTransactionReceipt({
285
- hash: await multiAdder.write.addValidators([validatorTuples]),
286
- });
256
+ const multiAdder = getContract({
257
+ address: multiAdderAddress.toString(),
258
+ abi: MultiAdderArtifact.contractAbi,
259
+ client: this.context.deployL1ContractsValues.l1Client,
260
+ });
261
+
262
+ const stakeNeeded = (await rollup.read.getActivationThreshold()) * BigInt(this.numberOfValidators);
263
+ await Promise.all(
264
+ [await stakingAsset.write.mint([multiAdder.address, stakeNeeded], {} as any)].map(txHash =>
265
+ this.context.deployL1ContractsValues.l1Client.waitForTransactionReceipt({ hash: txHash }),
266
+ ),
267
+ );
287
268
 
288
- await cheatCodes.rollup.advanceToEpoch(
289
- EpochNumber.fromBigInt(
290
- BigInt(await cheatCodes.rollup.getEpoch()) + (await rollup.read.getLagInEpochsForValidatorSet()) + 1n,
291
- ),
292
- );
269
+ const { validators } = this.getValidators();
270
+ this.validators = validators;
293
271
 
294
- // Send and await a tx to make sure we mine a block for the warp to correctly progress.
295
- await this._sendDummyTx(deployL1ContractsValues.l1Client);
272
+ const gseAddress = this.context.deployL1ContractsValues.l1ContractAddresses.gseAddress!;
273
+ if (!gseAddress) {
274
+ throw new Error('GSE contract not deployed');
275
+ }
276
+
277
+ const gseContract = new GSEContract(this.context.deployL1ContractsValues.l1Client, gseAddress.toString());
278
+
279
+ const makeValidatorTuples = async (validator: Operator) => {
280
+ const registrationTuple = await gseContract.makeRegistrationTuple(validator.bn254SecretKey.getValue());
281
+ return {
282
+ attester: validator.attester.toString() as `0x${string}`,
283
+ withdrawer: validator.withdrawer.toString() as `0x${string}`,
284
+ ...registrationTuple,
285
+ };
286
+ };
287
+ const validatorTuples = await Promise.all(validators.map(makeValidatorTuples));
288
+
289
+ await this.context.deployL1ContractsValues.l1Client.waitForTransactionReceipt({
290
+ hash: await multiAdder.write.addValidators([validatorTuples]),
296
291
  });
292
+
293
+ await this.context.cheatCodes.rollup.advanceToEpoch(
294
+ EpochNumber.fromBigInt(
295
+ BigInt(await this.context.cheatCodes.rollup.getEpoch()) +
296
+ (await rollup.read.getLagInEpochsForValidatorSet()) +
297
+ 1n,
298
+ ),
299
+ );
300
+
301
+ // Send and await a tx to make sure we mine a block for the warp to correctly progress.
302
+ await this._sendDummyTx(this.context.deployL1ContractsValues.l1Client);
297
303
  }
298
304
 
299
305
  async setupAccount() {
300
- await this.snapshotManager.snapshot(
301
- 'setup-account',
302
- deployAccounts(1, this.logger),
303
- ({ deployedAccounts }, { wallet }) => {
304
- this.deployedAccounts = deployedAccounts;
305
- [{ address: this.defaultAccountAddress }] = deployedAccounts;
306
- this.wallet = wallet;
307
- return Promise.resolve();
308
- },
309
- );
306
+ this.logger.info('Setting up account');
307
+ const { deployedAccounts } = await deployAccounts(
308
+ 1,
309
+ this.logger,
310
+ )({
311
+ wallet: this.context.wallet,
312
+ initialFundedAccounts: this.context.initialFundedAccounts,
313
+ });
314
+ this.deployedAccounts = deployedAccounts;
315
+ [{ address: this.defaultAccountAddress }] = deployedAccounts;
316
+ this.wallet = this.context.wallet;
310
317
  }
311
318
 
312
319
  async deploySpamContract() {
313
- await this.snapshotManager.snapshot(
314
- 'add-spam-contract',
315
- async () => {
316
- if (!this.wallet) {
317
- throw new Error('Call snapshot t.setupAccount before deploying account contract');
318
- }
319
-
320
- const spamContract = await SpamContract.deploy(this.wallet)
321
- .send({ from: this.defaultAccountAddress! })
322
- .deployed();
323
- return { contractAddress: spamContract.address };
324
- },
325
- ({ contractAddress }) => {
326
- if (!this.wallet) {
327
- throw new Error('Call snapshot t.setupAccount before deploying account contract');
328
- }
329
- this.spamContract = SpamContract.at(contractAddress, this.wallet);
330
- return Promise.resolve();
331
- },
332
- );
320
+ this.logger.info('Deploying spam contract');
321
+ if (!this.wallet) {
322
+ throw new Error('Call setupAccount before deploying spam contract');
323
+ }
324
+
325
+ const spamContract = await SpamContract.deploy(this.wallet).send({ from: this.defaultAccountAddress! });
326
+ this.spamContract = spamContract;
333
327
  }
334
328
 
335
329
  async removeInitialNode() {
336
- await this.snapshotManager.snapshot(
337
- 'remove-initial-validator',
338
- async ({ deployL1ContractsValues, aztecNode, dateProvider }) => {
339
- // Send and await a tx to make sure we mine a block for the warp to correctly progress.
340
- const { receipt } = await this._sendDummyTx(deployL1ContractsValues.l1Client);
341
- const block = await deployL1ContractsValues.l1Client.getBlock({
342
- blockNumber: receipt.blockNumber,
343
- });
344
- dateProvider.setTime(Number(block.timestamp) * 1000);
345
-
346
- await aztecNode.stop();
347
- },
348
- );
330
+ this.logger.info('Removing initial node');
331
+ // Send and await a tx to make sure we mine a block for the warp to correctly progress.
332
+ const { receipt } = await this._sendDummyTx(this.context.deployL1ContractsValues.l1Client);
333
+ const block = await this.context.deployL1ContractsValues.l1Client.getBlock({
334
+ blockNumber: receipt.blockNumber,
335
+ });
336
+ this.context.dateProvider.setTime(Number(block.timestamp) * 1000);
337
+
338
+ await this.context.aztecNodeService.stop();
349
339
  }
350
340
 
351
341
  async sendDummyTx() {
@@ -361,17 +351,31 @@ export class P2PNetworkTest {
361
351
  }
362
352
 
363
353
  async setup() {
364
- this.ctx = await this.snapshotManager.setup();
354
+ this.logger.info('Setting up subsystems from fresh');
355
+ this.context = await setup(
356
+ 0,
357
+ {
358
+ ...this.setupOptions,
359
+ fundSponsoredFPC: true,
360
+ skipAccountDeployment: true,
361
+ slasherFlavor: this.setupOptions.slasherFlavor ?? this.deployL1ContractsArgs.slasherFlavor ?? 'none',
362
+ aztecTargetCommitteeSize: 0,
363
+ l1ContractsArgs: this.deployL1ContractsArgs,
364
+ },
365
+ // Use checkpointed chain tip for PXE to avoid issues with blocks being dropped due to pruned anchor blocks.
366
+ { syncChainTip: 'checkpointed' },
367
+ );
368
+ this.ctx = this.context;
365
369
 
366
370
  const sponsoredFPCAddress = await getSponsoredFPCAddress();
367
- const initialFundedAccounts = [...this.ctx.initialFundedAccounts.map(a => a.address), sponsoredFPCAddress];
371
+ const initialFundedAccounts = [...this.context.initialFundedAccounts.map(a => a.address), sponsoredFPCAddress];
368
372
 
369
373
  const { prefilledPublicData } = await getGenesisValues(initialFundedAccounts);
370
374
  this.prefilledPublicData = prefilledPublicData;
371
375
 
372
- const rollupContract = RollupContract.getFromL1ContractsValues(this.ctx.deployL1ContractsValues);
373
- this.monitor = new ChainMonitor(rollupContract, this.ctx.dateProvider).start();
374
- this.monitor.on('l1-block', ({ timestamp }) => this.ctx.dateProvider.setTime(Number(timestamp) * 1000));
376
+ const rollupContract = RollupContract.getFromL1ContractsValues(this.context.deployL1ContractsValues);
377
+ this.monitor = new ChainMonitor(rollupContract, this.context.dateProvider).start();
378
+ this.monitor.on('l1-block', ({ timestamp }) => this.context.dateProvider.setTime(Number(timestamp) * 1000));
375
379
  }
376
380
 
377
381
  async stopNodes(nodes: AztecNodeService[]) {
@@ -432,7 +436,7 @@ export class P2PNetworkTest {
432
436
  async teardown() {
433
437
  await this.monitor.stop();
434
438
  await tryStop(this.bootstrapNode, this.logger);
435
- await this.snapshotManager.teardown();
439
+ await teardown(this.context);
436
440
  }
437
441
 
438
442
  async getContracts(): Promise<{
@@ -0,0 +1,207 @@
1
+ import type { AztecNodeService } from '@aztec/aztec-node';
2
+ import { createLogger } from '@aztec/aztec.js/log';
3
+ import { waitForTx } from '@aztec/aztec.js/node';
4
+ import { Tx } from '@aztec/aztec.js/tx';
5
+ import { RollupContract } from '@aztec/ethereum/contracts';
6
+ import { SlotNumber } from '@aztec/foundation/branded-types';
7
+ import { timesAsync } from '@aztec/foundation/collection';
8
+ import { retryUntil } from '@aztec/foundation/retry';
9
+
10
+ import { jest } from '@jest/globals';
11
+ import fs from 'fs';
12
+ import os from 'os';
13
+ import path from 'path';
14
+
15
+ import { shouldCollectMetrics } from '../../fixtures/fixtures.js';
16
+ import { createNodes } from '../../fixtures/setup_p2p_test.js';
17
+ import { P2PNetworkTest, SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES, WAIT_FOR_TX_TIMEOUT } from '../p2p_network.js';
18
+ import { prepareTransactions } from '../shared.js';
19
+
20
+ // Don't set this to a higher value than 9 because each node will use a different L1 publisher account and anvil seeds
21
+ export const NUM_VALIDATORS = 6;
22
+ export const NUM_TXS_PER_NODE = 2;
23
+ export const BOOT_NODE_UDP_PORT = 4500;
24
+
25
+ export const createReqrespDataDir = () => fs.mkdtempSync(path.join(os.tmpdir(), 'reqresp-'));
26
+
27
+ type ReqrespOptions = {
28
+ disableStatusHandshake?: boolean;
29
+ };
30
+
31
+ export async function createReqrespTest(options: ReqrespOptions = {}): Promise<P2PNetworkTest> {
32
+ const { disableStatusHandshake = false } = options;
33
+ const t = await P2PNetworkTest.create({
34
+ testName: 'e2e_p2p_reqresp_tx',
35
+ numberOfNodes: 0,
36
+ numberOfValidators: NUM_VALIDATORS,
37
+ basePort: BOOT_NODE_UDP_PORT,
38
+ // To collect metrics - run in aztec-packages `docker compose --profile metrics up`
39
+ metricsPort: shouldCollectMetrics(),
40
+ initialConfig: {
41
+ ...SHORTENED_BLOCK_TIME_CONFIG_NO_PRUNES,
42
+ aztecSlotDuration: 24,
43
+ ...(disableStatusHandshake ? { p2pDisableStatusHandshake: true } : {}),
44
+ listenAddress: '127.0.0.1',
45
+ aztecEpochDuration: 64, // stable committee
46
+ },
47
+ });
48
+ await t.setup();
49
+ await t.applyBaseSetup();
50
+ return t;
51
+ }
52
+
53
+ export async function cleanupReqrespTest(params: { t: P2PNetworkTest; nodes?: AztecNodeService[]; dataDir: string }) {
54
+ const { t, nodes, dataDir } = params;
55
+ if (nodes) {
56
+ await t.stopNodes(nodes);
57
+ }
58
+ await t.teardown();
59
+ for (let i = 0; i < NUM_VALIDATORS; i++) {
60
+ fs.rmSync(`${dataDir}-${i}`, { recursive: true, force: true, maxRetries: 3 });
61
+ }
62
+ }
63
+
64
+ const getNodePort = (nodeIndex: number) => BOOT_NODE_UDP_PORT + 1 + nodeIndex;
65
+
66
+ export async function runReqrespTxTest(params: {
67
+ t: P2PNetworkTest;
68
+ dataDir: string;
69
+ disableStatusHandshake?: boolean;
70
+ }): Promise<AztecNodeService[]> {
71
+ const { t, dataDir, disableStatusHandshake = false } = params;
72
+
73
+ if (!t.bootstrapNodeEnr) {
74
+ throw new Error('Bootstrap node ENR is not available');
75
+ }
76
+
77
+ t.logger.info('Creating nodes');
78
+ const aztecNodeConfig = disableStatusHandshake
79
+ ? { ...t.ctx.aztecNodeConfig, p2pDisableStatusHandshake: true }
80
+ : t.ctx.aztecNodeConfig;
81
+
82
+ const nodes = await createNodes(
83
+ aztecNodeConfig,
84
+ t.ctx.dateProvider,
85
+ t.bootstrapNodeEnr,
86
+ NUM_VALIDATORS,
87
+ BOOT_NODE_UDP_PORT,
88
+ t.prefilledPublicData,
89
+ dataDir,
90
+ shouldCollectMetrics(),
91
+ );
92
+
93
+ t.logger.info('Waiting for nodes to connect');
94
+ await t.waitForP2PMeshConnectivity(nodes, NUM_VALIDATORS);
95
+
96
+ await t.setupAccount();
97
+
98
+ const targetBlockNumber = await t.ctx.aztecNodeService.getBlockNumber();
99
+ await retryUntil(
100
+ async () => {
101
+ const blockNumbers = await Promise.all(nodes.map(node => node.getBlockNumber()));
102
+ return blockNumbers.every(blockNumber => blockNumber >= targetBlockNumber) ? true : undefined;
103
+ },
104
+ `validators to sync to L2 block ${targetBlockNumber}`,
105
+ 60,
106
+ 0.5,
107
+ );
108
+
109
+ t.logger.info('Preparing transactions to send');
110
+ const txBatches = await timesAsync(2, () =>
111
+ prepareTransactions(t.logger, t.ctx.aztecNodeService, NUM_TXS_PER_NODE, t.fundedAccount),
112
+ );
113
+
114
+ t.logger.info('Removing initial node');
115
+ await t.removeInitialNode();
116
+
117
+ t.logger.info('Starting fresh slot');
118
+ const [timestamp] = await t.ctx.cheatCodes.rollup.advanceToNextSlot();
119
+ t.ctx.dateProvider.setTime(Number(timestamp) * 1000);
120
+ const startSlotTimestamp = BigInt(timestamp);
121
+
122
+ const { proposerIndexes, nodesToTurnOffTxGossip } = await getProposerIndexes(t, startSlotTimestamp);
123
+ t.logger.info(`Turning off tx gossip for nodes: ${nodesToTurnOffTxGossip.map(getNodePort)}`);
124
+ t.logger.info(`Sending txs to proposer nodes: ${proposerIndexes.map(getNodePort)}`);
125
+
126
+ // Replace the p2p node implementation of some of the nodes with a spy such that it does not store transactions that are gossiped to it
127
+ // Original implementation of `handleGossipedTx` will store received transactions in the tx pool.
128
+ // We chose the first 2 nodes that will be the proposers for the next few slots
129
+ for (const nodeIndex of nodesToTurnOffTxGossip) {
130
+ const logger = createLogger(`p2p:${getNodePort(nodeIndex)}`);
131
+ jest.spyOn((nodes[nodeIndex] as any).p2pClient.p2pService, 'handleGossipedTx').mockImplementation(((
132
+ payloadData: Buffer,
133
+ ) => {
134
+ const txHash = Tx.fromBuffer(payloadData).getTxHash();
135
+ logger.info(`Skipping storage of gossiped transaction ${txHash.toString()}`);
136
+ return Promise.resolve();
137
+ }) as any);
138
+ }
139
+
140
+ // We send the tx to the proposer nodes directly, ignoring the pxe and node in each context
141
+ // We cannot just call tx.send since they were created using a pxe wired to the first node which is now stopped
142
+ t.logger.info('Sending transactions through proposer nodes');
143
+ const submittedTxs = await Promise.all(
144
+ txBatches.map(async (batch, batchIndex) => {
145
+ const proposerNode = nodes[proposerIndexes[batchIndex]];
146
+ await Promise.all(
147
+ batch.map(async tx => {
148
+ try {
149
+ await proposerNode.sendTx(tx);
150
+ } catch (err) {
151
+ t.logger.error(`Error sending tx: ${err}`);
152
+ throw err;
153
+ }
154
+ }),
155
+ );
156
+ return batch.map(tx => ({ node: proposerNode, txHash: tx.getTxHash() }));
157
+ }),
158
+ );
159
+
160
+ t.logger.info('Waiting for all transactions to be mined');
161
+ await Promise.all(
162
+ submittedTxs.flatMap((batch, batchIndex) =>
163
+ batch.map(async (submittedTx, txIndex) => {
164
+ t.logger.info(`Waiting for tx ${batchIndex}-${txIndex} ${submittedTx.txHash.toString()} to be mined`);
165
+ await waitForTx(submittedTx.node, submittedTx.txHash, { timeout: WAIT_FOR_TX_TIMEOUT * 1.5 });
166
+ t.logger.info(`Tx ${batchIndex}-${txIndex} ${submittedTx.txHash.toString()} has been mined`);
167
+ }),
168
+ ),
169
+ );
170
+
171
+ t.logger.info('All transactions mined');
172
+
173
+ return nodes;
174
+ }
175
+
176
+ async function getProposerIndexes(t: P2PNetworkTest, startSlotTimestamp: bigint) {
177
+ // Get the nodes for the next set of slots
178
+ const rollupContract = new RollupContract(
179
+ t.ctx.deployL1ContractsValues.l1Client,
180
+ t.ctx.deployL1ContractsValues.l1ContractAddresses.rollupAddress,
181
+ );
182
+
183
+ const attesters = await rollupContract.getAttesters();
184
+ const startSlot = await rollupContract.getSlotAt(startSlotTimestamp);
185
+
186
+ const proposers = await Promise.all(
187
+ Array.from({ length: 3 }, async (_, i) => {
188
+ const slot = SlotNumber(startSlot + i);
189
+ const slotTimestamp = await rollupContract.getTimestampForSlot(slot);
190
+ return await rollupContract.getProposerAt(slotTimestamp);
191
+ }),
192
+ );
193
+ // Get the indexes of the nodes that are responsible for the next two slots
194
+ const proposerIndexes = proposers.map(proposer => attesters.findIndex(a => a.equals(proposer)));
195
+
196
+ if (proposerIndexes.some(i => i === -1)) {
197
+ throw new Error(
198
+ `Proposer index not found for proposer ` +
199
+ `(proposers=${proposers.map(p => p.toString()).join(',')}, indices=${proposerIndexes.join(',')})`,
200
+ );
201
+ }
202
+
203
+ const nodesToTurnOffTxGossip = Array.from({ length: NUM_VALIDATORS }, (_, i) => i).filter(
204
+ i => !proposerIndexes.includes(i),
205
+ );
206
+ return { proposerIndexes, nodesToTurnOffTxGossip };
207
+ }