Skip to content

Commit 58e7243

Browse files
committed
feat: add migration script
1 parent 95aa2a7 commit 58e7243

File tree

6 files changed

+126
-20
lines changed

6 files changed

+126
-20
lines changed

l1-contracts/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,5 @@ gas_benchmark.diff
3636
/bench-out
3737

3838
/coverage
39+
40+
/script/registration_data.json

l1-contracts/foundry.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ fs_permissions = [
5555
{access = "read", path = "./test/staking_asset_handler/zkpassport/fixtures/valid_public_inputs.json"},
5656
{access = "read", path = "./test/fixtures/boosted_rewards/shares.json"},
5757
{access = "read", path = "./test/fixtures/boosted_rewards/activity_scores.json"},
58+
{access = "read", path = "./script/registration_data.json"},
5859
]
5960

6061
no_match_contract="(ScreamAndShoutTest|UniswapPortalTest|MerkleCheck)"
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// Copyright 2024 Aztec Labs.
3+
pragma solidity >=0.8.27;
4+
5+
import {Test} from "forge-std/Test.sol";
6+
7+
import {IInstance} from "@aztec/core/interfaces/IInstance.sol";
8+
import {MultiAdder, CheatDepositArgs} from "@aztec/mock/MultiAdder.sol";
9+
import {G1Point, G2Point} from "@aztec/shared/libraries/BN254Lib.sol";
10+
import {RollupBuilder} from "@test/builder/RollupBuilder.sol";
11+
import {TestERC20} from "@aztec/mock/TestERC20.sol";
12+
13+
struct RegistrationData {
14+
address attester;
15+
G1Point publicKeyInG1;
16+
G2Point publicKeyInG2;
17+
G1Point proofOfPossession;
18+
}
19+
20+
contract MigrationScript is Test {
21+
address internal constant ME = address(0xf8d7d601759CBcfB78044bA7cA9B0c0D6301A54f);
22+
23+
address public constant WITHDRAWER = address(0xdead);
24+
25+
// Update ME!
26+
IInstance public INSTANCE;
27+
TestERC20 public STAKING_ASSET;
28+
// No more!
29+
30+
MultiAdder public ADDER;
31+
32+
RegistrationData[] public $registrations;
33+
34+
function setUp() public {
35+
string memory root = vm.projectRoot();
36+
string memory path = string.concat(root, "/script/registration_data.json");
37+
string memory json = vm.readFile(path);
38+
bytes memory jsonBytes = vm.parseJson(json);
39+
RegistrationData[] memory registrations = abi.decode(jsonBytes, (RegistrationData[]));
40+
41+
for (uint256 i = 0; i < registrations.length; i++) {
42+
$registrations.push(registrations[i]);
43+
}
44+
}
45+
46+
function emulate() public {
47+
// If emulating we will deploy a rollup and other components ahead of time, otherwise
48+
// you should provide them by updating the values above.
49+
RollupBuilder builder = new RollupBuilder(ME).setUpdateOwnerships(false).deploy();
50+
51+
INSTANCE = IInstance(address(builder.getConfig().rollup));
52+
STAKING_ASSET = builder.getConfig().testERC20;
53+
54+
vm.prank(STAKING_ASSET.owner());
55+
STAKING_ASSET.addMinter(ME);
56+
57+
migrate();
58+
}
59+
60+
function migrate() public {
61+
uint256 activationThreshold = INSTANCE.getActivationThreshold();
62+
63+
vm.startBroadcast(ME);
64+
ADDER = new MultiAdder(address(INSTANCE), ME);
65+
STAKING_ASSET.mint(address(ADDER), activationThreshold * $registrations.length);
66+
vm.stopBroadcast();
67+
68+
uint256 start = 0;
69+
uint256 end = $registrations.length;
70+
uint256 batchSize = 10;
71+
72+
while (start < end) {
73+
uint256 batchEnd = start + batchSize;
74+
if (batchEnd > end) {
75+
batchEnd = end;
76+
}
77+
78+
CheatDepositArgs[] memory args = new CheatDepositArgs[](batchEnd - start);
79+
80+
for (uint256 i = start; i < batchEnd; i++) {
81+
emit log_named_address("Adding validator", $registrations[i].attester);
82+
args[i - start] = CheatDepositArgs(
83+
$registrations[i].attester,
84+
WITHDRAWER,
85+
$registrations[i].publicKeyInG1,
86+
$registrations[i].publicKeyInG2,
87+
$registrations[i].proofOfPossession
88+
);
89+
}
90+
91+
vm.startBroadcast(ME);
92+
ADDER.addValidators(args);
93+
vm.stopBroadcast();
94+
95+
start = batchEnd;
96+
}
97+
}
98+
}

l1-contracts/src/mock/MultiAdder.sol

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Copyright 2024 Aztec Labs.
33
pragma solidity >=0.8.27;
44

5-
import {IStaking} from "@aztec/core/interfaces/IStaking.sol";
5+
import {IInstance} from "@aztec/core/interfaces/IInstance.sol";
66
import {G1Point, G2Point} from "@aztec/shared/libraries/BN254Lib.sol";
77
import {IERC20} from "@oz/token/ERC20/IERC20.sol";
88

@@ -20,13 +20,13 @@ interface IMultiAdder {
2020

2121
contract MultiAdder is IMultiAdder {
2222
address public immutable OWNER;
23-
IStaking public immutable STAKING;
23+
IInstance public immutable STAKING;
2424

2525
error NotOwner();
2626

2727
constructor(address _staking, address _owner) {
2828
OWNER = _owner;
29-
STAKING = IStaking(_staking);
29+
STAKING = IInstance(_staking);
3030

3131
IERC20 stakingAsset = STAKING.getStakingAsset();
3232
stakingAsset.approve(address(STAKING), type(uint256).max);
@@ -44,6 +44,9 @@ contract MultiAdder is IMultiAdder {
4444
true
4545
);
4646
}
47-
STAKING.flushEntryQueue();
47+
48+
if (STAKING.getCurrentEpoch() >= STAKING.getNextFlushableEpoch()) {
49+
STAKING.flushEntryQueue();
50+
}
4851
}
4952
}

yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const TXS_PER_BLOCK = 1;
2525
const ROUND_SIZE = 2;
2626
const QUORUM_SIZE = 2;
2727
// Can't use 48 without chunking the addValidators call.
28-
const COMMITTEE_SIZE = 36;
28+
const COMMITTEE_SIZE = 16;
2929

3030
describe('e2e_gov_proposal', () => {
3131
let logger: Logger;

yarn-project/ethereum/src/deploy_l1_contracts.ts

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -795,31 +795,33 @@ export const addMultipleValidators = async (
795795

796796
// Mint tokens, approve them, use cheat code to initialize validator set without setting up the epoch.
797797
const stakeNeeded = activationThreshold * BigInt(validators.length);
798-
const { txHash } = await deployer.sendTransaction({
798+
799+
await deployer.l1TxUtils.sendAndMonitorTransaction({
799800
to: stakingAssetAddress,
800801
data: encodeFunctionData({
801802
abi: StakingAssetArtifact.contractAbi,
802803
functionName: 'mint',
803804
args: [multiAdder.toString(), stakeNeeded],
804805
}),
805806
});
806-
const receipt = await extendedClient.waitForTransactionReceipt({ hash: txHash });
807807

808-
if (receipt.status !== 'success') {
809-
throw new Error(`Failed to mint staking assets for validators: ${receipt.status}`);
810-
}
808+
const validatorCount = await rollup.getActiveAttesterCount();
811809

812-
const addValidatorsTxHash = await deployer.client.writeContract({
813-
address: multiAdder.toString(),
814-
abi: MultiAdderArtifact.contractAbi,
815-
functionName: 'addValidators',
816-
args: [validatorsTuples],
817-
});
818-
await extendedClient.waitForTransactionReceipt({ hash: addValidatorsTxHash });
819-
logger.info(`Initialized validator set`, {
820-
validators,
821-
txHash: addValidatorsTxHash,
810+
logger.info(`Adding ${validators.length} validators to the rollup`);
811+
812+
await deployer.l1TxUtils.sendAndMonitorTransaction({
813+
to: multiAdder.toString(),
814+
data: encodeFunctionData({
815+
abi: MultiAdderArtifact.contractAbi,
816+
functionName: 'addValidators',
817+
args: [validatorsTuples],
818+
}),
822819
});
820+
821+
const validatorCountAfter = await rollup.getActiveAttesterCount();
822+
if (validatorCountAfter < validatorCount + BigInt(validators.length)) {
823+
throw new Error(`Failed to add ${validators.length} validators. ${validatorCount} -> ${validatorCountAfter} `);
824+
}
823825
}
824826
}
825827
};

0 commit comments

Comments
 (0)