@aztec/ethereum 3.0.0-nightly.20250910 → 3.0.0-nightly.20250912

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 (37) hide show
  1. package/dest/config.d.ts +6 -4
  2. package/dest/config.d.ts.map +1 -1
  3. package/dest/config.js +12 -30
  4. package/dest/contracts/empire_slashing_proposer.d.ts +1 -1
  5. package/dest/contracts/empire_slashing_proposer.d.ts.map +1 -1
  6. package/dest/contracts/empire_slashing_proposer.js +1 -1
  7. package/dest/contracts/rollup.d.ts +13 -6
  8. package/dest/contracts/rollup.d.ts.map +1 -1
  9. package/dest/contracts/rollup.js +49 -23
  10. package/dest/deploy_l1_contracts.d.ts +4 -4
  11. package/dest/deploy_l1_contracts.d.ts.map +1 -1
  12. package/dest/deploy_l1_contracts.js +51 -25
  13. package/dest/l1_artifacts.d.ts +689 -62
  14. package/dest/l1_artifacts.d.ts.map +1 -1
  15. package/dest/l1_tx_utils.d.ts +4 -2
  16. package/dest/l1_tx_utils.d.ts.map +1 -1
  17. package/dest/l1_tx_utils.js +21 -13
  18. package/dest/l1_tx_utils_with_blobs.d.ts +2 -1
  19. package/dest/l1_tx_utils_with_blobs.d.ts.map +1 -1
  20. package/dest/l1_tx_utils_with_blobs.js +7 -5
  21. package/dest/queries.d.ts.map +1 -1
  22. package/dest/queries.js +8 -11
  23. package/dest/test/chain_monitor.d.ts +4 -0
  24. package/dest/test/chain_monitor.d.ts.map +1 -1
  25. package/dest/test/chain_monitor.js +57 -11
  26. package/dest/utils.d.ts.map +1 -1
  27. package/dest/utils.js +10 -161
  28. package/package.json +5 -5
  29. package/src/config.ts +17 -35
  30. package/src/contracts/empire_slashing_proposer.ts +6 -2
  31. package/src/contracts/rollup.ts +58 -22
  32. package/src/deploy_l1_contracts.ts +65 -22
  33. package/src/l1_tx_utils.ts +28 -9
  34. package/src/l1_tx_utils_with_blobs.ts +8 -2
  35. package/src/queries.ts +9 -7
  36. package/src/test/chain_monitor.ts +64 -8
  37. package/src/utils.ts +13 -185
@@ -3,7 +3,6 @@ import { EthAddress } from '@aztec/foundation/eth-address';
3
3
  import type { ViemSignature } from '@aztec/foundation/eth-signature';
4
4
  import { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
5
5
  import { RollupStorage } from '@aztec/l1-artifacts/RollupStorage';
6
- import { SlasherAbi } from '@aztec/l1-artifacts/SlasherAbi';
7
6
 
8
7
  import chunk from 'lodash.chunk';
9
8
  import {
@@ -11,8 +10,8 @@ import {
11
10
  type GetContractReturnType,
12
11
  type Hex,
13
12
  type StateOverride,
13
+ type WatchContractEventReturnType,
14
14
  encodeFunctionData,
15
- getAddress,
16
15
  getContract,
17
16
  hexToBigInt,
18
17
  keccak256,
@@ -160,13 +159,12 @@ export class RollupContract {
160
159
  public async getSlashingProposer(): Promise<
161
160
  EmpireSlashingProposerContract | TallySlashingProposerContract | undefined
162
161
  > {
163
- const slasherAddress = await this.rollup.read.getSlasher();
164
- if (EthAddress.fromString(slasherAddress).isZero()) {
162
+ const slasher = await this.getSlasherContract();
163
+ if (!slasher) {
165
164
  return undefined;
166
165
  }
167
166
 
168
- const slasher = getContract({ address: slasherAddress, abi: SlasherAbi, client: this.client });
169
- const proposerAddress = await slasher.read.PROPOSER();
167
+ const proposerAddress = await slasher.getProposer();
170
168
  const proposerAbi = [
171
169
  {
172
170
  type: 'function',
@@ -177,7 +175,7 @@ export class RollupContract {
177
175
  },
178
176
  ] as const;
179
177
 
180
- const proposer = getContract({ address: proposerAddress, abi: proposerAbi, client: this.client });
178
+ const proposer = getContract({ address: proposerAddress.toString(), abi: proposerAbi, client: this.client });
181
179
  const proposerType = await proposer.read.SLASHING_PROPOSER_TYPE();
182
180
  if (proposerType === SlashingProposerType.Tally.valueOf()) {
183
181
  return new TallySlashingProposerContract(this.client, proposerAddress);
@@ -223,6 +221,16 @@ export class RollupContract {
223
221
  return this.rollup.read.getEjectionThreshold();
224
222
  }
225
223
 
224
+ @memoize
225
+ getLocalEjectionThreshold() {
226
+ return this.rollup.read.getLocalEjectionThreshold();
227
+ }
228
+
229
+ @memoize
230
+ getLagInEpochs() {
231
+ return this.rollup.read.getLagInEpochs();
232
+ }
233
+
226
234
  @memoize
227
235
  getActivationThreshold() {
228
236
  return this.rollup.read.getActivationThreshold();
@@ -293,16 +301,19 @@ export class RollupContract {
293
301
  };
294
302
  }
295
303
 
296
- getSlasher() {
304
+ getSlasherAddress() {
297
305
  return this.rollup.read.getSlasher();
298
306
  }
299
307
 
300
308
  /**
301
309
  * Returns a SlasherContract instance for interacting with the slasher contract.
302
310
  */
303
- async getSlasherContract(): Promise<SlasherContract> {
304
- const slasherAddress = await this.getSlasher();
305
- return new SlasherContract(this.client, EthAddress.fromString(slasherAddress));
311
+ async getSlasherContract(): Promise<SlasherContract | undefined> {
312
+ const slasherAddress = EthAddress.fromString(await this.getSlasherAddress());
313
+ if (slasherAddress.isZero()) {
314
+ return undefined;
315
+ }
316
+ return new SlasherContract(this.client, slasherAddress);
306
317
  }
307
318
 
308
319
  getOwner() {
@@ -314,13 +325,11 @@ export class RollupContract {
314
325
  }
315
326
 
316
327
  public async getSlashingProposerAddress() {
317
- const slasherAddress = await this.getSlasher();
318
- const slasher = getContract({
319
- address: getAddress(slasherAddress.toString()),
320
- abi: SlasherAbi,
321
- client: this.client,
322
- });
323
- return EthAddress.fromString(await slasher.read.PROPOSER());
328
+ const slasher = await this.getSlasherContract();
329
+ if (!slasher) {
330
+ return EthAddress.ZERO;
331
+ }
332
+ return await slasher.getProposer();
324
333
  }
325
334
 
326
335
  getBlockReward() {
@@ -433,8 +442,15 @@ export class RollupContract {
433
442
  return this.rollup.read.getEntryQueueLength();
434
443
  }
435
444
 
436
- async getEpochNumber(blockNumber?: bigint) {
437
- blockNumber ??= await this.getBlockNumber();
445
+ getNextFlushableEpoch() {
446
+ return this.rollup.read.getNextFlushableEpoch();
447
+ }
448
+
449
+ getCurrentEpochNumber(): Promise<bigint> {
450
+ return this.rollup.read.getCurrentEpoch();
451
+ }
452
+
453
+ getEpochNumberForBlock(blockNumber: bigint) {
438
454
  return this.rollup.read.getEpochForBlock([BigInt(blockNumber)]);
439
455
  }
440
456
 
@@ -719,7 +735,9 @@ export class RollupContract {
719
735
  });
720
736
  }
721
737
 
722
- public listenToSlasherChanged(callback: (args: { oldSlasher: `0x${string}`; newSlasher: `0x${string}` }) => unknown) {
738
+ public listenToSlasherChanged(
739
+ callback: (args: { oldSlasher: `0x${string}`; newSlasher: `0x${string}` }) => unknown,
740
+ ): WatchContractEventReturnType {
723
741
  return this.rollup.watchEvent.SlasherUpdated(
724
742
  {},
725
743
  {
@@ -735,6 +753,22 @@ export class RollupContract {
735
753
  );
736
754
  }
737
755
 
756
+ public listenToBlockInvalidated(callback: (args: { blockNumber: bigint }) => unknown): WatchContractEventReturnType {
757
+ return this.rollup.watchEvent.BlockInvalidated(
758
+ {},
759
+ {
760
+ onLogs: logs => {
761
+ for (const log of logs) {
762
+ const args = log.args;
763
+ if (args.blockNumber !== undefined) {
764
+ callback({ blockNumber: args.blockNumber });
765
+ }
766
+ }
767
+ },
768
+ },
769
+ );
770
+ }
771
+
738
772
  public async getSlashEvents(l1BlockHash: Hex): Promise<{ amount: bigint; attester: EthAddress }[]> {
739
773
  const events = await this.rollup.getEvents.Slashed({}, { blockHash: l1BlockHash, strict: true });
740
774
  return events.map(event => ({
@@ -743,7 +777,9 @@ export class RollupContract {
743
777
  }));
744
778
  }
745
779
 
746
- public listenToSlash(callback: (args: { amount: bigint; attester: EthAddress }) => unknown) {
780
+ public listenToSlash(
781
+ callback: (args: { amount: bigint; attester: EthAddress }) => unknown,
782
+ ): WatchContractEventReturnType {
747
783
  return this.rollup.watchEvent.Slashed(
748
784
  {},
749
785
  {
@@ -5,6 +5,7 @@ import { EthAddress } from '@aztec/foundation/eth-address';
5
5
  import type { Fr } from '@aztec/foundation/fields';
6
6
  import { jsonStringify } from '@aztec/foundation/json-rpc';
7
7
  import { type Logger, createLogger } from '@aztec/foundation/log';
8
+ import { retryUntil } from '@aztec/foundation/retry';
8
9
  import { DateProvider } from '@aztec/foundation/timer';
9
10
  import type { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
10
11
 
@@ -33,7 +34,6 @@ import { createExtendedL1Client } from './client.js';
33
34
  import {
34
35
  type L1ContractsConfig,
35
36
  getEntryQueueConfig,
36
- getGSEConfiguration,
37
37
  getGovernanceConfiguration,
38
38
  getRewardBoostConfig,
39
39
  getRewardConfig,
@@ -193,13 +193,11 @@ export const deploySharedContracts = async (
193
193
  const stakingAssetAddress = await deployer.deploy(StakingAssetArtifact, ['Staking', 'STK', l1Client.account.address]);
194
194
  logger.verbose(`Deployed Staking Asset at ${stakingAssetAddress}`);
195
195
 
196
- const gseConfiguration = getGSEConfiguration(networkName);
197
-
198
196
  const gseAddress = await deployer.deploy(GSEArtifact, [
199
197
  l1Client.account.address,
200
198
  stakingAssetAddress.toString(),
201
- gseConfiguration.activationThreshold,
202
- gseConfiguration.ejectionThreshold,
199
+ args.activationThreshold,
200
+ args.ejectionThreshold,
203
201
  ]);
204
202
  logger.verbose(`Deployed GSE at ${gseAddress}`);
205
203
 
@@ -433,6 +431,7 @@ export const deployRollupForUpgrade = async (
433
431
  registryAddress: EthAddress,
434
432
  logger: Logger,
435
433
  txUtilsConfig: L1TxUtilsConfig,
434
+ flushEntryQueue: boolean = true,
436
435
  ) => {
437
436
  const deployer = new L1Deployer(
438
437
  extendedClient,
@@ -445,7 +444,14 @@ export const deployRollupForUpgrade = async (
445
444
 
446
445
  const addresses = await RegistryContract.collectAddresses(extendedClient, registryAddress, 'canonical');
447
446
 
448
- const { rollup, slashFactoryAddress } = await deployRollup(extendedClient, deployer, args, addresses, logger);
447
+ const { rollup, slashFactoryAddress } = await deployRollup(
448
+ extendedClient,
449
+ deployer,
450
+ args,
451
+ addresses,
452
+ flushEntryQueue,
453
+ logger,
454
+ );
449
455
 
450
456
  await deployer.waitForDeployments();
451
457
 
@@ -504,6 +510,7 @@ export const deployRollup = async (
504
510
  | 'gseAddress'
505
511
  | 'governanceAddress'
506
512
  >,
513
+ flushEntryQueue: boolean,
507
514
  logger: Logger,
508
515
  ) => {
509
516
  if (!addresses.gseAddress) {
@@ -533,6 +540,7 @@ export const deployRollup = async (
533
540
  aztecSlotDuration: BigInt(args.aztecSlotDuration),
534
541
  aztecEpochDuration: BigInt(args.aztecEpochDuration),
535
542
  targetCommitteeSize: BigInt(args.aztecTargetCommitteeSize),
543
+ lagInEpochs: BigInt(args.lagInEpochs),
536
544
  aztecProofSubmissionEpochs: BigInt(args.aztecProofSubmissionEpochs),
537
545
  slashingQuorum: BigInt(args.slashingQuorum ?? (args.slashingRoundSizeInEpochs * args.aztecEpochDuration) / 2 + 1),
538
546
  slashingRoundSize: BigInt(args.slashingRoundSizeInEpochs * args.aztecEpochDuration),
@@ -549,6 +557,7 @@ export const deployRollup = async (
549
557
  slasherFlavor: slasherFlavorToSolidityEnum(args.slasherFlavor),
550
558
  slashingOffsetInRounds: BigInt(args.slashingOffsetInRounds),
551
559
  slashAmounts: [args.slashAmountSmall, args.slashAmountMedium, args.slashAmountLarge],
560
+ localEjectionThreshold: args.localEjectionThreshold,
552
561
  };
553
562
 
554
563
  const genesisStateArgs = {
@@ -676,6 +685,7 @@ export const deployRollup = async (
676
685
  addresses.stakingAssetAddress.toString(),
677
686
  args.initialValidators,
678
687
  args.acceleratedTestDeployments,
688
+ flushEntryQueue,
679
689
  logger,
680
690
  );
681
691
  }
@@ -852,6 +862,7 @@ export const addMultipleValidators = async (
852
862
  stakingAssetAddress: Hex,
853
863
  validators: Operator[],
854
864
  acceleratedTestDeployments: boolean | undefined,
865
+ flushEntryQueue: boolean,
855
866
  logger: Logger,
856
867
  ) => {
857
868
  const rollup = new RollupContract(extendedClient, rollupAddress);
@@ -918,7 +929,7 @@ export const addMultipleValidators = async (
918
929
  data: encodeFunctionData({
919
930
  abi: MultiAdderArtifact.contractAbi,
920
931
  functionName: 'addValidators',
921
- args: [validatorsTuples, true],
932
+ args: [validatorsTuples, /* skip flushing */ true],
922
933
  }),
923
934
  },
924
935
  {
@@ -926,19 +937,49 @@ export const addMultipleValidators = async (
926
937
  },
927
938
  );
928
939
 
929
- await deployer.l1TxUtils.sendAndMonitorTransaction(
930
- {
931
- to: rollupAddress,
932
- data: encodeFunctionData({
933
- abi: RollupArtifact.contractAbi,
934
- functionName: 'flushEntryQueue',
935
- args: [],
936
- }),
937
- },
938
- {
939
- gasLimit: 40_000_000n,
940
- },
941
- );
940
+ let queueLength = await rollup.getEntryQueueLength();
941
+ while (flushEntryQueue && queueLength > 0n) {
942
+ logger.info(`Flushing entry queue with ${queueLength} entries`);
943
+
944
+ try {
945
+ await deployer.l1TxUtils.sendAndMonitorTransaction(
946
+ {
947
+ to: rollupAddress,
948
+ data: encodeFunctionData({
949
+ abi: RollupArtifact.contractAbi,
950
+ functionName: 'flushEntryQueue',
951
+ args: [],
952
+ }),
953
+ },
954
+ {
955
+ gasLimit: 20_000_000n,
956
+ },
957
+ );
958
+ } catch (err) {
959
+ logger.warn('Failed to flush queue', { err });
960
+ }
961
+
962
+ queueLength = await rollup.getEntryQueueLength();
963
+ // check if we drained the queue enough here so we can avoid sleep
964
+ if (queueLength === 0n) {
965
+ break;
966
+ }
967
+
968
+ logger.info(`Waiting for next flushable epoch to flush remaining ${queueLength} entries`);
969
+ await retryUntil(
970
+ async () => {
971
+ const [currentEpoch, flushableEpoch] = await Promise.all([
972
+ rollup.getCurrentEpochNumber(),
973
+ rollup.getNextFlushableEpoch(),
974
+ ]);
975
+ logger.debug(`Next flushable epoch is ${flushableEpoch} (current epoch is ${currentEpoch})`);
976
+ return currentEpoch >= flushableEpoch;
977
+ },
978
+ 'wait for next flushable epoch',
979
+ 3600,
980
+ 12,
981
+ );
982
+ }
942
983
  } else {
943
984
  await deployer.l1TxUtils.sendAndMonitorTransaction(
944
985
  {
@@ -946,7 +987,7 @@ export const addMultipleValidators = async (
946
987
  data: encodeFunctionData({
947
988
  abi: MultiAdderArtifact.contractAbi,
948
989
  functionName: 'addValidators',
949
- args: [validatorsTuples, false],
990
+ args: [validatorsTuples, /* skip flushing */ !flushEntryQueue],
950
991
  }),
951
992
  },
952
993
  {
@@ -1029,6 +1070,7 @@ export const deployL1Contracts = async (
1029
1070
  args: DeployL1ContractsArgs,
1030
1071
  txUtilsConfig: L1TxUtilsConfig = getL1TxUtilsConfigEnvVars(),
1031
1072
  createVerificationJson: string | false = false,
1073
+ flushEntryQueue: boolean = true,
1032
1074
  ): Promise<DeployL1ContractsReturnType> => {
1033
1075
  logger.info(`Deploying L1 contracts with config: ${jsonStringify(args)}`);
1034
1076
  validateConfig(args);
@@ -1095,6 +1137,7 @@ export const deployL1Contracts = async (
1095
1137
  stakingAssetAddress,
1096
1138
  governanceAddress,
1097
1139
  },
1140
+ flushEntryQueue,
1098
1141
  logger,
1099
1142
  );
1100
1143
 
@@ -1145,7 +1188,7 @@ export const deployL1Contracts = async (
1145
1188
 
1146
1189
  // Include Slasher and SlashingProposer (if deployed) in verification data
1147
1190
  try {
1148
- const slasherAddrHex = await rollup.getSlasher();
1191
+ const slasherAddrHex = await rollup.getSlasherAddress();
1149
1192
  const slasherAddr = EthAddress.fromString(slasherAddrHex);
1150
1193
  if (!slasherAddr.isZero()) {
1151
1194
  // Slasher constructor: (address _vetoer, address _governance)
@@ -279,7 +279,13 @@ export class ReadOnlyL1TxUtils {
279
279
  let blobBaseFee = 0n;
280
280
  if (isBlobTx) {
281
281
  try {
282
- blobBaseFee = await this.client.getBlobBaseFee();
282
+ blobBaseFee = await retry<bigint>(
283
+ () => this.client.getBlobBaseFee(),
284
+ 'Getting L1 blob base fee',
285
+ makeBackoff(times(2, () => 1)),
286
+ this.logger,
287
+ true,
288
+ );
283
289
  this.logger?.debug('L1 Blob base fee:', { blobBaseFee: formatGwei(blobBaseFee) });
284
290
  } catch {
285
291
  this.logger?.warn('Failed to get L1 blob base fee', attempt);
@@ -706,12 +712,14 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
706
712
  * Monitors a transaction until completion, handling speed-ups if needed
707
713
  * @param request - Original transaction request (needed for speed-ups)
708
714
  * @param initialTxHash - Hash of the initial transaction
715
+ * @param allVersions - Hashes of all transactions submitted under the same nonce (any of them could mine)
709
716
  * @param params - Parameters used in the initial transaction
710
717
  * @param gasConfig - Optional gas configuration
711
718
  */
712
719
  public async monitorTransaction(
713
720
  request: L1TxRequest,
714
721
  initialTxHash: Hex,
722
+ allVersions: Set<Hex>,
715
723
  params: { gasLimit: bigint },
716
724
  _gasConfig?: Partial<L1TxUtilsConfig> & { txTimeoutAt?: Date },
717
725
  _blobInputs?: L1BlobInputs,
@@ -743,7 +751,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
743
751
  }
744
752
  const nonce = tx.nonce;
745
753
 
746
- const txHashes = new Set<Hex>([initialTxHash]);
754
+ allVersions.add(initialTxHash);
747
755
  let currentTxHash = initialTxHash;
748
756
  let attempts = 0;
749
757
  let lastAttemptSent = this.dateProvider.now();
@@ -776,8 +784,9 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
776
784
  }));
777
785
 
778
786
  const currentNonce = await this.client.getTransactionCount({ address: account });
787
+ // If the current nonce on our account is greater than our transaction's nonce then a tx with the same nonce has been mined.
779
788
  if (currentNonce > nonce) {
780
- for (const hash of txHashes) {
789
+ for (const hash of allVersions) {
781
790
  try {
782
791
  const receipt = await this.client.getTransactionReceipt({ hash });
783
792
  if (receipt) {
@@ -796,6 +805,10 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
796
805
  }
797
806
  }
798
807
  }
808
+ // If we get here then we have checked all of our tx versions and not found anything.
809
+ // We should consider the nonce as MINED
810
+ this.state = TxUtilsState.MINED;
811
+ throw new Error(`Nonce ${nonce} is MINED but not by one of our expected transactions`);
799
812
  }
800
813
 
801
814
  this.logger?.trace(`Tx timeout check for ${currentTxHash}: ${isTimedOut()}`, {
@@ -857,7 +870,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
857
870
  },
858
871
  );
859
872
 
860
- const txData = {
873
+ const txData: PrepareTransactionRequestRequest = {
861
874
  ...request,
862
875
  ...blobInputs,
863
876
  nonce,
@@ -865,6 +878,9 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
865
878
  maxFeePerGas: newGasPrice.maxFeePerGas,
866
879
  maxPriorityFeePerGas: newGasPrice.maxPriorityFeePerGas,
867
880
  };
881
+ if (isBlobTx && newGasPrice.maxFeePerBlobGas) {
882
+ (txData as any).maxFeePerBlobGas = newGasPrice.maxFeePerBlobGas;
883
+ }
868
884
  const signedRequest = await this.prepareSignedTransaction(txData);
869
885
  const newHash = await this.client.sendRawTransaction({ serializedTransaction: signedRequest });
870
886
  if (!isCancelTx) {
@@ -882,7 +898,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
882
898
 
883
899
  currentTxHash = newHash;
884
900
 
885
- txHashes.add(currentTxHash);
901
+ allVersions.add(currentTxHash);
886
902
  lastAttemptSent = this.dateProvider.now();
887
903
  }
888
904
  await sleep(gasConfig.checkIntervalMs!);
@@ -904,7 +920,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
904
920
  this.state = TxUtilsState.NOT_MINED;
905
921
  } else if (gasConfig.cancelTxOnTimeout) {
906
922
  // Fire cancellation without awaiting to avoid blocking the main thread
907
- this.attemptTxCancellation(currentTxHash, nonce, isBlobTx, lastGasPrice, attempts).catch(err => {
923
+ this.attemptTxCancellation(currentTxHash, nonce, allVersions, isBlobTx, lastGasPrice, attempts).catch(err => {
908
924
  const viemError = formatViemError(err);
909
925
  this.logger?.error(`Failed to send cancellation for timed out tx ${currentTxHash}:`, viemError.message, {
910
926
  metaMessages: viemError.metaMessages,
@@ -938,7 +954,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
938
954
  blobInputs?: L1BlobInputs,
939
955
  ): Promise<{ receipt: TransactionReceipt; gasPrice: GasPrice }> {
940
956
  const { txHash, gasLimit, gasPrice } = await this.sendTransaction(request, gasConfig, blobInputs);
941
- const receipt = await this.monitorTransaction(request, txHash, { gasLimit }, gasConfig, blobInputs);
957
+ const receipt = await this.monitorTransaction(request, txHash, new Set(), { gasLimit }, gasConfig, blobInputs);
942
958
  return { receipt, gasPrice };
943
959
  }
944
960
 
@@ -973,6 +989,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
973
989
  /**
974
990
  * Attempts to cancel a transaction by sending a 0-value tx to self with same nonce but higher gas prices
975
991
  * @param nonce - The nonce of the transaction to cancel
992
+ * @param allVersions - Hashes of all transactions submitted under the same nonce (any of them could mine)
976
993
  * @param previousGasPrice - The gas price of the previous transaction
977
994
  * @param attempts - The number of attempts to cancel the transaction
978
995
  * @returns The hash of the cancellation transaction
@@ -980,6 +997,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
980
997
  protected async attemptTxCancellation(
981
998
  currentTxHash: Hex,
982
999
  nonce: number,
1000
+ allVersions: Set<Hex>,
983
1001
  isBlobTx = false,
984
1002
  previousGasPrice?: GasPrice,
985
1003
  attempts = 0,
@@ -1000,7 +1018,7 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
1000
1018
  previousGasPrice,
1001
1019
  );
1002
1020
 
1003
- this.logger?.debug(`Attempting to cancel L1 transaction ${currentTxHash} with nonce ${nonce}`, {
1021
+ this.logger?.info(`Attempting to cancel L1 transaction ${currentTxHash} with nonce ${nonce}`, {
1004
1022
  maxFeePerGas: formatGwei(cancelGasPrice.maxFeePerGas),
1005
1023
  maxPriorityFeePerGas: formatGwei(cancelGasPrice.maxPriorityFeePerGas),
1006
1024
  });
@@ -1022,11 +1040,12 @@ export class L1TxUtils extends ReadOnlyL1TxUtils {
1022
1040
 
1023
1041
  this.state = TxUtilsState.CANCELLED;
1024
1042
 
1025
- this.logger?.debug(`Sent cancellation tx ${cancelTxHash} for timed out tx ${currentTxHash}`, { nonce });
1043
+ this.logger?.info(`Sent cancellation tx ${cancelTxHash} for timed out tx ${currentTxHash}`, { nonce });
1026
1044
 
1027
1045
  const receipt = await this.monitorTransaction(
1028
1046
  request,
1029
1047
  cancelTxHash,
1048
+ allVersions,
1030
1049
  { gasLimit: 21_000n },
1031
1050
  undefined,
1032
1051
  undefined,
@@ -19,6 +19,7 @@ export class L1TxUtilsWithBlobs extends L1TxUtils {
19
19
  /**
20
20
  * Attempts to cancel a transaction by sending a 0-value tx to self with same nonce but higher gas prices
21
21
  * @param nonce - The nonce of the transaction to cancel
22
+ * @param allVersions - Hashes of all transactions submitted under the same nonce (any of them could mine)
22
23
  * @param previousGasPrice - The gas price of the previous transaction
23
24
  * @param attempts - The number of attempts to cancel the transaction
24
25
  * @returns The hash of the cancellation transaction
@@ -26,6 +27,7 @@ export class L1TxUtilsWithBlobs extends L1TxUtils {
26
27
  override async attemptTxCancellation(
27
28
  currentTxHash: Hex,
28
29
  nonce: number,
30
+ allVersions: Set<Hex>,
29
31
  isBlobTx = false,
30
32
  previousGasPrice?: GasPrice,
31
33
  attempts = 0,
@@ -42,7 +44,7 @@ export class L1TxUtilsWithBlobs extends L1TxUtils {
42
44
  previousGasPrice,
43
45
  );
44
46
 
45
- this.logger?.debug(`Attempting to cancel blob L1 transaction ${currentTxHash} with nonce ${nonce}`, {
47
+ this.logger?.info(`Attempting to cancel blob L1 transaction ${currentTxHash} with nonce ${nonce}`, {
46
48
  maxFeePerGas: formatGwei(cancelGasPrice.maxFeePerGas),
47
49
  maxPriorityFeePerGas: formatGwei(cancelGasPrice.maxPriorityFeePerGas),
48
50
  maxFeePerBlobGas:
@@ -65,9 +67,12 @@ export class L1TxUtilsWithBlobs extends L1TxUtils {
65
67
  const signedRequest = await this.prepareSignedTransaction(txData);
66
68
  const cancelTxHash = await this.client.sendRawTransaction({ serializedTransaction: signedRequest });
67
69
 
70
+ this.logger?.info(`Sent cancellation tx ${cancelTxHash} for timed out tx ${currentTxHash}`);
71
+
68
72
  const receipt = await this.monitorTransaction(
69
73
  request,
70
74
  cancelTxHash,
75
+ allVersions,
71
76
  { gasLimit: 21_000n },
72
77
  undefined,
73
78
  undefined,
@@ -94,11 +99,12 @@ export class L1TxUtilsWithBlobs extends L1TxUtils {
94
99
  const signedRequest = await this.prepareSignedTransaction(txData);
95
100
  const cancelTxHash = await this.client.sendRawTransaction({ serializedTransaction: signedRequest });
96
101
 
97
- this.logger?.debug(`Sent cancellation tx ${cancelTxHash} for timed out tx ${currentTxHash}`);
102
+ this.logger?.info(`Sent cancellation tx ${cancelTxHash} for timed out tx ${currentTxHash}`);
98
103
 
99
104
  const receipt = await this.monitorTransaction(
100
105
  request,
101
106
  cancelTxHash,
107
+ allVersions,
102
108
  { gasLimit: 21_000n },
103
109
  undefined,
104
110
  blobInputs,
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,10 @@ export async function getL1ContractsConfig(
37
33
  aztecSlotDuration,
38
34
  aztecProofSubmissionEpochs,
39
35
  aztecTargetCommitteeSize,
36
+ lagInEpochs,
40
37
  activationThreshold,
41
38
  ejectionThreshold,
39
+ localEjectionThreshold,
42
40
  governanceProposerQuorum,
43
41
  governanceProposerRoundSize,
44
42
  slashingQuorum,
@@ -60,8 +58,10 @@ export async function getL1ContractsConfig(
60
58
  rollup.getSlotDuration(),
61
59
  rollup.getProofSubmissionEpochs(),
62
60
  rollup.getTargetCommitteeSize(),
61
+ rollup.getLagInEpochs(),
63
62
  rollup.getActivationThreshold(),
64
63
  rollup.getEjectionThreshold(),
64
+ rollup.getLocalEjectionThreshold(),
65
65
  governanceProposer.getQuorumSize(),
66
66
  governanceProposer.getRoundSize(),
67
67
  slasherProposer?.getQuorumSize() ?? 0n,
@@ -70,7 +70,7 @@ export async function getL1ContractsConfig(
70
70
  slasherProposer?.getExecutionDelayInRounds() ?? 0n,
71
71
  slasherProposer?.type === 'tally' ? slasherProposer.getSlashOffsetInRounds() : 0n,
72
72
  slasherProposer?.type === 'tally' ? slasherProposer.getSlashingAmounts() : [0n, 0n, 0n],
73
- slasher.read.VETOER(),
73
+ slasher?.getVetoer() ?? EthAddress.ZERO,
74
74
  rollup.getManaTarget(),
75
75
  rollup.getProvingCostPerMana(),
76
76
  rollup.getVersion(),
@@ -85,15 +85,17 @@ export async function getL1ContractsConfig(
85
85
  aztecSlotDuration: Number(aztecSlotDuration),
86
86
  aztecProofSubmissionEpochs: Number(aztecProofSubmissionEpochs),
87
87
  aztecTargetCommitteeSize: Number(aztecTargetCommitteeSize),
88
+ lagInEpochs: Number(lagInEpochs),
88
89
  governanceProposerQuorum: Number(governanceProposerQuorum),
89
90
  governanceProposerRoundSize: Number(governanceProposerRoundSize),
90
91
  activationThreshold,
91
92
  ejectionThreshold,
93
+ localEjectionThreshold,
92
94
  slashingQuorum: Number(slashingQuorum),
93
95
  slashingRoundSizeInEpochs: Number(slashingRoundSize / aztecEpochDuration),
94
96
  slashingLifetimeInRounds: Number(slashingLifetimeInRounds),
95
97
  slashingExecutionDelayInRounds: Number(slashingExecutionDelayInRounds),
96
- slashingVetoer: EthAddress.fromString(slashingVetoer),
98
+ slashingVetoer,
97
99
  manaTarget: manaTarget,
98
100
  provingCostPerMana: provingCostPerMana,
99
101
  rollupVersion: Number(rollupVersion),