@aztec/aztec 0.0.1-commit.aada20e3 → 0.0.1-commit.b2a5d0dd1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/dest/bin/index.js +7 -3
  2. package/dest/cli/admin_api_key_store.d.ts +45 -0
  3. package/dest/cli/admin_api_key_store.d.ts.map +1 -0
  4. package/dest/cli/admin_api_key_store.js +98 -0
  5. package/dest/cli/aztec_start_action.d.ts +1 -1
  6. package/dest/cli/aztec_start_action.d.ts.map +1 -1
  7. package/dest/cli/aztec_start_action.js +72 -18
  8. package/dest/cli/aztec_start_options.d.ts +2 -2
  9. package/dest/cli/aztec_start_options.d.ts.map +1 -1
  10. package/dest/cli/aztec_start_options.js +38 -9
  11. package/dest/cli/cli.d.ts +1 -1
  12. package/dest/cli/cli.d.ts.map +1 -1
  13. package/dest/cli/cli.js +3 -4
  14. package/dest/cli/cmds/compile.d.ts +4 -0
  15. package/dest/cli/cmds/compile.d.ts.map +1 -0
  16. package/dest/cli/cmds/compile.js +155 -0
  17. package/dest/cli/cmds/profile.d.ts +4 -0
  18. package/dest/cli/cmds/profile.d.ts.map +1 -0
  19. package/dest/cli/cmds/profile.js +8 -0
  20. package/dest/cli/cmds/profile_flamegraph.d.ts +4 -0
  21. package/dest/cli/cmds/profile_flamegraph.d.ts.map +1 -0
  22. package/dest/cli/cmds/profile_flamegraph.js +52 -0
  23. package/dest/cli/cmds/profile_gates.d.ts +4 -0
  24. package/dest/cli/cmds/profile_gates.d.ts.map +1 -0
  25. package/dest/cli/cmds/profile_gates.js +58 -0
  26. package/dest/cli/cmds/profile_utils.d.ts +18 -0
  27. package/dest/cli/cmds/profile_utils.d.ts.map +1 -0
  28. package/dest/cli/cmds/profile_utils.js +50 -0
  29. package/dest/cli/cmds/standby.d.ts +32 -0
  30. package/dest/cli/cmds/standby.d.ts.map +1 -0
  31. package/dest/cli/cmds/standby.js +97 -0
  32. package/dest/cli/cmds/start_archiver.d.ts +2 -2
  33. package/dest/cli/cmds/start_archiver.d.ts.map +1 -1
  34. package/dest/cli/cmds/start_archiver.js +4 -2
  35. package/dest/cli/cmds/start_bot.d.ts +3 -3
  36. package/dest/cli/cmds/start_bot.d.ts.map +1 -1
  37. package/dest/cli/cmds/start_bot.js +9 -5
  38. package/dest/cli/cmds/start_node.d.ts +3 -2
  39. package/dest/cli/cmds/start_node.d.ts.map +1 -1
  40. package/dest/cli/cmds/start_node.js +73 -31
  41. package/dest/cli/cmds/start_prover_agent.d.ts +1 -1
  42. package/dest/cli/cmds/start_prover_agent.d.ts.map +1 -1
  43. package/dest/cli/cmds/start_prover_agent.js +3 -15
  44. package/dest/cli/cmds/start_prover_broker.d.ts +1 -1
  45. package/dest/cli/cmds/start_prover_broker.d.ts.map +1 -1
  46. package/dest/cli/cmds/start_prover_broker.js +12 -6
  47. package/dest/cli/cmds/utils/artifacts.d.ts +21 -0
  48. package/dest/cli/cmds/utils/artifacts.d.ts.map +1 -0
  49. package/dest/cli/cmds/utils/artifacts.js +24 -0
  50. package/dest/cli/cmds/utils/collect_crate_dirs.d.ts +21 -0
  51. package/dest/cli/cmds/utils/collect_crate_dirs.d.ts.map +1 -0
  52. package/dest/cli/cmds/utils/collect_crate_dirs.js +114 -0
  53. package/dest/cli/cmds/utils/needs_recompile.d.ts +10 -0
  54. package/dest/cli/cmds/utils/needs_recompile.d.ts.map +1 -0
  55. package/dest/cli/cmds/utils/needs_recompile.js +90 -0
  56. package/dest/cli/cmds/utils/spawn.d.ts +3 -0
  57. package/dest/cli/cmds/utils/spawn.d.ts.map +1 -0
  58. package/dest/cli/cmds/utils/spawn.js +16 -0
  59. package/dest/cli/cmds/utils/warn_if_aztec_version_mismatch.d.ts +4 -0
  60. package/dest/cli/cmds/utils/warn_if_aztec_version_mismatch.d.ts.map +1 -0
  61. package/dest/cli/cmds/utils/warn_if_aztec_version_mismatch.js +62 -0
  62. package/dest/cli/util.d.ts +7 -18
  63. package/dest/cli/util.d.ts.map +1 -1
  64. package/dest/cli/util.js +50 -86
  65. package/dest/examples/token.js +6 -6
  66. package/dest/local-network/banana_fpc.js +1 -1
  67. package/dest/local-network/local-network.d.ts +5 -4
  68. package/dest/local-network/local-network.d.ts.map +1 -1
  69. package/dest/local-network/local-network.js +53 -21
  70. package/dest/testing/anvil_test_watcher.d.ts +15 -3
  71. package/dest/testing/anvil_test_watcher.d.ts.map +1 -1
  72. package/dest/testing/anvil_test_watcher.js +85 -22
  73. package/dest/testing/cheat_codes.d.ts +11 -15
  74. package/dest/testing/cheat_codes.d.ts.map +1 -1
  75. package/dest/testing/cheat_codes.js +34 -32
  76. package/dest/testing/epoch_test_settler.d.ts +1 -1
  77. package/dest/testing/epoch_test_settler.d.ts.map +1 -1
  78. package/dest/testing/epoch_test_settler.js +3 -4
  79. package/dest/testing/index.d.ts +3 -2
  80. package/dest/testing/index.d.ts.map +1 -1
  81. package/dest/testing/index.js +1 -0
  82. package/dest/testing/token_allowed_setup.d.ts +7 -0
  83. package/dest/testing/token_allowed_setup.d.ts.map +1 -0
  84. package/dest/testing/token_allowed_setup.js +20 -0
  85. package/package.json +34 -34
  86. package/scripts/add_crate.sh +102 -0
  87. package/scripts/aztec.sh +15 -5
  88. package/scripts/init.sh +23 -19
  89. package/scripts/new.sh +48 -24
  90. package/scripts/setup_workspace.sh +68 -0
  91. package/src/bin/index.ts +7 -3
  92. package/src/cli/admin_api_key_store.ts +128 -0
  93. package/src/cli/aztec_start_action.ts +65 -14
  94. package/src/cli/aztec_start_options.ts +46 -10
  95. package/src/cli/cli.ts +3 -4
  96. package/src/cli/cmds/compile.ts +178 -0
  97. package/src/cli/cmds/profile.ts +25 -0
  98. package/src/cli/cmds/profile_flamegraph.ts +64 -0
  99. package/src/cli/cmds/profile_gates.ts +68 -0
  100. package/src/cli/cmds/profile_utils.ts +58 -0
  101. package/src/cli/cmds/standby.ts +132 -0
  102. package/src/cli/cmds/start_archiver.ts +8 -2
  103. package/src/cli/cmds/start_bot.ts +8 -5
  104. package/src/cli/cmds/start_node.ts +83 -35
  105. package/src/cli/cmds/start_prover_agent.ts +3 -6
  106. package/src/cli/cmds/start_prover_broker.ts +14 -14
  107. package/src/cli/cmds/utils/artifacts.ts +44 -0
  108. package/src/cli/cmds/utils/collect_crate_dirs.ts +118 -0
  109. package/src/cli/cmds/utils/needs_recompile.ts +98 -0
  110. package/src/cli/cmds/utils/spawn.ts +16 -0
  111. package/src/cli/cmds/utils/warn_if_aztec_version_mismatch.ts +77 -0
  112. package/src/cli/util.ts +57 -95
  113. package/src/examples/token.ts +8 -6
  114. package/src/local-network/banana_fpc.ts +1 -1
  115. package/src/local-network/local-network.ts +59 -22
  116. package/src/testing/anvil_test_watcher.ts +95 -20
  117. package/src/testing/cheat_codes.ts +42 -36
  118. package/src/testing/epoch_test_settler.ts +3 -4
  119. package/src/testing/index.ts +2 -1
  120. package/src/testing/token_allowed_setup.ts +19 -0
  121. package/dest/cli/cmds/start_prover_node.d.ts +0 -7
  122. package/dest/cli/cmds/start_prover_node.d.ts.map +0 -1
  123. package/dest/cli/cmds/start_prover_node.js +0 -108
  124. package/dest/cli/release_version.d.ts +0 -2
  125. package/dest/cli/release_version.d.ts.map +0 -1
  126. package/dest/cli/release_version.js +0 -14
  127. package/scripts/compile.sh +0 -44
  128. package/scripts/extract_function.js +0 -47
  129. package/scripts/flamegraph.sh +0 -59
  130. package/scripts/setup_project.sh +0 -31
  131. package/src/cli/cmds/start_prover_node.ts +0 -124
  132. package/src/cli/release_version.ts +0 -21
@@ -9,6 +9,11 @@ import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
9
9
 
10
10
  import { type GetContractReturnType, getAddress, getContract } from 'viem';
11
11
 
12
+ export type AnvilTestWatcherOpts = {
13
+ isLocalNetwork?: boolean;
14
+ isMarkingAsProven?: boolean;
15
+ };
16
+
12
17
  /**
13
18
  * Represents a watcher for a rollup contract.
14
19
  *
@@ -17,7 +22,8 @@ import { type GetContractReturnType, getAddress, getContract } from 'viem';
17
22
  * block within the slot. And if so, it will time travel into the next slot.
18
23
  */
19
24
  export class AnvilTestWatcher {
20
- private isLocalNetwork: boolean = false;
25
+ private isLocalNetwork;
26
+ private isMarkingAsProven;
21
27
 
22
28
  private rollup: GetContractReturnType<typeof RollupAbi, ViemClient>;
23
29
  private rollupCheatCodes: RollupCheatCodes;
@@ -29,13 +35,21 @@ export class AnvilTestWatcher {
29
35
 
30
36
  private logger: Logger = createLogger(`aztecjs:utils:watcher`);
31
37
 
32
- private isMarkingAsProven = true;
38
+ // Optional callback to check if there are pending txs in the mempool.
39
+ private getPendingTxCount?: () => Promise<number>;
40
+
41
+ // Optional callback to check if the sequencer is actively building a block.
42
+ private isSequencerBuilding?: () => boolean;
43
+
44
+ // Tracks when we first observed the current unfilled slot with pending txs (real wall time).
45
+ private unfilledSlotFirstSeen?: { slot: number; realTime: number };
33
46
 
34
47
  constructor(
35
48
  private cheatcodes: EthCheatCodes,
36
49
  rollupAddress: EthAddress,
37
50
  l1Client: ViemClient,
38
51
  private dateProvider?: TestDateProvider,
52
+ opts: AnvilTestWatcherOpts = {},
39
53
  ) {
40
54
  this.rollup = getContract({
41
55
  address: getAddress(rollupAddress.toString()),
@@ -47,6 +61,9 @@ export class AnvilTestWatcher {
47
61
  rollupAddress,
48
62
  });
49
63
 
64
+ this.isLocalNetwork = opts.isLocalNetwork ?? false;
65
+ this.isMarkingAsProven = opts.isMarkingAsProven ?? true;
66
+
50
67
  this.logger.debug(`Watcher created for rollup at ${rollupAddress}`);
51
68
  }
52
69
 
@@ -59,6 +76,16 @@ export class AnvilTestWatcher {
59
76
  this.isLocalNetwork = isLocalNetwork;
60
77
  }
61
78
 
79
+ /** Sets a callback to check for pending txs, used to skip unfilled slots faster when txs are waiting. */
80
+ setGetPendingTxCount(fn: () => Promise<number>) {
81
+ this.getPendingTxCount = fn;
82
+ }
83
+
84
+ /** Sets a callback to check if the sequencer is actively building, to avoid warping while it works. */
85
+ setIsSequencerBuilding(fn: () => boolean) {
86
+ this.isSequencerBuilding = fn;
87
+ }
88
+
62
89
  async start() {
63
90
  if (this.filledRunningPromise) {
64
91
  throw new Error('Watcher already watching for filled slot');
@@ -111,14 +138,21 @@ export class AnvilTestWatcher {
111
138
  return;
112
139
  }
113
140
 
114
- const l1Time = (await this.cheatcodes.timestamp()) * 1000;
141
+ const l1Time = (await this.cheatcodes.lastBlockTimestamp()) * 1000;
115
142
  const wallTime = this.dateProvider.now();
116
143
  if (l1Time > wallTime) {
117
144
  this.logger.warn(`L1 is ahead of wall time. Syncing wall time to L1 time`);
118
145
  this.dateProvider.setTime(l1Time);
119
146
  } else if (l1Time + Number(this.l2SlotDuration) * 1000 < wallTime) {
120
- this.logger.warn(`L1 is more than 1 L2 slot behind wall time. Warping to wall time`);
121
- await this.cheatcodes.warp(Math.ceil(wallTime / 1000));
147
+ // Warp L1 to the slot boundary at-or-before wall time. Rounding to a slot boundary (rather than
148
+ // `ceil(wallTime / 1000)`) keeps this loop's target aligned with `warpTimeIfNeeded`'s
149
+ // `nextSlotTimestamp` target, avoiding a race where the two loops pick timestamps a fraction of
150
+ // a second apart and one of them is then rejected by anvil as non-monotonic.
151
+ const wallSec = Math.floor(wallTime / 1000);
152
+ const targetSlot = await this.rollup.read.getSlotAt([BigInt(wallSec)]);
153
+ const targetTimestamp = Number(await this.rollup.read.getTimestampForSlot([targetSlot]));
154
+ this.logger.warn(`L1 is more than 1 L2 slot behind wall time. Warping to slot ${targetSlot} boundary`);
155
+ await this.warpToTimestamp(targetTimestamp);
122
156
  }
123
157
  }
124
158
 
@@ -131,16 +165,10 @@ export class AnvilTestWatcher {
131
165
  const nextSlotTimestamp = Number(await this.rollup.read.getTimestampForSlot([BigInt(nextSlot)]));
132
166
 
133
167
  if (BigInt(currentSlot) === checkpointLog.slotNumber) {
134
- // We should jump to the next slot
135
- try {
136
- await this.cheatcodes.warp(nextSlotTimestamp, {
137
- resetBlockInterval: true,
138
- });
139
- } catch (e) {
140
- this.logger.error(`Failed to warp to timestamp ${nextSlotTimestamp}: ${e}`);
168
+ // The current slot has been filled, we should jump to the next slot.
169
+ if (await this.warpToTimestamp(nextSlotTimestamp)) {
170
+ this.logger.info(`Slot ${currentSlot} was filled, jumped to next slot`);
141
171
  }
142
-
143
- this.logger.info(`Slot ${currentSlot} was filled, jumped to next slot`);
144
172
  return;
145
173
  }
146
174
 
@@ -149,18 +177,65 @@ export class AnvilTestWatcher {
149
177
  return;
150
178
  }
151
179
 
180
+ // If there are pending txs and the sequencer missed them, warp quickly (after a 2s real-time debounce) so the
181
+ // sequencer can retry in the next slot. Without this, we'd have to wait a full real-time slot duration (~36s) for
182
+ // the dateProvider to catch up to the next slot timestamp. We skip the warp if the sequencer is actively building
183
+ // to avoid invalidating its in-progress work.
184
+ if (this.getPendingTxCount) {
185
+ const pendingTxs = await this.getPendingTxCount();
186
+ if (pendingTxs > 0) {
187
+ if (this.isSequencerBuilding?.()) {
188
+ this.unfilledSlotFirstSeen = undefined;
189
+ return;
190
+ }
191
+
192
+ const realNow = Date.now();
193
+ if (!this.unfilledSlotFirstSeen || this.unfilledSlotFirstSeen.slot !== currentSlot) {
194
+ this.unfilledSlotFirstSeen = { slot: currentSlot, realTime: realNow };
195
+ return;
196
+ }
197
+
198
+ if (realNow - this.unfilledSlotFirstSeen.realTime > 2000) {
199
+ if (await this.warpToTimestamp(nextSlotTimestamp)) {
200
+ this.logger.info(`Slot ${currentSlot} was missed with pending txs, jumped to next slot`);
201
+ }
202
+ this.unfilledSlotFirstSeen = undefined;
203
+ }
204
+
205
+ return;
206
+ }
207
+ }
208
+
209
+ // Fallback: warp when the dateProvider time has passed the next slot timestamp.
152
210
  const currentTimestamp = this.dateProvider?.now() ?? Date.now();
153
211
  if (currentTimestamp > nextSlotTimestamp * 1000) {
154
- try {
155
- await this.cheatcodes.warp(nextSlotTimestamp, { resetBlockInterval: true });
156
- } catch (e) {
157
- this.logger.error(`Failed to warp to timestamp ${nextSlotTimestamp}: ${e}`);
212
+ if (await this.warpToTimestamp(nextSlotTimestamp)) {
213
+ this.logger.info(`Slot ${currentSlot} was missed, jumped to next slot`);
158
214
  }
159
-
160
- this.logger.info(`Slot ${currentSlot} was missed, jumped to next slot`);
161
215
  }
162
216
  } catch {
163
217
  this.logger.error('mineIfSlotFilled failed');
164
218
  }
165
219
  }
220
+
221
+ /**
222
+ * Warps L1 to `timestamp`, unless L1 is already at or past it. Returns true when a warp actually
223
+ * happened, false when skipped or on error. Callers use the return value to gate success logs.
224
+ */
225
+ private async warpToTimestamp(timestamp: number): Promise<boolean> {
226
+ try {
227
+ // Anvil rejects evm_setNextBlockTimestamp values <= the current block's timestamp. The two
228
+ // watcher loops can race and pick targets a fraction of a second apart; skip here rather than
229
+ // letting the second one error out noisily.
230
+ const lastTimestamp = await this.cheatcodes.lastBlockTimestamp();
231
+ if (timestamp <= lastTimestamp) {
232
+ return false;
233
+ }
234
+ await this.cheatcodes.warp(timestamp, { resetBlockInterval: true });
235
+ return true;
236
+ } catch (e) {
237
+ this.logger.error(`Failed to warp to timestamp ${timestamp}: ${e}`);
238
+ return false;
239
+ }
240
+ }
166
241
  }
@@ -1,9 +1,8 @@
1
1
  import { EthCheatCodes, RollupCheatCodes } from '@aztec/ethereum/test';
2
- import { BlockNumber } from '@aztec/foundation/branded-types';
3
- import { retryUntil } from '@aztec/foundation/retry';
2
+ import { SlotNumber } from '@aztec/foundation/branded-types';
3
+ import { createLogger } from '@aztec/foundation/log';
4
4
  import type { DateProvider } from '@aztec/foundation/timer';
5
- import type { SequencerClient } from '@aztec/sequencer-client';
6
- import type { AztecNode } from '@aztec/stdlib/interfaces/client';
5
+ import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client';
7
6
 
8
7
  /**
9
8
  * A class that provides utility functions for interacting with the chain.
@@ -12,6 +11,8 @@ import type { AztecNode } from '@aztec/stdlib/interfaces/client';
12
11
  * codes, please consider whether it makes sense to just introduce new utils in your tests instead.
13
12
  */
14
13
  export class CheatCodes {
14
+ private logger = createLogger('aztecjs:cheat_codes');
15
+
15
16
  constructor(
16
17
  /** Cheat codes for L1.*/
17
18
  public eth: EthCheatCodes,
@@ -30,50 +31,55 @@ export class CheatCodes {
30
31
 
31
32
  /**
32
33
  * Warps the L1 timestamp to a target timestamp and mines an L2 block that advances the L2 timestamp to at least
33
- * the target timestamp. L2 timestamp is not advanced exactly to the target timestamp because it is determined
34
- * by the slot number, which advances in fixed intervals.
35
- * This is useful for testing time-dependent contract behavior.
36
- * @param sequencerClient - The sequencer client to use to force an empty block to be mined.
37
- * @param node - The Aztec node used to query if a new block has been mined.
34
+ * the target timestamp. If the target timestamp falls within the current L2 slot (which already has a block),
35
+ * the timestamp is automatically adjusted forward to the start of the next slot so that `mineBlock()` succeeds.
36
+ * @param node - The Aztec node used to force an empty block to be mined.
38
37
  * @param targetTimestamp - The target timestamp to warp to (in seconds)
39
38
  */
40
- async warpL2TimeAtLeastTo(sequencerClient: SequencerClient, node: AztecNode, targetTimestamp: bigint | number) {
41
- const currentL2BlockNumber: BlockNumber = await node.getBlockNumber();
39
+ async warpL2TimeAtLeastTo(node: AztecNodeDebug, targetTimestamp: bigint | number) {
40
+ const targetBigInt = BigInt(targetTimestamp);
41
+ const currentTimestamp = BigInt(await this.eth.lastBlockTimestamp());
42
42
 
43
- // We warp the L1 timestamp
44
- await this.eth.warp(targetTimestamp, { resetBlockInterval: true });
43
+ if (targetBigInt <= currentTimestamp) {
44
+ throw new Error(
45
+ `warpL2TimeAtLeastTo: target timestamp ${targetBigInt} is not in the future (current L1 timestamp is ${currentTimestamp}).`,
46
+ );
47
+ }
45
48
 
46
- // Wait until an L2 block is mined
47
- const sequencer = sequencerClient.getSequencer();
48
- const minTxsPerBlock = sequencer.getConfig().minTxsPerBlock;
49
- sequencer.updateConfig({ minTxsPerBlock: 0 });
49
+ const currentSlot = await this.rollup.getSlot();
50
+ const targetSlot = await this.rollup.getSlotAt(targetBigInt);
50
51
 
51
- await retryUntil(
52
- async () => {
53
- const newL2BlockNumber: BlockNumber = await node.getBlockNumber();
54
- return newL2BlockNumber > currentL2BlockNumber;
55
- },
56
- 'new block after warping L2 time',
57
- 36,
58
- 1,
59
- );
52
+ let effectiveTimestamp = targetBigInt;
60
53
 
61
- // Restore original minTxsPerBlock
62
- sequencer.updateConfig({ minTxsPerBlock });
54
+ if (targetSlot <= currentSlot) {
55
+ // Target lands in the same (or earlier) slot — auto-adjust to the next slot's start.
56
+ const nextSlot = SlotNumber(currentSlot + 1);
57
+ const nextSlotTimestamp = await this.rollup.getTimestampForSlot(nextSlot);
58
+ this.logger.warn(
59
+ `warpL2TimeAtLeastTo: target timestamp ${targetBigInt} falls in current slot ${currentSlot}. ` +
60
+ `Auto-adjusting to start of slot ${nextSlot} at timestamp ${nextSlotTimestamp}.`,
61
+ );
62
+ effectiveTimestamp = nextSlotTimestamp;
63
+ }
64
+
65
+ await this.eth.warp(effectiveTimestamp, { resetBlockInterval: true });
66
+ await node.mineBlock();
63
67
  }
64
68
 
65
69
  /**
66
70
  * Warps the L1 timestamp forward by a specified duration and mines an L2 block that advances the L2 timestamp at
67
- * least by the duration. L2 timestamp is not advanced exactly by the duration because it is determined by the slot
68
- * number, which advances in fixed intervals.
69
- * This is useful for testing time-dependent contract behavior.
70
- * @param sequencerClient - The sequencer client to use to force an empty block to be mined.
71
- * @param node - The Aztec node used to query if a new block has been mined.
71
+ * least by the duration. If the duration is too short to cross an L2 slot boundary, the warp is automatically
72
+ * extended to the start of the next slot so that `mineBlock()` succeeds.
73
+ * @param node - The Aztec node used to force an empty block to be mined.
72
74
  * @param duration - The duration to advance time by (in seconds)
73
75
  */
74
- async warpL2TimeAtLeastBy(sequencerClient: SequencerClient, node: AztecNode, duration: bigint | number) {
75
- const currentTimestamp = await this.eth.timestamp();
76
+ async warpL2TimeAtLeastBy(node: AztecNodeDebug, duration: bigint | number) {
77
+ if (BigInt(duration) <= 0n) {
78
+ throw new Error(`warpL2TimeAtLeastBy: duration must be positive, got ${duration} seconds.`);
79
+ }
80
+
81
+ const currentTimestamp = await this.eth.lastBlockTimestamp();
76
82
  const targetTimestamp = BigInt(currentTimestamp) + BigInt(duration);
77
- await this.warpL2TimeAtLeastTo(sequencerClient, node, targetTimestamp);
83
+ await this.warpL2TimeAtLeastTo(node, targetTimestamp);
78
84
  }
79
85
  }
@@ -4,7 +4,7 @@ import { type EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
4
4
  import type { Logger } from '@aztec/foundation/log';
5
5
  import { EpochMonitor } from '@aztec/prover-node';
6
6
  import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
7
- import { computeL2ToL1MembershipWitnessFromMessagesInEpoch } from '@aztec/stdlib/messaging';
7
+ import { computeEpochOutHash } from '@aztec/stdlib/messaging';
8
8
 
9
9
  export class EpochTestSettler {
10
10
  private rollupCheatCodes: RollupCheatCodes;
@@ -51,9 +51,8 @@ export class EpochTestSettler {
51
51
  messagesInEpoch[checkpointIndex].push(block.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs));
52
52
  }
53
53
 
54
- const [firstMessage] = messagesInEpoch.flat(3);
55
- if (firstMessage) {
56
- const { root: outHash } = computeL2ToL1MembershipWitnessFromMessagesInEpoch(messagesInEpoch, firstMessage);
54
+ const outHash = computeEpochOutHash(messagesInEpoch);
55
+ if (!outHash.isZero()) {
57
56
  await this.rollupCheatCodes.insertOutbox(epoch, outHash.toBigInt());
58
57
  } else {
59
58
  this.log.info(`No L2 to L1 messages in epoch ${epoch}`);
@@ -1,4 +1,5 @@
1
- export { AnvilTestWatcher } from './anvil_test_watcher.js';
1
+ export { AnvilTestWatcher, type AnvilTestWatcherOpts } from './anvil_test_watcher.js';
2
2
  export { EthCheatCodes, RollupCheatCodes } from '@aztec/ethereum/test';
3
3
  export { CheatCodes } from './cheat_codes.js';
4
4
  export { EpochTestSettler } from './epoch_test_settler.js';
5
+ export { getTokenAllowedSetupFunctions } from './token_allowed_setup.js';
@@ -0,0 +1,19 @@
1
+ import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
2
+ import { buildAllowedElement } from '@aztec/p2p/msg_validators';
3
+ import { getContractClassFromArtifact } from '@aztec/stdlib/contract';
4
+ import type { AllowedElement } from '@aztec/stdlib/interfaces/server';
5
+
6
+ /**
7
+ * Returns Token-specific allowlist entries needed for FPC-based fee payments.
8
+ * These are test-only: FPC-based fee payment with custom tokens won't work on mainnet alpha.
9
+ */
10
+ export async function getTokenAllowedSetupFunctions(): Promise<AllowedElement[]> {
11
+ const tokenClassId = (await getContractClassFromArtifact(TokenContractArtifact)).id;
12
+ const target = { classId: tokenClassId };
13
+ return Promise.all([
14
+ // Token: needed for private transfers via FPC (transfer_to_public enqueues this)
15
+ buildAllowedElement(TokenContractArtifact, target, '_increase_public_balance', { onlySelf: true }),
16
+ // Token: needed for public transfers via FPC (fee_entrypoint_public enqueues this)
17
+ buildAllowedElement(TokenContractArtifact, target, 'transfer_in_public'),
18
+ ]);
19
+ }
@@ -1,7 +0,0 @@
1
- import type { NamespacedApiHandlers } from '@aztec/foundation/json-rpc/server';
2
- import type { LogFn } from '@aztec/foundation/log';
3
- import { type ProverNodeConfig } from '@aztec/prover-node';
4
- export declare function startProverNode(options: any, signalHandlers: (() => Promise<void>)[], services: NamespacedApiHandlers, userLog: LogFn): Promise<{
5
- config: ProverNodeConfig;
6
- }>;
7
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnRfcHJvdmVyX25vZGUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvY21kcy9zdGFydF9wcm92ZXJfbm9kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFLQSxPQUFPLEtBQUssRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBRS9FLE9BQU8sS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRW5ELE9BQU8sRUFDTCxLQUFLLGdCQUFnQixFQUl0QixNQUFNLG9CQUFvQixDQUFDO0FBUzVCLHdCQUFzQixlQUFlLENBQ25DLE9BQU8sRUFBRSxHQUFHLEVBQ1osY0FBYyxFQUFFLENBQUMsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUN2QyxRQUFRLEVBQUUscUJBQXFCLEVBQy9CLE9BQU8sRUFBRSxLQUFLLEdBQ2IsT0FBTyxDQUFDO0lBQUUsTUFBTSxFQUFFLGdCQUFnQixDQUFBO0NBQUUsQ0FBQyxDQStGdkMifQ==
@@ -1 +0,0 @@
1
- {"version":3,"file":"start_prover_node.d.ts","sourceRoot":"","sources":["../../../src/cli/cmds/start_prover_node.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE/E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EACL,KAAK,gBAAgB,EAItB,MAAM,oBAAoB,CAAC;AAS5B,wBAAsB,eAAe,CACnC,OAAO,EAAE,GAAG,EACZ,cAAc,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,EACvC,QAAQ,EAAE,qBAAqB,EAC/B,OAAO,EAAE,KAAK,GACb,OAAO,CAAC;IAAE,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC,CA+FvC"}
@@ -1,108 +0,0 @@
1
- import { getInitialTestAccountsData } from '@aztec/accounts/testing';
2
- import { Fr } from '@aztec/aztec.js/fields';
3
- import { getSponsoredFPCAddress } from '@aztec/cli/cli-utils';
4
- import { getL1Config } from '@aztec/cli/config';
5
- import { getPublicClient } from '@aztec/ethereum/client';
6
- import { Agent, makeUndiciFetch } from '@aztec/foundation/json-rpc/undici';
7
- import { ProvingJobConsumerSchema, createProvingJobBrokerClient } from '@aztec/prover-client/broker';
8
- import { createProverNode, getProverNodeConfigFromEnv, proverNodeConfigMappings } from '@aztec/prover-node';
9
- import { P2PApiSchema, ProverNodeApiSchema } from '@aztec/stdlib/interfaces/server';
10
- import { initTelemetryClient, makeTracedFetch, telemetryClientConfigMappings } from '@aztec/telemetry-client';
11
- import { getGenesisValues } from '@aztec/world-state/testing';
12
- import { extractRelevantOptions, preloadCrsDataForVerifying, setupUpdateMonitor } from '../util.js';
13
- import { getVersions } from '../versioning.js';
14
- import { startProverBroker } from './start_prover_broker.js';
15
- export async function startProverNode(options, signalHandlers, services, userLog) {
16
- if (options.node || options.sequencer || options.pxe || options.p2pBootstrap || options.txe) {
17
- userLog(`Starting a prover-node with --node, --sequencer, --pxe, --p2p-bootstrap, or --txe is not supported.`);
18
- process.exit(1);
19
- }
20
- let proverConfig = {
21
- ...getProverNodeConfigFromEnv(),
22
- ...extractRelevantOptions(options, proverNodeConfigMappings, 'proverNode')
23
- };
24
- if (!proverConfig.l1Contracts.registryAddress || proverConfig.l1Contracts.registryAddress.isZero()) {
25
- throw new Error('L1 registry address is required to start a Prover Node');
26
- }
27
- const followsCanonicalRollup = typeof proverConfig.rollupVersion !== 'number';
28
- const { addresses, config } = await getL1Config(proverConfig.l1Contracts.registryAddress, proverConfig.l1RpcUrls, proverConfig.l1ChainId, proverConfig.rollupVersion);
29
- process.env.ROLLUP_CONTRACT_ADDRESS ??= addresses.rollupAddress.toString();
30
- proverConfig.l1Contracts = addresses;
31
- proverConfig = {
32
- ...proverConfig,
33
- ...config
34
- };
35
- const testAccounts = proverConfig.testAccounts ? (await getInitialTestAccountsData()).map((a)=>a.address) : [];
36
- const sponsoredFPCAccounts = proverConfig.sponsoredFPC ? [
37
- await getSponsoredFPCAddress()
38
- ] : [];
39
- const initialFundedAccounts = testAccounts.concat(sponsoredFPCAccounts);
40
- userLog(`Initial funded accounts: ${initialFundedAccounts.map((a)=>a.toString()).join(', ')}`);
41
- const { genesisArchiveRoot, prefilledPublicData } = await getGenesisValues(initialFundedAccounts);
42
- userLog(`Genesis archive root: ${genesisArchiveRoot.toString()}`);
43
- if (!Fr.fromHexString(config.genesisArchiveTreeRoot).equals(genesisArchiveRoot)) {
44
- throw new Error(`The computed genesis archive tree root ${genesisArchiveRoot} does not match the expected genesis archive tree root ${config.genesisArchiveTreeRoot} for the rollup deployed at ${addresses.rollupAddress}`);
45
- }
46
- const telemetry = await initTelemetryClient(extractRelevantOptions(options, telemetryClientConfigMappings, 'tel'));
47
- let broker;
48
- if (proverConfig.proverBrokerUrl) {
49
- // at 1TPS we'd enqueue ~1k chonk verifier proofs and ~1k AVM proofs immediately
50
- // set a lower connection limit such that we don't overload the server
51
- // Keep retrying up to 30s
52
- const fetch = makeTracedFetch([
53
- 1,
54
- 2,
55
- 3,
56
- 3,
57
- 3,
58
- 3,
59
- 3,
60
- 3,
61
- 3,
62
- 3,
63
- 3
64
- ], false, makeUndiciFetch(new Agent({
65
- connections: 100
66
- })));
67
- broker = createProvingJobBrokerClient(proverConfig.proverBrokerUrl, getVersions(proverConfig), fetch);
68
- } else if (options.proverBroker) {
69
- ({ broker } = await startProverBroker(options, signalHandlers, services, userLog));
70
- } else {
71
- userLog(`--prover-broker-url or --prover-broker is required to start a Prover Node`);
72
- process.exit(1);
73
- }
74
- if (proverConfig.proverAgentCount === 0) {
75
- userLog(`Running prover node without local prover agent. Connect one or more prover agents to this node or pass --proverAgent.proverAgentCount`);
76
- }
77
- await preloadCrsDataForVerifying(proverConfig, userLog);
78
- const proverNode = await createProverNode(proverConfig, {
79
- telemetry,
80
- broker
81
- }, {
82
- prefilledPublicData
83
- });
84
- services.proverNode = [
85
- proverNode,
86
- ProverNodeApiSchema
87
- ];
88
- if (proverNode.getP2P()) {
89
- services.p2p = [
90
- proverNode.getP2P(),
91
- P2PApiSchema
92
- ];
93
- }
94
- if (!proverConfig.proverBrokerUrl) {
95
- services.provingJobSource = [
96
- proverNode.getProver().getProvingJobSource(),
97
- ProvingJobConsumerSchema
98
- ];
99
- }
100
- signalHandlers.push(proverNode.stop.bind(proverNode));
101
- await proverNode.start();
102
- if (proverConfig.autoUpdate !== 'disabled' && proverConfig.autoUpdateUrl) {
103
- await setupUpdateMonitor(proverConfig.autoUpdate, new URL(proverConfig.autoUpdateUrl), followsCanonicalRollup, getPublicClient(proverConfig), proverConfig.l1Contracts.registryAddress, signalHandlers);
104
- }
105
- return {
106
- config: proverConfig
107
- };
108
- }
@@ -1,2 +0,0 @@
1
- export declare const getCliVersion: () => any;
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVsZWFzZV92ZXJzaW9uLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2xpL3JlbGVhc2VfdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFLQSxlQUFPLE1BQU0sYUFBYSxXQWV6QixDQUFDIn0=
@@ -1 +0,0 @@
1
- {"version":3,"file":"release_version.d.ts","sourceRoot":"","sources":["../../src/cli/release_version.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,aAAa,WAezB,CAAC"}
@@ -1,14 +0,0 @@
1
- import { fileURLToPath } from '@aztec/foundation/url';
2
- import { readFileSync } from 'fs';
3
- import { dirname, resolve } from 'path';
4
- export const getCliVersion = ()=>{
5
- const packageJsonPath = resolve(dirname(fileURLToPath(import.meta.url)), '../../package.json');
6
- const cliVersion = JSON.parse(readFileSync(packageJsonPath).toString()).version;
7
- // If the version is 0.1.0, this is a placeholder version and we are in a docker container; query release please for the latest version
8
- if (cliVersion === '0.1.0') {
9
- const releasePleasePath = resolve(dirname(fileURLToPath(import.meta.url)), '../../../../.release-please-manifest.json');
10
- const releaseVersion = JSON.parse(readFileSync(releasePleasePath).toString())['.'];
11
- return releaseVersion;
12
- }
13
- return cliVersion;
14
- };
@@ -1,44 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- NARGO=${NARGO:-nargo}
5
- BB=${BB:-bb}
6
-
7
- # If help is requested, show Aztec-specific info then run nargo compile help and then exit in order to not trigger
8
- # transpilation
9
- for arg in "$@"; do
10
- if [ "$arg" == "--help" ] || [ "$arg" == "-h" ]; then
11
- cat << 'EOF'
12
- Aztec Compile - Compile Aztec Noir contracts
13
-
14
- This command compiles Aztec Noir contracts using nargo and then automatically
15
- postprocesses them to generate Aztec specific artifacts including:
16
- - Transpiled contract artifacts
17
- - Verification keys
18
-
19
- The compiled contracts will be placed in the target/ directory by default.
20
-
21
- ---
22
- Underlying nargo compile options:
23
-
24
- EOF
25
- nargo compile --help
26
- exit 0
27
- fi
28
- done
29
-
30
- # Run nargo compile.
31
- $NARGO compile "$@"
32
-
33
- echo "Postprocessing contract..."
34
- $BB aztec_process
35
-
36
- # Strip internal prefixes from all compiled contract JSONs in target directory
37
- # TODO: This should be part of bb aztec_process!
38
- for json in target/*.json; do
39
- temp_file="${json}.tmp"
40
- jq '.functions |= map(.name |= sub("^__aztec_nr_internals__"; ""))' "$json" > "$temp_file"
41
- mv "$temp_file" "$json"
42
- done
43
-
44
- echo "Compilation complete!"
@@ -1,47 +0,0 @@
1
- #!/usr/bin/env node
2
- import fs from 'fs/promises';
3
- import path from 'path';
4
-
5
- // Simple script to extract a contract function as a separate Noir artifact.
6
- // We need to use this since the transpiling that we do on public functions make the contract artifacts
7
- // unreadable by noir tooling, since they are no longer following the noir artifact format.
8
- async function main() {
9
- let [contractArtifactPath, functionName] = process.argv.slice(2);
10
- if (!contractArtifactPath || !functionName) {
11
- console.log('Usage: node extractFunctionAsNoirArtifact.js <contractArtifactPath> <functionName>');
12
- return;
13
- }
14
-
15
- const contractArtifact = JSON.parse(await fs.readFile(contractArtifactPath, 'utf8'));
16
- const func = contractArtifact.functions.find(f => f.name === functionName);
17
- if (!func) {
18
- console.error(`Function ${functionName} not found in ${contractArtifactPath}`);
19
- return;
20
- }
21
-
22
- const artifact = {
23
- noir_version: contractArtifact.noir_version,
24
- hash: 0,
25
- abi: func.abi,
26
- bytecode: func.bytecode,
27
- debug_symbols: func.debug_symbols,
28
- file_map: contractArtifact.file_map,
29
- expression_width: {
30
- Bounded: {
31
- width: 4,
32
- },
33
- },
34
- };
35
-
36
- const outputDir = path.dirname(contractArtifactPath);
37
- const outputName = path.basename(contractArtifactPath, '.json') + `-${functionName}.json`;
38
-
39
- const outPath = path.join(outputDir, outputName);
40
-
41
- await fs.writeFile(outPath, JSON.stringify(artifact, null, 2));
42
- }
43
-
44
- main().catch(err => {
45
- console.error(err);
46
- process.exit(1);
47
- });
@@ -1,59 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -eu
3
-
4
- # If first arg is -h or --help, print usage.
5
- if [ $# -lt 2 ] || [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
6
- cat << 'EOF'
7
- Aztec Flamegraph - Generate a gate count flamegraph for an aztec contract function.
8
-
9
- Usage: aztec flamegraph <contract_artifact> <function>
10
-
11
- Options:
12
- -h, --help Print help
13
-
14
- Will output an svg at <artifact_path>/<contract>-<function>-flamegraph.svg.
15
- You can open it in your browser to view it.
16
-
17
- EOF
18
- exit 0
19
- fi
20
-
21
- cleanup() {
22
- set +e
23
- if [ -f "$function_artifact" ]; then
24
- rm -f "$function_artifact"
25
- fi
26
- }
27
-
28
- trap cleanup EXIT
29
-
30
- # Get the directory of the script
31
- script_dir=$(realpath $(dirname $0))
32
-
33
- PROFILER=${PROFILER_PATH:-noir-profiler}
34
- BB=${BB:-bb}
35
-
36
- # first console arg is contract name in camel case or path to contract artifact
37
- contract=$1
38
-
39
- # second console arg is the contract function
40
- function=$2
41
-
42
- if [ ! -f "$contract" ]; then
43
- echo "Error: Contract artifact not found at: $contract"
44
- exit 1
45
- fi
46
- artifact_path=$contract
47
- function_artifact="${artifact_path%%.json}-${function}.json"
48
- output_dir=$(dirname "$artifact_path")
49
-
50
- # Extract artifact for the specific function.
51
- node $script_dir/extract_function.js "$artifact_path" $function
52
-
53
- # Generate the flamegraph
54
- $PROFILER gates --artifact-path "$function_artifact" --backend-path "$BB" --backend-gates-command "gates" --output "$output_dir" --scheme chonk --include_gates_per_opcode
55
-
56
- # Save as $artifact_name-$function-flamegraph.svg
57
- output_file="${function_artifact%%.json}-flamegraph.svg"
58
- mv "$output_dir/__aztec_nr_internals__${function}_gates.svg" "$output_file"
59
- echo "Flamegraph generated at: $output_file"