forked from vacp2p/rln-contract
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
336 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
96 changes: 96 additions & 0 deletions
96
deployments/sepolia/solcInputs/1e84cf161e19509fae5fd25de85477de.json
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
import { BigNumber } from "ethers"; | ||
import hre from "hardhat"; | ||
import { Provider } from "@ethersproject/providers"; | ||
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; | ||
import { Contract } from "ethers"; | ||
|
||
async function getRlnV1Registry(provider: Provider) { | ||
const rlnV1Abi = [ | ||
"function storages(uint16 index) public view returns (address)", | ||
]; | ||
|
||
const rlnV1Address = process.env.WAKU_RLNV1_REGISTRY_ADDRESS; | ||
if (!rlnV1Address) { | ||
throw new Error("WAKU_RLNV1_REGISTRY_ADDRESS env variable is not set"); | ||
} | ||
const rlnV1Registry = new hre.ethers.Contract( | ||
rlnV1Address, | ||
rlnV1Abi, | ||
provider | ||
); | ||
return rlnV1Registry; | ||
} | ||
|
||
async function getRlnV1Storage(rlnV1Registry: Contract) { | ||
const storageIndex = process.env.WAKU_RLNV1_STORAGE_INDEX; | ||
if (!storageIndex) { | ||
throw new Error("WAKU_RLNV1_STORAGE_INDEX env variable is not set"); | ||
} | ||
const storageAddress = await rlnV1Registry.storages(storageIndex); | ||
const rlnV1StorageAbi = [ | ||
"event MemberRegistered(uint256 idCommitment, uint256 index)", | ||
"function deployedBlockNumber() public view returns (uint32)", | ||
]; | ||
const rlnV1Storage = new hre.ethers.Contract( | ||
storageAddress, | ||
rlnV1StorageAbi, | ||
rlnV1Registry.provider | ||
); | ||
return rlnV1Storage; | ||
} | ||
|
||
async function getRlnV2Registry(signer: SignerWithAddress) { | ||
const rlnV2Abi = [ | ||
"function register(uint256[] calldata commitments, uint256[] calldata limits) public", | ||
"function usingStorageIndex() public view returns (uint16)", | ||
"function storages(uint16 index) public view returns (address)", | ||
]; | ||
const rlnV2Address = process.env.WAKU_RLNV2_REGISTRY_ADDRESS; | ||
|
||
if (!rlnV2Address) { | ||
throw new Error("WAKU_RLNV2_REGISTRY_ADDRESS env variable is not set"); | ||
} | ||
const rlnV2Registry = new hre.ethers.Contract(rlnV2Address, rlnV2Abi, signer); | ||
return rlnV2Registry; | ||
} | ||
|
||
async function getRlnV2Storage(rlnV2Registry: Contract) { | ||
const storageIndex = await rlnV2Registry.usingStorageIndex(); | ||
const storageAddress = await rlnV2Registry.storages(storageIndex); | ||
const rlnV2StorageAbi = [ | ||
"event MemberRegistered(uint256 idCommitment, uint256 index)", | ||
"function deployedBlockNumber() public view returns (uint32)", | ||
]; | ||
const rlnV2Storage = new hre.ethers.Contract( | ||
storageAddress, | ||
rlnV2StorageAbi, | ||
rlnV2Registry.provider | ||
); | ||
return rlnV2Storage; | ||
} | ||
|
||
async function getRlnV1Commitments(rlnV1Storage: Contract) { | ||
// iteratively loop from deployedBlockNumber to current block | ||
// collect commitments from MemberRegistered events | ||
const deployedBlockNumber = await rlnV1Storage.deployedBlockNumber(); | ||
const currentBlockNumber = await rlnV1Storage.provider.getBlockNumber(); | ||
if (!currentBlockNumber) { | ||
throw new Error("Could not get current block number"); | ||
} | ||
|
||
console.log( | ||
`Fetching commitments from block ${deployedBlockNumber} to ${currentBlockNumber}` | ||
); | ||
|
||
// chunk in batches of 10_000 | ||
const batchSize = 10_000; | ||
// fetch commitments by listening to events on rln-v1 | ||
const commitments: BigNumber[] = []; | ||
for (let i = deployedBlockNumber; i < currentBlockNumber; i += batchSize) { | ||
const normalizedBatch = Math.min(currentBlockNumber, i + batchSize); | ||
console.log(`Fetching commitments from block ${i} to ${normalizedBatch}`); | ||
const events = await rlnV1Storage.queryFilter( | ||
"MemberRegistered", | ||
i, | ||
normalizedBatch | ||
); | ||
for (const event of events) { | ||
commitments.push(event.args?.idCommitment); | ||
} | ||
} | ||
|
||
return commitments; | ||
} | ||
|
||
async function registerRlnV2Commitments( | ||
rlnV2Registry: Contract, | ||
commitments: BigNumber[] | ||
) { | ||
// register commitments on rln-v2, with a default limit of 1, in batches of 20 | ||
const limit = 1; | ||
const batch = 10; | ||
const total = commitments.length; | ||
for (let i = 0; i < total; i += batch) { | ||
const normalizedBatch = Math.min(total, i + batch); | ||
const commitmentsBatch = commitments.slice(i, normalizedBatch); | ||
const limits = Array(commitmentsBatch.length).fill(limit); | ||
console.log( | ||
`Registering commitments ${i} to ${normalizedBatch} of ${total}` | ||
); | ||
const tx = await rlnV2Registry.register(commitmentsBatch, limits); | ||
await tx.wait(); | ||
} | ||
} | ||
|
||
// this script is used to migrate from rln-v1 to rln-v2 | ||
// rln-v1 commitments are poseidon([identitySecret]), | ||
// rln-v2 commitments are poseidon([rlnV1Commitment, userMessageLimit]) | ||
// we set a default userMessageLimit to 1 for all migrating users, | ||
// to preserve the same message rate as in rln-v1 | ||
async function main() { | ||
const [deployer] = await hre.ethers.getSigners(); | ||
|
||
const rlnV1Registry = await getRlnV1Registry(deployer.provider!); | ||
const rlnV2Registry = await getRlnV2Registry(deployer); | ||
const rlnV1Storage = await getRlnV1Storage(rlnV1Registry); | ||
const rlnV2Storage = await getRlnV2Storage(rlnV2Registry); | ||
|
||
console.log( | ||
`Migrating from ${rlnV1Registry.address} registry to ${rlnV2Registry.address} registry` | ||
); | ||
console.log( | ||
`Migrating from ${rlnV1Storage.address} storage to ${rlnV2Storage.address} storage` | ||
); | ||
|
||
const commitments = await getRlnV1Commitments(rlnV1Storage); | ||
|
||
// register commitments on rln-v2, with a default limit of 1, in batches of 20 | ||
await registerRlnV2Commitments(rlnV2Registry, commitments); | ||
console.log(`Migrated ${commitments.length} commitments`); | ||
} | ||
|
||
// We recommend this pattern to be able to use async/await everywhere | ||
// and properly handle errors. | ||
main().catch((error) => { | ||
console.error(error); | ||
process.exitCode = 1; | ||
}); |