@aztec/ethereum 0.0.1-commit.24de95ac → 0.0.1-commit.2e2504e2

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 (208) hide show
  1. package/dest/account.d.ts +1 -1
  2. package/dest/chain.d.ts +1 -1
  3. package/dest/client.d.ts +1 -1
  4. package/dest/client.js +6 -2
  5. package/dest/config.d.ts +22 -68
  6. package/dest/config.d.ts.map +1 -1
  7. package/dest/config.js +57 -378
  8. package/dest/constants.d.ts +1 -1
  9. package/dest/contracts/empire_base.d.ts +7 -5
  10. package/dest/contracts/empire_base.d.ts.map +1 -1
  11. package/dest/contracts/empire_base.js +1 -1
  12. package/dest/contracts/empire_slashing_proposer.d.ts +6 -4
  13. package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
  14. package/dest/contracts/empire_slashing_proposer.js +30 -17
  15. package/dest/contracts/errors.d.ts +1 -1
  16. package/dest/contracts/errors.d.ts.map +1 -1
  17. package/dest/contracts/fee_asset_handler.d.ts +6 -5
  18. package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
  19. package/dest/contracts/fee_asset_handler.js +11 -9
  20. package/dest/contracts/fee_juice.d.ts +1 -1
  21. package/dest/contracts/fee_juice.d.ts.map +1 -1
  22. package/dest/contracts/governance.d.ts +18 -16
  23. package/dest/contracts/governance.d.ts.map +1 -1
  24. package/dest/contracts/governance.js +11 -1
  25. package/dest/contracts/governance_proposer.d.ts +6 -4
  26. package/dest/contracts/governance_proposer.d.ts.map +1 -1
  27. package/dest/contracts/governance_proposer.js +403 -11
  28. package/dest/contracts/gse.d.ts +1 -1
  29. package/dest/contracts/gse.d.ts.map +1 -1
  30. package/dest/contracts/inbox.d.ts +24 -3
  31. package/dest/contracts/inbox.d.ts.map +1 -1
  32. package/dest/contracts/inbox.js +36 -1
  33. package/dest/contracts/index.d.ts +3 -1
  34. package/dest/contracts/index.d.ts.map +1 -1
  35. package/dest/contracts/index.js +2 -0
  36. package/dest/contracts/log.d.ts +13 -0
  37. package/dest/contracts/log.d.ts.map +1 -0
  38. package/dest/contracts/log.js +1 -0
  39. package/dest/contracts/multicall.d.ts +2 -2
  40. package/dest/contracts/multicall.d.ts.map +1 -1
  41. package/dest/contracts/multicall.js +2 -1
  42. package/dest/contracts/outbox.d.ts +41 -0
  43. package/dest/contracts/outbox.d.ts.map +1 -0
  44. package/dest/contracts/outbox.js +86 -0
  45. package/dest/contracts/registry.d.ts +1 -1
  46. package/dest/contracts/registry.d.ts.map +1 -1
  47. package/dest/contracts/rollup.d.ts +194 -123
  48. package/dest/contracts/rollup.d.ts.map +1 -1
  49. package/dest/contracts/rollup.js +750 -184
  50. package/dest/contracts/slasher_contract.d.ts +1 -1
  51. package/dest/contracts/slasher_contract.d.ts.map +1 -1
  52. package/dest/contracts/tally_slashing_proposer.d.ts +9 -7
  53. package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
  54. package/dest/contracts/tally_slashing_proposer.js +11 -4
  55. package/dest/contracts/utils.d.ts +1 -1
  56. package/dest/deploy_aztec_l1_contracts.d.ts +260 -0
  57. package/dest/deploy_aztec_l1_contracts.d.ts.map +1 -0
  58. package/dest/deploy_aztec_l1_contracts.js +399 -0
  59. package/dest/deploy_l1_contract.d.ts +68 -0
  60. package/dest/deploy_l1_contract.d.ts.map +1 -0
  61. package/dest/deploy_l1_contract.js +312 -0
  62. package/dest/eth-signer/eth-signer.d.ts +1 -1
  63. package/dest/eth-signer/index.d.ts +1 -1
  64. package/dest/forwarder_proxy.d.ts +32 -0
  65. package/dest/forwarder_proxy.d.ts.map +1 -0
  66. package/dest/forwarder_proxy.js +93 -0
  67. package/dest/generated/l1-contracts-defaults.d.ts +30 -0
  68. package/dest/generated/l1-contracts-defaults.d.ts.map +1 -0
  69. package/dest/generated/l1-contracts-defaults.js +30 -0
  70. package/dest/l1_artifacts.d.ts +6597 -2046
  71. package/dest/l1_artifacts.d.ts.map +1 -1
  72. package/dest/l1_contract_addresses.d.ts +3 -3
  73. package/dest/l1_contract_addresses.d.ts.map +1 -1
  74. package/dest/l1_contract_addresses.js +3 -3
  75. package/dest/l1_reader.d.ts +3 -1
  76. package/dest/l1_reader.d.ts.map +1 -1
  77. package/dest/l1_reader.js +6 -0
  78. package/dest/l1_tx_utils/config.d.ts +5 -5
  79. package/dest/l1_tx_utils/config.d.ts.map +1 -1
  80. package/dest/l1_tx_utils/config.js +30 -7
  81. package/dest/l1_tx_utils/constants.d.ts +8 -2
  82. package/dest/l1_tx_utils/constants.d.ts.map +1 -1
  83. package/dest/l1_tx_utils/constants.js +27 -2
  84. package/dest/l1_tx_utils/factory.d.ts +1 -1
  85. package/dest/l1_tx_utils/fee-strategies/index.d.ts +10 -0
  86. package/dest/l1_tx_utils/fee-strategies/index.d.ts.map +1 -0
  87. package/dest/l1_tx_utils/fee-strategies/index.js +12 -0
  88. package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts +8 -0
  89. package/dest/l1_tx_utils/fee-strategies/p75_competitive.d.ts.map +1 -0
  90. package/dest/l1_tx_utils/fee-strategies/p75_competitive.js +129 -0
  91. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts +23 -0
  92. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.d.ts.map +1 -0
  93. package/dest/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.js +191 -0
  94. package/dest/l1_tx_utils/fee-strategies/types.d.ts +51 -0
  95. package/dest/l1_tx_utils/fee-strategies/types.d.ts.map +1 -0
  96. package/dest/l1_tx_utils/fee-strategies/types.js +3 -0
  97. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts +41 -0
  98. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts.map +1 -0
  99. package/dest/l1_tx_utils/forwarder_l1_tx_utils.js +48 -0
  100. package/dest/l1_tx_utils/index-blobs.d.ts +3 -0
  101. package/dest/l1_tx_utils/index-blobs.d.ts.map +1 -0
  102. package/dest/l1_tx_utils/index-blobs.js +2 -0
  103. package/dest/l1_tx_utils/index.d.ts +3 -1
  104. package/dest/l1_tx_utils/index.d.ts.map +1 -1
  105. package/dest/l1_tx_utils/index.js +2 -0
  106. package/dest/l1_tx_utils/interfaces.d.ts +2 -2
  107. package/dest/l1_tx_utils/interfaces.d.ts.map +1 -1
  108. package/dest/l1_tx_utils/l1_fee_analyzer.d.ts +233 -0
  109. package/dest/l1_tx_utils/l1_fee_analyzer.d.ts.map +1 -0
  110. package/dest/l1_tx_utils/l1_fee_analyzer.js +506 -0
  111. package/dest/l1_tx_utils/l1_tx_utils.d.ts +1 -2
  112. package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -1
  113. package/dest/l1_tx_utils/l1_tx_utils.js +23 -10
  114. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts +1 -1
  115. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts.map +1 -1
  116. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +19 -30
  117. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -1
  118. package/dest/l1_tx_utils/readonly_l1_tx_utils.js +55 -163
  119. package/dest/l1_tx_utils/signer.d.ts +1 -1
  120. package/dest/l1_tx_utils/types.d.ts +1 -1
  121. package/dest/l1_tx_utils/types.d.ts.map +1 -1
  122. package/dest/l1_tx_utils/utils.d.ts +1 -1
  123. package/dest/l1_types.d.ts +1 -1
  124. package/dest/publisher_manager.d.ts +3 -2
  125. package/dest/publisher_manager.d.ts.map +1 -1
  126. package/dest/publisher_manager.js +2 -2
  127. package/dest/queries.d.ts +2 -2
  128. package/dest/queries.d.ts.map +1 -1
  129. package/dest/queries.js +16 -6
  130. package/dest/test/chain_monitor.d.ts +27 -24
  131. package/dest/test/chain_monitor.d.ts.map +1 -1
  132. package/dest/test/chain_monitor.js +33 -36
  133. package/dest/test/delayed_tx_utils.d.ts +1 -1
  134. package/dest/test/delayed_tx_utils.d.ts.map +1 -1
  135. package/dest/test/eth_cheat_codes.d.ts +11 -3
  136. package/dest/test/eth_cheat_codes.d.ts.map +1 -1
  137. package/dest/test/eth_cheat_codes.js +11 -3
  138. package/dest/test/eth_cheat_codes_with_state.d.ts +1 -1
  139. package/dest/test/eth_cheat_codes_with_state.d.ts.map +1 -1
  140. package/dest/test/index.d.ts +1 -1
  141. package/dest/test/rollup_cheat_codes.d.ts +17 -13
  142. package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
  143. package/dest/test/rollup_cheat_codes.js +62 -38
  144. package/dest/test/start_anvil.d.ts +4 -1
  145. package/dest/test/start_anvil.d.ts.map +1 -1
  146. package/dest/test/start_anvil.js +3 -2
  147. package/dest/test/tx_delayer.d.ts +1 -1
  148. package/dest/test/tx_delayer.d.ts.map +1 -1
  149. package/dest/test/tx_delayer.js +4 -3
  150. package/dest/test/upgrade_utils.d.ts +1 -1
  151. package/dest/types.d.ts +57 -2
  152. package/dest/types.d.ts.map +1 -1
  153. package/dest/utils.d.ts +16 -3
  154. package/dest/utils.d.ts.map +1 -1
  155. package/dest/utils.js +64 -0
  156. package/dest/zkPassportVerifierAddress.d.ts +1 -1
  157. package/package.json +34 -14
  158. package/src/client.ts +2 -2
  159. package/src/config.ts +71 -458
  160. package/src/contracts/README.md +157 -0
  161. package/src/contracts/empire_base.ts +6 -5
  162. package/src/contracts/empire_slashing_proposer.ts +32 -32
  163. package/src/contracts/fee_asset_handler.ts +10 -7
  164. package/src/contracts/governance.ts +10 -1
  165. package/src/contracts/governance_proposer.ts +20 -6
  166. package/src/contracts/inbox.ts +55 -3
  167. package/src/contracts/index.ts +2 -0
  168. package/src/contracts/log.ts +13 -0
  169. package/src/contracts/multicall.ts +5 -2
  170. package/src/contracts/outbox.ts +98 -0
  171. package/src/contracts/rollup.ts +421 -160
  172. package/src/contracts/tally_slashing_proposer.ts +15 -8
  173. package/src/deploy_aztec_l1_contracts.ts +623 -0
  174. package/src/deploy_l1_contract.ts +362 -0
  175. package/src/forwarder_proxy.ts +108 -0
  176. package/src/generated/l1-contracts-defaults.ts +32 -0
  177. package/src/l1_contract_addresses.ts +22 -20
  178. package/src/l1_reader.ts +8 -0
  179. package/src/l1_tx_utils/config.ts +32 -11
  180. package/src/l1_tx_utils/constants.ts +13 -2
  181. package/src/l1_tx_utils/fee-strategies/index.ts +22 -0
  182. package/src/l1_tx_utils/fee-strategies/p75_competitive.ts +163 -0
  183. package/src/l1_tx_utils/fee-strategies/p75_competitive_blob_txs_only.ts +245 -0
  184. package/src/l1_tx_utils/fee-strategies/types.ts +56 -0
  185. package/src/l1_tx_utils/forwarder_l1_tx_utils.ts +119 -0
  186. package/src/l1_tx_utils/index-blobs.ts +2 -0
  187. package/src/l1_tx_utils/index.ts +2 -0
  188. package/src/l1_tx_utils/interfaces.ts +1 -1
  189. package/src/l1_tx_utils/l1_fee_analyzer.ts +803 -0
  190. package/src/l1_tx_utils/l1_tx_utils.ts +30 -10
  191. package/src/l1_tx_utils/readonly_l1_tx_utils.ts +69 -209
  192. package/src/publisher_manager.ts +4 -2
  193. package/src/queries.ts +17 -6
  194. package/src/test/chain_monitor.ts +51 -49
  195. package/src/test/eth_cheat_codes.ts +9 -3
  196. package/src/test/rollup_cheat_codes.ts +63 -43
  197. package/src/test/start_anvil.ts +5 -1
  198. package/src/test/tx_delayer.ts +5 -3
  199. package/src/types.ts +62 -0
  200. package/src/utils.ts +83 -1
  201. package/dest/deploy_l1_contracts.d.ts +0 -226
  202. package/dest/deploy_l1_contracts.d.ts.map +0 -1
  203. package/dest/deploy_l1_contracts.js +0 -1473
  204. package/dest/index.d.ts +0 -18
  205. package/dest/index.d.ts.map +0 -1
  206. package/dest/index.js +0 -17
  207. package/src/deploy_l1_contracts.ts +0 -1849
  208. package/src/index.ts +0 -17
@@ -1,4 +1,6 @@
1
- import { InboxContract, type RollupContract } from '@aztec/ethereum/contracts';
1
+ import type { RollupContract } from '@aztec/ethereum/contracts';
2
+ import { InboxContract } from '@aztec/ethereum/contracts';
3
+ import { CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
2
4
  import { EthAddress } from '@aztec/foundation/eth-address';
3
5
  import { createLogger } from '@aztec/foundation/log';
4
6
  import { promiseWithResolvers } from '@aztec/foundation/promise';
@@ -10,11 +12,13 @@ import type { ViemClient } from '../types.js';
10
12
 
11
13
  export type ChainMonitorEventMap = {
12
14
  'l1-block': [{ l1BlockNumber: number; timestamp: bigint }];
13
- 'l2-block': [{ l2BlockNumber: number; l1BlockNumber: number; l2SlotNumber: number; timestamp: bigint }];
14
- 'l2-block-proven': [{ l2ProvenBlockNumber: number; l1BlockNumber: number; timestamp: bigint }];
15
+ checkpoint: [
16
+ { checkpointNumber: CheckpointNumber; l1BlockNumber: number; l2SlotNumber: SlotNumber; timestamp: bigint },
17
+ ];
18
+ 'checkpoint-proven': [{ provenCheckpointNumber: CheckpointNumber; l1BlockNumber: number; timestamp: bigint }];
15
19
  'l2-messages': [{ totalL2Messages: number; l1BlockNumber: number }];
16
- 'l2-epoch': [{ l2EpochNumber: number; timestamp: bigint; committee: EthAddress[] | undefined }];
17
- 'l2-slot': [{ l2SlotNumber: number; timestamp: bigint }];
20
+ 'l2-epoch': [{ l2EpochNumber: EpochNumber; timestamp: bigint; committee: EthAddress[] | undefined }];
21
+ 'l2-slot': [{ l2SlotNumber: SlotNumber; timestamp: bigint }];
18
22
  };
19
23
 
20
24
  /** Utility class that polls the chain on quick intervals and logs new L1 blocks, L2 blocks, and L2 proofs. */
@@ -27,20 +31,20 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
27
31
 
28
32
  /** Current L1 block number */
29
33
  public l1BlockNumber!: number;
30
- /** Current L2 block number */
31
- public l2BlockNumber!: number;
32
- /** Current L2 proven block number */
33
- public l2ProvenBlockNumber!: number;
34
- /** L1 timestamp for the current L2 block */
35
- public l2BlockTimestamp!: bigint;
36
- /** L1 timestamp for the proven L2 block */
37
- public l2ProvenBlockTimestamp!: bigint;
34
+ /** Current checkpoint number */
35
+ public checkpointNumber!: CheckpointNumber;
36
+ /** Current proven checkpoint number */
37
+ public provenCheckpointNumber!: CheckpointNumber;
38
+ /** L1 timestamp for the current checkpoint */
39
+ public checkpointTimestamp!: bigint;
40
+ /** L1 timestamp for the proven checkpoint */
41
+ public provenCheckpointTimestamp!: bigint;
38
42
  /** Total number of L2 messages pushed into the Inbox */
39
43
  public totalL2Messages: number = 0;
40
44
  /** Current L2 epoch number */
41
- public l2EpochNumber!: bigint;
45
+ public l2EpochNumber!: EpochNumber;
42
46
  /** Current L2 slot number */
43
- public l2SlotNumber!: bigint;
47
+ public l2SlotNumber!: SlotNumber;
44
48
 
45
49
  constructor(
46
50
  private readonly rollup: RollupContract,
@@ -114,28 +118,28 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
114
118
  this.emit('l1-block', { l1BlockNumber: newL1BlockNumber, timestamp });
115
119
  let msg = `L1 block ${newL1BlockNumber} mined at ${timestampString}`;
116
120
 
117
- const newL2BlockNumber = Number(await this.rollup.getBlockNumber());
118
- if (this.l2BlockNumber !== newL2BlockNumber) {
119
- const epochNumber = await this.rollup.getEpochNumberForBlock(BigInt(newL2BlockNumber));
120
- msg += ` with new L2 block ${newL2BlockNumber} for epoch ${epochNumber}`;
121
- this.l2BlockNumber = newL2BlockNumber;
122
- this.l2BlockTimestamp = timestamp;
123
- this.emit('l2-block', {
124
- l2BlockNumber: newL2BlockNumber,
121
+ const newCheckpointNumber = await this.rollup.getCheckpointNumber();
122
+ if (this.checkpointNumber !== newCheckpointNumber) {
123
+ const epochNumber = await this.rollup.getEpochNumberForCheckpoint(newCheckpointNumber);
124
+ msg += ` with new checkpoint ${newCheckpointNumber} for epoch ${epochNumber}`;
125
+ this.checkpointNumber = newCheckpointNumber;
126
+ this.checkpointTimestamp = timestamp;
127
+ this.emit('checkpoint', {
128
+ checkpointNumber: newCheckpointNumber,
125
129
  l1BlockNumber: newL1BlockNumber,
126
- l2SlotNumber: Number(l2SlotNumber),
130
+ l2SlotNumber,
127
131
  timestamp,
128
132
  });
129
133
  }
130
134
 
131
- const newL2ProvenBlockNumber = Number(await this.rollup.getProvenBlockNumber());
132
- if (this.l2ProvenBlockNumber !== newL2ProvenBlockNumber) {
133
- const epochNumber = await this.rollup.getEpochNumberForBlock(BigInt(newL2ProvenBlockNumber));
134
- msg += ` with proof up to L2 block ${newL2ProvenBlockNumber} for epoch ${epochNumber}`;
135
- this.l2ProvenBlockNumber = newL2ProvenBlockNumber;
136
- this.l2ProvenBlockTimestamp = timestamp;
137
- this.emit('l2-block-proven', {
138
- l2ProvenBlockNumber: newL2ProvenBlockNumber,
135
+ const newProvenCheckpointNumber = await this.rollup.getProvenCheckpointNumber();
136
+ if (this.provenCheckpointNumber !== newProvenCheckpointNumber) {
137
+ const epochNumber = await this.rollup.getEpochNumberForCheckpoint(newProvenCheckpointNumber);
138
+ msg += ` with proof up to checkpoint ${newProvenCheckpointNumber} for epoch ${epochNumber}`;
139
+ this.provenCheckpointNumber = newProvenCheckpointNumber;
140
+ this.provenCheckpointTimestamp = timestamp;
141
+ this.emit('checkpoint-proven', {
142
+ provenCheckpointNumber: newProvenCheckpointNumber,
139
143
  l1BlockNumber: newL1BlockNumber,
140
144
  timestamp,
141
145
  });
@@ -152,14 +156,14 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
152
156
  let committee: EthAddress[] | undefined;
153
157
  if (l2Epoch !== this.l2EpochNumber) {
154
158
  this.l2EpochNumber = l2Epoch;
155
- committee = (await this.rollup.getCurrentEpochCommittee())?.map(addr => EthAddress.fromString(addr));
156
- this.emit('l2-epoch', { l2EpochNumber: Number(l2Epoch), timestamp, committee });
159
+ committee = await this.rollup.getCurrentEpochCommittee();
160
+ this.emit('l2-epoch', { l2EpochNumber: l2Epoch, timestamp, committee });
157
161
  msg += ` starting new epoch ${this.l2EpochNumber} `;
158
162
  }
159
163
 
160
164
  if (l2SlotNumber !== this.l2SlotNumber) {
161
165
  this.l2SlotNumber = l2SlotNumber;
162
- this.emit('l2-slot', { l2SlotNumber: Number(l2SlotNumber), timestamp });
166
+ this.emit('l2-slot', { l2SlotNumber, timestamp });
163
167
  }
164
168
 
165
169
  this.logger.info(msg, {
@@ -168,8 +172,8 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
168
172
  l1BlockNumber: this.l1BlockNumber,
169
173
  l2SlotNumber,
170
174
  l2Epoch,
171
- l2BlockNumber: this.l2BlockNumber,
172
- l2ProvenBlockNumber: this.l2ProvenBlockNumber,
175
+ checkpointNumber: this.checkpointNumber,
176
+ provenCheckpointNumber: this.provenCheckpointNumber,
173
177
  totalL2Messages: this.totalL2Messages,
174
178
  committee,
175
179
  });
@@ -177,14 +181,13 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
177
181
  return this;
178
182
  }
179
183
 
180
- public waitUntilL2Slot(slot: number | bigint): Promise<void> {
181
- const targetSlot = typeof slot === 'bigint' ? slot.valueOf() : slot;
182
- if (this.l2SlotNumber >= targetSlot) {
184
+ public waitUntilL2Slot(slot: SlotNumber): Promise<void> {
185
+ if (this.l2SlotNumber >= slot) {
183
186
  return Promise.resolve();
184
187
  }
185
188
  return new Promise(resolve => {
186
- const listener = (data: { l2SlotNumber: number; timestamp: bigint }) => {
187
- if (data.l2SlotNumber >= targetSlot) {
189
+ const listener = (data: { l2SlotNumber: SlotNumber; timestamp: bigint }) => {
190
+ if (data.l2SlotNumber >= slot) {
188
191
  this.off('l2-slot', listener);
189
192
  resolve();
190
193
  }
@@ -225,19 +228,18 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
225
228
  });
226
229
  }
227
230
 
228
- public waitUntilL2Block(l2BlockNumber: number | bigint): Promise<void> {
229
- const targetBlock = typeof l2BlockNumber === 'bigint' ? l2BlockNumber.valueOf() : l2BlockNumber;
230
- if (this.l2BlockNumber >= targetBlock) {
231
+ public waitUntilCheckpoint(checkpointNumber: CheckpointNumber): Promise<void> {
232
+ if (this.checkpointNumber >= checkpointNumber) {
231
233
  return Promise.resolve();
232
234
  }
233
235
  return new Promise(resolve => {
234
- const listener = (data: { l2BlockNumber: number; timestamp: bigint }) => {
235
- if (data.l2BlockNumber >= targetBlock) {
236
- this.off('l2-block', listener);
236
+ const listener = (data: { checkpointNumber: CheckpointNumber; timestamp: bigint }) => {
237
+ if (data.checkpointNumber >= checkpointNumber) {
238
+ this.off('checkpoint', listener);
237
239
  resolve();
238
240
  }
239
241
  };
240
- this.on('l2-block', listener);
242
+ this.on('checkpoint', listener);
241
243
  });
242
244
  }
243
245
  }
@@ -1,12 +1,13 @@
1
1
  import { toBigIntBE, toHex } from '@aztec/foundation/bigint-buffer';
2
- import { keccak256 } from '@aztec/foundation/crypto';
2
+ import { keccak256 } from '@aztec/foundation/crypto/keccak';
3
3
  import { EthAddress } from '@aztec/foundation/eth-address';
4
4
  import { jsonStringify } from '@aztec/foundation/json-rpc';
5
5
  import { createLogger } from '@aztec/foundation/log';
6
6
  import { pluralize } from '@aztec/foundation/string';
7
7
  import type { DateProvider, TestDateProvider } from '@aztec/foundation/timer';
8
8
 
9
- import { type Hex, type Transaction, createPublicClient, fallback, hexToNumber, http } from 'viem';
9
+ import { type Chain, type Hex, type Transaction, createPublicClient, fallback, hexToNumber, http } from 'viem';
10
+ import { foundry } from 'viem/chains';
10
11
 
11
12
  import type { ViemPublicClient } from '../types.js';
12
13
 
@@ -28,9 +29,14 @@ export class EthCheatCodes {
28
29
  * The logger to use for the eth cheatcodes
29
30
  */
30
31
  public logger = createLogger('ethereum:cheat_codes'),
32
+ /**
33
+ * The chain configuration provided to Anvil
34
+ */
35
+ public chain: Chain = foundry,
31
36
  ) {
32
37
  this.publicClient = createPublicClient({
33
- transport: fallback(this.rpcUrls.map(url => http(url))),
38
+ transport: fallback(this.rpcUrls.map(url => http(url, { batch: false }))),
39
+ chain: chain,
34
40
  });
35
41
  }
36
42
 
@@ -1,5 +1,7 @@
1
- import { RollupContract, type ViemPublicClient } from '@aztec/ethereum';
1
+ import { OutboxContract, RollupContract } from '@aztec/ethereum/contracts';
2
2
  import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
3
+ import type { ViemPublicClient } from '@aztec/ethereum/types';
4
+ import { CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
5
  import { EthAddress } from '@aztec/foundation/eth-address';
4
6
  import { createLogger } from '@aztec/foundation/log';
5
7
  import type { DateProvider } from '@aztec/foundation/timer';
@@ -14,7 +16,6 @@ import {
14
16
  hexToBigInt,
15
17
  http,
16
18
  } from 'viem';
17
- import { foundry } from 'viem/chains';
18
19
 
19
20
  import { EthCheatCodes } from './eth_cheat_codes.js';
20
21
 
@@ -30,8 +31,8 @@ export class RollupCheatCodes {
30
31
  addresses: Pick<L1ContractAddresses, 'rollupAddress'>,
31
32
  ) {
32
33
  this.client = createPublicClient({
33
- chain: foundry,
34
- transport: fallback(ethCheatCodes.rpcUrls.map(url => http(url))),
34
+ chain: ethCheatCodes.chain,
35
+ transport: fallback(ethCheatCodes.rpcUrls.map(url => http(url, { batch: false }))),
35
36
  });
36
37
  this.rollup = getContract({
37
38
  abi: RollupAbi,
@@ -50,15 +51,24 @@ export class RollupCheatCodes {
50
51
  }
51
52
 
52
53
  /** Returns the current slot */
53
- public async getSlot() {
54
+ public async getSlot(): Promise<SlotNumber> {
54
55
  const ts = BigInt((await this.client.getBlock()).timestamp);
55
- return await this.rollup.read.getSlotAt([ts]);
56
+ return SlotNumber.fromBigInt(await this.rollup.read.getSlotAt([ts]));
57
+ }
58
+
59
+ /** Returns the number of seconds until the start of the given slot based on L1 block timestamp. */
60
+ public async getSecondsUntilSlot(slot: SlotNumber): Promise<number> {
61
+ const [currentTimestamp, targetTimestamp] = await Promise.all([
62
+ this.client.getBlock().then(b => BigInt(b.timestamp)),
63
+ this.rollup.read.getTimestampForSlot([BigInt(slot)]),
64
+ ]);
65
+ return Math.max(0, Number(targetTimestamp - currentTimestamp));
56
66
  }
57
67
 
58
68
  /** Returns the current epoch */
59
- public async getEpoch() {
69
+ public async getEpoch(): Promise<EpochNumber> {
60
70
  const slotNumber = await this.getSlot();
61
- return await this.rollup.read.getEpochAtSlot([slotNumber]);
71
+ return EpochNumber.fromBigInt(await this.rollup.read.getEpochAtSlot([BigInt(slotNumber)]));
62
72
  }
63
73
 
64
74
  /**
@@ -66,13 +76,13 @@ export class RollupCheatCodes {
66
76
  * @returns The pending and proven chain tips
67
77
  */
68
78
  public async getTips(): Promise<{
69
- /** The pending chain tip */ pending: bigint;
70
- /** The proven chain tip */ proven: bigint;
79
+ /** The pending chain tip */ pending: CheckpointNumber;
80
+ /** The proven chain tip */ proven: CheckpointNumber;
71
81
  }> {
72
- const res = await this.rollup.read.getTips();
82
+ const { pending, proven } = await this.rollup.read.getTips();
73
83
  return {
74
- pending: res.pendingBlockNumber,
75
- proven: res.provenBlockNumber,
84
+ pending: CheckpointNumber.fromBigInt(pending),
85
+ proven: CheckpointNumber.fromBigInt(proven),
76
86
  };
77
87
  }
78
88
 
@@ -81,16 +91,16 @@ export class RollupCheatCodes {
81
91
  */
82
92
  public async debugRollup() {
83
93
  const rollup = new RollupContract(this.client, this.rollup.address);
84
- const pendingNum = await rollup.getBlockNumber();
85
- const provenNum = await rollup.getProvenBlockNumber();
94
+ const pendingNum = await rollup.getCheckpointNumber();
95
+ const provenNum = await rollup.getProvenCheckpointNumber();
86
96
  const validators = await rollup.getAttesters();
87
97
  const committee = await rollup.getCurrentEpochCommittee();
88
98
  const archive = await rollup.archive();
89
99
  const slot = await this.getSlot();
90
100
  const epochNum = await rollup.getEpochNumberForSlotNumber(slot);
91
101
 
92
- this.logger.info(`Pending block num: ${pendingNum}`);
93
- this.logger.info(`Proven block num: ${provenNum}`);
102
+ this.logger.info(`Pending checkpoint num: ${pendingNum}`);
103
+ this.logger.info(`Proven checkpoint num: ${provenNum}`);
94
104
  this.logger.info(`Validators: ${validators.map(v => v.toString()).join(', ')}`);
95
105
  this.logger.info(`Committee: ${committee?.map(v => v.toString()).join(', ')}`);
96
106
  this.logger.info(`Archive: ${archive}`);
@@ -101,13 +111,13 @@ export class RollupCheatCodes {
101
111
  /** Fetches the epoch and slot duration config from the rollup contract */
102
112
  public async getConfig(): Promise<{
103
113
  /** Epoch duration */ epochDuration: bigint;
104
- /** Slot duration */ slotDuration: bigint;
114
+ /** Slot duration */ slotDuration: number;
105
115
  }> {
106
116
  const [epochDuration, slotDuration] = await Promise.all([
107
117
  this.rollup.read.getEpochDuration(),
108
118
  this.rollup.read.getSlotDuration(),
109
119
  ]);
110
- return { epochDuration, slotDuration };
120
+ return { epochDuration, slotDuration: Number(slotDuration) };
111
121
  }
112
122
 
113
123
  /**
@@ -116,18 +126,18 @@ export class RollupCheatCodes {
116
126
  * @param opts - Options
117
127
  */
118
128
  public async advanceToEpoch(
119
- epoch: bigint | number,
129
+ epoch: EpochNumber,
120
130
  opts: {
121
131
  /** Offset in seconds */
122
132
  offset?: number;
123
133
  } = {},
124
134
  ) {
125
135
  const { epochDuration: slotsInEpoch } = await this.getConfig();
126
- const timestamp =
127
- (await this.rollup.read.getTimestampForSlot([BigInt(epoch) * slotsInEpoch])) + BigInt(opts.offset ?? 0);
136
+ const slotNumber = SlotNumber(Number(epoch) * Number(slotsInEpoch));
137
+ const timestamp = (await this.rollup.read.getTimestampForSlot([BigInt(slotNumber)])) + BigInt(opts.offset ?? 0);
128
138
  try {
129
139
  await this.ethCheatCodes.warp(Number(timestamp), { ...opts, silent: true, resetBlockInterval: true });
130
- this.logger.warn(`Warped to epoch ${epoch}`);
140
+ this.logger.warn(`Warped to epoch ${epoch}`, { offset: opts.offset, timestamp });
131
141
  } catch (err) {
132
142
  this.logger.warn(`Warp to epoch ${epoch} failed: ${err}`);
133
143
  }
@@ -138,8 +148,8 @@ export class RollupCheatCodes {
138
148
  public async advanceToNextEpoch() {
139
149
  const slot = await this.getSlot();
140
150
  const { epochDuration, slotDuration } = await this.getConfig();
141
- const slotsUntilNextEpoch = epochDuration - (slot % epochDuration) + 1n;
142
- const timeToNextEpoch = slotsUntilNextEpoch * slotDuration;
151
+ const slotsUntilNextEpoch = epochDuration - (BigInt(slot) % epochDuration) + 1n;
152
+ const timeToNextEpoch = slotsUntilNextEpoch * BigInt(slotDuration);
143
153
  const l1Timestamp = BigInt((await this.client.getBlock()).timestamp);
144
154
  await this.ethCheatCodes.warp(Number(l1Timestamp + timeToNextEpoch), {
145
155
  silent: true,
@@ -151,10 +161,11 @@ export class RollupCheatCodes {
151
161
  /** Warps time in L1 until the beginning of the next slot. */
152
162
  public async advanceToNextSlot() {
153
163
  const currentSlot = await this.getSlot();
154
- const timestamp = await this.rollup.read.getTimestampForSlot([currentSlot + 1n]);
164
+ const nextSlot = SlotNumber(currentSlot + 1);
165
+ const timestamp = await this.rollup.read.getTimestampForSlot([BigInt(nextSlot)]);
155
166
  await this.ethCheatCodes.warp(Number(timestamp), { silent: true, resetBlockInterval: true });
156
- this.logger.warn(`Advanced to slot ${currentSlot + 1n}`);
157
- return [timestamp, currentSlot + 1n];
167
+ this.logger.warn(`Advanced to slot ${nextSlot}`);
168
+ return [timestamp, nextSlot];
158
169
  }
159
170
 
160
171
  /**
@@ -163,42 +174,42 @@ export class RollupCheatCodes {
163
174
  */
164
175
  public async advanceSlots(howMany: number) {
165
176
  const l1Timestamp = (await this.client.getBlock()).timestamp;
166
- const slotDuration = await this.rollup.read.getSlotDuration();
167
- const timeToWarp = BigInt(howMany) * slotDuration;
177
+ const slotDuration = Number(await this.rollup.read.getSlotDuration());
178
+ const timeToWarp = BigInt(howMany) * BigInt(slotDuration);
168
179
  await this.ethCheatCodes.warp(l1Timestamp + timeToWarp, { silent: true, resetBlockInterval: true });
169
180
  const [slot, epoch] = await Promise.all([this.getSlot(), this.getEpoch()]);
170
181
  this.logger.warn(`Advanced ${howMany} slots up to slot ${slot} in epoch ${epoch}`);
171
182
  }
172
183
 
173
184
  /**
174
- * Marks the specified block (or latest if none) as proven
175
- * @param maybeBlockNumber - The block number to mark as proven (defaults to latest pending)
185
+ * Marks the specified checkpoint (or latest if none) as proven
186
+ * @param maybeCheckpointNumber - The checkpoint number to mark as proven (defaults to latest pending)
176
187
  */
177
- public markAsProven(maybeBlockNumber?: number | bigint) {
188
+ public markAsProven(maybeCheckpointNumber?: CheckpointNumber) {
178
189
  return this.ethCheatCodes.execWithPausedAnvil(async () => {
179
190
  const tipsBefore = await this.getTips();
180
191
  const { pending, proven } = tipsBefore;
181
192
 
182
- let blockNumber = maybeBlockNumber;
183
- if (blockNumber === undefined || blockNumber > pending) {
184
- blockNumber = pending;
193
+ let checkpointNumber = maybeCheckpointNumber;
194
+ if (checkpointNumber === undefined || checkpointNumber > pending) {
195
+ checkpointNumber = pending;
185
196
  }
186
- if (blockNumber <= proven) {
187
- this.logger.debug(`Block ${blockNumber} is already proven`);
197
+ if (checkpointNumber <= proven) {
198
+ this.logger.debug(`Checkpoint ${checkpointNumber} is already proven`);
188
199
  return;
189
200
  }
190
201
 
191
202
  // @note @LHerskind this is heavily dependent on the storage layout and size of values
192
203
  // The rollupStore is a struct and if the size of elements or the struct changes, this can break
193
- const provenBlockNumberSlot = hexToBigInt(RollupContract.stfStorageSlot);
204
+ const provenCheckpointNumberSlot = hexToBigInt(RollupContract.stfStorageSlot);
194
205
 
195
206
  // Need to pack it as a single 32 byte word
196
- const newValue = (BigInt(tipsBefore.pending) << 128n) | BigInt(blockNumber);
197
- await this.ethCheatCodes.store(EthAddress.fromString(this.rollup.address), provenBlockNumberSlot, newValue);
207
+ const newValue = (BigInt(tipsBefore.pending) << 128n) | BigInt(checkpointNumber);
208
+ await this.ethCheatCodes.store(EthAddress.fromString(this.rollup.address), provenCheckpointNumberSlot, newValue);
198
209
 
199
210
  const tipsAfter = await this.getTips();
200
211
  if (tipsAfter.pending < tipsAfter.proven) {
201
- throw new Error('Overwrote pending tip to a block in the past');
212
+ throw new Error('Overwrote pending tip to a checkpoint in the past');
202
213
  }
203
214
 
204
215
  this.logger.info(
@@ -209,7 +220,7 @@ export class RollupCheatCodes {
209
220
 
210
221
  /**
211
222
  * Overrides the inProgress field of the Inbox contract state
212
- * @param howMuch - How many blocks to move it forward
223
+ * @param howMuch - How many checkpoints to move it forward
213
224
  */
214
225
  public advanceInboxInProgress(howMuch: number | bigint): Promise<bigint> {
215
226
  return this.ethCheatCodes.execWithPausedAnvil(async () => {
@@ -248,6 +259,15 @@ export class RollupCheatCodes {
248
259
  });
249
260
  }
250
261
 
262
+ public insertOutbox(epoch: EpochNumber, outHash: bigint) {
263
+ return this.ethCheatCodes.execWithPausedAnvil(async () => {
264
+ const outboxAddress = await this.rollup.read.getOutbox();
265
+ const epochRootSlot = OutboxContract.getEpochRootStorageSlot(epoch);
266
+ await this.ethCheatCodes.store(EthAddress.fromString(outboxAddress), epochRootSlot, outHash);
267
+ this.logger.warn(`Advanced outbox to epoch ${epoch} with out hash ${outHash}`);
268
+ });
269
+ }
270
+
251
271
  /**
252
272
  * Executes an action impersonated as the owner of the Rollup contract.
253
273
  * @param action - The action to execute
@@ -15,6 +15,9 @@ export async function startAnvil(
15
15
  log?: boolean;
16
16
  captureMethodCalls?: boolean;
17
17
  accounts?: number;
18
+ chainId?: number;
19
+ /** The hardfork to use - note: @viem/anvil types are out of date but 'cancun' and 'latest' work */
20
+ hardfork?: string;
18
21
  } = {},
19
22
  ): Promise<{ anvil: Anvil; methodCalls?: string[]; rpcUrl: string; stop: () => Promise<void> }> {
20
23
  const anvilBinary = resolve(dirname(fileURLToPath(import.meta.url)), '../../', 'scripts/anvil_kill_wrapper.sh');
@@ -30,11 +33,12 @@ export async function startAnvil(
30
33
  const anvil = createAnvil({
31
34
  anvilBinary,
32
35
  host: '127.0.0.1',
33
- port: opts.port ?? 8545,
36
+ port: opts.port ?? (process.env.ANVIL_PORT ? parseInt(process.env.ANVIL_PORT) : 8545),
34
37
  blockTime: opts.l1BlockTime,
35
38
  stopTimeout: 1000,
36
39
  accounts: opts.accounts ?? 20,
37
40
  gasLimit: 45_000_000n,
41
+ chainId: opts.chainId ?? 31337,
38
42
  });
39
43
 
40
44
  // Listen to the anvil output to get the port.
@@ -18,6 +18,8 @@ import {
18
18
 
19
19
  import { type ViemClient, isExtendedClient } from '../types.js';
20
20
 
21
+ const MAX_WAIT_TIME_SECONDS = 180;
22
+
21
23
  export function waitUntilBlock<T extends Client>(
22
24
  client: T,
23
25
  blockNumber: number | bigint,
@@ -36,7 +38,7 @@ export function waitUntilBlock<T extends Client>(
36
38
  return currentBlockNumber >= BigInt(blockNumber);
37
39
  },
38
40
  `Wait until L1 block ${blockNumber}`,
39
- timeout ?? 120,
41
+ timeout ?? MAX_WAIT_TIME_SECONDS,
40
42
  0.1,
41
43
  );
42
44
  }
@@ -66,7 +68,7 @@ export function waitUntilL1Timestamp<T extends Client>(
66
68
  return currentTs >= BigInt(timestamp);
67
69
  },
68
70
  `Wait until L1 timestamp ${timestamp}`,
69
- timeout ?? 120,
71
+ timeout ?? MAX_WAIT_TIME_SECONDS,
70
72
  0.1,
71
73
  );
72
74
  }
@@ -230,7 +232,7 @@ export function withDelayer<T extends ViemClient>(
230
232
  return Promise.resolve(txHash!);
231
233
  } else {
232
234
  const txHash = await client.sendRawTransaction(...args);
233
- logger.verbose(`Sent tx immediately ${txHash}`);
235
+ logger.debug(`Sent tx immediately ${txHash}`);
234
236
  delayer.sentTxHashes.push(txHash);
235
237
  return txHash;
236
238
  }
package/src/types.ts CHANGED
@@ -5,6 +5,7 @@ import type {
5
5
  Client,
6
6
  FallbackTransport,
7
7
  GetContractReturnType,
8
+ Hex,
8
9
  HttpTransport,
9
10
  PublicActions,
10
11
  PublicClient,
@@ -16,6 +17,67 @@ import type {
16
17
  /** Type for a viem public client */
17
18
  export type ViemPublicClient = PublicClient<FallbackTransport<HttpTransport[]>, Chain>;
18
19
 
20
+ export type PublicRpcDebugSchema = [
21
+ {
22
+ Method: 'debug_traceTransaction';
23
+ Parameters: [txHash: `0x${string}`, options: { tracer: 'callTracer' }];
24
+ ReturnType: DebugCallTrace;
25
+ },
26
+ {
27
+ Method: 'trace_transaction';
28
+ Parameters: [txHash: `0x${string}`];
29
+ ReturnType: TraceTransactionResponse[];
30
+ },
31
+ ];
32
+
33
+ /** Return type for a debug_traceTransaction call */
34
+ export type DebugCallTrace = {
35
+ from: Hex;
36
+ to?: Hex;
37
+ type: string;
38
+ input?: Hex;
39
+ output?: Hex;
40
+ gas?: Hex;
41
+ gasUsed?: Hex;
42
+ value?: Hex;
43
+ error?: string;
44
+ calls?: DebugCallTrace[];
45
+ };
46
+
47
+ /** Action object for a trace_transaction call */
48
+ export type TraceAction = {
49
+ from: Hex;
50
+ to?: Hex;
51
+ callType: string;
52
+ gas?: Hex;
53
+ input?: Hex;
54
+ value?: Hex;
55
+ };
56
+
57
+ /** Result object for a trace_transaction call */
58
+ export type TraceResult = {
59
+ gasUsed?: Hex;
60
+ output?: Hex;
61
+ };
62
+
63
+ /** Return type for a single trace in trace_transaction response */
64
+ export type TraceTransactionResponse = {
65
+ action: TraceAction;
66
+ result?: TraceResult;
67
+ error?: string;
68
+ subtraces: number;
69
+ traceAddress: number[];
70
+ type: string;
71
+ };
72
+
73
+ /** Type for a viem public client with support for debug methods */
74
+ export type ViemPublicDebugClient = PublicClient<
75
+ FallbackTransport<HttpTransport[]>,
76
+ Chain,
77
+ undefined,
78
+ [...PublicRpcSchema, ...PublicRpcDebugSchema]
79
+ >;
80
+
19
81
  export type ExtendedViemWalletClient = Client<
20
82
  FallbackTransport<readonly HttpTransport[]>,
21
83
  Chain,