@aztec/ethereum 3.0.0-nightly.20251128 → 3.0.0-nightly.20251201.2

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 (35) hide show
  1. package/dest/contracts/empire_base.d.ts +6 -5
  2. package/dest/contracts/empire_base.d.ts.map +1 -1
  3. package/dest/contracts/empire_base.js +1 -1
  4. package/dest/contracts/empire_slashing_proposer.d.ts +5 -4
  5. package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
  6. package/dest/contracts/empire_slashing_proposer.js +8 -2
  7. package/dest/contracts/governance_proposer.d.ts +5 -4
  8. package/dest/contracts/governance_proposer.d.ts.map +1 -1
  9. package/dest/contracts/governance_proposer.js +8 -2
  10. package/dest/contracts/rollup.d.ts +9 -22
  11. package/dest/contracts/rollup.d.ts.map +1 -1
  12. package/dest/contracts/rollup.js +13 -16
  13. package/dest/contracts/tally_slashing_proposer.d.ts +6 -5
  14. package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
  15. package/dest/contracts/tally_slashing_proposer.js +3 -3
  16. package/dest/deploy_l1_contracts.d.ts +1 -1
  17. package/dest/deploy_l1_contracts.d.ts.map +1 -1
  18. package/dest/deploy_l1_contracts.js +4 -3
  19. package/dest/l1_artifacts.d.ts +4 -66
  20. package/dest/l1_artifacts.d.ts.map +1 -1
  21. package/dest/test/chain_monitor.d.ts +6 -6
  22. package/dest/test/chain_monitor.d.ts.map +1 -1
  23. package/dest/test/chain_monitor.js +4 -5
  24. package/dest/test/rollup_cheat_codes.d.ts +6 -6
  25. package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
  26. package/dest/test/rollup_cheat_codes.js +15 -13
  27. package/package.json +5 -5
  28. package/src/contracts/empire_base.ts +6 -5
  29. package/src/contracts/empire_slashing_proposer.ts +11 -5
  30. package/src/contracts/governance_proposer.ts +11 -5
  31. package/src/contracts/rollup.ts +16 -35
  32. package/src/contracts/tally_slashing_proposer.ts +8 -7
  33. package/src/deploy_l1_contracts.ts +4 -3
  34. package/src/test/chain_monitor.ts +10 -11
  35. package/src/test/rollup_cheat_codes.ts +17 -16
@@ -1,5 +1,5 @@
1
1
  import { RollupContract } from '@aztec/ethereum';
2
- import { EpochNumber } from '@aztec/foundation/branded-types';
2
+ import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
3
  import { EthAddress } from '@aztec/foundation/eth-address';
4
4
  import { createLogger } from '@aztec/foundation/log';
5
5
  import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
@@ -29,14 +29,14 @@ import { EthCheatCodes } from './eth_cheat_codes.js';
29
29
  }
30
30
  /** Returns the current slot */ async getSlot() {
31
31
  const ts = BigInt((await this.client.getBlock()).timestamp);
32
- return await this.rollup.read.getSlotAt([
32
+ return SlotNumber.fromBigInt(await this.rollup.read.getSlotAt([
33
33
  ts
34
- ]);
34
+ ]));
35
35
  }
36
36
  /** Returns the current epoch */ async getEpoch() {
37
37
  const slotNumber = await this.getSlot();
38
38
  return EpochNumber.fromBigInt(await this.rollup.read.getEpochAtSlot([
39
- slotNumber
39
+ BigInt(slotNumber)
40
40
  ]));
41
41
  }
42
42
  /**
@@ -71,7 +71,7 @@ import { EthCheatCodes } from './eth_cheat_codes.js';
71
71
  ]);
72
72
  return {
73
73
  epochDuration,
74
- slotDuration
74
+ slotDuration: Number(slotDuration)
75
75
  };
76
76
  }
77
77
  /**
@@ -80,8 +80,9 @@ import { EthCheatCodes } from './eth_cheat_codes.js';
80
80
  * @param opts - Options
81
81
  */ async advanceToEpoch(epoch, opts = {}) {
82
82
  const { epochDuration: slotsInEpoch } = await this.getConfig();
83
+ const slotNumber = SlotNumber(epoch * Number(slotsInEpoch));
83
84
  const timestamp = await this.rollup.read.getTimestampForSlot([
84
- BigInt(epoch) * slotsInEpoch
85
+ BigInt(slotNumber)
85
86
  ]) + BigInt(opts.offset ?? 0);
86
87
  try {
87
88
  await this.ethCheatCodes.warp(Number(timestamp), {
@@ -98,8 +99,8 @@ import { EthCheatCodes } from './eth_cheat_codes.js';
98
99
  /** Warps time in L1 until the next epoch */ async advanceToNextEpoch() {
99
100
  const slot = await this.getSlot();
100
101
  const { epochDuration, slotDuration } = await this.getConfig();
101
- const slotsUntilNextEpoch = epochDuration - slot % epochDuration + 1n;
102
- const timeToNextEpoch = slotsUntilNextEpoch * slotDuration;
102
+ const slotsUntilNextEpoch = epochDuration - BigInt(slot) % epochDuration + 1n;
103
+ const timeToNextEpoch = slotsUntilNextEpoch * BigInt(slotDuration);
103
104
  const l1Timestamp = BigInt((await this.client.getBlock()).timestamp);
104
105
  await this.ethCheatCodes.warp(Number(l1Timestamp + timeToNextEpoch), {
105
106
  silent: true,
@@ -109,17 +110,18 @@ import { EthCheatCodes } from './eth_cheat_codes.js';
109
110
  }
110
111
  /** Warps time in L1 until the beginning of the next slot. */ async advanceToNextSlot() {
111
112
  const currentSlot = await this.getSlot();
113
+ const nextSlot = SlotNumber(currentSlot + 1);
112
114
  const timestamp = await this.rollup.read.getTimestampForSlot([
113
- currentSlot + 1n
115
+ BigInt(nextSlot)
114
116
  ]);
115
117
  await this.ethCheatCodes.warp(Number(timestamp), {
116
118
  silent: true,
117
119
  resetBlockInterval: true
118
120
  });
119
- this.logger.warn(`Advanced to slot ${currentSlot + 1n}`);
121
+ this.logger.warn(`Advanced to slot ${nextSlot}`);
120
122
  return [
121
123
  timestamp,
122
- currentSlot + 1n
124
+ nextSlot
123
125
  ];
124
126
  }
125
127
  /**
@@ -127,8 +129,8 @@ import { EthCheatCodes } from './eth_cheat_codes.js';
127
129
  * @param howMany - The number of slots to advance.
128
130
  */ async advanceSlots(howMany) {
129
131
  const l1Timestamp = (await this.client.getBlock()).timestamp;
130
- const slotDuration = await this.rollup.read.getSlotDuration();
131
- const timeToWarp = BigInt(howMany) * slotDuration;
132
+ const slotDuration = Number(await this.rollup.read.getSlotDuration());
133
+ const timeToWarp = BigInt(howMany) * BigInt(slotDuration);
132
134
  await this.ethCheatCodes.warp(l1Timestamp + timeToWarp, {
133
135
  silent: true,
134
136
  resetBlockInterval: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/ethereum",
3
- "version": "3.0.0-nightly.20251128",
3
+ "version": "3.0.0-nightly.20251201.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -31,10 +31,10 @@
31
31
  "../package.common.json"
32
32
  ],
33
33
  "dependencies": {
34
- "@aztec/blob-lib": "3.0.0-nightly.20251128",
35
- "@aztec/constants": "3.0.0-nightly.20251128",
36
- "@aztec/foundation": "3.0.0-nightly.20251128",
37
- "@aztec/l1-artifacts": "3.0.0-nightly.20251128",
34
+ "@aztec/blob-lib": "3.0.0-nightly.20251201.2",
35
+ "@aztec/constants": "3.0.0-nightly.20251201.2",
36
+ "@aztec/foundation": "3.0.0-nightly.20251201.2",
37
+ "@aztec/l1-artifacts": "3.0.0-nightly.20251201.2",
38
38
  "@viem/anvil": "^0.0.10",
39
39
  "dotenv": "^16.0.3",
40
40
  "lodash.chunk": "^4.2.0",
@@ -1,3 +1,4 @@
1
+ import type { SlotNumber } from '@aztec/foundation/branded-types';
1
2
  import type { EthAddress } from '@aztec/foundation/eth-address';
2
3
  import { Signature } from '@aztec/foundation/eth-signature';
3
4
  import { EmpireBaseAbi } from '@aztec/l1-artifacts/EmpireBaseAbi';
@@ -11,12 +12,12 @@ export interface IEmpireBase {
11
12
  getRoundInfo(
12
13
  rollupAddress: Hex,
13
14
  round: bigint,
14
- ): Promise<{ lastSignalSlot: bigint; payloadWithMostSignals: Hex; executed: boolean }>;
15
- computeRound(slot: bigint): Promise<bigint>;
15
+ ): Promise<{ lastSignalSlot: SlotNumber; payloadWithMostSignals: Hex; executed: boolean }>;
16
+ computeRound(slot: SlotNumber): Promise<bigint>;
16
17
  createSignalRequest(payload: Hex): L1TxRequest;
17
18
  createSignalRequestWithSignature(
18
19
  payload: Hex,
19
- round: bigint,
20
+ slot: SlotNumber,
20
21
  chainId: number,
21
22
  signerAddress: Hex,
22
23
  signer: (msg: TypedDataDefinition) => Promise<Hex>,
@@ -51,7 +52,7 @@ export function encodeSignalWithSignature(payload: Hex, signature: Signature) {
51
52
  export async function signSignalWithSig(
52
53
  signer: (msg: TypedDataDefinition) => Promise<Hex>,
53
54
  payload: Hex,
54
- slot: bigint,
55
+ slot: SlotNumber,
55
56
  instance: Hex,
56
57
  verifyingContract: Hex,
57
58
  chainId: number,
@@ -79,7 +80,7 @@ export async function signSignalWithSig(
79
80
 
80
81
  const message = {
81
82
  payload,
82
- slot,
83
+ slot: BigInt(slot),
83
84
  instance,
84
85
  };
85
86
 
@@ -1,3 +1,4 @@
1
+ import { SlotNumber } from '@aztec/foundation/branded-types';
1
2
  import { EthAddress } from '@aztec/foundation/eth-address';
2
3
  import { createLogger } from '@aztec/foundation/log';
3
4
  import { retryUntil } from '@aztec/foundation/retry';
@@ -67,8 +68,8 @@ export class EmpireSlashingProposerContract extends EventEmitter implements IEmp
67
68
  return this.proposer.read.getCurrentRound();
68
69
  }
69
70
 
70
- public computeRound(slot: bigint): Promise<bigint> {
71
- return this.proposer.read.computeRound([slot]);
71
+ public computeRound(slot: SlotNumber): Promise<bigint> {
72
+ return this.proposer.read.computeRound([BigInt(slot)]);
72
73
  }
73
74
 
74
75
  public getInstance() {
@@ -78,8 +79,13 @@ export class EmpireSlashingProposerContract extends EventEmitter implements IEmp
78
79
  public async getRoundInfo(
79
80
  rollupAddress: Hex,
80
81
  round: bigint,
81
- ): Promise<{ lastSignalSlot: bigint; payloadWithMostSignals: Hex; executed: boolean }> {
82
- return await this.proposer.read.getRoundData([rollupAddress, round]);
82
+ ): Promise<{ lastSignalSlot: SlotNumber; payloadWithMostSignals: Hex; executed: boolean }> {
83
+ const result = await this.proposer.read.getRoundData([rollupAddress, round]);
84
+ return {
85
+ lastSignalSlot: SlotNumber.fromBigInt(result.lastSignalSlot),
86
+ payloadWithMostSignals: result.payloadWithMostSignals,
87
+ executed: result.executed,
88
+ };
83
89
  }
84
90
 
85
91
  public getPayloadSignals(rollupAddress: Hex, round: bigint, payload: Hex): Promise<bigint> {
@@ -95,7 +101,7 @@ export class EmpireSlashingProposerContract extends EventEmitter implements IEmp
95
101
 
96
102
  public async createSignalRequestWithSignature(
97
103
  payload: Hex,
98
- slot: bigint,
104
+ slot: SlotNumber,
99
105
  chainId: number,
100
106
  signerAddress: Hex,
101
107
  signer: (msg: TypedDataDefinition) => Promise<Hex>,
@@ -1,3 +1,4 @@
1
+ import { SlotNumber } from '@aztec/foundation/branded-types';
1
2
  import { memoize } from '@aztec/foundation/decorators';
2
3
  import { EthAddress } from '@aztec/foundation/eth-address';
3
4
  import { GovernanceProposerAbi } from '@aztec/l1-artifacts/GovernanceProposerAbi';
@@ -54,15 +55,20 @@ export class GovernanceProposerContract implements IEmpireBase {
54
55
  return this.proposer.read.getInstance();
55
56
  }
56
57
 
57
- public computeRound(slot: bigint): Promise<bigint> {
58
- return this.proposer.read.computeRound([slot]);
58
+ public computeRound(slot: SlotNumber): Promise<bigint> {
59
+ return this.proposer.read.computeRound([BigInt(slot)]);
59
60
  }
60
61
 
61
62
  public async getRoundInfo(
62
63
  rollupAddress: Hex,
63
64
  round: bigint,
64
- ): Promise<{ lastSignalSlot: bigint; payloadWithMostSignals: Hex; executed: boolean }> {
65
- return await this.proposer.read.getRoundData([rollupAddress, round]);
65
+ ): Promise<{ lastSignalSlot: SlotNumber; payloadWithMostSignals: Hex; executed: boolean }> {
66
+ const result = await this.proposer.read.getRoundData([rollupAddress, round]);
67
+ return {
68
+ lastSignalSlot: SlotNumber.fromBigInt(result.lastSignalSlot),
69
+ payloadWithMostSignals: result.payloadWithMostSignals,
70
+ executed: result.executed,
71
+ };
66
72
  }
67
73
 
68
74
  public getPayloadSignals(rollupAddress: Hex, round: bigint, payload: Hex): Promise<bigint> {
@@ -78,7 +84,7 @@ export class GovernanceProposerContract implements IEmpireBase {
78
84
 
79
85
  public async createSignalRequestWithSignature(
80
86
  payload: Hex,
81
- slot: bigint,
87
+ slot: SlotNumber,
82
88
  chainId: number,
83
89
  signerAddress: Hex,
84
90
  signer: (msg: TypedDataDefinition) => Promise<Hex>,
@@ -1,4 +1,4 @@
1
- import { EpochNumber } from '@aztec/foundation/branded-types';
1
+ import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
2
2
  import { memoize } from '@aztec/foundation/decorators';
3
3
  import { EthAddress } from '@aztec/foundation/eth-address';
4
4
  import type { ViemSignature } from '@aztec/foundation/eth-signature';
@@ -83,22 +83,6 @@ export type ViemGasFees = {
83
83
  feePerL2Gas: bigint;
84
84
  };
85
85
 
86
- export type ViemStateReference = {
87
- l1ToL2MessageTree: ViemAppendOnlyTreeSnapshot;
88
- partialStateReference: ViemPartialStateReference;
89
- };
90
-
91
- export type ViemPartialStateReference = {
92
- noteHashTree: ViemAppendOnlyTreeSnapshot;
93
- nullifierTree: ViemAppendOnlyTreeSnapshot;
94
- publicDataTree: ViemAppendOnlyTreeSnapshot;
95
- };
96
-
97
- export type ViemAppendOnlyTreeSnapshot = {
98
- root: `0x${string}`;
99
- nextAvailableLeafIndex: number;
100
- };
101
-
102
86
  export enum SlashingProposerType {
103
87
  None = 0,
104
88
  Tally = 1,
@@ -209,8 +193,8 @@ export class RollupContract {
209
193
  }
210
194
 
211
195
  @memoize
212
- getSlotDuration() {
213
- return this.rollup.read.getSlotDuration();
196
+ async getSlotDuration(): Promise<number> {
197
+ return Number(await this.rollup.read.getSlotDuration());
214
198
  }
215
199
 
216
200
  @memoize
@@ -301,7 +285,7 @@ export class RollupContract {
301
285
  return {
302
286
  l1StartBlock,
303
287
  l1GenesisTime,
304
- slotDuration: Number(slotDuration),
288
+ slotDuration,
305
289
  epochDuration: Number(epochDuration),
306
290
  proofSubmissionEpochs: Number(proofSubmissionEpochs),
307
291
  };
@@ -350,8 +334,8 @@ export class RollupContract {
350
334
  return this.rollup.read.getProvenCheckpointNumber();
351
335
  }
352
336
 
353
- getSlotNumber() {
354
- return this.rollup.read.getCurrentSlot();
337
+ async getSlotNumber(): Promise<SlotNumber> {
338
+ return SlotNumber.fromBigInt(await this.rollup.read.getCurrentSlot());
355
339
  }
356
340
 
357
341
  getL1FeesAt(timestamp: bigint) {
@@ -440,8 +424,8 @@ export class RollupContract {
440
424
  return this.rollup.read.getTips();
441
425
  }
442
426
 
443
- getTimestampForSlot(slot: bigint) {
444
- return this.rollup.read.getTimestampForSlot([slot]);
427
+ getTimestampForSlot(slot: SlotNumber) {
428
+ return this.rollup.read.getTimestampForSlot([BigInt(slot)]);
445
429
  }
446
430
 
447
431
  getEntryQueueLength() {
@@ -501,8 +485,8 @@ export class RollupContract {
501
485
  return EthAddress.fromString(await this.rollup.read.getFeeAssetPortal());
502
486
  }
503
487
 
504
- public async getEpochNumberForSlotNumber(slotNumber: bigint): Promise<EpochNumber> {
505
- return EpochNumber.fromBigInt(await this.rollup.read.getEpochAtSlot([slotNumber]));
488
+ public async getEpochNumberForSlotNumber(slotNumber: SlotNumber): Promise<EpochNumber> {
489
+ return EpochNumber.fromBigInt(await this.rollup.read.getEpochAtSlot([BigInt(slotNumber)]));
506
490
  }
507
491
 
508
492
  getEpochProofPublicInputs(
@@ -552,14 +536,11 @@ export class RollupContract {
552
536
  public async canProposeAtNextEthBlock(
553
537
  archive: Buffer,
554
538
  account: `0x${string}` | Account,
555
- slotDuration: bigint | number,
539
+ slotDuration: number,
556
540
  opts: { forcePendingCheckpointNumber?: number } = {},
557
- ): Promise<{ slot: bigint; checkpointNumber: bigint; timeOfNextL1Slot: bigint }> {
558
- if (typeof slotDuration === 'number') {
559
- slotDuration = BigInt(slotDuration);
560
- }
541
+ ): Promise<{ slot: SlotNumber; checkpointNumber: bigint; timeOfNextL1Slot: bigint }> {
561
542
  const latestBlock = await this.client.getBlock();
562
- const timeOfNextL1Slot = latestBlock.timestamp + slotDuration;
543
+ const timeOfNextL1Slot = latestBlock.timestamp + BigInt(slotDuration);
563
544
  const who = typeof account === 'string' ? account : account.address;
564
545
 
565
546
  try {
@@ -574,7 +555,7 @@ export class RollupContract {
574
555
  stateOverride: await this.makePendingCheckpointNumberOverride(opts.forcePendingCheckpointNumber),
575
556
  });
576
557
 
577
- return { slot, checkpointNumber, timeOfNextL1Slot };
558
+ return { slot: SlotNumber.fromBigInt(slot), checkpointNumber, timeOfNextL1Slot };
578
559
  } catch (err: unknown) {
579
560
  throw formatViemError(err);
580
561
  }
@@ -653,8 +634,8 @@ export class RollupContract {
653
634
  return this.rollup.read.getManaBaseFeeAt([timestamp, inFeeAsset]);
654
635
  }
655
636
 
656
- getSlotAt(timestamp: bigint) {
657
- return this.rollup.read.getSlotAt([timestamp]);
637
+ async getSlotAt(timestamp: bigint): Promise<SlotNumber> {
638
+ return SlotNumber.fromBigInt(await this.rollup.read.getSlotAt([timestamp]));
658
639
  }
659
640
 
660
641
  async status(checkpointNumber: bigint, options?: { blockNumber?: bigint }) {
@@ -1,4 +1,5 @@
1
1
  import { type L1TxRequest, type ViemClient, tryExtractEvent } from '@aztec/ethereum';
2
+ import { SlotNumber } from '@aztec/foundation/branded-types';
2
3
  import { Buffer32 } from '@aztec/foundation/buffer';
3
4
  import { EthAddress } from '@aztec/foundation/eth-address';
4
5
  import { Signature } from '@aztec/foundation/eth-signature';
@@ -97,8 +98,8 @@ export class TallySlashingProposerContract {
97
98
  * @param slot - The slot number to check at
98
99
  * @returns Whether the round is ready to execute
99
100
  */
100
- public async isRoundReadyToExecute(round: bigint, slot: bigint): Promise<boolean> {
101
- return await this.contract.read.isRoundReadyToExecute([round, slot]);
101
+ public async isRoundReadyToExecute(round: bigint, slot: SlotNumber): Promise<boolean> {
102
+ return await this.contract.read.isRoundReadyToExecute([round, BigInt(slot)]);
102
103
  }
103
104
 
104
105
  /** Returns the slash actions and payload address for a given round (zero if no slash actions) */
@@ -149,7 +150,7 @@ export class TallySlashingProposerContract {
149
150
  */
150
151
  public async buildVoteRequestFromSigner(
151
152
  votes: Hex,
152
- slot: bigint,
153
+ slot: SlotNumber,
153
154
  signer: (msg: TypedDataDefinition) => Promise<Hex>,
154
155
  ): Promise<L1TxRequest> {
155
156
  const typedData = this.buildVoteTypedData(votes, slot);
@@ -166,7 +167,7 @@ export class TallySlashingProposerContract {
166
167
  }
167
168
 
168
169
  /** Returns the typed data definition to EIP712-sign for voting */
169
- public buildVoteTypedData(votes: Hex, slot: bigint): TypedDataDefinition {
170
+ public buildVoteTypedData(votes: Hex, slot: SlotNumber): TypedDataDefinition {
170
171
  const domain = {
171
172
  name: 'TallySlashingProposer',
172
173
  version: '1',
@@ -187,12 +188,12 @@ export class TallySlashingProposerContract {
187
188
  ],
188
189
  };
189
190
 
190
- return { domain, types, primaryType: 'Vote', message: { votes, slot } };
191
+ return { domain, types, primaryType: 'Vote', message: { votes, slot: BigInt(slot) } };
191
192
  }
192
193
 
193
194
  /** Gets the digest to sign for voting directly from the contract */
194
- public async getVoteDataDigest(votes: Hex, slot: bigint): Promise<Buffer32> {
195
- return Buffer32.fromString(await this.contract.read.getVoteSignatureDigest([votes, slot]));
195
+ public async getVoteDataDigest(votes: Hex, slot: SlotNumber): Promise<Buffer32> {
196
+ return Buffer32.fromString(await this.contract.read.getVoteSignatureDigest([votes, BigInt(slot)]));
196
197
  }
197
198
 
198
199
  /**
@@ -1,4 +1,5 @@
1
1
  import { L1_TO_L2_MSG_SUBTREE_HEIGHT } from '@aztec/constants';
2
+ import { SlotNumber } from '@aztec/foundation/branded-types';
2
3
  import { SecretValue, getActiveNetworkName } from '@aztec/foundation/config';
3
4
  import { keccak256String } from '@aztec/foundation/crypto';
4
5
  import { EthAddress } from '@aztec/foundation/eth-address';
@@ -1519,13 +1520,13 @@ export const deployL1Contracts = async (
1519
1520
  // Need to get the time
1520
1521
  const currentSlot = await rollup.getSlotNumber();
1521
1522
 
1522
- if (BigInt(currentSlot) === 0n) {
1523
- const ts = Number(await rollup.getTimestampForSlot(1n));
1523
+ if (currentSlot === 0) {
1524
+ const ts = Number(await rollup.getTimestampForSlot(SlotNumber(1)));
1524
1525
  await rpcCall('evm_setNextBlockTimestamp', [ts]);
1525
1526
  await rpcCall('hardhat_mine', [1]);
1526
1527
  const currentSlot = await rollup.getSlotNumber();
1527
1528
 
1528
- if (BigInt(currentSlot) !== 1n) {
1529
+ if (currentSlot !== 1) {
1529
1530
  throw new Error(`Error jumping time: current slot is ${currentSlot}`);
1530
1531
  }
1531
1532
  logger.info(`Jumped to slot 1`);
@@ -1,5 +1,5 @@
1
1
  import { InboxContract, type RollupContract } from '@aztec/ethereum/contracts';
2
- import { EpochNumber } from '@aztec/foundation/branded-types';
2
+ import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
3
  import { EthAddress } from '@aztec/foundation/eth-address';
4
4
  import { createLogger } from '@aztec/foundation/log';
5
5
  import { promiseWithResolvers } from '@aztec/foundation/promise';
@@ -11,11 +11,11 @@ import type { ViemClient } from '../types.js';
11
11
 
12
12
  export type ChainMonitorEventMap = {
13
13
  'l1-block': [{ l1BlockNumber: number; timestamp: bigint }];
14
- checkpoint: [{ checkpointNumber: number; l1BlockNumber: number; l2SlotNumber: number; timestamp: bigint }];
14
+ checkpoint: [{ checkpointNumber: number; l1BlockNumber: number; l2SlotNumber: SlotNumber; timestamp: bigint }];
15
15
  'checkpoint-proven': [{ provenCheckpointNumber: number; l1BlockNumber: number; timestamp: bigint }];
16
16
  'l2-messages': [{ totalL2Messages: number; l1BlockNumber: number }];
17
17
  'l2-epoch': [{ l2EpochNumber: EpochNumber; timestamp: bigint; committee: EthAddress[] | undefined }];
18
- 'l2-slot': [{ l2SlotNumber: number; timestamp: bigint }];
18
+ 'l2-slot': [{ l2SlotNumber: SlotNumber; timestamp: bigint }];
19
19
  };
20
20
 
21
21
  /** Utility class that polls the chain on quick intervals and logs new L1 blocks, L2 blocks, and L2 proofs. */
@@ -41,7 +41,7 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
41
41
  /** Current L2 epoch number */
42
42
  public l2EpochNumber!: EpochNumber;
43
43
  /** Current L2 slot number */
44
- public l2SlotNumber!: bigint;
44
+ public l2SlotNumber!: SlotNumber;
45
45
 
46
46
  constructor(
47
47
  private readonly rollup: RollupContract,
@@ -124,7 +124,7 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
124
124
  this.emit('checkpoint', {
125
125
  checkpointNumber: newCheckpointNumber,
126
126
  l1BlockNumber: newL1BlockNumber,
127
- l2SlotNumber: Number(l2SlotNumber),
127
+ l2SlotNumber,
128
128
  timestamp,
129
129
  });
130
130
  }
@@ -160,7 +160,7 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
160
160
 
161
161
  if (l2SlotNumber !== this.l2SlotNumber) {
162
162
  this.l2SlotNumber = l2SlotNumber;
163
- this.emit('l2-slot', { l2SlotNumber: Number(l2SlotNumber), timestamp });
163
+ this.emit('l2-slot', { l2SlotNumber, timestamp });
164
164
  }
165
165
 
166
166
  this.logger.info(msg, {
@@ -178,14 +178,13 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
178
178
  return this;
179
179
  }
180
180
 
181
- public waitUntilL2Slot(slot: number | bigint): Promise<void> {
182
- const targetSlot = typeof slot === 'bigint' ? slot.valueOf() : slot;
183
- if (this.l2SlotNumber >= targetSlot) {
181
+ public waitUntilL2Slot(slot: SlotNumber): Promise<void> {
182
+ if (this.l2SlotNumber >= slot) {
184
183
  return Promise.resolve();
185
184
  }
186
185
  return new Promise(resolve => {
187
- const listener = (data: { l2SlotNumber: number; timestamp: bigint }) => {
188
- if (data.l2SlotNumber >= targetSlot) {
186
+ const listener = (data: { l2SlotNumber: SlotNumber; timestamp: bigint }) => {
187
+ if (data.l2SlotNumber >= slot) {
189
188
  this.off('l2-slot', listener);
190
189
  resolve();
191
190
  }
@@ -1,6 +1,6 @@
1
1
  import { RollupContract, type ViemPublicClient } from '@aztec/ethereum';
2
2
  import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
3
- import { EpochNumber } from '@aztec/foundation/branded-types';
3
+ import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
4
4
  import { EthAddress } from '@aztec/foundation/eth-address';
5
5
  import { createLogger } from '@aztec/foundation/log';
6
6
  import type { DateProvider } from '@aztec/foundation/timer';
@@ -50,15 +50,15 @@ export class RollupCheatCodes {
50
50
  }
51
51
 
52
52
  /** Returns the current slot */
53
- public async getSlot() {
53
+ public async getSlot(): Promise<SlotNumber> {
54
54
  const ts = BigInt((await this.client.getBlock()).timestamp);
55
- return await this.rollup.read.getSlotAt([ts]);
55
+ return SlotNumber.fromBigInt(await this.rollup.read.getSlotAt([ts]));
56
56
  }
57
57
 
58
58
  /** Returns the current epoch */
59
59
  public async getEpoch(): Promise<EpochNumber> {
60
60
  const slotNumber = await this.getSlot();
61
- return EpochNumber.fromBigInt(await this.rollup.read.getEpochAtSlot([slotNumber]));
61
+ return EpochNumber.fromBigInt(await this.rollup.read.getEpochAtSlot([BigInt(slotNumber)]));
62
62
  }
63
63
 
64
64
  /**
@@ -97,13 +97,13 @@ export class RollupCheatCodes {
97
97
  /** Fetches the epoch and slot duration config from the rollup contract */
98
98
  public async getConfig(): Promise<{
99
99
  /** Epoch duration */ epochDuration: bigint;
100
- /** Slot duration */ slotDuration: bigint;
100
+ /** Slot duration */ slotDuration: number;
101
101
  }> {
102
102
  const [epochDuration, slotDuration] = await Promise.all([
103
103
  this.rollup.read.getEpochDuration(),
104
104
  this.rollup.read.getSlotDuration(),
105
105
  ]);
106
- return { epochDuration, slotDuration };
106
+ return { epochDuration, slotDuration: Number(slotDuration) };
107
107
  }
108
108
 
109
109
  /**
@@ -112,15 +112,15 @@ export class RollupCheatCodes {
112
112
  * @param opts - Options
113
113
  */
114
114
  public async advanceToEpoch(
115
- epoch: EpochNumber | bigint | number,
115
+ epoch: EpochNumber,
116
116
  opts: {
117
117
  /** Offset in seconds */
118
118
  offset?: number;
119
119
  } = {},
120
120
  ) {
121
121
  const { epochDuration: slotsInEpoch } = await this.getConfig();
122
- const timestamp =
123
- (await this.rollup.read.getTimestampForSlot([BigInt(epoch) * slotsInEpoch])) + BigInt(opts.offset ?? 0);
122
+ const slotNumber = SlotNumber(epoch * Number(slotsInEpoch));
123
+ const timestamp = (await this.rollup.read.getTimestampForSlot([BigInt(slotNumber)])) + BigInt(opts.offset ?? 0);
124
124
  try {
125
125
  await this.ethCheatCodes.warp(Number(timestamp), { ...opts, silent: true, resetBlockInterval: true });
126
126
  this.logger.warn(`Warped to epoch ${epoch}`);
@@ -134,8 +134,8 @@ export class RollupCheatCodes {
134
134
  public async advanceToNextEpoch() {
135
135
  const slot = await this.getSlot();
136
136
  const { epochDuration, slotDuration } = await this.getConfig();
137
- const slotsUntilNextEpoch = epochDuration - (slot % epochDuration) + 1n;
138
- const timeToNextEpoch = slotsUntilNextEpoch * slotDuration;
137
+ const slotsUntilNextEpoch = epochDuration - (BigInt(slot) % epochDuration) + 1n;
138
+ const timeToNextEpoch = slotsUntilNextEpoch * BigInt(slotDuration);
139
139
  const l1Timestamp = BigInt((await this.client.getBlock()).timestamp);
140
140
  await this.ethCheatCodes.warp(Number(l1Timestamp + timeToNextEpoch), {
141
141
  silent: true,
@@ -147,10 +147,11 @@ export class RollupCheatCodes {
147
147
  /** Warps time in L1 until the beginning of the next slot. */
148
148
  public async advanceToNextSlot() {
149
149
  const currentSlot = await this.getSlot();
150
- const timestamp = await this.rollup.read.getTimestampForSlot([currentSlot + 1n]);
150
+ const nextSlot = SlotNumber(currentSlot + 1);
151
+ const timestamp = await this.rollup.read.getTimestampForSlot([BigInt(nextSlot)]);
151
152
  await this.ethCheatCodes.warp(Number(timestamp), { silent: true, resetBlockInterval: true });
152
- this.logger.warn(`Advanced to slot ${currentSlot + 1n}`);
153
- return [timestamp, currentSlot + 1n];
153
+ this.logger.warn(`Advanced to slot ${nextSlot}`);
154
+ return [timestamp, nextSlot];
154
155
  }
155
156
 
156
157
  /**
@@ -159,8 +160,8 @@ export class RollupCheatCodes {
159
160
  */
160
161
  public async advanceSlots(howMany: number) {
161
162
  const l1Timestamp = (await this.client.getBlock()).timestamp;
162
- const slotDuration = await this.rollup.read.getSlotDuration();
163
- const timeToWarp = BigInt(howMany) * slotDuration;
163
+ const slotDuration = Number(await this.rollup.read.getSlotDuration());
164
+ const timeToWarp = BigInt(howMany) * BigInt(slotDuration);
164
165
  await this.ethCheatCodes.warp(l1Timestamp + timeToWarp, { silent: true, resetBlockInterval: true });
165
166
  const [slot, epoch] = await Promise.all([this.getSlot(), this.getEpoch()]);
166
167
  this.logger.warn(`Advanced ${howMany} slots up to slot ${slot} in epoch ${epoch}`);