diff --git a/contracts/verifiers/SP1Verifier.sol b/contracts/verifiers/SP1Verifier.sol index 2373a41f..199e72a9 100644 --- a/contracts/verifiers/SP1Verifier.sol +++ b/contracts/verifiers/SP1Verifier.sol @@ -4,6 +4,9 @@ pragma solidity ^0.8.20; import {ISP1Verifier, ISP1VerifierWithHash} from "../v2/interfaces/ISP1Verifier.sol"; import {PlonkVerifier} from "./PlonkVerifier.sol"; +// Current deployments: https://github.com/succinctlabs/sp1-contracts/tree/main/contracts/deployments +// Local deployments should deploy this contract. Any existing chain should use already deployed contracts by SP1 + /// @title SP1 Verifier /// @author Succinct Labs /// @notice This contracts implements a solidity verifier for SP1. @@ -23,7 +26,8 @@ contract SP1Verifier is PlonkVerifier, ISP1VerifierWithHash { /// @inheritdoc ISP1VerifierWithHash function VERIFIER_HASH() public pure returns (bytes32) { - return 0xc430ff7f31a22c5f7607f3ed2a2f5621af340bc45a44179319cba5761664e1f0; + return + 0xc430ff7f31a22c5f7607f3ed2a2f5621af340bc45a44179319cba5761664e1f0; } /// @notice Hashes the public values to a field elements inside Bn254. @@ -58,4 +62,4 @@ contract SP1Verifier is PlonkVerifier, ISP1VerifierWithHash { revert InvalidProof(); } } -} \ No newline at end of file +} diff --git a/deployment/v2/4_createRollup.ts b/deployment/v2/4_createRollup.ts index 185184e9..3d087864 100644 --- a/deployment/v2/4_createRollup.ts +++ b/deployment/v2/4_createRollup.ts @@ -146,18 +146,28 @@ async function main() { } let verifierContract; + let verifierName; if (realVerifier === true) { - let verifierName = `FflonkVerifier_${forkID}`; + if (consensusContract != "PolygonPessimisticConsensus") { + verifierName = `FflonkVerifier_${forkID}`; - const VerifierRollup = await ethers.getContractFactory(verifierName, deployer); - verifierContract = await VerifierRollup.deploy(); - await verifierContract.waitForDeployment(); + const VerifierRollup = await ethers.getContractFactory(verifierName, deployer); + verifierContract = await VerifierRollup.deploy(); + await verifierContract.waitForDeployment(); + } else { + verifierName = "SP1Verifier"; + const VerifierRollup = await ethers.getContractFactory(verifierName, deployer); + verifierContract = await VerifierRollup.deploy(); + await verifierContract.waitForDeployment(); + } } else { - const VerifierRollupHelperFactory = await ethers.getContractFactory("VerifierRollupHelperMock", deployer); + verifierName = "VerifierRollupHelperMock"; + const VerifierRollupHelperFactory = await ethers.getContractFactory(verifierName, deployer); verifierContract = await VerifierRollupHelperFactory.deploy(); await verifierContract.waitForDeployment(); } console.log("#######################\n"); + console.log("Verifier name:", verifierName); console.log("Verifier deployed to:", verifierContract.target); // Since it's a mock deployment deployer has all the rights diff --git a/tools/addRollupType/README.md b/tools/addRollupType/README.md index ff9a2c11..c3863a17 100644 --- a/tools/addRollupType/README.md +++ b/tools/addRollupType/README.md @@ -8,12 +8,14 @@ npm i ## Setup - Config file - - `consensusContract`: select between consensus contract. Supprted: `["PolygonZkEVMEtrog", "PolygonValidiumEtrog"]` + - `consensusContract`: select between consensus contract. Supported: `["PolygonZkEVMEtrog", "PolygonValidiumEtrog", "PolygonPessimisticConsensus"]` + - `consensusContractAddress`: gets this address instead of deployong a new consensus implementation - `polygonRollupManagerAddress`: polygonRollupManager smart contract address - `verifierAddress`: verifier to be used - `description`: string to describe rollup type added. Example: "Type: Validium, Version: etrog, genesis: /ipfs/QmUXnRoPbUmZuEZCGyiHjEsoNcFVu3hLtSvhpnfBS2mAYU" - `forkID`: forkID to be used - - `rollupCompatibilityID`: rollup compatibility ID + - `programVKey`: program key for pessimsitic consensus + - `genesisRoot`: initial genesis root. Must match the `genesis.json` generated. - `timelockDelay`: timelock delay - `timelockSalt(optional)`: timelock salt - `predecessor(optional)`: timelock predecessor diff --git a/tools/addRollupType/addRollupType.ts b/tools/addRollupType/addRollupType.ts index 67eadf16..8703c1a7 100644 --- a/tools/addRollupType/addRollupType.ts +++ b/tools/addRollupType/addRollupType.ts @@ -30,8 +30,8 @@ async function main() { "consensusContract", "polygonRollupManagerAddress", "verifierAddress", - "rollupCompatibilityID", "genesisRoot", + "programVKey", ]; for (const parameterName of mandatoryDeploymentParameters) { @@ -42,15 +42,16 @@ async function main() { const { description, - rollupCompatibilityID, forkID, consensusContract, polygonRollupManagerAddress, verifierAddress, genesisRoot, + programVKey, } = addRollupParameters; - const supportedConensus = ["PolygonZkEVMEtrog", "PolygonValidiumEtrog"]; + const supportedConensus = ["PolygonZkEVMEtrog", "PolygonValidiumEtrog", "PolygonPessimisticConsensus"]; + const isPessimistic = consensusContract === "PolygonPessimisticConsensus"; if (!supportedConensus.includes(consensusContract)) { throw new Error(`Consensus contract not supported, supported contracts are: ${supportedConensus}`); @@ -115,24 +116,27 @@ async function main() { const polygonZkEVMGlobalExitRootAddress = await rollupManagerContract.globalExitRootManager(); const polTokenAddress = await rollupManagerContract.pol(); - // Sanity checks genesisRoot - if (genesisRoot !== genesis.root) { - throw new Error(`Genesis root in the 'add_rollup_type.json' does not match the root in the 'genesis.json'`); - } + if (!isPessimistic) { + // checks for rollups + // Sanity checks genesisRoot + if (genesisRoot !== genesis.root) { + throw new Error(`Genesis root in the 'add_rollup_type.json' does not match the root in the 'genesis.json'`); + } - // get bridge address in genesis file - let genesisBridgeAddress = ethers.ZeroAddress; - for (let i = 0; i < genesis.genesis.length; i++) { - if (genesis.genesis[i].contractName === "PolygonZkEVMBridge proxy") { - genesisBridgeAddress = genesis.genesis[i].address; - break; + // get bridge address in genesis file + let genesisBridgeAddress = ethers.ZeroAddress; + for (let i = 0; i < genesis.genesis.length; i++) { + if (genesis.genesis[i].contractName === "PolygonZkEVMBridge proxy") { + genesisBridgeAddress = genesis.genesis[i].address; + break; + } } - } - if (polygonZkEVMBridgeAddress.toLowerCase() !== genesisBridgeAddress.toLowerCase()) { - throw new Error( - `'PolygonZkEVMBridge proxy' root in the 'genesis.json' does not match 'bridgeAddress' in the 'PolygonRollupManager'` - ); + if (polygonZkEVMBridgeAddress.toLowerCase() !== genesisBridgeAddress.toLowerCase()) { + throw new Error( + `'PolygonZkEVMBridge proxy' root in the 'genesis.json' does not match 'bridgeAddress' in the 'PolygonRollupManager'` + ); + } } // Check roles @@ -151,13 +155,13 @@ async function main() { await rollupManagerContract.grantRole(ADD_ROLLUP_TYPE_ROLE, deployer.address); // Create consensus implementation if needed - let polygonConsensusContractAddress; + let consensusContractAddress; if ( - typeof addRollupParameters.polygonconsensusContract !== "undefined" && - ethers.isAddress(addRollupParameters.polygonconsensusContract) + typeof addRollupParameters.consensusContractAddress !== "undefined" && + ethers.isAddress(addRollupParameters.consensusContractAddress) ) { - polygonConsensusContractAddress = addRollupParameters.polygonconsensusContract; + consensusContractAddress = addRollupParameters.consensusContractAddress; } else { const PolygonconsensusFactory = (await ethers.getContractFactory(consensusContract, deployer)) as any; let PolygonconsensusContract; @@ -171,6 +175,7 @@ async function main() { await PolygonconsensusContract.waitForDeployment(); console.log("#######################\n"); + console.log(`new consensus name: ${consensusContract}`); console.log(`new PolygonconsensusContract impl: ${PolygonconsensusContract.target}`); console.log("you can verify the new impl address with:"); @@ -184,19 +189,34 @@ async function main() { polygonRollupManagerAddress, ]); - polygonConsensusContractAddress = PolygonconsensusContract.target; + consensusContractAddress = PolygonconsensusContract.target; + } + + // Add a new rollup type + let rollupVerifierType; + let genesisFinal; + let programVKeyFinal; + + if (consensusContract == "PolygonPessimisticConsensus") { + rollupVerifierType = 1; + genesisFinal = ethers.ZeroHash; + programVKeyFinal = programVKey || ethers.ZeroHash; + } else { + rollupVerifierType = 0; + genesisFinal = genesis.root; + programVKeyFinal = ethers.ZeroHash; } - // Add a new rollup type with timelock console.log( await ( await rollupManagerContract.addNewRollupType( - polygonConsensusContractAddress, + consensusContractAddress, verifierAddress, forkID, - rollupCompatibilityID, - genesis.root, - description + rollupVerifierType, + genesisFinal, + description, + programVKeyFinal ) ).wait() ); diff --git a/tools/addRollupType/addRollupTypeTimelock.ts b/tools/addRollupType/addRollupTypeTimelock.ts index 71b022f6..92c95595 100644 --- a/tools/addRollupType/addRollupTypeTimelock.ts +++ b/tools/addRollupType/addRollupTypeTimelock.ts @@ -28,9 +28,9 @@ async function main() { "forkID", "consensusContract", "verifierAddress", - "rollupCompatibilityID", "timelockDelay", "genesisRoot", + "programVKey", ]; for (const parameterName of mandatoryDeploymentParameters) { @@ -41,19 +41,25 @@ async function main() { const { description, - rollupCompatibilityID, forkID, consensusContract, polygonRollupManagerAddress, verifierAddress, timelockDelay, genesisRoot, + programVKey, } = addRollupParameters; const salt = addRollupParameters.timelockSalt || ethers.ZeroHash; const predecessor = addRollupParameters.predecessor || ethers.ZeroHash; - const supportedConensus = ["PolygonZkEVMEtrog", "PolygonValidiumEtrog", "PolygonValidiumStorageMigration"]; + const supportedConensus = [ + "PolygonZkEVMEtrog", + "PolygonValidiumEtrog", + "PolygonValidiumStorageMigration", + "PolygonPessimisticConsensus", + ]; + const isPessimistic = consensusContract === "PolygonPessimisticConsensus"; if (!supportedConensus.includes(consensusContract)) { throw new Error(`Consensus contract not supported, supported contracts are: ${supportedConensus}`); @@ -118,35 +124,40 @@ async function main() { const polygonZkEVMGlobalExitRootAddress = await rollupManagerContract.globalExitRootManager(); const polTokenAddress = await rollupManagerContract.pol(); - // Sanity checks genesisRoot - if (genesisRoot !== genesis.root) { - throw new Error(`Genesis root in the 'add_rollup_type.json' does not match the root in the 'genesis.json'`); - } + if (!isPessimistic) { + // checks for rollups + // Sanity checks genesisRoot + if (genesisRoot !== genesis.root) { + throw new Error(`Genesis root in the 'add_rollup_type.json' does not match the root in the 'genesis.json'`); + } - // get bridge address in genesis file - let genesisBridgeAddress = ethers.ZeroAddress; - for (let i = 0; i < genesis.genesis.lenght; i++) { - if (genesis.genesis[i].contractName === "PolygonZkEVMBridge proxy") { - genesisBridgeAddress = genesis.genesis[i].address; - break; + // get bridge address in genesis file + let genesisBridgeAddress = ethers.ZeroAddress; + for (let i = 0; i < genesis.genesis.lenght; i++) { + if (genesis.genesis[i].contractName === "PolygonZkEVMBridge proxy") { + genesisBridgeAddress = genesis.genesis[i].address; + break; + } } - } - if (polygonZkEVMBridgeAddress.toLowerCase() !== genesisBridgeAddress.toLowerCase()) { - throw new Error( - `'PolygonZkEVMBridge proxy' root in the 'genesis.json' does not match 'bridgeAddress' in the 'PolygonRollupManager'` - ); + if (polygonZkEVMBridgeAddress.toLowerCase() !== genesisBridgeAddress.toLowerCase()) { + throw new Error( + `'PolygonZkEVMBridge proxy' root in the 'genesis.json' does not match 'bridgeAddress' in the 'PolygonRollupManager'` + ); + } } - // Create consensus implementation + // Create consensus implementation if needed const PolygonconsensusFactory = (await ethers.getContractFactory(consensusContract, deployer)) as any; let PolygonconsensusContract; let PolygonconsensusContractAddress; if ( - addRollupParameters.polygonconsensusContract === undefined || - addRollupParameters.polygonconsensusContract === "" + typeof addRollupParameters.consensusContractAddress !== "undefined" && + ethers.isAddress(addRollupParameters.consensusContractAddress) ) { + PolygonconsensusContractAddress = addRollupParameters.consensusContractAddress; + } else { PolygonconsensusContract = await PolygonconsensusFactory.deploy( polygonZkEVMGlobalExitRootAddress, polTokenAddress, @@ -158,6 +169,7 @@ async function main() { PolygonconsensusContractAddress = PolygonconsensusContract.target; console.log("#######################\n"); + console.log(`new consensus name: ${consensusContract}`); console.log(`new PolygonconsensusContract impl: ${PolygonconsensusContractAddress}`); console.log("you can verify the new impl address with:"); @@ -170,13 +182,26 @@ async function main() { polygonZkEVMBridgeAddress, polygonRollupManagerAddress, ]); - } else { - PolygonconsensusContractAddress = addRollupParameters.polygonconsensusContract; } // load timelock const timelockContractFactory = await ethers.getContractFactory("PolygonZkEVMTimelock", deployer); + // Add a new rollup type + let rollupVerifierType; + let genesisFinal; + let programVKeyFinal; + + if (consensusContract == "PolygonPessimisticConsensus") { + rollupVerifierType = 1; + genesisFinal = ethers.ZeroHash; + programVKeyFinal = programVKey || ethers.ZeroHash; + } else { + rollupVerifierType = 0; + genesisFinal = genesis.root; + programVKeyFinal = ethers.ZeroHash; + } + const operation = genOperation( polygonRollupManagerAddress, 0, // value @@ -184,9 +209,10 @@ async function main() { PolygonconsensusContractAddress, verifierAddress, forkID, - rollupCompatibilityID, - genesis.root, + rollupVerifierType, + genesisFinal, description, + programVKeyFinal, ]), predecessor, // predecessor salt // salt diff --git a/tools/addRollupType/add_rollup_type.json.example b/tools/addRollupType/add_rollup_type.json.example index f65f64c5..d1e76ba2 100644 --- a/tools/addRollupType/add_rollup_type.json.example +++ b/tools/addRollupType/add_rollup_type.json.example @@ -1,16 +1,16 @@ { "consensusContract": "PolygonValidiumEtrog", - "polygonconsensusContract": "", + "consensusContractAddress": "", "polygonRollupManagerAddress": "0x5132A183E9F3CB7C848b0AAC5Ae0c4f0491B7aB2", "verifierAddress": "0x1C3A3da552b8662CD69538356b1E7c2E9CC1EBD8", "description": "Type: Validium, Version: etrog, genesis: /ipfs/QmUXnRoPbUmZuEZCGyiHjEsoNcFVu3hLtSvhpnfBS2mAYU", "forkID": 7, - "rollupCompatibilityID": 0, "timelockDelay": 864000, "timelockSalt": "", "deployerPvtKey": "", "maxFeePerGas":"", "maxPriorityFeePerGas":"", "multiplierGas": "", - "genesisRoot": "0xe3a7d8bae497945ba8ddc51c69564f60ad4c1a990b9c7bdbd27f7929bfa8f272" + "genesisRoot": "0xe3a7d8bae497945ba8ddc51c69564f60ad4c1a990b9c7bdbd27f7929bfa8f272", + "programVKey": "0xaabbccddeeff00112233445566778899aabbccddeeff00112233445566778899" }