@aztec/ethereum 3.0.0-nightly.20250919 → 3.0.0-nightly.20250920

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.
@@ -5,12 +5,12 @@ 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';
9
8
  import { DateProvider } from '@aztec/foundation/timer';
10
9
  import type { RollupAbi } from '@aztec/l1-artifacts/RollupAbi';
11
10
 
12
11
  import type { Abi, Narrow } from 'abitype';
13
12
  import { mkdir, writeFile } from 'fs/promises';
13
+ import chunk from 'lodash.chunk';
14
14
  import {
15
15
  type Chain,
16
16
  type ContractConstructorArgs,
@@ -76,8 +76,6 @@ import { ZK_PASSPORT_DOMAIN, ZK_PASSPORT_SCOPE, ZK_PASSPORT_VERIFIER_ADDRESS } f
76
76
 
77
77
  export const DEPLOYER_ADDRESS: Hex = '0x4e59b44847b379578588920cA78FbF26c0B4956C';
78
78
 
79
- const networkName = getActiveNetworkName();
80
-
81
79
  export type Operator = {
82
80
  attester: EthAddress;
83
81
  withdrawer: EthAddress;
@@ -183,6 +181,8 @@ export const deploySharedContracts = async (
183
181
  args: DeployL1ContractsArgs,
184
182
  logger: Logger,
185
183
  ) => {
184
+ const networkName = getActiveNetworkName();
185
+
186
186
  logger.info(`Deploying shared contracts for network configuration: ${networkName}`);
187
187
 
188
188
  const txHashes: Hex[] = [];
@@ -314,6 +314,7 @@ export const deploySharedContracts = async (
314
314
  stakingAsset: stakingAssetAddress.toString(),
315
315
  registry: registryAddress.toString(),
316
316
  withdrawer: AMIN.toString(),
317
+ validatorsToFlush: 16n,
317
318
  mintInterval: BigInt(60 * 60 * 24),
318
319
  depositsPerMint: BigInt(10),
319
320
  depositMerkleRoot: '0x0000000000000000000000000000000000000000000000000000000000000000',
@@ -431,7 +432,6 @@ export const deployRollupForUpgrade = async (
431
432
  registryAddress: EthAddress,
432
433
  logger: Logger,
433
434
  txUtilsConfig: L1TxUtilsConfig,
434
- flushEntryQueue: boolean = true,
435
435
  ) => {
436
436
  const deployer = new L1Deployer(
437
437
  extendedClient,
@@ -444,14 +444,7 @@ export const deployRollupForUpgrade = async (
444
444
 
445
445
  const addresses = await RegistryContract.collectAddresses(extendedClient, registryAddress, 'canonical');
446
446
 
447
- const { rollup, slashFactoryAddress } = await deployRollup(
448
- extendedClient,
449
- deployer,
450
- args,
451
- addresses,
452
- flushEntryQueue,
453
- logger,
454
- );
447
+ const { rollup, slashFactoryAddress } = await deployRollup(extendedClient, deployer, args, addresses, logger);
455
448
 
456
449
  await deployer.waitForDeployments();
457
450
 
@@ -510,12 +503,12 @@ export const deployRollup = async (
510
503
  | 'gseAddress'
511
504
  | 'governanceAddress'
512
505
  >,
513
- flushEntryQueue: boolean,
514
506
  logger: Logger,
515
507
  ) => {
516
508
  if (!addresses.gseAddress) {
517
509
  throw new Error('GSE address is required when deploying');
518
510
  }
511
+ const networkName = getActiveNetworkName();
519
512
 
520
513
  logger.info(`Deploying rollup using network configuration: ${networkName}`);
521
514
 
@@ -686,7 +679,6 @@ export const deployRollup = async (
686
679
  addresses.stakingAssetAddress.toString(),
687
680
  args.initialValidators,
688
681
  args.acceleratedTestDeployments,
689
- flushEntryQueue,
690
682
  logger,
691
683
  );
692
684
  }
@@ -863,7 +855,6 @@ export const addMultipleValidators = async (
863
855
  stakingAssetAddress: Hex,
864
856
  validators: Operator[],
865
857
  acceleratedTestDeployments: boolean | undefined,
866
- flushEntryQueue: boolean,
867
858
  logger: Logger,
868
859
  ) => {
869
860
  const rollup = new RollupContract(extendedClient, rollupAddress);
@@ -889,130 +880,111 @@ export const addMultipleValidators = async (
889
880
  validators = enrichedValidators.filter(v => v.status === 0).map(v => v.operator);
890
881
  }
891
882
 
892
- if (validators.length > 0) {
893
- const gseContract = new GSEContract(extendedClient, gseAddress);
894
- const multiAdder = await deployer.deploy(MultiAdderArtifact, [rollupAddress, deployer.client.account.address]);
895
-
896
- const makeValidatorTuples = async (validator: Operator) => {
897
- const registrationTuple = await gseContract.makeRegistrationTuple(validator.bn254SecretKey.getValue());
898
- return {
899
- attester: getAddress(validator.attester.toString()),
900
- withdrawer: getAddress(validator.withdrawer.toString()),
901
- ...registrationTuple,
902
- };
883
+ if (validators.length === 0) {
884
+ logger.warn('No validators to add. Skipping.');
885
+ return;
886
+ }
887
+
888
+ const gseContract = new GSEContract(extendedClient, gseAddress);
889
+ const multiAdder = await deployer.deploy(MultiAdderArtifact, [rollupAddress, deployer.client.account.address]);
890
+
891
+ const makeValidatorTuples = async (validator: Operator) => {
892
+ const registrationTuple = await gseContract.makeRegistrationTuple(validator.bn254SecretKey.getValue());
893
+ return {
894
+ attester: getAddress(validator.attester.toString()),
895
+ withdrawer: getAddress(validator.withdrawer.toString()),
896
+ ...registrationTuple,
903
897
  };
898
+ };
904
899
 
905
- const validatorsTuples = await Promise.all(validators.map(makeValidatorTuples));
900
+ const validatorsTuples = await Promise.all(validators.map(makeValidatorTuples));
906
901
 
907
- // Mint tokens, approve them, use cheat code to initialize validator set without setting up the epoch.
908
- const stakeNeeded = activationThreshold * BigInt(validators.length);
902
+ // Mint tokens, approve them, use cheat code to initialize validator set without setting up the epoch.
903
+ const stakeNeeded = activationThreshold * BigInt(validators.length);
909
904
 
910
- await deployer.l1TxUtils.sendAndMonitorTransaction({
911
- to: stakingAssetAddress,
912
- data: encodeFunctionData({
913
- abi: StakingAssetArtifact.contractAbi,
914
- functionName: 'mint',
915
- args: [multiAdder.toString(), stakeNeeded],
916
- }),
917
- });
905
+ await deployer.l1TxUtils.sendAndMonitorTransaction({
906
+ to: stakingAssetAddress,
907
+ data: encodeFunctionData({
908
+ abi: StakingAssetArtifact.contractAbi,
909
+ functionName: 'mint',
910
+ args: [multiAdder.toString(), stakeNeeded],
911
+ }),
912
+ });
918
913
 
919
- const entryQueueLengthBefore = await rollup.getEntryQueueLength();
920
- const validatorCountBefore = await rollup.getActiveAttesterCount();
921
-
922
- logger.info(`Adding ${validators.length} validators to the rollup`);
923
-
924
- // Adding to the queue and flushing need to be done in two transactions
925
- // if we are adding many validators.
926
- if (validatorsTuples.length > 10) {
927
- await deployer.l1TxUtils.sendAndMonitorTransaction(
928
- {
929
- to: multiAdder.toString(),
930
- data: encodeFunctionData({
931
- abi: MultiAdderArtifact.contractAbi,
932
- functionName: 'addValidators',
933
- args: [validatorsTuples, /* skip flushing */ true],
934
- }),
935
- },
936
- {
937
- gasLimit: 40_000_000n,
938
- },
939
- );
914
+ const entryQueueLengthBefore = await rollup.getEntryQueueLength();
915
+ const validatorCountBefore = await rollup.getActiveAttesterCount();
940
916
 
941
- let queueLength = await rollup.getEntryQueueLength();
942
- while (flushEntryQueue && queueLength > 0n) {
943
- logger.info(`Flushing entry queue with ${queueLength} entries`);
944
-
945
- try {
946
- await deployer.l1TxUtils.sendAndMonitorTransaction(
947
- {
948
- to: rollupAddress,
949
- data: encodeFunctionData({
950
- abi: RollupArtifact.contractAbi,
951
- functionName: 'flushEntryQueue',
952
- args: [],
953
- }),
954
- },
955
- {
956
- gasLimit: 20_000_000n,
957
- },
958
- );
959
- } catch (err) {
960
- logger.warn('Failed to flush queue', { err });
961
- }
917
+ logger.info(`Adding ${validators.length} validators to the rollup`);
962
918
 
963
- queueLength = await rollup.getEntryQueueLength();
964
- // check if we drained the queue enough here so we can avoid sleep
965
- if (queueLength === 0n) {
966
- break;
967
- }
919
+ const chunkSize = 16;
968
920
 
969
- logger.info(`Waiting for next flushable epoch to flush remaining ${queueLength} entries`);
970
- await retryUntil(
971
- async () => {
972
- const [currentEpoch, flushableEpoch] = await Promise.all([
973
- rollup.getCurrentEpochNumber(),
974
- rollup.getNextFlushableEpoch(),
975
- ]);
976
- logger.debug(`Next flushable epoch is ${flushableEpoch} (current epoch is ${currentEpoch})`);
977
- return currentEpoch >= flushableEpoch;
978
- },
979
- 'wait for next flushable epoch',
980
- 3600,
981
- 12,
982
- );
983
- }
984
- } else {
985
- await deployer.l1TxUtils.sendAndMonitorTransaction(
986
- {
987
- to: multiAdder.toString(),
988
- data: encodeFunctionData({
989
- abi: MultiAdderArtifact.contractAbi,
990
- functionName: 'addValidators',
991
- args: [validatorsTuples, /* skip flushing */ !flushEntryQueue],
992
- }),
993
- },
994
- {
995
- gasLimit: 45_000_000n,
996
- },
997
- );
998
- }
921
+ // We will add `chunkSize` validators to the queue until we have covered all of our validators.
922
+ // The `chunkSize` needs to be small enough to fit inside a single tx, therefore 16.
923
+ for (const c of chunk(validatorsTuples, chunkSize)) {
924
+ await deployer.l1TxUtils.sendAndMonitorTransaction(
925
+ {
926
+ to: multiAdder.toString(),
927
+ data: encodeFunctionData({
928
+ abi: MultiAdderArtifact.contractAbi,
929
+ functionName: 'addValidators',
930
+ args: [c, BigInt(0)],
931
+ }),
932
+ },
933
+ {
934
+ gasLimit: 16_000_000n,
935
+ },
936
+ );
937
+ }
999
938
 
1000
- const entryQueueLengthAfter = await rollup.getEntryQueueLength();
1001
- const validatorCountAfter = await rollup.getActiveAttesterCount();
939
+ // After adding to the queue, we will now try to flush from it.
940
+ // We are explicitly doing this as a second step instead of as part of adding to benefit
941
+ // from the accounting used to speed the process up.
942
+ // As the queue computes the amount of possible flushes in an epoch when told to flush,
943
+ // waiting until we have added all we want allows us to benefit in the case were we added
944
+ // enough to pass the bootstrap set size without needing to wait another epoch.
945
+ // This is useful when we are testing as it speeds up the tests slightly.
946
+ while (true) {
947
+ // If the queue is empty, we can break
948
+ if ((await rollup.getEntryQueueLength()) == 0n) {
949
+ break;
950
+ }
1002
951
 
1003
- if (
1004
- entryQueueLengthAfter + validatorCountAfter <
1005
- entryQueueLengthBefore + validatorCountBefore + BigInt(validators.length)
1006
- ) {
1007
- throw new Error(
1008
- `Failed to add ${validators.length} validators. Active validators: ${validatorCountBefore} -> ${validatorCountAfter}. Queue: ${entryQueueLengthBefore} -> ${entryQueueLengthAfter}`,
1009
- );
952
+ // If there are no available validator flushes, no need to even try
953
+ if ((await rollup.getAvailableValidatorFlushes()) == 0n) {
954
+ break;
1010
955
  }
1011
956
 
1012
- logger.info(
1013
- `Added ${validators.length} validators. Active validators: ${validatorCountBefore} -> ${validatorCountAfter}. Queue: ${entryQueueLengthBefore} -> ${entryQueueLengthAfter}`,
957
+ // Note that we are flushing at most `chunkSize` at each call
958
+ await deployer.l1TxUtils.sendAndMonitorTransaction(
959
+ {
960
+ to: rollup.address,
961
+ data: encodeFunctionData({
962
+ abi: RollupArtifact.contractAbi,
963
+ functionName: 'flushEntryQueue',
964
+ args: [BigInt(chunkSize)],
965
+ }),
966
+ },
967
+ {
968
+ gasLimit: 16_000_000n,
969
+ },
970
+ );
971
+ }
972
+
973
+ const entryQueueLengthAfter = await rollup.getEntryQueueLength();
974
+ const validatorCountAfter = await rollup.getActiveAttesterCount();
975
+
976
+ if (
977
+ entryQueueLengthAfter + validatorCountAfter <
978
+ entryQueueLengthBefore + validatorCountBefore + BigInt(validators.length)
979
+ ) {
980
+ throw new Error(
981
+ `Failed to add ${validators.length} validators. Active validators: ${validatorCountBefore} -> ${validatorCountAfter}. Queue: ${entryQueueLengthBefore} -> ${entryQueueLengthAfter}. A likely issue is the bootstrap size.`,
1014
982
  );
1015
983
  }
984
+
985
+ logger.info(
986
+ `Added ${validators.length} validators. Active validators: ${validatorCountBefore} -> ${validatorCountAfter}. Queue: ${entryQueueLengthBefore} -> ${entryQueueLengthAfter}`,
987
+ );
1016
988
  }
1017
989
  };
1018
990
 
@@ -1071,7 +1043,6 @@ export const deployL1Contracts = async (
1071
1043
  args: DeployL1ContractsArgs,
1072
1044
  txUtilsConfig: L1TxUtilsConfig = getL1TxUtilsConfigEnvVars(),
1073
1045
  createVerificationJson: string | false = false,
1074
- flushEntryQueue: boolean = true,
1075
1046
  ): Promise<DeployL1ContractsReturnType> => {
1076
1047
  logger.info(`Deploying L1 contracts with config: ${jsonStringify(args)}`);
1077
1048
  validateConfig(args);
@@ -1138,7 +1109,6 @@ export const deployL1Contracts = async (
1138
1109
  stakingAssetAddress,
1139
1110
  governanceAddress,
1140
1111
  },
1141
- flushEntryQueue,
1142
1112
  logger,
1143
1113
  );
1144
1114
 
@@ -1294,6 +1264,7 @@ export const deployL1Contracts = async (
1294
1264
  // Ensure the verification output directory exists
1295
1265
  await mkdir(createVerificationJson, { recursive: true });
1296
1266
  const verificationOutputPath = `${createVerificationJson}/l1-verify-${chain.id}-${formattedDate.slice(0, 6)}-${formattedDate.slice(6)}.json`;
1267
+ const networkName = getActiveNetworkName();
1297
1268
  const verificationData = {
1298
1269
  chainId: chain.id,
1299
1270
  network: networkName,