Skip to content

Commit

Permalink
remove create2 deployment for groth16 verifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
daveroga committed Oct 31, 2024
1 parent d3ef181 commit c26d2f0
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 258 deletions.
214 changes: 82 additions & 132 deletions helpers/DeployHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,13 @@ import { deployPoseidons } from "./PoseidonDeployHelper";
import { GenesisUtilsWrapper, PrimitiveTypeUtilsWrapper } from "../typechain-types";
import {
SmtLibModule,
Groth16VerifierMTPWrapperModule,
Groth16VerifierSigWrapperModule,
Groth16VerifierV3WrapperModule,
VCPaymentModule,
StateProxyModule,
IdentityTreeStoreProxyModule,
CredentialAtomicQueryMTPV2ValidatorProxyModule,
CredentialAtomicQuerySigV2ValidatorProxyModule,
CredentialAtomicQueryV3ValidatorProxyModule,
UniversalVerifierProxyModule,
Groth16VerifierStateTransitionModule,
} from "../ignition";
import { chainIdInfoMap, contractsInfo } from "./constants";
import {
Expand Down Expand Up @@ -77,31 +73,32 @@ export class DeployHelper {
deployStrategy,
);

const groth16VerifierStateTransition = await this.deployGroth16VerifierStateTransition(
g16VerifierContractName,
const {
state,
stateLib,
stateCrossChainLib,
crossChainProofValidator,
groth16VerifierStateTransition,
defaultIdType,
} = await this.deployState(
supportedIdTypes,
deployStrategy,
await smtLib.getAddress(),
await poseidon1Elements.getAddress(),
g16VerifierContractName,
);

const { state, stateLib, stateCrossChainLib, crossChainProofValidator, defaultIdType } =
await this.deployState(
supportedIdTypes,
deployStrategy,
await smtLib.getAddress(),
await poseidon1Elements.getAddress(),
await groth16VerifierStateTransition.getAddress(),
);

return {
state,
stateLib,
stateCrossChainLib,
crossChainProofValidator,
stateLib: stateLib!,
stateCrossChainLib: stateCrossChainLib!,
crossChainProofValidator: crossChainProofValidator!,
defaultIdType,
smtLib,
poseidon1: poseidon1Elements,
poseidon2: poseidon2Elements,
poseidon3: poseidon3Elements,
groth16verifier: groth16VerifierStateTransition,
groth16verifier: groth16VerifierStateTransition!,
};
}

Expand All @@ -110,12 +107,15 @@ export class DeployHelper {
deployStrategy: "basic" | "create2" = "basic",
smtLibAddress: string,
poseidon1Address: string,
groth16verifierAddress: string,
g16VerifierContractName:
| "Groth16VerifierStateTransition"
| "Groth16VerifierStub" = "Groth16VerifierStateTransition",
): Promise<{
state: Contract;
stateLib: Contract;
stateCrossChainLib: Contract;
crossChainProofValidator: Contract;
stateLib: Contract | null;
stateCrossChainLib: Contract | null;
crossChainProofValidator: Contract | null;
groth16VerifierStateTransition: Contract | null;
defaultIdType;
}> {
this.log("======== State: deploy started ========");
Expand All @@ -129,6 +129,42 @@ export class DeployHelper {

const owner = this.signers[0];

let state;
let create2AlreadyDeployed = false;
if (deployStrategy === "create2") {
state = await getUnifiedContract(contractsInfo.STATE.name);

if (state) {
let version;
try {
version = await state.VERSION();
} catch (e) {
create2AlreadyDeployed = true;
Logger.warning(
`Create2AnchorAddress implementation already deployed to TransparentUpgradeableProxy of ${contractsInfo.STATE.name}.`,
);
}

if (version) {
tmpContractDeployments.remove();
Logger.warning(
`${contractsInfo.STATE.name} found already deployed to: ${await state?.getAddress()}`,
);
return {
state,
stateLib: null,
stateCrossChainLib: null,
crossChainProofValidator: null,
groth16VerifierStateTransition: null,
defaultIdType,
};
}
}
}

const groth16VerifierStateTransition =
await this.deployGroth16VerifierStateTransition(g16VerifierContractName);

let stateLib;
stateLib = await tmpContractDeployments.getContract(contractsInfo.STATE_LIB.name);
if (stateLib) {
Expand Down Expand Up @@ -190,43 +226,13 @@ export class DeployHelper {
contractsInfo.CREATE2_ADDRESS_ANCHOR.name,
);

let state;
let create2AlreadyDeployed = false;
if (deployStrategy === "create2") {
this.log("deploying with CREATE2 strategy...");

// Deploying State contract to predictable address but with dummy implementation
const tx = await crossChainProofValidator.deploymentTransaction();
await waitNotToInterfereWithHardhatIgnition(tx as ContractTransactionResponse);

state = await getUnifiedContract(contractsInfo.STATE.name);

if (state) {
let version;
try {
version = await state.VERSION();
} catch (e) {
create2AlreadyDeployed = true;
Logger.warning(
`Create2AnchorAddress implementation already deployed to TransparentUpgradeableProxy of ${contractsInfo.STATE.name}.`,
);
}

if (version) {
tmpContractDeployments.remove();
Logger.warning(
`${contractsInfo.STATE.name} found already deployed to: ${await state?.getAddress()}`,
);
return {
state,
stateLib,
stateCrossChainLib,
crossChainProofValidator,
defaultIdType,
};
}
}

if (!create2AlreadyDeployed) {
state = (
await ignition.deploy(StateProxyModule, {
Expand All @@ -246,7 +252,7 @@ export class DeployHelper {
call: {
fn: "initialize",
args: [
groth16verifierAddress,
await groth16VerifierStateTransition.getAddress(),
defaultIdType,
await owner.getAddress(),
await crossChainProofValidator.getAddress(),
Expand All @@ -259,7 +265,7 @@ export class DeployHelper {
state = await upgrades.deployProxy(
StateFactory,
[
groth16verifierAddress,
await groth16VerifierStateTransition.getAddress(),
defaultIdType,
await owner.getAddress(),
await crossChainProofValidator.getAddress(),
Expand Down Expand Up @@ -293,6 +299,7 @@ export class DeployHelper {
stateLib,
stateCrossChainLib,
crossChainProofValidator,
groth16VerifierStateTransition,
defaultIdType,
};
}
Expand Down Expand Up @@ -522,37 +529,18 @@ export class DeployHelper {
g16VerifierContractName:
| "Groth16VerifierStateTransition"
| "Groth16VerifierStub" = "Groth16VerifierStateTransition",
deployStrategy: "basic" | "create2" = "basic",
): Promise<Contract> {
const owner = this.signers[0];

let g16Verifier;
if (deployStrategy === "create2") {
this.log("deploying with CREATE2 strategy...");
// Check that contract exists and skip deployment in this case
g16Verifier = await getUnifiedContract(g16VerifierContractName);
if (g16Verifier) {
Logger.warning(
`${g16VerifierContractName} found already deployed to: ${await g16Verifier?.getAddress()}`,
);
return g16Verifier;
}
this.log("deploying Groth16VerifierStateTransition...");

g16Verifier = (
await ignition.deploy(Groth16VerifierStateTransitionModule, {
strategy: deployStrategy,
})
).verifier;
if (
["Groth16VerifierStateTransition", "Groth16VerifierStub"].includes(g16VerifierContractName)
) {
g16Verifier = await ethers.deployContract(g16VerifierContractName);
} else {
this.log("deploying Groth16VerifierStateTransition...");

if (
["Groth16VerifierStateTransition", "Groth16VerifierStub"].includes(g16VerifierContractName)
) {
g16Verifier = await ethers.deployContract(g16VerifierContractName);
} else {
throw new Error("invalid verifierContractName");
}
throw new Error("invalid verifierContractName");
}

await g16Verifier.waitForDeployment();
Expand Down Expand Up @@ -601,15 +589,15 @@ export class DeployHelper {
return verification;
}

getValidatorVerification(verifierType: "mtpV2" | "sigV2" | "v3"): {
getValidatorVerification(validatorType: "mtpV2" | "sigV2" | "v3"): {
contract: string;
constructorArgsImplementation: any[];
constructorArgsProxy?: any[];
constructorArgsProxyAdmin?: any[];
libraries: any;
} {
let verification;
switch (verifierType) {
switch (validatorType) {
case "mtpV2":
verification = contractsInfo.VALIDATOR_MTP.verificationOpts;
break;
Expand All @@ -623,48 +611,11 @@ export class DeployHelper {
return verification;
}

async deployGroth16VerifierWrapper(
verifierType: "mtpV2" | "sigV2" | "v3",
deployStrategy: "basic" | "create2" = "basic",
): Promise<Contract> {
async deployGroth16VerifierWrapper(verifierType: "mtpV2" | "sigV2" | "v3"): Promise<Contract> {
const g16VerifierContractWrapperName = this.getGroth16VerifierWrapperName(verifierType);

let groth16VerifierWrapper;
if (deployStrategy === "create2") {
this.log("deploying with CREATE2 strategy...");

let g16VerifierWrapperModule;
switch (verifierType) {
case "mtpV2":
g16VerifierWrapperModule = Groth16VerifierMTPWrapperModule;
break;
case "sigV2":
g16VerifierWrapperModule = Groth16VerifierSigWrapperModule;
break;
case "v3":
g16VerifierWrapperModule = Groth16VerifierV3WrapperModule;
break;
}

await waitNotToInterfereWithHardhatIgnition(undefined);
const groth16VerifierWrapper = await ethers.deployContract(g16VerifierContractWrapperName);

// Check that contract exists and skip deployment in this case
groth16VerifierWrapper = await getUnifiedContract(g16VerifierContractWrapperName);
if (groth16VerifierWrapper) {
Logger.warning(
`${g16VerifierContractWrapperName} found already deployed to: ${await groth16VerifierWrapper?.getAddress()}`,
);
return groth16VerifierWrapper;
}
groth16VerifierWrapper = (
await ignition.deploy(g16VerifierWrapperModule, {
strategy: deployStrategy,
})
).wrapper;
} else {
this.log("deploying with BASIC strategy...");
groth16VerifierWrapper = await ethers.deployContract(g16VerifierContractWrapperName);
}
await groth16VerifierWrapper.waitForDeployment();
Logger.success(
`${g16VerifierContractWrapperName} Wrapper deployed to: ${await groth16VerifierWrapper.getAddress()}`,
Expand All @@ -679,36 +630,31 @@ export class DeployHelper {
deployStrategy: "basic" | "create2" = "basic",
): Promise<{
state: any;
groth16VerifierWrapper: any;
groth16VerifierWrapperInfo: any;
validator: any;
}> {
const groth16VerifierWrapper = await this.deployGroth16VerifierWrapper(
validatorType,
deployStrategy,
);

const contracts = await this.deployValidatorContracts(
validatorType,
stateAddress,
await groth16VerifierWrapper.getAddress(),
deployStrategy,
);

const state = await ethers.getContractAt("State", stateAddress);
return {
validator: contracts.validator,
groth16VerifierWrapper,
groth16VerifierWrapperInfo: contracts.groth16VerifierWrapperInfo,
state,
};
}

async deployValidatorContracts(
validatorType: "mtpV2" | "sigV2" | "v3",
stateAddress: string,
groth16VerifierWrapperAddress: string,
deployStrategy: "basic" | "create2" = "basic",
): Promise<{
state: any;
validator: any;
groth16VerifierWrapper: any;
}> {
const owner = this.signers[0];

Expand All @@ -725,6 +671,8 @@ export class DeployHelper {
break;
}

const groth16VerifierWrapper = await this.deployGroth16VerifierWrapper(validatorType);

const ValidatorFactory = await ethers.getContractFactory(validatorContractName);
const Create2AddressAnchorFactory = await ethers.getContractFactory(
contractsInfo.CREATE2_ADDRESS_ANCHOR.name,
Expand Down Expand Up @@ -770,6 +718,7 @@ export class DeployHelper {
return {
validator,
state: await ethers.getContractAt("State", stateAddress),
groth16VerifierWrapper,
};
}
}
Expand All @@ -792,14 +741,14 @@ export class DeployHelper {
redeployImplementation: "always",
call: {
fn: "initialize",
args: [groth16VerifierWrapperAddress, stateAddress, await owner.getAddress()],
args: [await groth16VerifierWrapper.getAddress(), stateAddress, await owner.getAddress()],
},
});
} else {
this.log("deploying with BASIC strategy...");

validator = await upgrades.deployProxy(ValidatorFactory, [
groth16VerifierWrapperAddress,
await groth16VerifierWrapper.getAddress(),
stateAddress,
await owner.getAddress(),
]);
Expand All @@ -812,6 +761,7 @@ export class DeployHelper {
return {
validator,
state,
groth16VerifierWrapper,
};
}

Expand Down
Loading

0 comments on commit c26d2f0

Please sign in to comment.