@aztec/ethereum 2.1.0-rc.9 → 3.0.0-devnet.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/client.d.ts +1 -1
- package/dest/client.d.ts.map +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +13 -3
- package/dest/contracts/rollup.d.ts +2 -2
- package/dest/contracts/rollup.d.ts.map +1 -1
- package/dest/contracts/rollup.js +9 -6
- package/dest/contracts/tally_slashing_proposer.d.ts +7 -1
- package/dest/contracts/tally_slashing_proposer.d.ts.map +1 -1
- package/dest/contracts/tally_slashing_proposer.js +12 -2
- package/dest/deploy_l1_contracts.d.ts +4 -3
- package/dest/deploy_l1_contracts.d.ts.map +1 -1
- package/dest/deploy_l1_contracts.js +241 -205
- package/dest/l1_artifacts.d.ts +730 -192
- package/dest/l1_artifacts.d.ts.map +1 -1
- package/dest/l1_artifacts.js +5 -5
- package/dest/l1_reader.d.ts +1 -1
- package/dest/l1_reader.d.ts.map +1 -1
- package/dest/l1_reader.js +1 -1
- package/dest/test/eth_cheat_codes.d.ts +15 -6
- package/dest/test/eth_cheat_codes.d.ts.map +1 -1
- package/dest/test/eth_cheat_codes.js +17 -9
- package/dest/test/rollup_cheat_codes.d.ts +8 -8
- package/dest/test/rollup_cheat_codes.d.ts.map +1 -1
- package/dest/test/rollup_cheat_codes.js +36 -4
- package/dest/test/upgrade_utils.d.ts.map +1 -1
- package/dest/test/upgrade_utils.js +2 -1
- package/dest/zkPassportVerifierAddress.js +1 -1
- package/package.json +6 -6
- package/src/client.ts +1 -1
- package/src/config.ts +14 -4
- package/src/contracts/rollup.ts +9 -8
- package/src/contracts/tally_slashing_proposer.ts +12 -3
- package/src/deploy_l1_contracts.ts +221 -152
- package/src/l1_artifacts.ts +6 -6
- package/src/l1_reader.ts +2 -2
- package/src/test/eth_cheat_codes.ts +25 -12
- package/src/test/rollup_cheat_codes.ts +49 -12
- package/src/test/upgrade_utils.ts +2 -1
- package/src/zkPassportVerifierAddress.ts +1 -1
|
@@ -147,8 +147,8 @@ export type VerificationRecord = {
|
|
|
147
147
|
export interface DeployL1ContractsArgs extends Omit<L1ContractsConfig, keyof L1TxUtilsConfig> {
|
|
148
148
|
/** The vk tree root. */
|
|
149
149
|
vkTreeRoot: Fr;
|
|
150
|
-
/** The
|
|
151
|
-
|
|
150
|
+
/** The hash of the protocol contracts. */
|
|
151
|
+
protocolContractsHash: Fr;
|
|
152
152
|
/** The genesis root of the archive tree. */
|
|
153
153
|
genesisArchiveRoot: Fr;
|
|
154
154
|
/** The salt for CREATE2 deployment. */
|
|
@@ -279,6 +279,8 @@ export const deploySharedContracts = async (
|
|
|
279
279
|
const deployedStaking = await deployer.deploy(StakingAssetArtifact, ['Staking', 'STK', l1Client.account.address]);
|
|
280
280
|
stakingAssetAddress = deployedStaking.address;
|
|
281
281
|
logger.verbose(`Deployed Staking Asset at ${stakingAssetAddress}`);
|
|
282
|
+
|
|
283
|
+
await deployer.waitForDeployments();
|
|
282
284
|
}
|
|
283
285
|
|
|
284
286
|
const gseAddress = (
|
|
@@ -352,7 +354,7 @@ export const deploySharedContracts = async (
|
|
|
352
354
|
const coinIssuerAddress = (
|
|
353
355
|
await deployer.deploy(CoinIssuerArtifact, [
|
|
354
356
|
feeAssetAddress.toString(),
|
|
355
|
-
|
|
357
|
+
2n * 10n ** 17n, // hard cap of 20% per year
|
|
356
358
|
l1Client.account.address,
|
|
357
359
|
])
|
|
358
360
|
).address;
|
|
@@ -514,6 +516,199 @@ const getZkPassportScopes = (args: DeployL1ContractsArgs): [string, string] => {
|
|
|
514
516
|
return [domain, scope];
|
|
515
517
|
};
|
|
516
518
|
|
|
519
|
+
/**
|
|
520
|
+
* Generates verification records for a deployed rollup and its associated contracts (Inbox, Outbox, Slasher, etc).
|
|
521
|
+
* @param rollup - The deployed rollup contract.
|
|
522
|
+
* @param deployer - The L1 deployer instance.
|
|
523
|
+
* @param args - The deployment arguments used for the rollup.
|
|
524
|
+
* @param addresses - The L1 contract addresses.
|
|
525
|
+
* @param extendedClient - The extended viem wallet client.
|
|
526
|
+
* @param logger - The logger.
|
|
527
|
+
*/
|
|
528
|
+
async function generateRollupVerificationRecords(
|
|
529
|
+
rollup: RollupContract,
|
|
530
|
+
deployer: L1Deployer,
|
|
531
|
+
args: {
|
|
532
|
+
slashingVetoer: EthAddress;
|
|
533
|
+
slashingRoundSizeInEpochs: number;
|
|
534
|
+
aztecEpochDuration: number;
|
|
535
|
+
slashingQuorum?: number;
|
|
536
|
+
slashingLifetimeInRounds: number;
|
|
537
|
+
slashingExecutionDelayInRounds: number;
|
|
538
|
+
slasherFlavor: 'none' | 'tally' | 'empire';
|
|
539
|
+
slashAmountSmall: bigint;
|
|
540
|
+
slashAmountMedium: bigint;
|
|
541
|
+
slashAmountLarge: bigint;
|
|
542
|
+
aztecTargetCommitteeSize: number;
|
|
543
|
+
slashingOffsetInRounds: number;
|
|
544
|
+
},
|
|
545
|
+
addresses: Pick<L1ContractAddresses, 'feeJuiceAddress'>,
|
|
546
|
+
extendedClient: ExtendedViemWalletClient,
|
|
547
|
+
logger: Logger,
|
|
548
|
+
): Promise<void> {
|
|
549
|
+
try {
|
|
550
|
+
// Add Inbox / Outbox verification records (constructor args are created inside RollupCore)
|
|
551
|
+
const rollupAddr = rollup.address;
|
|
552
|
+
const rollupAddresses = await rollup.getRollupAddresses();
|
|
553
|
+
const inboxAddr = rollupAddresses.inboxAddress.toString();
|
|
554
|
+
const outboxAddr = rollupAddresses.outboxAddress.toString();
|
|
555
|
+
const feeAsset = rollupAddresses.feeJuiceAddress.toString();
|
|
556
|
+
const version = await rollup.getVersion();
|
|
557
|
+
|
|
558
|
+
const inboxCtor = encodeAbiParameters(
|
|
559
|
+
[{ type: 'address' }, { type: 'address' }, { type: 'uint256' }, { type: 'uint256' }],
|
|
560
|
+
[rollupAddr, feeAsset, version, BigInt(L1_TO_L2_MSG_SUBTREE_HEIGHT)],
|
|
561
|
+
);
|
|
562
|
+
|
|
563
|
+
const outboxCtor = encodeAbiParameters([{ type: 'address' }, { type: 'uint256' }], [rollupAddr, version]);
|
|
564
|
+
|
|
565
|
+
deployer.verificationRecords.push(
|
|
566
|
+
{ name: 'Inbox', address: inboxAddr, constructorArgsHex: inboxCtor, libraries: [] },
|
|
567
|
+
{ name: 'Outbox', address: outboxAddr, constructorArgsHex: outboxCtor, libraries: [] },
|
|
568
|
+
);
|
|
569
|
+
|
|
570
|
+
// Include Slasher and SlashingProposer (if deployed) in verification data
|
|
571
|
+
try {
|
|
572
|
+
const slasherAddrHex = await rollup.getSlasherAddress();
|
|
573
|
+
const slasherAddr = EthAddress.fromString(slasherAddrHex);
|
|
574
|
+
if (!slasherAddr.isZero()) {
|
|
575
|
+
// Slasher constructor: (address _vetoer, address _governance)
|
|
576
|
+
const slasherCtor = encodeAbiParameters(
|
|
577
|
+
[{ type: 'address' }, { type: 'address' }],
|
|
578
|
+
[args.slashingVetoer.toString(), extendedClient.account.address],
|
|
579
|
+
);
|
|
580
|
+
deployer.verificationRecords.push({
|
|
581
|
+
name: 'Slasher',
|
|
582
|
+
address: slasherAddr.toString(),
|
|
583
|
+
constructorArgsHex: slasherCtor,
|
|
584
|
+
libraries: [],
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
// Proposer address is stored in Slasher.PROPOSER()
|
|
588
|
+
const proposerAddr = (await rollup.getSlashingProposerAddress()).toString();
|
|
589
|
+
|
|
590
|
+
// Compute constructor args matching deployment path in RollupCore
|
|
591
|
+
const computedRoundSize = BigInt(args.slashingRoundSizeInEpochs * args.aztecEpochDuration);
|
|
592
|
+
const computedQuorum = BigInt(
|
|
593
|
+
args.slashingQuorum ?? (args.slashingRoundSizeInEpochs * args.aztecEpochDuration) / 2 + 1,
|
|
594
|
+
);
|
|
595
|
+
const lifetimeInRounds = BigInt(args.slashingLifetimeInRounds);
|
|
596
|
+
const executionDelayInRounds = BigInt(args.slashingExecutionDelayInRounds);
|
|
597
|
+
|
|
598
|
+
if (args.slasherFlavor === 'tally') {
|
|
599
|
+
const slashAmounts: readonly [bigint, bigint, bigint] = [
|
|
600
|
+
args.slashAmountSmall,
|
|
601
|
+
args.slashAmountMedium,
|
|
602
|
+
args.slashAmountLarge,
|
|
603
|
+
];
|
|
604
|
+
const committeeSize = BigInt(args.aztecTargetCommitteeSize);
|
|
605
|
+
const epochDuration = BigInt(args.aztecEpochDuration);
|
|
606
|
+
const slashOffsetInRounds = BigInt(args.slashingOffsetInRounds);
|
|
607
|
+
|
|
608
|
+
const proposerCtor = encodeAbiParameters(
|
|
609
|
+
[
|
|
610
|
+
{ type: 'address' },
|
|
611
|
+
{ type: 'address' },
|
|
612
|
+
{ type: 'uint256' },
|
|
613
|
+
{ type: 'uint256' },
|
|
614
|
+
{ type: 'uint256' },
|
|
615
|
+
{ type: 'uint256' },
|
|
616
|
+
{ type: 'uint256[3]' },
|
|
617
|
+
{ type: 'uint256' },
|
|
618
|
+
{ type: 'uint256' },
|
|
619
|
+
{ type: 'uint256' },
|
|
620
|
+
],
|
|
621
|
+
[
|
|
622
|
+
rollup.address,
|
|
623
|
+
slasherAddr.toString(),
|
|
624
|
+
computedQuorum,
|
|
625
|
+
computedRoundSize,
|
|
626
|
+
lifetimeInRounds,
|
|
627
|
+
executionDelayInRounds,
|
|
628
|
+
slashAmounts,
|
|
629
|
+
committeeSize,
|
|
630
|
+
epochDuration,
|
|
631
|
+
slashOffsetInRounds,
|
|
632
|
+
],
|
|
633
|
+
);
|
|
634
|
+
|
|
635
|
+
deployer.verificationRecords.push({
|
|
636
|
+
name: 'TallySlashingProposer',
|
|
637
|
+
address: proposerAddr,
|
|
638
|
+
constructorArgsHex: proposerCtor,
|
|
639
|
+
libraries: [],
|
|
640
|
+
});
|
|
641
|
+
} else if (args.slasherFlavor === 'empire') {
|
|
642
|
+
const proposerCtor = encodeAbiParameters(
|
|
643
|
+
[
|
|
644
|
+
{ type: 'address' },
|
|
645
|
+
{ type: 'address' },
|
|
646
|
+
{ type: 'uint256' },
|
|
647
|
+
{ type: 'uint256' },
|
|
648
|
+
{ type: 'uint256' },
|
|
649
|
+
{ type: 'uint256' },
|
|
650
|
+
],
|
|
651
|
+
[
|
|
652
|
+
rollup.address,
|
|
653
|
+
slasherAddr.toString(),
|
|
654
|
+
computedQuorum,
|
|
655
|
+
computedRoundSize,
|
|
656
|
+
lifetimeInRounds,
|
|
657
|
+
executionDelayInRounds,
|
|
658
|
+
],
|
|
659
|
+
);
|
|
660
|
+
|
|
661
|
+
deployer.verificationRecords.push({
|
|
662
|
+
name: 'EmpireSlashingProposer',
|
|
663
|
+
address: proposerAddr,
|
|
664
|
+
constructorArgsHex: proposerCtor,
|
|
665
|
+
libraries: [],
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
} catch (e) {
|
|
670
|
+
logger.warn(`Failed to add Slasher/Proposer verification records: ${String(e)}`);
|
|
671
|
+
}
|
|
672
|
+
} catch (e) {
|
|
673
|
+
throw new Error(`Failed to generate rollup verification records: ${String(e)}`);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Writes verification records to a JSON file for later forge verify.
|
|
679
|
+
* @param deployer - The L1 deployer containing verification records.
|
|
680
|
+
* @param outputDirectory - The directory to write the verification file to.
|
|
681
|
+
* @param chainId - The chain ID.
|
|
682
|
+
* @param filenameSuffix - Optional suffix for the filename (e.g., 'upgrade').
|
|
683
|
+
* @param logger - The logger.
|
|
684
|
+
*/
|
|
685
|
+
async function writeVerificationJson(
|
|
686
|
+
deployer: L1Deployer,
|
|
687
|
+
outputDirectory: string,
|
|
688
|
+
chainId: number,
|
|
689
|
+
filenameSuffix: string = '',
|
|
690
|
+
logger: Logger,
|
|
691
|
+
): Promise<void> {
|
|
692
|
+
try {
|
|
693
|
+
const date = new Date();
|
|
694
|
+
const formattedDate = date.toISOString().slice(2, 19).replace(/[-T:]/g, '');
|
|
695
|
+
// Ensure the verification output directory exists
|
|
696
|
+
await mkdir(outputDirectory, { recursive: true });
|
|
697
|
+
const suffix = filenameSuffix ? `-${filenameSuffix}` : '';
|
|
698
|
+
const verificationOutputPath = `${outputDirectory}/l1-verify${suffix}-${chainId}-${formattedDate.slice(0, 6)}-${formattedDate.slice(6)}.json`;
|
|
699
|
+
const networkName = getActiveNetworkName();
|
|
700
|
+
const verificationData = {
|
|
701
|
+
chainId: chainId,
|
|
702
|
+
network: networkName,
|
|
703
|
+
records: deployer.verificationRecords,
|
|
704
|
+
};
|
|
705
|
+
await writeFile(verificationOutputPath, JSON.stringify(verificationData, null, 2));
|
|
706
|
+
logger.info(`Wrote L1 verification data to ${verificationOutputPath}`);
|
|
707
|
+
} catch (e) {
|
|
708
|
+
logger.warn(`Failed to write L1 verification data file: ${String(e)}`);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
517
712
|
/**
|
|
518
713
|
* Deploys a new rollup, using the existing canonical version to derive certain values (addresses of assets etc).
|
|
519
714
|
* @param clients - The L1 clients.
|
|
@@ -521,6 +716,7 @@ const getZkPassportScopes = (args: DeployL1ContractsArgs): [string, string] => {
|
|
|
521
716
|
* @param registryAddress - The address of the registry.
|
|
522
717
|
* @param logger - The logger.
|
|
523
718
|
* @param txUtilsConfig - The L1 tx utils config.
|
|
719
|
+
* @param createVerificationJson - Optional path to write verification data for forge verify.
|
|
524
720
|
*/
|
|
525
721
|
export const deployRollupForUpgrade = async (
|
|
526
722
|
extendedClient: ExtendedViemWalletClient,
|
|
@@ -531,6 +727,7 @@ export const deployRollupForUpgrade = async (
|
|
|
531
727
|
registryAddress: EthAddress,
|
|
532
728
|
logger: Logger,
|
|
533
729
|
txUtilsConfig: L1TxUtilsConfig,
|
|
730
|
+
createVerificationJson: string | false = false,
|
|
534
731
|
) => {
|
|
535
732
|
const deployer = new L1Deployer(
|
|
536
733
|
extendedClient,
|
|
@@ -539,6 +736,7 @@ export const deployRollupForUpgrade = async (
|
|
|
539
736
|
args.acceleratedTestDeployments,
|
|
540
737
|
logger,
|
|
541
738
|
txUtilsConfig,
|
|
739
|
+
!!createVerificationJson,
|
|
542
740
|
);
|
|
543
741
|
|
|
544
742
|
const addresses = await RegistryContract.collectAddresses(extendedClient, registryAddress, 'canonical');
|
|
@@ -547,6 +745,12 @@ export const deployRollupForUpgrade = async (
|
|
|
547
745
|
|
|
548
746
|
await deployer.waitForDeployments();
|
|
549
747
|
|
|
748
|
+
// Write verification data (constructor args + linked libraries) to file for later forge verify
|
|
749
|
+
if (createVerificationJson) {
|
|
750
|
+
await generateRollupVerificationRecords(rollup, deployer, args, addresses, extendedClient, logger);
|
|
751
|
+
await writeVerificationJson(deployer, createVerificationJson, extendedClient.chain.id, 'upgrade', logger);
|
|
752
|
+
}
|
|
753
|
+
|
|
550
754
|
return { rollup, slashFactoryAddress };
|
|
551
755
|
};
|
|
552
756
|
|
|
@@ -653,11 +857,12 @@ export const deployRollup = async (
|
|
|
653
857
|
slashAmounts: [args.slashAmountSmall, args.slashAmountMedium, args.slashAmountLarge],
|
|
654
858
|
localEjectionThreshold: args.localEjectionThreshold,
|
|
655
859
|
slashingDisableDuration: BigInt(args.slashingDisableDuration ?? 0n),
|
|
860
|
+
earliestRewardsClaimableTimestamp: 0n,
|
|
656
861
|
};
|
|
657
862
|
|
|
658
863
|
const genesisStateArgs = {
|
|
659
864
|
vkTreeRoot: args.vkTreeRoot.toString(),
|
|
660
|
-
|
|
865
|
+
protocolContractsHash: args.protocolContractsHash.toString(),
|
|
661
866
|
genesisArchiveRoot: args.genesisArchiveRoot.toString(),
|
|
662
867
|
};
|
|
663
868
|
|
|
@@ -1057,7 +1262,7 @@ export const addMultipleValidators = async (
|
|
|
1057
1262
|
data: encodeFunctionData({
|
|
1058
1263
|
abi: MultiAdderArtifact.contractAbi,
|
|
1059
1264
|
functionName: 'addValidators',
|
|
1060
|
-
args: [c, BigInt(
|
|
1265
|
+
args: [c, BigInt(0)],
|
|
1061
1266
|
}),
|
|
1062
1267
|
},
|
|
1063
1268
|
{
|
|
@@ -1277,144 +1482,8 @@ export const deployL1Contracts = async (
|
|
|
1277
1482
|
|
|
1278
1483
|
// Write verification data (constructor args + linked libraries) to file for later forge verify
|
|
1279
1484
|
if (createVerificationJson) {
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
const rollupAddr = l1Contracts.rollupAddress.toString();
|
|
1283
|
-
const inboxAddr = l1Contracts.inboxAddress.toString();
|
|
1284
|
-
const outboxAddr = l1Contracts.outboxAddress.toString();
|
|
1285
|
-
const feeAsset = l1Contracts.feeJuiceAddress.toString();
|
|
1286
|
-
const version = await rollup.getVersion();
|
|
1287
|
-
|
|
1288
|
-
const inboxCtor = encodeAbiParameters(
|
|
1289
|
-
[{ type: 'address' }, { type: 'address' }, { type: 'uint256' }, { type: 'uint256' }],
|
|
1290
|
-
[rollupAddr, feeAsset, version, BigInt(L1_TO_L2_MSG_SUBTREE_HEIGHT)],
|
|
1291
|
-
);
|
|
1292
|
-
|
|
1293
|
-
const outboxCtor = encodeAbiParameters([{ type: 'address' }, { type: 'uint256' }], [rollupAddr, version]);
|
|
1294
|
-
|
|
1295
|
-
deployer.verificationRecords.push(
|
|
1296
|
-
{ name: 'Inbox', address: inboxAddr, constructorArgsHex: inboxCtor, libraries: [] },
|
|
1297
|
-
{ name: 'Outbox', address: outboxAddr, constructorArgsHex: outboxCtor, libraries: [] },
|
|
1298
|
-
);
|
|
1299
|
-
|
|
1300
|
-
// Include Slasher and SlashingProposer (if deployed) in verification data
|
|
1301
|
-
try {
|
|
1302
|
-
const slasherAddrHex = await rollup.getSlasherAddress();
|
|
1303
|
-
const slasherAddr = EthAddress.fromString(slasherAddrHex);
|
|
1304
|
-
if (!slasherAddr.isZero()) {
|
|
1305
|
-
// Slasher constructor: (address _vetoer, address _governance)
|
|
1306
|
-
const slasherCtor = encodeAbiParameters(
|
|
1307
|
-
[{ type: 'address' }, { type: 'address' }],
|
|
1308
|
-
[args.slashingVetoer.toString(), l1Client.account.address],
|
|
1309
|
-
);
|
|
1310
|
-
deployer.verificationRecords.push({
|
|
1311
|
-
name: 'Slasher',
|
|
1312
|
-
address: slasherAddr.toString(),
|
|
1313
|
-
constructorArgsHex: slasherCtor,
|
|
1314
|
-
libraries: [],
|
|
1315
|
-
});
|
|
1316
|
-
|
|
1317
|
-
// Proposer address is stored in Slasher.PROPOSER()
|
|
1318
|
-
const proposerAddr = (await rollup.getSlashingProposerAddress()).toString();
|
|
1319
|
-
|
|
1320
|
-
// Compute constructor args matching deployment path in RollupCore
|
|
1321
|
-
const computedRoundSize = BigInt(args.slashingRoundSizeInEpochs * args.aztecEpochDuration);
|
|
1322
|
-
const computedQuorum = BigInt(
|
|
1323
|
-
args.slashingQuorum ?? (args.slashingRoundSizeInEpochs * args.aztecEpochDuration) / 2 + 1,
|
|
1324
|
-
);
|
|
1325
|
-
const lifetimeInRounds = BigInt(args.slashingLifetimeInRounds);
|
|
1326
|
-
const executionDelayInRounds = BigInt(args.slashingExecutionDelayInRounds);
|
|
1327
|
-
|
|
1328
|
-
if (args.slasherFlavor === 'tally') {
|
|
1329
|
-
const slashAmounts: readonly [bigint, bigint, bigint] = [
|
|
1330
|
-
args.slashAmountSmall,
|
|
1331
|
-
args.slashAmountMedium,
|
|
1332
|
-
args.slashAmountLarge,
|
|
1333
|
-
];
|
|
1334
|
-
const committeeSize = BigInt(args.aztecTargetCommitteeSize);
|
|
1335
|
-
const epochDuration = BigInt(args.aztecEpochDuration);
|
|
1336
|
-
const slashOffsetInRounds = BigInt(args.slashingOffsetInRounds);
|
|
1337
|
-
|
|
1338
|
-
const proposerCtor = encodeAbiParameters(
|
|
1339
|
-
[
|
|
1340
|
-
{ type: 'address' },
|
|
1341
|
-
{ type: 'address' },
|
|
1342
|
-
{ type: 'uint256' },
|
|
1343
|
-
{ type: 'uint256' },
|
|
1344
|
-
{ type: 'uint256' },
|
|
1345
|
-
{ type: 'uint256' },
|
|
1346
|
-
{ type: 'uint256[3]' },
|
|
1347
|
-
{ type: 'uint256' },
|
|
1348
|
-
{ type: 'uint256' },
|
|
1349
|
-
{ type: 'uint256' },
|
|
1350
|
-
],
|
|
1351
|
-
[
|
|
1352
|
-
rollup.address,
|
|
1353
|
-
slasherAddr.toString(),
|
|
1354
|
-
computedQuorum,
|
|
1355
|
-
computedRoundSize,
|
|
1356
|
-
lifetimeInRounds,
|
|
1357
|
-
executionDelayInRounds,
|
|
1358
|
-
slashAmounts,
|
|
1359
|
-
committeeSize,
|
|
1360
|
-
epochDuration,
|
|
1361
|
-
slashOffsetInRounds,
|
|
1362
|
-
],
|
|
1363
|
-
);
|
|
1364
|
-
|
|
1365
|
-
deployer.verificationRecords.push({
|
|
1366
|
-
name: 'TallySlashingProposer',
|
|
1367
|
-
address: proposerAddr,
|
|
1368
|
-
constructorArgsHex: proposerCtor,
|
|
1369
|
-
libraries: [],
|
|
1370
|
-
});
|
|
1371
|
-
} else if (args.slasherFlavor === 'empire') {
|
|
1372
|
-
const proposerCtor = encodeAbiParameters(
|
|
1373
|
-
[
|
|
1374
|
-
{ type: 'address' },
|
|
1375
|
-
{ type: 'address' },
|
|
1376
|
-
{ type: 'uint256' },
|
|
1377
|
-
{ type: 'uint256' },
|
|
1378
|
-
{ type: 'uint256' },
|
|
1379
|
-
{ type: 'uint256' },
|
|
1380
|
-
],
|
|
1381
|
-
[
|
|
1382
|
-
rollup.address,
|
|
1383
|
-
slasherAddr.toString(),
|
|
1384
|
-
computedQuorum,
|
|
1385
|
-
computedRoundSize,
|
|
1386
|
-
lifetimeInRounds,
|
|
1387
|
-
executionDelayInRounds,
|
|
1388
|
-
],
|
|
1389
|
-
);
|
|
1390
|
-
|
|
1391
|
-
deployer.verificationRecords.push({
|
|
1392
|
-
name: 'EmpireSlashingProposer',
|
|
1393
|
-
address: proposerAddr,
|
|
1394
|
-
constructorArgsHex: proposerCtor,
|
|
1395
|
-
libraries: [],
|
|
1396
|
-
});
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
} catch (e) {
|
|
1400
|
-
logger.warn(`Failed to add Slasher/Proposer verification records: ${String(e)}`);
|
|
1401
|
-
}
|
|
1402
|
-
const date = new Date();
|
|
1403
|
-
const formattedDate = date.toISOString().slice(2, 19).replace(/[-T:]/g, '');
|
|
1404
|
-
// Ensure the verification output directory exists
|
|
1405
|
-
await mkdir(createVerificationJson, { recursive: true });
|
|
1406
|
-
const verificationOutputPath = `${createVerificationJson}/l1-verify-${chain.id}-${formattedDate.slice(0, 6)}-${formattedDate.slice(6)}.json`;
|
|
1407
|
-
const networkName = getActiveNetworkName();
|
|
1408
|
-
const verificationData = {
|
|
1409
|
-
chainId: chain.id,
|
|
1410
|
-
network: networkName,
|
|
1411
|
-
records: deployer.verificationRecords,
|
|
1412
|
-
};
|
|
1413
|
-
await writeFile(verificationOutputPath, JSON.stringify(verificationData, null, 2));
|
|
1414
|
-
logger.info(`Wrote L1 verification data to ${verificationOutputPath}`);
|
|
1415
|
-
} catch (e) {
|
|
1416
|
-
logger.warn(`Failed to write L1 verification data file: ${String(e)}`);
|
|
1417
|
-
}
|
|
1485
|
+
await generateRollupVerificationRecords(rollup, deployer, args, l1Contracts, l1Client, logger);
|
|
1486
|
+
await writeVerificationJson(deployer, createVerificationJson, chain.id, '', logger);
|
|
1418
1487
|
}
|
|
1419
1488
|
|
|
1420
1489
|
if (isAnvilTestChain(chain.id)) {
|
|
@@ -1564,7 +1633,6 @@ export class L1Deployer {
|
|
|
1564
1633
|
}
|
|
1565
1634
|
}
|
|
1566
1635
|
|
|
1567
|
-
// docs:start:deployL1Contract
|
|
1568
1636
|
/**
|
|
1569
1637
|
* Helper function to deploy ETH contracts.
|
|
1570
1638
|
* @param walletClient - A viem WalletClient.
|
|
@@ -1708,10 +1776,10 @@ export async function deployL1Contract(
|
|
|
1708
1776
|
const existing = await extendedClient.getCode({ address: resultingAddress });
|
|
1709
1777
|
if (existing === undefined || existing === '0x') {
|
|
1710
1778
|
try {
|
|
1711
|
-
await l1TxUtils.simulate({ to: DEPLOYER_ADDRESS, data: concatHex([salt, calldata])
|
|
1779
|
+
await l1TxUtils.simulate({ to: DEPLOYER_ADDRESS, data: concatHex([salt, calldata]), gas: gasLimit });
|
|
1712
1780
|
} catch (err) {
|
|
1713
1781
|
logger?.error(`Failed to simulate deployment tx using universal deployer`, err);
|
|
1714
|
-
await l1TxUtils.simulate({ to: null, data: encodeDeployData({ abi, bytecode, args }) });
|
|
1782
|
+
await l1TxUtils.simulate({ to: null, data: encodeDeployData({ abi, bytecode, args }), gas: gasLimit });
|
|
1715
1783
|
}
|
|
1716
1784
|
const res = await l1TxUtils.sendTransaction(
|
|
1717
1785
|
{ to: DEPLOYER_ADDRESS, data: concatHex([salt, calldata]) },
|
|
@@ -1726,10 +1794,13 @@ export async function deployL1Contract(
|
|
|
1726
1794
|
}
|
|
1727
1795
|
} else {
|
|
1728
1796
|
const deployData = encodeDeployData({ abi, bytecode, args });
|
|
1729
|
-
const { receipt } = await l1TxUtils.sendAndMonitorTransaction(
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1797
|
+
const { receipt } = await l1TxUtils.sendAndMonitorTransaction(
|
|
1798
|
+
{
|
|
1799
|
+
to: null,
|
|
1800
|
+
data: deployData,
|
|
1801
|
+
},
|
|
1802
|
+
{ gasLimit },
|
|
1803
|
+
);
|
|
1733
1804
|
|
|
1734
1805
|
txHash = receipt.transactionHash;
|
|
1735
1806
|
resultingAddress = receipt.contractAddress;
|
|
@@ -1765,5 +1836,3 @@ export function getExpectedAddress(
|
|
|
1765
1836
|
calldata,
|
|
1766
1837
|
};
|
|
1767
1838
|
}
|
|
1768
|
-
|
|
1769
|
-
// docs:end:deployL1Contract
|
package/src/l1_artifacts.ts
CHANGED
|
@@ -33,10 +33,10 @@ import {
|
|
|
33
33
|
RegisterNewRollupVersionPayloadBytecode,
|
|
34
34
|
RegistryAbi,
|
|
35
35
|
RegistryBytecode,
|
|
36
|
-
RewardDeploymentExtLibAbi,
|
|
37
|
-
RewardDeploymentExtLibBytecode,
|
|
38
36
|
RewardDistributorAbi,
|
|
39
37
|
RewardDistributorBytecode,
|
|
38
|
+
RewardExtLibAbi,
|
|
39
|
+
RewardExtLibBytecode,
|
|
40
40
|
RollupAbi,
|
|
41
41
|
RollupBytecode,
|
|
42
42
|
RollupLinkReferences,
|
|
@@ -102,10 +102,10 @@ export const RollupArtifact = {
|
|
|
102
102
|
contractAbi: ValidatorOperationsExtLibAbi,
|
|
103
103
|
contractBytecode: ValidatorOperationsExtLibBytecode as Hex,
|
|
104
104
|
},
|
|
105
|
-
|
|
106
|
-
name: '
|
|
107
|
-
contractAbi:
|
|
108
|
-
contractBytecode:
|
|
105
|
+
RewardExtLib: {
|
|
106
|
+
name: 'RewardExtLib',
|
|
107
|
+
contractAbi: RewardExtLibAbi,
|
|
108
|
+
contractBytecode: RewardExtLibBytecode as Hex,
|
|
109
109
|
},
|
|
110
110
|
TallySlasherDeploymentExtLib: {
|
|
111
111
|
name: 'TallySlasherDeploymentExtLib',
|
package/src/l1_reader.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { type L1ContractAddresses, l1ContractAddressesMapping } from './l1_contr
|
|
|
4
4
|
|
|
5
5
|
/** Configuration of the L1GlobalReader. */
|
|
6
6
|
export interface L1ReaderConfig {
|
|
7
|
-
/**
|
|
7
|
+
/** List of URLs of Ethereum RPC nodes that services will connect to (comma separated). */
|
|
8
8
|
l1RpcUrls: string[];
|
|
9
9
|
/** The chain ID of the ethereum host. */
|
|
10
10
|
l1ChainId: number;
|
|
@@ -26,7 +26,7 @@ export const l1ReaderConfigMappings: ConfigMappingsType<L1ReaderConfig> = {
|
|
|
26
26
|
},
|
|
27
27
|
l1RpcUrls: {
|
|
28
28
|
env: 'ETHEREUM_HOSTS',
|
|
29
|
-
description: '
|
|
29
|
+
description: 'List of URLs of Ethereum RPC nodes that services will connect to (comma separated).',
|
|
30
30
|
parseEnv: (val: string) => val.split(',').map(url => url.trim()),
|
|
31
31
|
defaultValue: [],
|
|
32
32
|
},
|
|
@@ -4,7 +4,7 @@ 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
|
-
import type { TestDateProvider } from '@aztec/foundation/timer';
|
|
7
|
+
import type { DateProvider, TestDateProvider } from '@aztec/foundation/timer';
|
|
8
8
|
|
|
9
9
|
import { type Hex, type Transaction, createPublicClient, fallback, hexToNumber, http } from 'viem';
|
|
10
10
|
|
|
@@ -20,6 +20,10 @@ export class EthCheatCodes {
|
|
|
20
20
|
* The RPC URL to use for interacting with the chain
|
|
21
21
|
*/
|
|
22
22
|
public rpcUrls: string[],
|
|
23
|
+
/**
|
|
24
|
+
* The date provider to use for time operations
|
|
25
|
+
*/
|
|
26
|
+
public dateProvider: DateProvider | TestDateProvider,
|
|
23
27
|
/**
|
|
24
28
|
* The logger to use for the eth cheatcodes
|
|
25
29
|
*/
|
|
@@ -230,12 +234,12 @@ export class EthCheatCodes {
|
|
|
230
234
|
/**
|
|
231
235
|
* Set the next block timestamp and mines the block.
|
|
232
236
|
* Optionally resets interval mining so the next block is mined in `blockInterval` seconds from now.
|
|
233
|
-
*
|
|
237
|
+
* Always updates the injected date provider to follow L1 time.
|
|
234
238
|
* @param timestamp - The timestamp to set the next block to
|
|
235
239
|
*/
|
|
236
240
|
public async warp(
|
|
237
241
|
timestamp: number | bigint,
|
|
238
|
-
opts: { silent?: boolean; resetBlockInterval?: boolean
|
|
242
|
+
opts: { silent?: boolean; resetBlockInterval?: boolean } = {},
|
|
239
243
|
): Promise<void> {
|
|
240
244
|
let blockInterval: number | null = null;
|
|
241
245
|
try {
|
|
@@ -250,8 +254,10 @@ export class EthCheatCodes {
|
|
|
250
254
|
await this.rpcCall('evm_setNextBlockTimestamp', [Number(timestamp)]);
|
|
251
255
|
// And mine a block so the timestamp goes into effect now
|
|
252
256
|
await this.doMine();
|
|
253
|
-
// Update the date provider
|
|
254
|
-
|
|
257
|
+
// Update the injected date provider so it follows L1 time
|
|
258
|
+
if ('setTime' in this.dateProvider) {
|
|
259
|
+
this.dateProvider.setTime(Number(timestamp) * 1000);
|
|
260
|
+
}
|
|
255
261
|
} catch (err) {
|
|
256
262
|
throw new Error(`Error warping: ${err}`);
|
|
257
263
|
} finally {
|
|
@@ -282,14 +288,21 @@ export class EthCheatCodes {
|
|
|
282
288
|
* @param slot - The storage slot
|
|
283
289
|
* @param value - The value to set the storage slot to
|
|
284
290
|
*/
|
|
285
|
-
public async store(
|
|
291
|
+
public async store(
|
|
292
|
+
contract: EthAddress,
|
|
293
|
+
slot: bigint,
|
|
294
|
+
value: bigint,
|
|
295
|
+
opts: { silent?: boolean } = {},
|
|
296
|
+
): Promise<void> {
|
|
286
297
|
// for the rpc call, we need to change value to be a 32 byte hex string.
|
|
287
298
|
try {
|
|
288
299
|
await this.rpcCall('hardhat_setStorageAt', [contract.toString(), toHex(slot), toHex(value, true)]);
|
|
289
300
|
} catch (err) {
|
|
290
301
|
throw new Error(`Error setting storage for contract ${contract} at ${slot}: ${err}`);
|
|
291
302
|
}
|
|
292
|
-
|
|
303
|
+
if (!opts.silent) {
|
|
304
|
+
this.logger.warn(`Set L1 storage for contract ${contract} at ${slot} to ${value}`);
|
|
305
|
+
}
|
|
293
306
|
}
|
|
294
307
|
|
|
295
308
|
/**
|
|
@@ -499,7 +512,7 @@ export class EthCheatCodes {
|
|
|
499
512
|
this.logger.warn(`Mined ${blockCount} empty L1 ${pluralize('block', blockCount)}`);
|
|
500
513
|
}
|
|
501
514
|
|
|
502
|
-
public async execWithPausedAnvil(fn: () => Promise<
|
|
515
|
+
public async execWithPausedAnvil<T>(fn: () => Promise<T>): Promise<T> {
|
|
503
516
|
const [blockInterval, wasAutoMining] = await Promise.all([this.getIntervalMining(), this.isAutoMining()]);
|
|
504
517
|
try {
|
|
505
518
|
if (blockInterval !== null) {
|
|
@@ -510,7 +523,7 @@ export class EthCheatCodes {
|
|
|
510
523
|
await this.setAutomine(false, { silent: true });
|
|
511
524
|
}
|
|
512
525
|
|
|
513
|
-
await fn();
|
|
526
|
+
return await fn();
|
|
514
527
|
} finally {
|
|
515
528
|
try {
|
|
516
529
|
// restore automine if necessary
|
|
@@ -532,10 +545,10 @@ export class EthCheatCodes {
|
|
|
532
545
|
}
|
|
533
546
|
}
|
|
534
547
|
|
|
535
|
-
public async syncDateProvider(
|
|
548
|
+
public async syncDateProvider() {
|
|
536
549
|
const timestamp = await this.timestamp();
|
|
537
|
-
if ('setTime' in dateProvider) {
|
|
538
|
-
dateProvider.setTime(timestamp * 1000);
|
|
550
|
+
if ('setTime' in this.dateProvider) {
|
|
551
|
+
this.dateProvider.setTime(timestamp * 1000);
|
|
539
552
|
}
|
|
540
553
|
}
|
|
541
554
|
}
|