@aztec/ethereum 3.0.0-canary.a9708bd → 3.0.0-devnet.20251212

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 (195) hide show
  1. package/dest/account.d.ts +1 -1
  2. package/dest/chain.d.ts +1 -1
  3. package/dest/client.d.ts +2 -2
  4. package/dest/client.d.ts.map +1 -1
  5. package/dest/config.d.ts +16 -8
  6. package/dest/config.d.ts.map +1 -1
  7. package/dest/config.js +160 -62
  8. package/dest/constants.d.ts +1 -1
  9. package/dest/contracts/empire_base.d.ts +7 -6
  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 +7 -6
  13. package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
  14. package/dest/contracts/empire_slashing_proposer.js +9 -3
  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 +4 -4
  18. package/dest/contracts/fee_asset_handler.d.ts.map +1 -1
  19. package/dest/contracts/fee_juice.d.ts +1 -1
  20. package/dest/contracts/fee_juice.d.ts.map +1 -1
  21. package/dest/contracts/governance.d.ts +16 -16
  22. package/dest/contracts/governance.d.ts.map +1 -1
  23. package/dest/contracts/governance.js +7 -3
  24. package/dest/contracts/governance_proposer.d.ts +6 -6
  25. package/dest/contracts/governance_proposer.d.ts.map +1 -1
  26. package/dest/contracts/governance_proposer.js +9 -4
  27. package/dest/contracts/gse.d.ts +1 -1
  28. package/dest/contracts/gse.d.ts.map +1 -1
  29. package/dest/contracts/inbox.d.ts +1 -1
  30. package/dest/contracts/inbox.d.ts.map +1 -1
  31. package/dest/contracts/index.d.ts +1 -1
  32. package/dest/contracts/multicall.d.ts +5 -7
  33. package/dest/contracts/multicall.d.ts.map +1 -1
  34. package/dest/contracts/multicall.js +6 -4
  35. package/dest/contracts/registry.d.ts +1 -1
  36. package/dest/contracts/registry.d.ts.map +1 -1
  37. package/dest/contracts/rollup.d.ts +83 -72
  38. package/dest/contracts/rollup.d.ts.map +1 -1
  39. package/dest/contracts/rollup.js +144 -139
  40. package/dest/contracts/slasher_contract.d.ts +11 -1
  41. package/dest/contracts/slasher_contract.d.ts.map +1 -1
  42. package/dest/contracts/slasher_contract.js +18 -0
  43. package/dest/contracts/tally_slashing_proposer.d.ts +30 -9
  44. package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
  45. package/dest/contracts/tally_slashing_proposer.js +58 -8
  46. package/dest/contracts/utils.d.ts +1 -1
  47. package/dest/deploy_l1_contracts.d.ts +477 -15
  48. package/dest/deploy_l1_contracts.d.ts.map +1 -1
  49. package/dest/deploy_l1_contracts.js +610 -386
  50. package/dest/eth-signer/eth-signer.d.ts +1 -1
  51. package/dest/eth-signer/index.d.ts +1 -1
  52. package/dest/forwarder_proxy.d.ts +32 -0
  53. package/dest/forwarder_proxy.d.ts.map +1 -0
  54. package/dest/forwarder_proxy.js +93 -0
  55. package/dest/l1_artifacts.d.ts +14258 -6015
  56. package/dest/l1_artifacts.d.ts.map +1 -1
  57. package/dest/l1_artifacts.js +10 -5
  58. package/dest/l1_contract_addresses.d.ts +8 -4
  59. package/dest/l1_contract_addresses.d.ts.map +1 -1
  60. package/dest/l1_contract_addresses.js +16 -26
  61. package/dest/l1_reader.d.ts +4 -2
  62. package/dest/l1_reader.d.ts.map +1 -1
  63. package/dest/l1_reader.js +14 -8
  64. package/dest/l1_tx_utils/config.d.ts +59 -0
  65. package/dest/l1_tx_utils/config.d.ts.map +1 -0
  66. package/dest/l1_tx_utils/config.js +96 -0
  67. package/dest/l1_tx_utils/constants.d.ts +6 -0
  68. package/dest/l1_tx_utils/constants.d.ts.map +1 -0
  69. package/dest/l1_tx_utils/constants.js +14 -0
  70. package/dest/l1_tx_utils/factory.d.ts +24 -0
  71. package/dest/l1_tx_utils/factory.d.ts.map +1 -0
  72. package/dest/l1_tx_utils/factory.js +12 -0
  73. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts +41 -0
  74. package/dest/l1_tx_utils/forwarder_l1_tx_utils.d.ts.map +1 -0
  75. package/dest/l1_tx_utils/forwarder_l1_tx_utils.js +48 -0
  76. package/dest/l1_tx_utils/index-blobs.d.ts +3 -0
  77. package/dest/l1_tx_utils/index-blobs.d.ts.map +1 -0
  78. package/dest/l1_tx_utils/index-blobs.js +2 -0
  79. package/dest/l1_tx_utils/index.d.ts +10 -0
  80. package/dest/l1_tx_utils/index.d.ts.map +1 -0
  81. package/dest/l1_tx_utils/index.js +10 -0
  82. package/dest/l1_tx_utils/interfaces.d.ts +76 -0
  83. package/dest/l1_tx_utils/interfaces.d.ts.map +1 -0
  84. package/dest/l1_tx_utils/interfaces.js +4 -0
  85. package/dest/l1_tx_utils/l1_tx_utils.d.ts +94 -0
  86. package/dest/l1_tx_utils/l1_tx_utils.d.ts.map +1 -0
  87. package/dest/l1_tx_utils/l1_tx_utils.js +623 -0
  88. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts +26 -0
  89. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.d.ts.map +1 -0
  90. package/dest/l1_tx_utils/l1_tx_utils_with_blobs.js +26 -0
  91. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts +94 -0
  92. package/dest/l1_tx_utils/readonly_l1_tx_utils.d.ts.map +1 -0
  93. package/dest/l1_tx_utils/readonly_l1_tx_utils.js +431 -0
  94. package/dest/l1_tx_utils/signer.d.ts +4 -0
  95. package/dest/l1_tx_utils/signer.d.ts.map +1 -0
  96. package/dest/l1_tx_utils/signer.js +16 -0
  97. package/dest/l1_tx_utils/types.d.ts +67 -0
  98. package/dest/l1_tx_utils/types.d.ts.map +1 -0
  99. package/dest/l1_tx_utils/types.js +26 -0
  100. package/dest/l1_tx_utils/utils.d.ts +4 -0
  101. package/dest/l1_tx_utils/utils.d.ts.map +1 -0
  102. package/dest/l1_tx_utils/utils.js +14 -0
  103. package/dest/l1_types.d.ts +1 -1
  104. package/dest/publisher_manager.d.ts +8 -3
  105. package/dest/publisher_manager.d.ts.map +1 -1
  106. package/dest/publisher_manager.js +36 -8
  107. package/dest/queries.d.ts +1 -1
  108. package/dest/queries.d.ts.map +1 -1
  109. package/dest/queries.js +13 -12
  110. package/dest/test/chain_monitor.d.ts +33 -19
  111. package/dest/test/chain_monitor.d.ts.map +1 -1
  112. package/dest/test/chain_monitor.js +100 -33
  113. package/dest/test/delayed_tx_utils.d.ts +3 -3
  114. package/dest/test/delayed_tx_utils.d.ts.map +1 -1
  115. package/dest/test/delayed_tx_utils.js +2 -2
  116. package/dest/test/eth_cheat_codes.d.ts +36 -14
  117. package/dest/test/eth_cheat_codes.d.ts.map +1 -1
  118. package/dest/test/eth_cheat_codes.js +124 -31
  119. package/dest/test/eth_cheat_codes_with_state.d.ts +1 -1
  120. package/dest/test/eth_cheat_codes_with_state.d.ts.map +1 -1
  121. package/dest/test/index.d.ts +1 -1
  122. package/dest/test/rollup_cheat_codes.d.ts +23 -20
  123. package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
  124. package/dest/test/rollup_cheat_codes.js +79 -42
  125. package/dest/test/start_anvil.d.ts +2 -1
  126. package/dest/test/start_anvil.d.ts.map +1 -1
  127. package/dest/test/start_anvil.js +2 -1
  128. package/dest/test/tx_delayer.d.ts +1 -1
  129. package/dest/test/tx_delayer.d.ts.map +1 -1
  130. package/dest/test/tx_delayer.js +3 -2
  131. package/dest/test/upgrade_utils.d.ts +1 -1
  132. package/dest/test/upgrade_utils.d.ts.map +1 -1
  133. package/dest/test/upgrade_utils.js +3 -2
  134. package/dest/types.d.ts +57 -2
  135. package/dest/types.d.ts.map +1 -1
  136. package/dest/utils.d.ts +2 -2
  137. package/dest/utils.d.ts.map +1 -1
  138. package/dest/utils.js +10 -161
  139. package/dest/zkPassportVerifierAddress.d.ts +1 -1
  140. package/dest/zkPassportVerifierAddress.js +1 -1
  141. package/package.json +27 -13
  142. package/src/client.ts +1 -1
  143. package/src/config.ts +177 -65
  144. package/src/contracts/empire_base.ts +7 -6
  145. package/src/contracts/empire_slashing_proposer.ts +18 -8
  146. package/src/contracts/fee_asset_handler.ts +1 -1
  147. package/src/contracts/governance.ts +3 -3
  148. package/src/contracts/governance_proposer.ts +14 -9
  149. package/src/contracts/multicall.ts +12 -10
  150. package/src/contracts/rollup.ts +170 -171
  151. package/src/contracts/slasher_contract.ts +22 -0
  152. package/src/contracts/tally_slashing_proposer.ts +63 -12
  153. package/src/deploy_l1_contracts.ts +610 -337
  154. package/src/forwarder_proxy.ts +108 -0
  155. package/src/l1_artifacts.ts +14 -6
  156. package/src/l1_contract_addresses.ts +17 -26
  157. package/src/l1_reader.ts +17 -9
  158. package/src/l1_tx_utils/README.md +177 -0
  159. package/src/l1_tx_utils/config.ts +161 -0
  160. package/src/l1_tx_utils/constants.ts +18 -0
  161. package/src/l1_tx_utils/factory.ts +64 -0
  162. package/src/l1_tx_utils/forwarder_l1_tx_utils.ts +119 -0
  163. package/src/l1_tx_utils/index-blobs.ts +2 -0
  164. package/src/l1_tx_utils/index.ts +12 -0
  165. package/src/l1_tx_utils/interfaces.ts +86 -0
  166. package/src/l1_tx_utils/l1_tx_utils.ts +738 -0
  167. package/src/l1_tx_utils/l1_tx_utils_with_blobs.ts +77 -0
  168. package/src/l1_tx_utils/readonly_l1_tx_utils.ts +557 -0
  169. package/src/l1_tx_utils/signer.ts +28 -0
  170. package/src/l1_tx_utils/types.ts +85 -0
  171. package/src/l1_tx_utils/utils.ts +16 -0
  172. package/src/publisher_manager.ts +51 -9
  173. package/src/queries.ts +16 -8
  174. package/src/test/chain_monitor.ts +118 -36
  175. package/src/test/delayed_tx_utils.ts +2 -2
  176. package/src/test/eth_cheat_codes.ts +149 -30
  177. package/src/test/rollup_cheat_codes.ts +94 -52
  178. package/src/test/start_anvil.ts +2 -0
  179. package/src/test/tx_delayer.ts +4 -2
  180. package/src/test/upgrade_utils.ts +3 -2
  181. package/src/types.ts +62 -0
  182. package/src/utils.ts +12 -184
  183. package/src/zkPassportVerifierAddress.ts +1 -1
  184. package/dest/index.d.ts +0 -18
  185. package/dest/index.d.ts.map +0 -1
  186. package/dest/index.js +0 -17
  187. package/dest/l1_tx_utils.d.ts +0 -250
  188. package/dest/l1_tx_utils.d.ts.map +0 -1
  189. package/dest/l1_tx_utils.js +0 -826
  190. package/dest/l1_tx_utils_with_blobs.d.ts +0 -19
  191. package/dest/l1_tx_utils_with_blobs.d.ts.map +0 -1
  192. package/dest/l1_tx_utils_with_blobs.js +0 -85
  193. package/src/index.ts +0 -17
  194. package/src/l1_tx_utils.ts +0 -1105
  195. package/src/l1_tx_utils_with_blobs.ts +0 -144
@@ -0,0 +1,85 @@
1
+ import type { BlobKzgInstance } from '@aztec/blob-lib/types';
2
+ import { EthAddress } from '@aztec/foundation/eth-address';
3
+ import type { ViemTransactionSignature } from '@aztec/foundation/eth-signature';
4
+
5
+ import type { Abi, Address, Hex, TransactionReceipt, TransactionSerializable } from 'viem';
6
+
7
+ import type { L1TxUtilsConfig } from './config.js';
8
+
9
+ export interface L1TxRequest {
10
+ to: Address | null;
11
+ data?: Hex;
12
+ value?: bigint;
13
+ abi?: Abi;
14
+ }
15
+
16
+ export type L1TxConfig = Partial<L1TxUtilsConfig> & { gasLimit?: bigint; txTimeoutAt?: Date };
17
+
18
+ export interface L1BlobInputs {
19
+ blobs: Uint8Array[];
20
+ kzg: BlobKzgInstance;
21
+ maxFeePerBlobGas?: bigint;
22
+ }
23
+
24
+ export interface GasPrice {
25
+ maxFeePerGas: bigint;
26
+ maxPriorityFeePerGas: bigint;
27
+ maxFeePerBlobGas?: bigint;
28
+ }
29
+
30
+ export type TransactionStats = {
31
+ /** Address of the sender. */
32
+ sender: string;
33
+ /** Hash of the transaction. */
34
+ transactionHash: string;
35
+ /** Size in bytes of the tx calldata */
36
+ calldataSize: number;
37
+ /** Gas required to pay for the calldata inclusion (depends on size and number of zeros) */
38
+ calldataGas: number;
39
+ };
40
+
41
+ export enum TxUtilsState {
42
+ IDLE,
43
+ SENT,
44
+ SPEED_UP,
45
+ CANCELLED,
46
+ NOT_MINED,
47
+ MINED,
48
+ }
49
+
50
+ export const TerminalTxUtilsState = [TxUtilsState.IDLE, TxUtilsState.MINED, TxUtilsState.NOT_MINED];
51
+
52
+ export type L1TxState = {
53
+ id: number;
54
+ txHashes: Hex[];
55
+ cancelTxHashes: Hex[];
56
+ gasLimit: bigint;
57
+ gasPrice: GasPrice;
58
+ txConfigOverrides: L1TxConfig;
59
+ request: L1TxRequest;
60
+ status: TxUtilsState;
61
+ nonce: number;
62
+ sentAtL1Ts: Date;
63
+ lastSentAtL1Ts: Date;
64
+ receipt?: TransactionReceipt;
65
+ blobInputs: L1BlobInputs | undefined;
66
+ };
67
+
68
+ export type SigningCallback = (
69
+ transaction: TransactionSerializable,
70
+ signingAddress: EthAddress,
71
+ ) => Promise<ViemTransactionSignature>;
72
+
73
+ export class UnknownMinedTxError extends Error {
74
+ constructor(nonce: number, account: string) {
75
+ super(`Nonce ${nonce} from account ${account} is MINED but not by one of our expected transactions`);
76
+ this.name = 'UnknownMinedTxError';
77
+ }
78
+ }
79
+
80
+ export class DroppedTransactionError extends Error {
81
+ constructor(nonce: number, account: string) {
82
+ super(`Transaction with nonce ${nonce} from account ${account} was dropped from the mempool`);
83
+ this.name = 'DroppedTransactionError';
84
+ }
85
+ }
@@ -0,0 +1,16 @@
1
+ import { compactArray } from '@aztec/foundation/collection';
2
+
3
+ import type { ContractFunctionExecutionError } from 'viem';
4
+
5
+ export function tryGetCustomErrorNameContractFunction(err: ContractFunctionExecutionError) {
6
+ return compactArray([err.shortMessage, ...(err.metaMessages ?? []).slice(0, 2).map(s => s.trim())]).join(' ');
7
+ }
8
+
9
+ /*
10
+ * Returns cost of calldata usage in Ethereum.
11
+ * @param data - Calldata.
12
+ * @returns 4 for each zero byte, 16 for each nonzero.
13
+ */
14
+ export function getCalldataGasUsage(data: Uint8Array) {
15
+ return data.filter(byte => byte === 0).length * 4 + data.filter(byte => byte !== 0).length * 16;
16
+ }
@@ -1,31 +1,73 @@
1
+ import { pick } from '@aztec/foundation/collection';
1
2
  import { createLogger } from '@aztec/foundation/log';
2
3
 
3
- import { L1TxUtils, TxUtilsState } from './l1_tx_utils.js';
4
+ import { L1TxUtils, TxUtilsState } from './l1_tx_utils/index.js';
4
5
 
5
- const sortOrder = [TxUtilsState.IDLE, TxUtilsState.MINED];
6
- const invalidStates = [TxUtilsState.SENT, TxUtilsState.SPEED_UP, TxUtilsState.CANCELLED, TxUtilsState.NOT_MINED]; // Cancelled and not mined are states that can be handled by a later iteration
6
+ // Defines the order in which we prioritise publishers based on their state (first is better)
7
+ const sortOrder = [
8
+ // Always prefer sending from idle publishers
9
+ TxUtilsState.IDLE,
10
+ // Then from publishers that have sent a tx and it got mined
11
+ TxUtilsState.MINED,
12
+ // Then from publishers that have sent a tx but it's in-flight
13
+ TxUtilsState.SPEED_UP,
14
+ TxUtilsState.SENT,
15
+ // We leave cancelled and not-mined states for last, since these represent failures to mines and could be problematic
16
+ TxUtilsState.CANCELLED,
17
+ TxUtilsState.NOT_MINED,
18
+ ];
19
+
20
+ // Which states represent a busy publisher that we should avoid if possible
21
+ const busyStates: TxUtilsState[] = [
22
+ TxUtilsState.SENT,
23
+ TxUtilsState.SPEED_UP,
24
+ TxUtilsState.CANCELLED,
25
+ TxUtilsState.NOT_MINED,
26
+ ];
7
27
 
8
28
  export type PublisherFilter<UtilsType extends L1TxUtils> = (utils: UtilsType) => boolean;
9
29
 
10
30
  export class PublisherManager<UtilsType extends L1TxUtils = L1TxUtils> {
11
- private log = createLogger('PublisherManager');
31
+ private log = createLogger('publisher:manager');
32
+ private config: { publisherAllowInvalidStates?: boolean };
12
33
 
13
- constructor(private publishers: UtilsType[]) {
34
+ constructor(
35
+ private publishers: UtilsType[],
36
+ config: { publisherAllowInvalidStates?: boolean },
37
+ ) {
14
38
  this.log.info(`PublisherManager initialized with ${publishers.length} publishers.`);
15
39
  this.publishers = publishers;
40
+ this.config = pick(config, 'publisherAllowInvalidStates');
41
+ }
42
+
43
+ /** Loads the state of all publishers and resumes monitoring any pending txs */
44
+ public async loadState(): Promise<void> {
45
+ await Promise.all(this.publishers.map(pub => pub.loadStateAndResumeMonitoring()));
16
46
  }
17
47
 
18
48
  // Finds and prioritises available publishers based on
19
49
  // 1. Validity as per the provided filter function
20
50
  // 2. Validity based on the state the publisher is in
21
- // 3. Priority based on state as defined bu sortOrder
51
+ // 3. Priority based on state as defined by sortOrder
22
52
  // 4. Then priority based on highest balance
23
53
  // 5. Then priority based on least recently used
24
54
  public async getAvailablePublisher(filter: PublisherFilter<UtilsType> = () => true): Promise<UtilsType> {
55
+ this.log.debug(`Getting available publisher`, {
56
+ publishers: this.publishers.map(p => ({
57
+ address: p.getSenderAddress(),
58
+ state: p.state,
59
+ lastMined: p.lastMinedAtBlockNumber,
60
+ })),
61
+ });
62
+
25
63
  // Extract the valid publishers
26
- const validPublishers = this.publishers.filter(
27
- (pub: UtilsType) => !invalidStates.includes(pub.state) && filter(pub),
28
- );
64
+ let validPublishers = this.publishers.filter((pub: UtilsType) => !busyStates.includes(pub.state) && filter(pub));
65
+
66
+ // If none found but we allow invalid (busy) states, try again including them
67
+ if (validPublishers.length === 0 && this.config.publisherAllowInvalidStates) {
68
+ this.log.warn(`No valid publishers found. Trying again including invalid states.`);
69
+ validPublishers = this.publishers.filter(pub => filter(pub));
70
+ }
29
71
 
30
72
  // Error if none found
31
73
  if (validPublishers.length === 0) {
package/src/queries.ts CHANGED
@@ -1,7 +1,4 @@
1
1
  import { EthAddress } from '@aztec/foundation/eth-address';
2
- import { SlasherAbi } from '@aztec/l1-artifacts/SlasherAbi';
3
-
4
- import { getContract } from 'viem';
5
2
 
6
3
  import type { L1ContractsConfig } from './config.js';
7
4
  import { ReadOnlyGovernanceContract } from './contracts/governance.js';
@@ -27,8 +24,7 @@ export async function getL1ContractsConfig(
27
24
  const rollupAddress = addresses.rollupAddress ?? (await governanceProposer.getRollupAddress());
28
25
  const rollup = new RollupContract(publicClient, rollupAddress.toString());
29
26
  const slasherProposer = await rollup.getSlashingProposer();
30
- const slasherAddress = await rollup.getSlasher();
31
- const slasher = getContract({ address: slasherAddress, abi: SlasherAbi, client: publicClient });
27
+ const slasher = await rollup.getSlasherContract();
32
28
 
33
29
  const [
34
30
  l1StartBlock,
@@ -37,8 +33,11 @@ export async function getL1ContractsConfig(
37
33
  aztecSlotDuration,
38
34
  aztecProofSubmissionEpochs,
39
35
  aztecTargetCommitteeSize,
36
+ lagInEpochsForValidatorSet,
37
+ lagInEpochsForRandao,
40
38
  activationThreshold,
41
39
  ejectionThreshold,
40
+ localEjectionThreshold,
42
41
  governanceProposerQuorum,
43
42
  governanceProposerRoundSize,
44
43
  slashingQuorum,
@@ -48,6 +47,7 @@ export async function getL1ContractsConfig(
48
47
  slashingOffsetInRounds,
49
48
  slashingAmounts,
50
49
  slashingVetoer,
50
+ slashingDisableDuration,
51
51
  manaTarget,
52
52
  provingCostPerMana,
53
53
  rollupVersion,
@@ -60,8 +60,11 @@ export async function getL1ContractsConfig(
60
60
  rollup.getSlotDuration(),
61
61
  rollup.getProofSubmissionEpochs(),
62
62
  rollup.getTargetCommitteeSize(),
63
+ rollup.getLagInEpochsForValidatorSet(),
64
+ rollup.getLagInEpochsForRandao(),
63
65
  rollup.getActivationThreshold(),
64
66
  rollup.getEjectionThreshold(),
67
+ rollup.getLocalEjectionThreshold(),
65
68
  governanceProposer.getQuorumSize(),
66
69
  governanceProposer.getRoundSize(),
67
70
  slasherProposer?.getQuorumSize() ?? 0n,
@@ -70,7 +73,8 @@ export async function getL1ContractsConfig(
70
73
  slasherProposer?.getExecutionDelayInRounds() ?? 0n,
71
74
  slasherProposer?.type === 'tally' ? slasherProposer.getSlashOffsetInRounds() : 0n,
72
75
  slasherProposer?.type === 'tally' ? slasherProposer.getSlashingAmounts() : [0n, 0n, 0n],
73
- slasher.read.VETOER(),
76
+ slasher?.getVetoer() ?? EthAddress.ZERO,
77
+ slasher?.getSlashingDisableDuration() ?? 0,
74
78
  rollup.getManaTarget(),
75
79
  rollup.getProvingCostPerMana(),
76
80
  rollup.getVersion(),
@@ -85,16 +89,20 @@ export async function getL1ContractsConfig(
85
89
  aztecSlotDuration: Number(aztecSlotDuration),
86
90
  aztecProofSubmissionEpochs: Number(aztecProofSubmissionEpochs),
87
91
  aztecTargetCommitteeSize: Number(aztecTargetCommitteeSize),
92
+ lagInEpochsForValidatorSet: Number(lagInEpochsForValidatorSet),
93
+ lagInEpochsForRandao: Number(lagInEpochsForRandao),
88
94
  governanceProposerQuorum: Number(governanceProposerQuorum),
89
95
  governanceProposerRoundSize: Number(governanceProposerRoundSize),
90
96
  activationThreshold,
91
97
  ejectionThreshold,
98
+ localEjectionThreshold,
92
99
  slashingQuorum: Number(slashingQuorum),
93
100
  slashingRoundSizeInEpochs: Number(slashingRoundSize / aztecEpochDuration),
94
101
  slashingLifetimeInRounds: Number(slashingLifetimeInRounds),
95
102
  slashingExecutionDelayInRounds: Number(slashingExecutionDelayInRounds),
96
- slashingVetoer: EthAddress.fromString(slashingVetoer),
97
- manaTarget: manaTarget,
103
+ slashingVetoer,
104
+ slashingDisableDuration,
105
+ manaTarget,
98
106
  provingCostPerMana: provingCostPerMana,
99
107
  rollupVersion: Number(rollupVersion),
100
108
  genesisArchiveTreeRoot,
@@ -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,10 +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; 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 }];
20
+ 'l2-epoch': [{ l2EpochNumber: EpochNumber; timestamp: bigint; committee: EthAddress[] | undefined }];
21
+ 'l2-slot': [{ l2SlotNumber: SlotNumber; timestamp: bigint }];
17
22
  };
18
23
 
19
24
  /** Utility class that polls the chain on quick intervals and logs new L1 blocks, L2 blocks, and L2 proofs. */
@@ -26,18 +31,20 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
26
31
 
27
32
  /** Current L1 block number */
28
33
  public l1BlockNumber!: number;
29
- /** Current L2 block number */
30
- public l2BlockNumber!: number;
31
- /** Current L2 proven block number */
32
- public l2ProvenBlockNumber!: number;
33
- /** L1 timestamp for the current L2 block */
34
- public l2BlockTimestamp!: bigint;
35
- /** L1 timestamp for the proven L2 block */
36
- 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;
37
42
  /** Total number of L2 messages pushed into the Inbox */
38
43
  public totalL2Messages: number = 0;
39
44
  /** Current L2 epoch number */
40
- public l2EpochNumber!: bigint;
45
+ public l2EpochNumber!: EpochNumber;
46
+ /** Current L2 slot number */
47
+ public l2SlotNumber!: SlotNumber;
41
48
 
42
49
  constructor(
43
50
  private readonly rollup: RollupContract,
@@ -99,30 +106,40 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
99
106
  }
100
107
  this.l1BlockNumber = newL1BlockNumber;
101
108
 
102
- const block = await this.l1Client.getBlock({ blockNumber: BigInt(newL1BlockNumber), includeTransactions: false });
103
- const timestamp = block.timestamp;
109
+ const [l2SlotNumber, l2Epoch, l1block] = await Promise.all([
110
+ this.rollup.getSlotNumber(),
111
+ this.rollup.getCurrentEpoch(),
112
+ this.l1Client.getBlock({ blockNumber: BigInt(newL1BlockNumber), includeTransactions: false }),
113
+ ]);
114
+
115
+ const timestamp = l1block.timestamp;
104
116
  const timestampString = new Date(Number(timestamp) * 1000).toTimeString().split(' ')[0];
105
117
 
106
118
  this.emit('l1-block', { l1BlockNumber: newL1BlockNumber, timestamp });
107
119
  let msg = `L1 block ${newL1BlockNumber} mined at ${timestampString}`;
108
120
 
109
- const newL2BlockNumber = Number(await this.rollup.getBlockNumber());
110
- if (this.l2BlockNumber !== newL2BlockNumber) {
111
- const epochNumber = await this.rollup.getEpochNumber(BigInt(newL2BlockNumber));
112
- msg += ` with new L2 block ${newL2BlockNumber} for epoch ${epochNumber}`;
113
- this.l2BlockNumber = newL2BlockNumber;
114
- this.l2BlockTimestamp = timestamp;
115
- this.emit('l2-block', { l2BlockNumber: newL2BlockNumber, l1BlockNumber: newL1BlockNumber, timestamp });
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,
129
+ l1BlockNumber: newL1BlockNumber,
130
+ l2SlotNumber,
131
+ timestamp,
132
+ });
116
133
  }
117
134
 
118
- const newL2ProvenBlockNumber = Number(await this.rollup.getProvenBlockNumber());
119
- if (this.l2ProvenBlockNumber !== newL2ProvenBlockNumber) {
120
- const epochNumber = await this.rollup.getEpochNumber(BigInt(newL2ProvenBlockNumber));
121
- msg += ` with proof up to L2 block ${newL2ProvenBlockNumber} for epoch ${epochNumber}`;
122
- this.l2ProvenBlockNumber = newL2ProvenBlockNumber;
123
- this.l2ProvenBlockTimestamp = timestamp;
124
- this.emit('l2-block-proven', {
125
- 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,
126
143
  l1BlockNumber: newL1BlockNumber,
127
144
  timestamp,
128
145
  });
@@ -136,14 +153,17 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
136
153
  this.emit('l2-messages', { totalL2Messages: newTotalL2Messages, l1BlockNumber: newL1BlockNumber });
137
154
  }
138
155
 
139
- const [l2SlotNumber, l2Epoch] = await Promise.all([this.rollup.getSlotNumber(), this.rollup.getCurrentEpoch()]);
140
-
141
156
  let committee: EthAddress[] | undefined;
142
157
  if (l2Epoch !== this.l2EpochNumber) {
143
158
  this.l2EpochNumber = l2Epoch;
144
159
  committee = (await this.rollup.getCurrentEpochCommittee())?.map(addr => EthAddress.fromString(addr));
145
- this.emit('l2-epoch', { l2EpochNumber: Number(l2Epoch), timestamp, committee });
146
- msg += ` starting new epoch ${this.l2EpochNumber} with committee ${committee?.join(', ') ?? 'undefined'}`;
160
+ this.emit('l2-epoch', { l2EpochNumber: l2Epoch, timestamp, committee });
161
+ msg += ` starting new epoch ${this.l2EpochNumber} `;
162
+ }
163
+
164
+ if (l2SlotNumber !== this.l2SlotNumber) {
165
+ this.l2SlotNumber = l2SlotNumber;
166
+ this.emit('l2-slot', { l2SlotNumber, timestamp });
147
167
  }
148
168
 
149
169
  this.logger.info(msg, {
@@ -152,12 +172,74 @@ export class ChainMonitor extends EventEmitter<ChainMonitorEventMap> {
152
172
  l1BlockNumber: this.l1BlockNumber,
153
173
  l2SlotNumber,
154
174
  l2Epoch,
155
- l2BlockNumber: this.l2BlockNumber,
156
- l2ProvenBlockNumber: this.l2ProvenBlockNumber,
175
+ checkpointNumber: this.checkpointNumber,
176
+ provenCheckpointNumber: this.provenCheckpointNumber,
157
177
  totalL2Messages: this.totalL2Messages,
158
178
  committee,
159
179
  });
160
180
 
161
181
  return this;
162
182
  }
183
+
184
+ public waitUntilL2Slot(slot: SlotNumber): Promise<void> {
185
+ if (this.l2SlotNumber >= slot) {
186
+ return Promise.resolve();
187
+ }
188
+ return new Promise(resolve => {
189
+ const listener = (data: { l2SlotNumber: SlotNumber; timestamp: bigint }) => {
190
+ if (data.l2SlotNumber >= slot) {
191
+ this.off('l2-slot', listener);
192
+ resolve();
193
+ }
194
+ };
195
+ this.on('l2-slot', listener);
196
+ });
197
+ }
198
+
199
+ public waitUntilL1Block(block: number | bigint): Promise<void> {
200
+ const targetBlock = typeof block === 'bigint' ? block.valueOf() : block;
201
+ if (this.l1BlockNumber >= targetBlock) {
202
+ return Promise.resolve();
203
+ }
204
+ return new Promise(resolve => {
205
+ const listener = (data: { l1BlockNumber: number; timestamp: bigint }) => {
206
+ if (data.l1BlockNumber >= targetBlock) {
207
+ this.off('l1-block', listener);
208
+ resolve();
209
+ }
210
+ };
211
+ this.on('l1-block', listener);
212
+ });
213
+ }
214
+
215
+ public waitUntilL1Timestamp(timestamp: number | bigint): Promise<void> {
216
+ const targetTimestamp = typeof timestamp === 'bigint' ? timestamp.valueOf() : timestamp;
217
+ if (this.l1BlockNumber >= targetTimestamp) {
218
+ return Promise.resolve();
219
+ }
220
+ return new Promise(resolve => {
221
+ const listener = (data: { l1BlockNumber: number; timestamp: bigint }) => {
222
+ if (data.timestamp >= targetTimestamp) {
223
+ this.off('l1-block', listener);
224
+ resolve();
225
+ }
226
+ };
227
+ this.on('l1-block', listener);
228
+ });
229
+ }
230
+
231
+ public waitUntilCheckpoint(checkpointNumber: CheckpointNumber): Promise<void> {
232
+ if (this.checkpointNumber >= checkpointNumber) {
233
+ return Promise.resolve();
234
+ }
235
+ return new Promise(resolve => {
236
+ const listener = (data: { checkpointNumber: CheckpointNumber; timestamp: bigint }) => {
237
+ if (data.checkpointNumber >= checkpointNumber) {
238
+ this.off('checkpoint', listener);
239
+ resolve();
240
+ }
241
+ };
242
+ this.on('checkpoint', listener);
243
+ });
244
+ }
163
245
  }
@@ -2,8 +2,8 @@ import { EthAddress } from '@aztec/foundation/eth-address';
2
2
  import { type Logger, createLogger } from '@aztec/foundation/log';
3
3
  import { DateProvider } from '@aztec/foundation/timer';
4
4
 
5
- import { type L1TxUtilsConfig, createViemSigner } from '../l1_tx_utils.js';
6
- import { L1TxUtilsWithBlobs } from '../l1_tx_utils_with_blobs.js';
5
+ import { type L1TxUtilsConfig, createViemSigner } from '../l1_tx_utils/index.js';
6
+ import { L1TxUtilsWithBlobs } from '../l1_tx_utils/l1_tx_utils_with_blobs.js';
7
7
  import type { ExtendedViemWalletClient } from '../types.js';
8
8
  import { type Delayer, withDelayer } from './tx_delayer.js';
9
9