From b8f847b58a5ff7326482b69774f112c0fcb750e5 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Thu, 25 Jul 2024 15:04:16 +0200 Subject: [PATCH 01/16] WIP --- contracts/v2/PolygonRollupManager.sol | 1 + .../PolygonPessimisticConsensus.test.ts | 163 +++++++ .../PolygonRollupManager-Pessimistic.test.ts | 458 ++++++++++++++++++ 3 files changed, 622 insertions(+) create mode 100644 test/contractsv2/PolygonPessimisticConsensus.test.ts create mode 100644 test/contractsv2/PolygonRollupManager-Pessimistic.test.ts diff --git a/contracts/v2/PolygonRollupManager.sol b/contracts/v2/PolygonRollupManager.sol index 18e554365..638606eac 100644 --- a/contracts/v2/PolygonRollupManager.sol +++ b/contracts/v2/PolygonRollupManager.sol @@ -550,6 +550,7 @@ contract PolygonRollupManager is } else { rollup.batchNumToStateRoot[0] = initRoot; } + // rollup type is 0, since it does not follow any rollup type emit AddExistingRollup( rollupID, diff --git a/test/contractsv2/PolygonPessimisticConsensus.test.ts b/test/contractsv2/PolygonPessimisticConsensus.test.ts new file mode 100644 index 000000000..8ea85906b --- /dev/null +++ b/test/contractsv2/PolygonPessimisticConsensus.test.ts @@ -0,0 +1,163 @@ +/* eslint-disable no-plusplus, no-await-in-loop */ +import {expect} from "chai"; +import {ethers, upgrades} from "hardhat"; +import {Address, PolygonPessimisticConsensus} from "../../typechain-types"; + +describe("PolygonPessimisticConsensus", () => { + let deployer: any; + let trustedSequencer: any; + let admin: any; + + let PolygonPPConsensusContract: PolygonPessimisticConsensus; + + const gerManagerAddress = "0xA00000000000000000000000000000000000000A" as unknown as Address; + const polTokenAddress = "0xB00000000000000000000000000000000000000B" as unknown as Address; + const rollupManagerAddress = "0xC00000000000000000000000000000000000000C" as unknown as Address; + const bridgeAddress = "0xD00000000000000000000000000000000000000D" as unknown as Address; + + const urlSequencer = "http://zkevm-json-rpc:8123"; + const networkName = "zkevm"; + const networkID = 1; + + // Native token will be ether + const gasTokenAddress = ethers.ZeroAddress; + + beforeEach("Deploy contract", async () => { + upgrades.silenceWarnings(); + + // load signers + [deployer, trustedSequencer, admin] = await ethers.getSigners(); + + // deploy consensus + // create polygonPessimisticConsensus implementation + const ppConsensusFactory = await ethers.getContractFactory("PolygonPessimisticConsensus"); + PolygonPPConsensusContract = await ppConsensusFactory.deploy( + gerManagerAddress, + polTokenAddress, + bridgeAddress, + rollupManagerAddress + ); + await PolygonPPConsensusContract.waitForDeployment(); + }); + + it("should check the initalized parameters", async () => { + // initialize zkEVM using non admin address + await expect( + PolygonPPConsensusContract.initialize( + admin.address, + trustedSequencer.address, + networkID, + gasTokenAddress, + urlSequencer, + networkName + ) + ).to.be.revertedWithCustomError(PolygonPPConsensusContract, "OnlyRollupManager"); + + // initialize using rollup manager + await ethers.provider.send("hardhat_impersonateAccount", [rollupManagerAddress]); + const rolllupManagerSigner = await ethers.getSigner(rollupManagerAddress as any); + await PolygonPPConsensusContract.connect(rolllupManagerSigner).initialize( + admin.address, + trustedSequencer.address, + networkID, + gasTokenAddress, + urlSequencer, + networkName, + {gasPrice: 0} + ); + + expect(await PolygonPPConsensusContract.admin()).to.be.equal(admin.address); + expect(await PolygonPPConsensusContract.trustedSequencer()).to.be.equal(trustedSequencer.address); + expect(await PolygonPPConsensusContract.trustedSequencerURL()).to.be.equal(urlSequencer); + expect(await PolygonPPConsensusContract.networkName()).to.be.equal(networkName); + expect(await PolygonPPConsensusContract.gasTokenAddress()).to.be.equal(gasTokenAddress); + + // initialize again + await expect( + PolygonPPConsensusContract.connect(rolllupManagerSigner).initialize( + admin.address, + trustedSequencer.address, + networkID, + gasTokenAddress, + urlSequencer, + networkName, + {gasPrice: 0} + ) + ).to.be.revertedWith("Initializable: contract is already initialized"); + }); + + it("should check admin functions", async () => { + // initialize using rollup manager + await ethers.provider.send("hardhat_impersonateAccount", [rollupManagerAddress]); + const rolllupManagerSigner = await ethers.getSigner(rollupManagerAddress as any); + await PolygonPPConsensusContract.connect(rolllupManagerSigner).initialize( + admin.address, + trustedSequencer.address, + networkID, + gasTokenAddress, + urlSequencer, + networkName, + {gasPrice: 0} + ); + + // setTrustedSequencer + await expect(PolygonPPConsensusContract.setTrustedSequencer(deployer.address)).to.be.revertedWithCustomError( + PolygonPPConsensusContract, + "OnlyAdmin" + ); + + await expect(PolygonPPConsensusContract.connect(admin).setTrustedSequencer(deployer.address)) + .to.emit(PolygonPPConsensusContract, "SetTrustedSequencer") + .withArgs(deployer.address); + + // setTrustedSequencerURL + await expect(PolygonPPConsensusContract.setTrustedSequencerURL("0x1253")).to.be.revertedWithCustomError( + PolygonPPConsensusContract, + "OnlyAdmin" + ); + await expect(PolygonPPConsensusContract.connect(admin).setTrustedSequencerURL("0x1253")) + .to.emit(PolygonPPConsensusContract, "SetTrustedSequencerURL") + .withArgs("0x1253"); + + // transferAdminRole & acceptAdminRole + await expect(PolygonPPConsensusContract.connect(admin).transferAdminRole(deployer.address)) + .to.emit(PolygonPPConsensusContract, "TransferAdminRole") + .withArgs(deployer.address); + + await expect(PolygonPPConsensusContract.connect(admin).acceptAdminRole()).to.be.revertedWithCustomError( + PolygonPPConsensusContract, + "OnlyPendingAdmin" + ); + + await expect(PolygonPPConsensusContract.connect(deployer).acceptAdminRole()) + .to.emit(PolygonPPConsensusContract, "AcceptAdminRole") + .withArgs(deployer.address); + }); + + it("should check getConsensusHash", async () => { + // initialize using rollup manager + await ethers.provider.send("hardhat_impersonateAccount", [rollupManagerAddress]); + const rolllupManagerSigner = await ethers.getSigner(rollupManagerAddress as any); + await PolygonPPConsensusContract.connect(rolllupManagerSigner).initialize( + admin.address, + trustedSequencer.address, + networkID, + gasTokenAddress, + urlSequencer, + networkName, + {gasPrice: 0} + ); + + // pessimistic constant CONSENSUS_TYPE = 0; + const CONSENSUS_TYPE = 0; + const consensusHashJs = ethers.solidityPackedKeccak256( + ["uint32", "address"], + [CONSENSUS_TYPE, trustedSequencer.address] + ); + + // getConsensusHash + const resGetConsensusHash = await PolygonPPConsensusContract.getConsensusHash(); + + expect(resGetConsensusHash).to.be.equal(consensusHashJs); + }); +}); diff --git a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts new file mode 100644 index 000000000..506199064 --- /dev/null +++ b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts @@ -0,0 +1,458 @@ +/* eslint-disable no-plusplus, no-await-in-loop */ +import {expect} from "chai"; +import {ethers, upgrades} from "hardhat"; +import { + VerifierRollupHelperMock, + ERC20PermitMock, + PolygonRollupManagerMock, + PolygonZkEVMGlobalExitRootV2, + PolygonZkEVMBridgeV2, + PolygonZkEVMEtrog, + PolygonRollupBaseEtrog, + TokenWrapped, + Address, + PolygonDataCommittee, + PolygonPessimisticConsensus, +} from "../../typechain-types"; +import {takeSnapshot, time} from "@nomicfoundation/hardhat-network-helpers"; + +enum VerifierType { + StateTransition = 0, + Pessimistic = 1, +} + +describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { + let deployer: any; + let timelock: any; + let emergencyCouncil: any; + let trustedAggregator: any; + let trustedSequencer: any; + let admin: any; + let beneficiary: any; + + let verifierContract: VerifierRollupHelperMock; + let polygonZkEVMBridgeContract: PolygonZkEVMBridgeV2; + let polTokenContract: ERC20PermitMock; + let polygonZkEVMGlobalExitRoot: PolygonZkEVMGlobalExitRootV2; + let rollupManagerContract: PolygonRollupManagerMock; + let PolygonPPConsensusContract: PolygonPessimisticConsensus; + + const polTokenName = "POL Token"; + const polTokenSymbol = "POL"; + const polTokenInitialBalance = ethers.parseEther("20000000"); + + const pendingStateTimeoutDefault = 100; + const trustedAggregatorTimeout = 100; + const FORCE_BATCH_TIMEOUT = 60 * 60 * 24 * 5; // 5 days + + // BRidge constants + const networkIDMainnet = 0; + const networkIDRollup = 1; + + const LEAF_TYPE_ASSET = 0; + const LEAF_TYPE_MESSAGE = 1; + + const globalExitRootL2Address = "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa" as unknown as Address; + + let firstDeployment = true; + + //roles + const DEFAULT_ADMIN_ROLE = ethers.ZeroHash; + const ADD_ROLLUP_TYPE_ROLE = ethers.id("ADD_ROLLUP_TYPE_ROLE"); + const OBSOLETE_ROLLUP_TYPE_ROLE = ethers.id("OBSOLETE_ROLLUP_TYPE_ROLE"); + const CREATE_ROLLUP_ROLE = ethers.id("CREATE_ROLLUP_ROLE"); + const ADD_EXISTING_ROLLUP_ROLE = ethers.id("ADD_EXISTING_ROLLUP_ROLE"); + const UPDATE_ROLLUP_ROLE = ethers.id("UPDATE_ROLLUP_ROLE"); + const TRUSTED_AGGREGATOR_ROLE = ethers.id("TRUSTED_AGGREGATOR_ROLE"); + const TRUSTED_AGGREGATOR_ROLE_ADMIN = ethers.id("TRUSTED_AGGREGATOR_ROLE_ADMIN"); + const TWEAK_PARAMETERS_ROLE = ethers.id("TWEAK_PARAMETERS_ROLE"); + const SET_FEE_ROLE = ethers.id("SET_FEE_ROLE"); + const STOP_EMERGENCY_ROLE = ethers.id("STOP_EMERGENCY_ROLE"); + const EMERGENCY_COUNCIL_ROLE = ethers.id("EMERGENCY_COUNCIL_ROLE"); + const EMERGENCY_COUNCIL_ADMIN = ethers.id("EMERGENCY_COUNCIL_ADMIN"); + + const SIGNATURE_BYTES = 32 + 32 + 1; + const EFFECTIVE_PERCENTAGE_BYTES = 1; + + beforeEach("Deploy contract", async () => { + upgrades.silenceWarnings(); + + // load signers + [deployer, trustedAggregator, trustedSequencer, admin, timelock, emergencyCouncil, beneficiary] = + await ethers.getSigners(); + + // deploy mock verifier + const VerifierRollupHelperFactory = await ethers.getContractFactory("VerifierRollupHelperMock"); + verifierContract = await VerifierRollupHelperFactory.deploy(); + + // deploy pol + const polTokenFactory = await ethers.getContractFactory("ERC20PermitMock"); + polTokenContract = await polTokenFactory.deploy( + polTokenName, + polTokenSymbol, + deployer.address, + polTokenInitialBalance + ); + + /* + * deploy global exit root manager + * In order to not have trouble with nonce deploy first proxy admin + */ + await upgrades.deployProxyAdmin(); + + if ((await upgrades.admin.getInstance()).target !== "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0") { + firstDeployment = false; + } + const nonceProxyBridge = + Number(await ethers.provider.getTransactionCount(deployer.address)) + (firstDeployment ? 3 : 2); + + const nonceProxyZkevm = nonceProxyBridge + 2; // Always have to redeploy impl since the polygonZkEVMGlobalExitRoot address changes + + const precalculateBridgeAddress = ethers.getCreateAddress({ + from: deployer.address, + nonce: nonceProxyBridge, + }); + const precalculateRollupManagerAddress = ethers.getCreateAddress({ + from: deployer.address, + nonce: nonceProxyZkevm, + }); + firstDeployment = false; + + // deploy globalExitRoot + const PolygonZkEVMGlobalExitRootFactory = await ethers.getContractFactory("PolygonZkEVMGlobalExitRootV2"); + polygonZkEVMGlobalExitRoot = await upgrades.deployProxy(PolygonZkEVMGlobalExitRootFactory, [], { + constructorArgs: [precalculateRollupManagerAddress, precalculateBridgeAddress], + unsafeAllow: ["constructor", "state-variable-immutable"], + }); + + // deploy PolygonZkEVMBridge + const polygonZkEVMBridgeFactory = await ethers.getContractFactory("PolygonZkEVMBridgeV2"); + polygonZkEVMBridgeContract = await upgrades.deployProxy(polygonZkEVMBridgeFactory, [], { + initializer: false, + unsafeAllow: ["constructor"], + }); + + // deploy polygon rollup manager mock + const PolygonRollupManagerFactory = await ethers.getContractFactory("PolygonRollupManagerMock"); + + rollupManagerContract = (await upgrades.deployProxy(PolygonRollupManagerFactory, [], { + initializer: false, + constructorArgs: [ + polygonZkEVMGlobalExitRoot.target, + polTokenContract.target, + polygonZkEVMBridgeContract.target, + ], + unsafeAllow: ["constructor", "state-variable-immutable"], + })) as unknown as PolygonRollupManagerMock; + + await rollupManagerContract.waitForDeployment(); + + // check precalculated address + expect(precalculateBridgeAddress).to.be.equal(polygonZkEVMBridgeContract.target); + expect(precalculateRollupManagerAddress).to.be.equal(rollupManagerContract.target); + + await polygonZkEVMBridgeContract.initialize( + networkIDMainnet, + ethers.ZeroAddress, // zero for ether + ethers.ZeroAddress, // zero for ether + polygonZkEVMGlobalExitRoot.target, + rollupManagerContract.target, + "0x" + ); + + // Initialize Mock + await rollupManagerContract.initializeMock( + trustedAggregator.address, + pendingStateTimeoutDefault, + trustedAggregatorTimeout, + admin.address, + timelock.address, + emergencyCouncil.address + ); + + // fund sequencer address with Matic tokens + await polTokenContract.transfer(trustedSequencer.address, ethers.parseEther("1000")); + }); + + it("should check the initalized parameters", async () => { + expect(await rollupManagerContract.globalExitRootManager()).to.be.equal(polygonZkEVMGlobalExitRoot.target); + expect(await rollupManagerContract.pol()).to.be.equal(polTokenContract.target); + expect(await rollupManagerContract.bridgeAddress()).to.be.equal(polygonZkEVMBridgeContract.target); + + expect(await rollupManagerContract.getBatchFee()).to.be.equal(ethers.parseEther("0.1")); + expect(await rollupManagerContract.getForcedBatchFee()).to.be.equal(ethers.parseEther("10")); + expect(await rollupManagerContract.calculateRewardPerBatch()).to.be.equal(0); + + // Check roles + expect(await rollupManagerContract.hasRole(DEFAULT_ADMIN_ROLE, timelock.address)).to.be.equal(true); + expect(await rollupManagerContract.hasRole(ADD_ROLLUP_TYPE_ROLE, timelock.address)).to.be.equal(true); + expect(await rollupManagerContract.hasRole(UPDATE_ROLLUP_ROLE, timelock.address)).to.be.equal(true); + expect(await rollupManagerContract.hasRole(ADD_EXISTING_ROLLUP_ROLE, timelock.address)).to.be.equal(true); + + expect(await rollupManagerContract.hasRole(TRUSTED_AGGREGATOR_ROLE, trustedAggregator.address)).to.be.equal( + true + ); + + expect(await rollupManagerContract.hasRole(OBSOLETE_ROLLUP_TYPE_ROLE, admin.address)).to.be.equal(true); + expect(await rollupManagerContract.hasRole(CREATE_ROLLUP_ROLE, admin.address)).to.be.equal(true); + expect(await rollupManagerContract.hasRole(TRUSTED_AGGREGATOR_ROLE_ADMIN, admin.address)).to.be.equal(true); + expect(await rollupManagerContract.hasRole(TWEAK_PARAMETERS_ROLE, admin.address)).to.be.equal(true); + expect(await rollupManagerContract.hasRole(SET_FEE_ROLE, admin.address)).to.be.equal(true); + expect(await rollupManagerContract.hasRole(STOP_EMERGENCY_ROLE, admin.address)).to.be.equal(true); + + expect(await rollupManagerContract.hasRole(EMERGENCY_COUNCIL_ROLE, emergencyCouncil.address)).to.be.equal(true); + expect(await rollupManagerContract.hasRole(EMERGENCY_COUNCIL_ADMIN, emergencyCouncil.address)).to.be.equal( + true + ); + }); + + it("should add a new rollup type: PolygonConsensusPessimistic", async () => { + // deploy consensus + // create polygonPessimisticConsensus implementation + const ppConsensusFactory = await ethers.getContractFactory("PolygonPessimisticConsensus"); + PolygonPPConsensusContract = await ppConsensusFactory.deploy( + polygonZkEVMGlobalExitRoot.target, + polTokenContract.target, + polygonZkEVMBridgeContract.target, + rollupManagerContract.target + ); + await PolygonPPConsensusContract.waitForDeployment(); + + // Try to add a new rollup type + const forkID = 11; // just metadata for pessimistic consensus + const genesis = ethers.ZeroHash; + const description = "new pessimistic consensus"; + const programVKey = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; + const newRollupTypeID = 1; + const nonZeroGenesis = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; + + // sender does not have _ADD_ROLLUP_TYPE_ROLE role + await expect( + rollupManagerContract.addNewRollupType( + PolygonPPConsensusContract.target, + verifierContract.target, + forkID, + VerifierType.Pessimistic, + genesis, + description, + programVKey + ) + ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); + + // genesis != 0 on Pessimistic Verifier type + await expect( + rollupManagerContract + .connect(timelock) + .addNewRollupType( + PolygonPPConsensusContract.target, + verifierContract.target, + forkID, + VerifierType.Pessimistic, + nonZeroGenesis, + description, + programVKey + ) + ).to.be.revertedWithCustomError(rollupManagerContract, "InvalidRollupType"); + + // correct add new rollup via timelock + await expect( + rollupManagerContract + .connect(timelock) + .addNewRollupType( + PolygonPPConsensusContract.target, + verifierContract.target, + forkID, + VerifierType.Pessimistic, + genesis, + description, + programVKey + ) + ) + .to.emit(rollupManagerContract, "AddNewRollupType") + .withArgs( + newRollupTypeID, + PolygonPPConsensusContract.target, + verifierContract.target, + forkID, + VerifierType.Pessimistic, + genesis, + description, + programVKey + ); + + // assert new rollup type + const createdRollupType = await rollupManagerContract.rollupTypeMap(newRollupTypeID); + + const expectedRollupType = [ + PolygonPPConsensusContract.target, + verifierContract.target, + forkID, + VerifierType.Pessimistic, + false, + genesis, + programVKey, + ]; + + expect(createdRollupType).to.be.deep.equal(expectedRollupType); + + // do obsoleteRollupType + await expect(rollupManagerContract.obsoleteRollupType(newRollupTypeID)).to.be.revertedWithCustomError( + rollupManagerContract, + "AddressDoNotHaveRequiredRole" + ); + + await expect(rollupManagerContract.connect(admin).obsoleteRollupType(newRollupTypeID)) + .to.emit(rollupManagerContract, "ObsoleteRollupType") + .withArgs(newRollupTypeID); + }); + + it("should create a new rollup: PolygonConsensusPessimistic", async () => { + // deploy consensus + // create polygonPessimisticConsensus implementation + const ppConsensusFactory = await ethers.getContractFactory("PolygonPessimisticConsensus"); + PolygonPPConsensusContract = await ppConsensusFactory.deploy( + polygonZkEVMGlobalExitRoot.target, + polTokenContract.target, + polygonZkEVMBridgeContract.target, + rollupManagerContract.target + ); + await PolygonPPConsensusContract.waitForDeployment(); + + // Try to add a new rollup type + const forkID = 11; // just metadata for pessimistic consensus + const genesis = ethers.ZeroHash; + const description = "new pessimistic consensus"; + const programVKey = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; + const newRollupTypeID = 1; + + // correct add new rollup via timelock + await expect( + rollupManagerContract + .connect(timelock) + .addNewRollupType( + PolygonPPConsensusContract.target, + verifierContract.target, + forkID, + VerifierType.Pessimistic, + genesis, + description, + programVKey + ) + ) + .to.emit(rollupManagerContract, "AddNewRollupType") + .withArgs( + newRollupTypeID, + PolygonPPConsensusContract.target, + verifierContract.target, + forkID, + VerifierType.Pessimistic, + genesis, + description, + programVKey + ); + + // create new pessimsitic: only admin + const chainID = 1; + const gasTokenAddress = ethers.ZeroAddress; + const urlSequencer = "https://pessimistic:8545"; + const networkName = "testPessimistic"; + const newCreatedRollupID = 1; + + // Only admin can create new zkEVMs + await expect( + rollupManagerContract.createNewRollup( + newRollupTypeID, + chainID, + admin.address, + trustedSequencer.address, + gasTokenAddress, + urlSequencer, + networkName + ) + ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); + + // create new pessimistic + const newZKEVMAddress = ethers.getCreateAddress({ + from: rollupManagerContract.target as string, + nonce: 1, + }); + const newZkEVMContract = ppConsensusFactory.attach(newZKEVMAddress) as PolygonPessimisticConsensus; + + await expect( + rollupManagerContract + .connect(admin) + .createNewRollup( + newRollupTypeID, + chainID, + admin.address, + trustedSequencer.address, + gasTokenAddress, + urlSequencer, + networkName + ) + ) + .to.emit(rollupManagerContract, "CreateNewRollup") + .withArgs(newCreatedRollupID, newRollupTypeID, newZKEVMAddress, chainID, gasTokenAddress); + + // assert new rollup created + expect(await newZkEVMContract.admin()).to.be.equal(admin.address); + expect(await newZkEVMContract.trustedSequencer()).to.be.equal(trustedSequencer.address); + expect(await newZkEVMContract.trustedSequencerURL()).to.be.equal(urlSequencer); + expect(await newZkEVMContract.networkName()).to.be.equal(networkName); + + // assert new rollup + const resRollupData = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); + + const expectedRollupData = [ + newZKEVMAddress, + chainID, + verifierContract.target, + forkID, + ethers.ZeroHash, + 0, + 0, + 0, + 0, + newRollupTypeID, + VerifierType.Pessimistic, + ethers.ZeroHash, + programVKey, + ]; + + expect(expectedRollupData).to.be.deep.equal(resRollupData); + }); + + it("should add an existing rollup: PolygonConsensusPessimistic", async () => { + // add existing rollup + const rollupAddress = "0xAa000000000000000000000000000000000000Bb"; + const forkID = 1; + const chainID = 1; + const initLER = "0xff000000000000000000000000000000000000000000000000000000000000ff"; + const programVKey = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; + + // add existing rollup: pessimistic type + const newCreatedRollupID = 1; + + await expect( + rollupManagerContract + .connect(timelock) + .addExistingRollup( + rollupAddress, + verifierContract.target, + forkID, + chainID, + initLER, + VerifierType.Pessimistic, + programVKey + ) + ) + .to.emit(rollupManagerContract, "AddExistingRollup") + .withArgs(newCreatedRollupID, forkID, rollupAddress, chainID, VerifierType.Pessimistic, 0, programVKey); + }); + + it("should prevent to update rollup by rollup admin if different verifier type", async () => {}); + + it("should update rollup: pessismsitic type", async () => {}); + + it("should verify pessimistic proof: pessismsitic type", async () => {}); +}); From a7e7955f90b1e0a7343a6d5a489d5025c3e98b51 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Fri, 26 Jul 2024 09:32:58 +0200 Subject: [PATCH 02/16] test full pesismistic --- contracts/mocks/VerifierRollupHelperMock.sol | 10 +- contracts/v2/PolygonRollupManager.sol | 15 +- .../PolygonRollupManager-Pessimistic.test.ts | 413 +++++++++++++++++- 3 files changed, 420 insertions(+), 18 deletions(-) diff --git a/contracts/mocks/VerifierRollupHelperMock.sol b/contracts/mocks/VerifierRollupHelperMock.sol index 85e6b9192..4544d6efb 100644 --- a/contracts/mocks/VerifierRollupHelperMock.sol +++ b/contracts/mocks/VerifierRollupHelperMock.sol @@ -3,12 +3,20 @@ pragma solidity 0.8.20; import "../interfaces/IVerifierRollup.sol"; +import "../v2/interfaces/ISP1Verifier.sol"; -contract VerifierRollupHelperMock is IVerifierRollup { +contract VerifierRollupHelperMock is IVerifierRollup, ISP1Verifier { function verifyProof( bytes32[24] calldata proof, uint256[1] memory pubSignals ) public pure override returns (bool) { return true; } + + // SP1 interface + function verifyProof( + bytes32 programVKey, + bytes calldata publicValues, + bytes calldata proofBytes + ) public pure {} } diff --git a/contracts/v2/PolygonRollupManager.sol b/contracts/v2/PolygonRollupManager.sol index 638606eac..dd537a270 100644 --- a/contracts/v2/PolygonRollupManager.sol +++ b/contracts/v2/PolygonRollupManager.sol @@ -593,13 +593,6 @@ contract PolygonRollupManager is revert UpdateToOldRollupTypeID(); } - if ( - rollup.rollupVerifierType != - rollupTypeMap[newRollupTypeID].rollupVerifierType - ) { - revert UpdateNotCompatible(); - } - _updateRollup(rollupContract, newRollupTypeID, new bytes(0)); } @@ -655,13 +648,7 @@ contract PolygonRollupManager is // Check rollup types if (rollup.rollupVerifierType != newRollupType.rollupVerifierType) { - // Currently the transition from pessimistic to state transition is not allowed - if (rollup.rollupVerifierType == VerifierType.Pessimistic) { - revert RollupTypeObsolete(); - } - - // Update rollup verifier type - rollup.rollupVerifierType = newRollupType.rollupVerifierType; + revert UpdateNotCompatible(); } // Update rollup parameters diff --git a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts index 506199064..9d955cb7f 100644 --- a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts +++ b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts @@ -450,9 +450,416 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { .withArgs(newCreatedRollupID, forkID, rollupAddress, chainID, VerifierType.Pessimistic, 0, programVKey); }); - it("should prevent to update rollup by rollup admin if different verifier type", async () => {}); + it("should prevent to update rollup with different VerifierTypes", async () => { + // deploy consensus + // create polygonPessimisticConsensus implementation + const ppConsensusFactory = await ethers.getContractFactory("PolygonPessimisticConsensus"); + PolygonPPConsensusContract = await ppConsensusFactory.deploy( + polygonZkEVMGlobalExitRoot.target, + polTokenContract.target, + polygonZkEVMBridgeContract.target, + rollupManagerContract.target + ); + await PolygonPPConsensusContract.waitForDeployment(); + + // Try to add a new rollup type + const forkID = 11; // just metadata for pessimistic consensus + const genesis = ethers.ZeroHash; + const description = "new pessimistic consensus"; + const programVKey = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; + const newRollupTypeID = 1; + + // correct add new rollup via timelock + await rollupManagerContract + .connect(timelock) + .addNewRollupType( + PolygonPPConsensusContract.target, + verifierContract.target, + forkID, + VerifierType.Pessimistic, + genesis, + description, + programVKey + ); + + // create new pessimsitic: only admin + const chainID = 1; + const gasTokenAddress = ethers.ZeroAddress; + const urlSequencer = "https://pessimistic:8545"; + const networkName = "testPessimistic"; + const pessimisticRollupID = 1; + + // create new pessimistic + await rollupManagerContract + .connect(admin) + .createNewRollup( + newRollupTypeID, + chainID, + admin.address, + trustedSequencer.address, + gasTokenAddress, + urlSequencer, + networkName + ); + + // Create zkEVM implementation + const PolygonZKEVMV2Factory = await ethers.getContractFactory("PolygonZkEVMEtrog"); + const PolygonZKEVMV2Contract = await PolygonZKEVMV2Factory.deploy( + polygonZkEVMGlobalExitRoot.target, + polTokenContract.target, + polygonZkEVMBridgeContract.target, + rollupManagerContract.target + ); + await PolygonZKEVMV2Contract.waitForDeployment(); + + // Add a new rollup type with timelock + const genesisRandom = "0x0000000000000000000000000000000000000000000000000000000000000001"; + const description2 = "description"; + const chainID2 = 2; + const stateTransistionRollupID = 2; + + // add new rollup type StateTransistion with programVKey != 0 + await expect( + rollupManagerContract + .connect(timelock) + .addNewRollupType( + PolygonZKEVMV2Contract.target, + verifierContract.target, + forkID, + VerifierType.StateTransition, + genesisRandom, + description2, + programVKey + ) + ).to.be.revertedWithCustomError(rollupManagerContract, "InvalidRollupType"); + + // add new rollup type stateTranstion correctly + const newRollupTypeID2 = 2; + + await rollupManagerContract + .connect(timelock) + .addNewRollupType( + PolygonZKEVMV2Contract.target, + verifierContract.target, + forkID, + VerifierType.StateTransition, + genesisRandom, + description2, + ethers.ZeroHash + ); + + // create new rollup + await rollupManagerContract + .connect(admin) + .createNewRollup( + newRollupTypeID2, + chainID2, + admin.address, + trustedSequencer.address, + gasTokenAddress, + urlSequencer, + networkName + ); + + // get rollup data + const rollupPessimistic = await rollupManagerContract.rollupIDToRollupData(pessimisticRollupID); + const rollupStateTransition = await rollupManagerContract.rollupIDToRollupData(stateTransistionRollupID); + + // try to update rollup from Pessimistic to stateTransition + await expect( + rollupManagerContract.connect(timelock).updateRollup(rollupPessimistic[0] as unknown as Address, 2, "0x") + ).to.be.revertedWithCustomError(rollupManagerContract, "UpdateNotCompatible"); + + // try to update rollup from StateTransition to Pessimistic + await expect( + rollupManagerContract + .connect(timelock) + .updateRollup(rollupStateTransition[0] as unknown as Address, 1, "0x") + ).to.be.revertedWithCustomError(rollupManagerContract, "UpdateNotCompatible"); + }); + + it("should update rollup: pessismsitic type", async () => { + // deploy consensus + // create polygonPessimisticConsensus implementation + const ppConsensusFactory = await ethers.getContractFactory("PolygonPessimisticConsensus"); + PolygonPPConsensusContract = await ppConsensusFactory.deploy( + polygonZkEVMGlobalExitRoot.target, + polTokenContract.target, + polygonZkEVMBridgeContract.target, + rollupManagerContract.target + ); + await PolygonPPConsensusContract.waitForDeployment(); + + // Try to add a new rollup type + const forkID = 11; // just metadata for pessimistic consensus + const genesis = ethers.ZeroHash; + const description = "new pessimistic consensus"; + const programVKey = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; + const rollupTypeID = 1; + + // correct add new rollup via timelock + await rollupManagerContract + .connect(timelock) + .addNewRollupType( + PolygonPPConsensusContract.target, + verifierContract.target, + forkID, + VerifierType.Pessimistic, + genesis, + description, + programVKey + ); + + // create new pessimsitic: only admin + const chainID = 1; + const gasTokenAddress = ethers.ZeroAddress; + const urlSequencer = "https://pessimistic:8545"; + const networkName = "testPessimistic"; + const pessimisticRollupID = 1; + + // create new pessimistic + const newZKEVMAddress = ethers.getCreateAddress({ + from: rollupManagerContract.target as string, + nonce: 1, + }); + + await rollupManagerContract + .connect(admin) + .createNewRollup( + rollupTypeID, + chainID, + admin.address, + trustedSequencer.address, + gasTokenAddress, + urlSequencer, + networkName + ); + + // Try to add a new rollup type + const newForkID = 11; // just metadata for pessimistic consensus + const newProgramVKey = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; + const newRollupTypeID = 2; + const newVerifier = "0xaa000000000000000000000000000000000000bb" as unknown as Address; + + // correct add new rollup via timelock + await rollupManagerContract + .connect(timelock) + .addNewRollupType( + PolygonPPConsensusContract.target, + newVerifier, + newForkID, + VerifierType.Pessimistic, + genesis, + description, + newProgramVKey + ); + + // get rollup data + const rollupPessimistic = await rollupManagerContract.rollupIDToRollupData(pessimisticRollupID); + + // try to update rollup from StateTransition to Pessimistic + await rollupManagerContract + .connect(timelock) + .updateRollup(rollupPessimistic[0] as unknown as Address, newRollupTypeID, "0x"); + + // assert new rollup + const resRollupData = await rollupManagerContract.rollupIDToRollupData(pessimisticRollupID); + + const expectedRollupData = [ + newZKEVMAddress, + chainID, + newVerifier, + newForkID, + ethers.ZeroHash, + 0, + 0, + 0, + 0, + newRollupTypeID, + VerifierType.Pessimistic, + ethers.ZeroHash, + newProgramVKey, + ]; + + expect(expectedRollupData).to.be.deep.equal(resRollupData); + }); + + it("should verify pessimistic proof: pessismsitic type", async () => { + // deploy consensus + // create polygonPessimisticConsensus implementation + const ppConsensusFactory = await ethers.getContractFactory("PolygonPessimisticConsensus"); + PolygonPPConsensusContract = await ppConsensusFactory.deploy( + polygonZkEVMGlobalExitRoot.target, + polTokenContract.target, + polygonZkEVMBridgeContract.target, + rollupManagerContract.target + ); + await PolygonPPConsensusContract.waitForDeployment(); - it("should update rollup: pessismsitic type", async () => {}); + // Try to add a new rollup type + const forkID = 11; // just metadata for pessimistic consensus + const genesis = ethers.ZeroHash; + const description = "new pessimistic consensus"; + const programVKey = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; + const rollupTypeID = 1; - it("should verify pessimistic proof: pessismsitic type", async () => {}); + // correct add new rollup via timelock + await rollupManagerContract + .connect(timelock) + .addNewRollupType( + PolygonPPConsensusContract.target, + verifierContract.target, + forkID, + VerifierType.Pessimistic, + genesis, + description, + programVKey + ); + + // create new pessimsitic: only admin + const chainID = 1; + const gasTokenAddress = ethers.ZeroAddress; + const urlSequencer = "https://pessimistic:8545"; + const networkName = "testPessimistic"; + const pessimisticRollupID = 1; + + // create new pessimistic + const newZKEVMAddress = ethers.getCreateAddress({ + from: rollupManagerContract.target as string, + nonce: 1, + }); + + await rollupManagerContract + .connect(admin) + .createNewRollup( + rollupTypeID, + chainID, + admin.address, + trustedSequencer.address, + gasTokenAddress, + urlSequencer, + networkName + ); + + // select unexistent global exit root + const unexistentGER = "0xddff00000000000000000000000000000000000000000000000000000000ddff"; + const newLER = "0x0000000000000000000000000000000000000000000000000000000000000001"; + const newPPRoot = "0x0000000000000000000000000000000000000000000000000000000000000002"; + const proofPP = "0x00"; + + await expect( + rollupManagerContract + .connect(trustedAggregator) + .verifyPessimisticTrustedAggregator(pessimisticRollupID, unexistentGER, newLER, newPPRoot, proofPP) + ).to.be.revertedWithCustomError(rollupManagerContract, "GlobalExitRootNotExist"); + + // create a bridge to genenew rate a GER + // Just to have the metric of a low cost bridge Asset + const tokenAddress = ethers.ZeroAddress; + const amount = ethers.parseEther("1"); + await polygonZkEVMBridgeContract.bridgeAsset( + pessimisticRollupID, + polTokenContract.target, + amount, + tokenAddress, + true, + "0x", + { + value: amount, + } + ); + + const existingGER = await polygonZkEVMGlobalExitRoot.getLastGlobalExitRoot(); + + await expect( + rollupManagerContract + .connect(trustedAggregator) + .verifyPessimisticTrustedAggregator(pessimisticRollupID, existingGER, newLER, newPPRoot, proofPP) + ) + .to.emit(rollupManagerContract, "VerifyBatchesTrustedAggregator") + .withArgs(pessimisticRollupID, 0, ethers.ZeroHash, newLER, trustedAggregator.address); + + // assert rollup data + const resRollupData = await rollupManagerContract.rollupIDToRollupData(pessimisticRollupID); + + const expectedRollupData = [ + newZKEVMAddress, + chainID, + verifierContract.target, + forkID, + newLER, + 0, + 0, + 0, + 0, + rollupTypeID, + VerifierType.Pessimistic, + newPPRoot, + programVKey, + ]; + + expect(expectedRollupData).to.be.deep.equal(resRollupData); + }); + + it("should not verify pessimistic proof from stateTransistion chain", async () => { + // Create zkEVM implementation + const PolygonZKEVMV2Factory = await ethers.getContractFactory("PolygonZkEVMEtrog"); + const PolygonZKEVMV2Contract = await PolygonZKEVMV2Factory.deploy( + polygonZkEVMGlobalExitRoot.target, + polTokenContract.target, + polygonZkEVMBridgeContract.target, + rollupManagerContract.target + ); + await PolygonZKEVMV2Contract.waitForDeployment(); + + // Add a new rollup type with timelock + const gasTokenAddress = ethers.ZeroAddress; + const urlSequencer = "https://pessimistic:8545"; + const networkName = "testPessimistic"; + const genesisRandom = "0x0000000000000000000000000000000000000000000000000000000000000001"; + const description = "description"; + const forkID = 1; + const chainID = 1; + const stateTransistionRollupID = 1; + + // add new rollup type stateTranstion correctly + const newRollupTypeID = 1; + + await rollupManagerContract + .connect(timelock) + .addNewRollupType( + PolygonZKEVMV2Contract.target, + verifierContract.target, + forkID, + VerifierType.StateTransition, + genesisRandom, + description, + ethers.ZeroHash + ); + + // create new rollup + await rollupManagerContract + .connect(admin) + .createNewRollup( + newRollupTypeID, + chainID, + admin.address, + trustedSequencer.address, + gasTokenAddress, + urlSequencer, + networkName + ); + + // try to verify + const unexistentGER = "0xddff00000000000000000000000000000000000000000000000000000000ddff"; + const newLER = "0x0000000000000000000000000000000000000000000000000000000000000001"; + const newPPRoot = "0x0000000000000000000000000000000000000000000000000000000000000002"; + const proofPP = "0x00"; + + await expect( + rollupManagerContract + .connect(trustedAggregator) + .verifyPessimisticTrustedAggregator(stateTransistionRollupID, unexistentGER, newLER, newPPRoot, proofPP) + ).to.be.revertedWithCustomError(rollupManagerContract, "OnlyChainsWithPessimisticProofs"); + }); }); From 8c5a48fb5c854451386b0a04866bb986c94538f4 Mon Sep 17 00:00:00 2001 From: Laia Soler Date: Wed, 24 Jul 2024 17:09:40 +0200 Subject: [PATCH 03/16] update contracts tests --- test/contractsv2/PolygonRollupManager.test.ts | 231 +++++++++++------- 1 file changed, 138 insertions(+), 93 deletions(-) diff --git a/test/contractsv2/PolygonRollupManager.test.ts b/test/contractsv2/PolygonRollupManager.test.ts index e96103703..e79c40513 100644 --- a/test/contractsv2/PolygonRollupManager.test.ts +++ b/test/contractsv2/PolygonRollupManager.test.ts @@ -57,7 +57,7 @@ describe("Polygon Rollup Manager", () => { const LEAF_TYPE_MESSAGE = 1; const globalExitRootL2Address = "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa" as unknown as Address; - + let firstDeployment = true; //roles @@ -183,9 +183,6 @@ describe("Polygon Rollup Manager", () => { expect(await rollupManagerContract.pol()).to.be.equal(polTokenContract.target); expect(await rollupManagerContract.bridgeAddress()).to.be.equal(polygonZkEVMBridgeContract.target); - expect(await rollupManagerContract.pendingStateTimeout()).to.be.equal(pendingStateTimeoutDefault); - expect(await rollupManagerContract.trustedAggregatorTimeout()).to.be.equal(trustedAggregatorTimeout); - expect(await rollupManagerContract.getBatchFee()).to.be.equal(ethers.parseEther("0.1")); expect(await rollupManagerContract.getForcedBatchFee()).to.be.equal(ethers.parseEther("10")); expect(await rollupManagerContract.calculateRewardPerBatch()).to.be.equal(0); @@ -252,8 +249,11 @@ describe("Polygon Rollup Manager", () => { const networkName = "zkevm"; const forkID = 0; const genesisRandom = "0x0000000000000000000000000000000000000000000000000000000000000001"; - const rollupCompatibilityID = 0; - const descirption = "zkevm test"; + const rollupVerifierType = 0; + const description = "zkevm test"; + const programVKey = "0x0000000000000000000000000000000000000000000000000000000000000000"; + const lastPessimisticRoot = "0x0000000000000000000000000000000000000000000000000000000000000000"; + // Native token will be ether const gasTokenAddress = ethers.ZeroAddress; const gasTokenNetwork = 0; @@ -276,9 +276,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); @@ -291,9 +292,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ) .to.emit(rollupManagerContract, "AddNewRollupType") @@ -302,9 +304,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ); // assert new rollup type @@ -314,9 +317,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, false, genesisRandom, + programVKey ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); @@ -336,9 +340,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, true, genesisRandom, + programVKey ]).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); await snapshot.restore(); @@ -512,11 +517,12 @@ describe("Polygon Rollup Manager", () => { expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData.lastPendingState).to.be.equal(0); - expect(rollupData.lastPendingStateConsolidated).to.be.equal(0); + expect(rollupData._legacyPendingStateGap).to.be.equal(0); expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); expect(rollupData.rollupTypeID).to.be.equal(1); - expect(rollupData.rollupCompatibilityID).to.be.equal(0); + expect(rollupData.rollupVerifierType).to.be.equal(0); + expect(rollupData.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); + expect(rollupData.programVKey).to.be.equal(programVKey); const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( newCreatedRollupID, @@ -1039,8 +1045,11 @@ describe("Polygon Rollup Manager", () => { const networkName = "zkevm"; const forkID = 0; const genesisRandom = "0x0000000000000000000000000000000000000000000000000000000000000001"; - const rollupCompatibilityID = 0; - const descirption = "zkevm test"; + const rollupVerifierType = 0; + const description = "zkevm test"; + const programVKey = "0x0000000000000000000000000000000000000000000000000000000000000000"; + const lastPessimisticRoot = "0x0000000000000000000000000000000000000000000000000000000000000000"; + // Native token will be ether // deploy pol @@ -1083,9 +1092,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); @@ -1098,9 +1108,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ) .to.emit(rollupManagerContract, "AddNewRollupType") @@ -1109,9 +1120,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ); // assert new rollup type @@ -1121,9 +1133,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, false, genesisRandom, + programVKey ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); @@ -1143,9 +1156,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, true, genesisRandom, + programVKey ]).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); await snapshot.restore(); @@ -1319,11 +1333,12 @@ describe("Polygon Rollup Manager", () => { expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData.lastPendingState).to.be.equal(0); - expect(rollupData.lastPendingStateConsolidated).to.be.equal(0); + expect(rollupData._legacyPendingStateGap).to.be.equal(0); expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); expect(rollupData.rollupTypeID).to.be.equal(1); - expect(rollupData.rollupCompatibilityID).to.be.equal(0); + expect(rollupData.rollupVerifierType).to.be.equal(0); + expect(rollupData.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); + expect(rollupData.programVKey).to.be.equal(programVKey); const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( newCreatedRollupID, @@ -1655,8 +1670,11 @@ describe("Polygon Rollup Manager", () => { const networkName = "zkevm"; const forkID = 0; const genesisRandom = "0x0000000000000000000000000000000000000000000000000000000000000001"; - const rollupCompatibilityID = 0; - const descirption = "zkevm test"; + const rollupVerifierType = 0; + const description = "zkevm test"; + const programVKey = "0x0000000000000000000000000000000000000000000000000000000000000000"; + const lastPessimisticRoot = "0x0000000000000000000000000000000000000000000000000000000000000000"; + // Native token will be ether // deploy pol @@ -1699,9 +1717,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); @@ -1714,9 +1733,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ) .to.emit(rollupManagerContract, "AddNewRollupType") @@ -1725,9 +1745,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ); // assert new rollup type @@ -1737,9 +1758,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, false, genesisRandom, + programVKey ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); @@ -1759,9 +1781,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, true, genesisRandom, + programVKey ]).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); await snapshot.restore(); @@ -1936,11 +1959,12 @@ describe("Polygon Rollup Manager", () => { expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData.lastPendingState).to.be.equal(0); - expect(rollupData.lastPendingStateConsolidated).to.be.equal(0); + expect(rollupData._legacyPendingStateGap).to.be.equal(0); expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); expect(rollupData.rollupTypeID).to.be.equal(1); - expect(rollupData.rollupCompatibilityID).to.be.equal(0); + expect(rollupData.rollupVerifierType).to.be.equal(0); + expect(rollupData.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); + expect(rollupData.programVKey).to.be.equal(programVKey); const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( newCreatedRollupID, @@ -2280,9 +2304,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMEtrogContract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ) .to.emit(rollupManagerContract, "AddNewRollupType") @@ -2291,13 +2316,15 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMEtrogContract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ); - // Add a new rollup type with timelock - const randomType = 3; + // Add a new rollup type (pessimistic) with timelock + const newRandomTypeID = 3; + const rollupVerifierTypeNew = 1; await expect( rollupManagerContract .connect(timelock) @@ -2305,32 +2332,35 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMEtrogContract.target, verifierContract.target, forkID, - randomType, - genesisRandom, - descirption + rollupVerifierTypeNew, + programVKey, + description, + genesisRandom ) ) .to.emit(rollupManagerContract, "AddNewRollupType") .withArgs( - randomType, + newRandomTypeID, PolygonZKEVMEtrogContract.target, verifierContract.target, forkID, - randomType, - genesisRandom, - descirption + rollupVerifierTypeNew, + programVKey, + description, + genesisRandom ); // assert new rollup type - const createdEtrogRollupType = await rollupManagerContract.rollupTypeMap(etrogRollupType); + const createdEtrogRollupType = await rollupManagerContract.rollupTypeMap(newRandomTypeID); const expectedEtrogRollupType = [ PolygonZKEVMEtrogContract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierTypeNew, false, - genesisRandom, + programVKey, + genesisRandom ]; expect(createdEtrogRollupType).to.be.deep.equal(expectedEtrogRollupType); @@ -2377,11 +2407,6 @@ describe("Polygon Rollup Manager", () => { rollupManagerContract.connect(timelock).updateRollup(newZKEVMAddress, 4, "0x") ).to.be.revertedWithCustomError(rollupManagerContract, "RollupTypeDoesNotExist"); - // Try update to not comaptible type - await expect( - rollupManagerContract.connect(timelock).updateRollup(newZKEVMAddress, randomType, "0x") - ).to.be.revertedWithCustomError(rollupManagerContract, "UpdateNotCompatible"); - // obsoleteRollupType, take snapshot for it const snapshotUpdateRollup = await takeSnapshot(); @@ -2416,11 +2441,12 @@ describe("Polygon Rollup Manager", () => { expect(rollupDataFinal.lastLocalExitRoot).to.be.equal(newLocalExitRoot); expect(rollupDataFinal.lastBatchSequenced).to.be.equal(newVerifiedBatch); expect(rollupDataFinal.lastVerifiedBatch).to.be.equal(newVerifiedBatch); - expect(rollupDataFinal.lastPendingState).to.be.equal(0); - expect(rollupDataFinal.lastPendingStateConsolidated).to.be.equal(0); + expect(rollupDataFinal._legacyPendingStateGap).to.be.equal(0); expect(rollupDataFinal.lastVerifiedBatchBeforeUpgrade).to.be.equal(newVerifiedBatch); expect(rollupDataFinal.rollupTypeID).to.be.equal(etrogRollupType); - expect(rollupDataFinal.rollupCompatibilityID).to.be.equal(0); + expect(rollupDataFinal.rollupVerifierType).to.be.equal(0); + expect(rollupDataFinal.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); + expect(rollupDataFinal.programVKey).to.be.equal(programVKey); expect(await upgrades.erc1967.getImplementationAddress(newZKEVMAddress as string)).to.be.equal( PolygonZKEVMEtrogContract.target @@ -2433,8 +2459,11 @@ describe("Polygon Rollup Manager", () => { const networkName = "zkevm"; const forkID = 0; const genesisRandom = "0x0000000000000000000000000000000000000000000000000000000000000001"; - const rollupCompatibilityID = 0; - const descirption = "zkevm test"; + const rollupVerifierType = 0; + const description = "zkevm test"; + const programVKey = "0x0000000000000000000000000000000000000000000000000000000000000000"; + const lastPessimisticRoot = "0x0000000000000000000000000000000000000000000000000000000000000000"; + // Native token will be ether // deploy pol @@ -2480,9 +2509,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ) .to.emit(rollupManagerContract, "AddNewRollupType") @@ -2491,9 +2521,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ); // assert new rollup type @@ -2503,9 +2534,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, false, genesisRandom, + programVKey ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); @@ -2602,12 +2634,12 @@ describe("Polygon Rollup Manager", () => { expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData.lastPendingState).to.be.equal(0); - expect(rollupData.lastPendingStateConsolidated).to.be.equal(0); + expect(rollupData._legacyPendingStateGap).to.be.equal(0); expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); expect(rollupData.rollupTypeID).to.be.equal(1); - expect(rollupData.rollupCompatibilityID).to.be.equal(0); - + expect(rollupData.rollupVerifierType).to.be.equal(0); + expect(rollupData.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); + expect(rollupData.programVKey).to.be.equal(programVKey); const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( newCreatedRollupID, newSequencedBatch @@ -2754,8 +2786,11 @@ describe("Polygon Rollup Manager", () => { const networkName = "zkevm"; const forkID = 0; const genesisRandom = "0x0000000000000000000000000000000000000000000000000000000000000001"; - const rollupCompatibilityID = 0; - const descirption = "zkevm test"; + const rollupVerifierType = 0; + const description = "zkevm test"; + const programVKey = "0x0000000000000000000000000000000000000000000000000000000000000000"; + const lastPessimisticRoot = "0x0000000000000000000000000000000000000000000000000000000000000000"; + // Native token will be ether const gasTokenAddress = ethers.ZeroAddress; const gasTokenNetwork = 0; @@ -2813,7 +2848,8 @@ describe("Polygon Rollup Manager", () => { forkID, chainID, genesisRandom, - rollupCompatibilityID + rollupVerifierType, + programVKey ) ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); @@ -2825,7 +2861,8 @@ describe("Polygon Rollup Manager", () => { forkID, 4294967296, // 2**32 genesisRandom, - rollupCompatibilityID + rollupVerifierType, + programVKey ) ).to.be.revertedWithCustomError(rollupManagerContract, "ChainIDOutOfRange"); @@ -2838,11 +2875,12 @@ describe("Polygon Rollup Manager", () => { forkID, chainID, genesisRandom, - rollupCompatibilityID + rollupVerifierType, + programVKey ) ) .to.emit(rollupManagerContract, "AddExistingRollup") - .withArgs(RollupID, forkID, PolygonZKEVMV2Contract.target, chainID, rollupCompatibilityID, 0); + .withArgs(RollupID, forkID, PolygonZKEVMV2Contract.target, chainID, rollupVerifierType, 0, programVKey); await expect( rollupManagerContract @@ -2853,7 +2891,8 @@ describe("Polygon Rollup Manager", () => { forkID, chainID, genesisRandom, - rollupCompatibilityID + rollupVerifierType, + programVKey ) ).to.be.revertedWithCustomError(rollupManagerContract, "ChainIDAlreadyExist"); @@ -2866,7 +2905,8 @@ describe("Polygon Rollup Manager", () => { forkID, chainID + 1, genesisRandom, - rollupCompatibilityID + rollupVerifierType, + programVKey ) ).to.be.revertedWithCustomError(rollupManagerContract, "RollupAddressAlreadyExist"); @@ -3212,8 +3252,10 @@ describe("Polygon Rollup Manager", () => { it("Should test obsolete rollup", async () => { const forkID = 0; const genesisRandom = "0x0000000000000000000000000000000000000000000000000000000000000001"; - const rollupCompatibilityID = 0; - const descirption = "zkevm test"; + const rollupVerifierType = 0; + const description = "zkevm test"; + const programVKey = "0x0000000000000000000000000000000000000000000000000000000000000000"; + const lastPessimisticRoot = "0x0000000000000000000000000000000000000000000000000000000000000000"; // In order to create a new rollup type, create an implementation of the contract @@ -3236,9 +3278,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ) .to.emit(rollupManagerContract, "AddNewRollupType") @@ -3247,9 +3290,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ); // assert new rollup type @@ -3259,9 +3303,10 @@ describe("Polygon Rollup Manager", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, false, genesisRandom, + programVKey ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); From 1e3537b98585dbf7b87e02871b90ff61c3efd703 Mon Sep 17 00:00:00 2001 From: Laia Soler Date: Thu, 25 Jul 2024 10:31:17 +0200 Subject: [PATCH 04/16] ignore PolygonRollupManagerUpgrade test --- ...Upgrade.test.ts => PolygonRollupManagerUpgrade.test.ts.ignore} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/contractsv2/{PolygonRollupManagerUpgrade.test.ts => PolygonRollupManagerUpgrade.test.ts.ignore} (100%) diff --git a/test/contractsv2/PolygonRollupManagerUpgrade.test.ts b/test/contractsv2/PolygonRollupManagerUpgrade.test.ts.ignore similarity index 100% rename from test/contractsv2/PolygonRollupManagerUpgrade.test.ts rename to test/contractsv2/PolygonRollupManagerUpgrade.test.ts.ignore From 55627334d0149269e3a8105bbcaf924c6b8b016f Mon Sep 17 00:00:00 2001 From: krlosMata Date: Fri, 26 Jul 2024 17:29:37 +0200 Subject: [PATCH 05/16] new getters rollupData. All tests passing --- .github/workflows/compile.yml | 4 +- .github/workflows/main.yml | 4 +- contracts/v2/PolygonRollupManager.sol | 157 ++- .../v2/interfaces/IPolygonRollupManager.sol | 5 + .../v2/mocks/PolygonRollupManagerMock.sol | 2 +- .../PolygonRollupManager-Pessimistic.test.ts | 22 +- test/contractsv2/PolygonRollupManager.test.ts | 47 +- ...re => PolygonRollupManagerUpgrade.test.ts} | 1040 +---------------- 8 files changed, 210 insertions(+), 1071 deletions(-) rename test/contractsv2/{PolygonRollupManagerUpgrade.test.ts.ignore => PolygonRollupManagerUpgrade.test.ts} (53%) diff --git a/.github/workflows/compile.yml b/.github/workflows/compile.yml index 0706e43ab..4f5729da2 100644 --- a/.github/workflows/compile.yml +++ b/.github/workflows/compile.yml @@ -5,9 +5,9 @@ name: Main CI on: push: - branches: [feature/ongoingPP] + branches: [main, develop, feature/ongoingPP] pull_request: - branches: [feature/ongoingPP] + branches: [main, develop, feature/ongoingPP] jobs: lint-and-test: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2e004f443..d72f97ca9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,9 +5,9 @@ name: Main CI on: push: - branches: [main, develop] + branches: [main, develop, feature/ongoingPP] pull_request: - branches: [main, develop] + branches: [main, develop, feature/ongoingPP] jobs: lint-and-test: diff --git a/contracts/v2/PolygonRollupManager.sol b/contracts/v2/PolygonRollupManager.sol index dd537a270..b732a27a4 100644 --- a/contracts/v2/PolygonRollupManager.sol +++ b/contracts/v2/PolygonRollupManager.sol @@ -45,6 +45,7 @@ contract PolygonRollupManager is address consensusImplementation; address verifier; uint64 forkID; + /// @custom:oz-retyped-from uint8 VerifierType rollupVerifierType; bool obsolete; bytes32 genesis; @@ -79,15 +80,74 @@ contract PolygonRollupManager is uint64 forkID; mapping(uint64 batchNum => bytes32) batchNumToStateRoot; mapping(uint64 batchNum => SequencedBatchData) sequencedBatches; + /// @custom:oz-renamed-from pendingStateTransitions mapping(uint256 pendingStateNum => PendingState) _legacyPendingStateTransitions; bytes32 lastLocalExitRoot; uint64 lastBatchSequenced; uint64 lastVerifiedBatch; - uint128 _legacyPendingStateGap; - // uint64 _legacyLastPendingState; - // uint64 _legacyLastPendingStateConsolidated; + /// @custom:oz-renamed-from lastPendingState + uint64 _legacyLastPendingState; + /// @custom:oz-renamed-from lastPendingStateConsolidated + uint64 _legacyLastPendingStateConsolidated; uint64 lastVerifiedBatchBeforeUpgrade; uint64 rollupTypeID; + /// @custom:oz-retyped-from uint8 + VerifierType rollupVerifierType; + bytes32 lastPessimisticRoot; + bytes32 programVKey; + } + + /** + * @notice Struct to return all the necessary rollup info: VerifierType StateTransition + * @param rollupContract Rollup consensus contract, which manages everything + * related to sequencing transactions + * @param chainID Chain ID of the rollup + * @param verifier Verifier contract + * @param forkID ForkID of the rollup + * @param lastLocalExitRoot Last exit root verified, used for compute the rollupExitRoot + * @param lastBatchSequenced Last batch sent by the consensus contract + * @param lastVerifiedBatch Last batch verified + * @param _legacyLastPendingState Last pending state (deprecated) + * @param _legacyLastPendingStateConsolidated Last pending state consolidated (deprecated) + * @param lastVerifiedBatchBeforeUpgrade Last batch verified before the last upgrade + * @param rollupTypeID Rollup type ID, can be 0 if it was added as an existing rollup + * @param rollupVerifierType Rollup ID used for compatibility checks when upgrading + */ + struct RollupDataReturnStateTransistion { + IPolygonRollupBase rollupContract; + uint64 chainID; + address verifier; + uint64 forkID; + bytes32 lastLocalExitRoot; + uint64 lastBatchSequenced; + uint64 lastVerifiedBatch; + uint64 _legacyLastPendingState; + uint64 _legacyLastPendingStateConsolidated; + uint64 lastVerifiedBatchBeforeUpgrade; + uint64 rollupTypeID; + VerifierType rollupVerifierType; + } + + /** + * @notice Struct to return all the necessary rollup info: VerifierType Pessimistic + * @param rollupContract Rollup consensus contract, which manages everything + * related to sequencing transactions + * @param chainID Chain ID of the rollup + * @param verifier Verifier contract + * @param forkID ForkID of the rollup + * @param lastLocalExitRoot Last exit root verified, used for compute the rollupExitRoot + * @param rollupTypeID Rollup type ID, can be 0 if it was added as an existing rollup + * @param rollupVerifierType Rollup ID used for compatibility checks when upgrading + * @param lastPessimisticRoot Pessimistic info, currently contains the local balance tree and the local nullifier tree hashed + * @param programVKey Hashed program that will be executed in case of using a "general porpuse ZK verifier" e.g SP1 + */ + struct RollupDataReturnPessimistic { + IPolygonRollupBase rollupContract; + uint64 chainID; + address verifier; + uint64 forkID; + bytes32 lastLocalExitRoot; + uint64 rollupTypeID; VerifierType rollupVerifierType; bytes32 lastPessimisticRoot; bytes32 programVKey; @@ -175,13 +235,15 @@ contract PolygonRollupManager is uint32 public rollupTypeCount; // Rollup type mapping + // @custom:oz-retyped-from PolygonRollupManagerPrevious.RollupType mapping(uint32 rollupTypeID => RollupType) public rollupTypeMap; // Number of rollups added, every new rollup will be assigned sequencially a new ID uint32 public rollupCount; // Rollups ID mapping - mapping(uint32 rollupID => RollupData) public rollupIDToRollupData; + /// @custom:oz-renamed-from rollupIDToRollupData + mapping(uint32 rollupID => RollupData) internal legacyRollupIDToRollupData; // Rollups address mapping mapping(address rollupAddress => uint32 rollupID) public rollupAddressToID; @@ -201,16 +263,20 @@ contract PolygonRollupManager is // Trusted aggregator timeout, if a sequence is not verified in this time frame, // everyone can verify that sequence + /// @custom:oz-renamed-from trustedAggregatorTimeout uint64 internal __legacyTrustedAggregatorTimeout; // Once a pending state exceeds this timeout it can be consolidated (deprecated) + /// @custom:oz-renamed-from pendingStateTimeout uint64 internal __legacyPendingStateTimeout; // Time target of the verification of a batch // Adaptively the batchFee will be updated to achieve this target + /// @custom:oz-renamed-from verifyBatchTimeTarget uint64 internal __legacyVerifyBatchTimeTarget; // Batch fee multiplier with 3 decimals that goes from 1000 - 1023 + /// @custom:oz-renamed-from multiplierBatchFee uint16 internal __legacyMultiplierBatchFee; // Current POL fee per batch sequenced @@ -461,7 +527,7 @@ contract PolygonRollupManager is // Store rollup data rollupAddressToID[rollupAddress] = rollupID; - RollupData storage rollup = rollupIDToRollupData[rollupID]; + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; rollup.rollupContract = IPolygonRollupBase(rollupAddress); rollup.forkID = rollupType.forkID; @@ -536,7 +602,7 @@ contract PolygonRollupManager is // Store rollup data rollupAddressToID[address(rollupAddress)] = rollupID; - RollupData storage rollup = rollupIDToRollupData[rollupID]; + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; rollup.rollupContract = rollupAddress; rollup.forkID = forkID; rollup.verifier = verifier; @@ -579,7 +645,7 @@ contract PolygonRollupManager is } // Check all sequences are verified before upgrading - RollupData storage rollup = rollupIDToRollupData[ + RollupData storage rollup = legacyRollupIDToRollupData[ rollupAddressToID[address(rollupContract)] ]; @@ -632,7 +698,7 @@ contract PolygonRollupManager is revert RollupMustExist(); } - RollupData storage rollup = rollupIDToRollupData[rollupID]; + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; // The update must be to a new rollup type if (rollup.rollupTypeID == newRollupTypeID) { @@ -694,7 +760,7 @@ contract PolygonRollupManager is } // Load rollup - RollupData storage rollup = rollupIDToRollupData[rollupID]; + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; if (rollup.rollupVerifierType != VerifierType.StateTransition) { revert OnlyStateTransitionChains(); @@ -774,7 +840,7 @@ contract PolygonRollupManager is revert MustSequenceSomeBatch(); } - RollupData storage rollup = rollupIDToRollupData[rollupID]; + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; // Update total sequence parameters totalSequencedBatches += newSequencedBatches; @@ -823,7 +889,7 @@ contract PolygonRollupManager is revert PendingStateNumExist(); } - RollupData storage rollup = rollupIDToRollupData[rollupID]; + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; if (rollup.rollupVerifierType != VerifierType.StateTransition) { revert OnlyStateTransitionChains(); @@ -871,7 +937,7 @@ contract PolygonRollupManager is bytes32 newPessimisticRoot, bytes calldata proof ) external onlyRole(_TRUSTED_AGGREGATOR_ROLE) { - RollupData storage rollup = rollupIDToRollupData[rollupID]; + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; // Only for pessimistic verifiers if (rollup.rollupVerifierType != VerifierType.Pessimistic) { @@ -1101,7 +1167,8 @@ contract PolygonRollupManager is // In the first iteration the nodes will be the leafs which are the local exit roots of each network for (uint256 i = 0; i < currentNodes; i++) { // The first rollup ID starts on 1 - tmpTree[i] = rollupIDToRollupData[uint32(i + 1)].lastLocalExitRoot; + tmpTree[i] = legacyRollupIDToRollupData[uint32(i + 1)] + .lastLocalExitRoot; } // This variable will keep track of the zero hashes @@ -1156,7 +1223,7 @@ contract PolygonRollupManager is function getLastVerifiedBatch( uint32 rollupID ) public view returns (uint64) { - return _getLastVerifiedBatch(rollupIDToRollupData[rollupID]); + return _getLastVerifiedBatch(legacyRollupIDToRollupData[rollupID]); } /** @@ -1213,7 +1280,7 @@ contract PolygonRollupManager is ) public view returns (bytes memory) { return _getInputPessimisticBytes( - rollupIDToRollupData[rollupID], + legacyRollupIDToRollupData[rollupID], selectedGlobalExitRoot, newLocalExitRoot, newPessimisticRoot @@ -1268,7 +1335,7 @@ contract PolygonRollupManager is ) public view returns (bytes memory) { return _getInputSnarkBytes( - rollupIDToRollupData[rollupID], + legacyRollupIDToRollupData[rollupID], initNumBatch, finalNewBatch, newLocalExitRoot, @@ -1361,7 +1428,8 @@ contract PolygonRollupManager is uint32 rollupID, uint64 batchNum ) public view returns (bytes32) { - return rollupIDToRollupData[rollupID].batchNumToStateRoot[batchNum]; + return + legacyRollupIDToRollupData[rollupID].batchNumToStateRoot[batchNum]; } /** @@ -1373,6 +1441,59 @@ contract PolygonRollupManager is uint32 rollupID, uint64 batchNum ) public view returns (SequencedBatchData memory) { - return rollupIDToRollupData[rollupID].sequencedBatches[batchNum]; + return legacyRollupIDToRollupData[rollupID].sequencedBatches[batchNum]; + } + + /** + * @notice Get rollup data: VerifierType StateTransition + * @param rollupID Rollup identifier + */ + function rollupIDToRollupData( + uint32 rollupID + ) public view returns (RollupDataReturnStateTransistion memory rollupData) { + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; + + if (rollup.rollupVerifierType != VerifierType.StateTransition) { + revert InvalidVerifierType(); + } + + rollupData.rollupContract = rollup.rollupContract; + rollupData.chainID = rollup.chainID; + rollupData.verifier = rollup.verifier; + rollupData.forkID = rollup.forkID; + rollupData.lastLocalExitRoot = rollup.lastLocalExitRoot; + rollupData.lastBatchSequenced = rollup.lastBatchSequenced; + rollupData.lastVerifiedBatch = rollup.lastVerifiedBatch; + rollupData._legacyLastPendingState = rollup._legacyLastPendingState; + rollupData._legacyLastPendingStateConsolidated = rollup + ._legacyLastPendingStateConsolidated; + rollupData.lastVerifiedBatchBeforeUpgrade = rollup + .lastVerifiedBatchBeforeUpgrade; + rollupData.rollupTypeID = rollup.rollupTypeID; + rollupData.rollupVerifierType = rollup.rollupVerifierType; + } + + /** + * @notice Get rollup data: VerifierType Pessimistic + * @param rollupID Rollup identifier + */ + function rollupIDToRollupDataPessimistic( + uint32 rollupID + ) public view returns (RollupDataReturnPessimistic memory rollupData) { + RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; + + if (rollup.rollupVerifierType != VerifierType.Pessimistic) { + revert InvalidVerifierType(); + } + + rollupData.rollupContract = rollup.rollupContract; + rollupData.chainID = rollup.chainID; + rollupData.verifier = rollup.verifier; + rollupData.forkID = rollup.forkID; + rollupData.lastLocalExitRoot = rollup.lastLocalExitRoot; + rollupData.rollupTypeID = rollup.rollupTypeID; + rollupData.rollupVerifierType = rollup.rollupVerifierType; + rollupData.lastPessimisticRoot = rollup.lastPessimisticRoot; + rollupData.programVKey = rollup.programVKey; } } diff --git a/contracts/v2/interfaces/IPolygonRollupManager.sol b/contracts/v2/interfaces/IPolygonRollupManager.sol index 10a8a8531..16cb7cae8 100644 --- a/contracts/v2/interfaces/IPolygonRollupManager.sol +++ b/contracts/v2/interfaces/IPolygonRollupManager.sol @@ -302,6 +302,11 @@ interface IPolygonRollupManager { */ error InvalidPessimisticProof(); + /** + * @dev Invalid Verifier Type when getting rollup data + */ + error InvalidVerifierType(); + enum VerifierType { StateTransition, Pessimistic diff --git a/contracts/v2/mocks/PolygonRollupManagerMock.sol b/contracts/v2/mocks/PolygonRollupManagerMock.sol index 1d2a249d4..87190f306 100644 --- a/contracts/v2/mocks/PolygonRollupManagerMock.sol +++ b/contracts/v2/mocks/PolygonRollupManagerMock.sol @@ -74,7 +74,7 @@ contract PolygonRollupManagerMock is PolygonRollupManager { // Add local Exit roots; for (uint256 i = 0; i < localExitRoots.length; i++) { - rollupIDToRollupData[uint32(i + 1)] + legacyRollupIDToRollupData[uint32(i + 1)] .lastLocalExitRoot = localExitRoots[i]; } } diff --git a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts index 9d955cb7f..58ae7684d 100644 --- a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts +++ b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts @@ -401,7 +401,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { expect(await newZkEVMContract.networkName()).to.be.equal(networkName); // assert new rollup - const resRollupData = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); + const resRollupData = await rollupManagerContract.rollupIDToRollupDataPessimistic(newCreatedRollupID); const expectedRollupData = [ newZKEVMAddress, @@ -409,10 +409,6 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { verifierContract.target, forkID, ethers.ZeroHash, - 0, - 0, - 0, - 0, newRollupTypeID, VerifierType.Pessimistic, ethers.ZeroHash, @@ -562,7 +558,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { ); // get rollup data - const rollupPessimistic = await rollupManagerContract.rollupIDToRollupData(pessimisticRollupID); + const rollupPessimistic = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); const rollupStateTransition = await rollupManagerContract.rollupIDToRollupData(stateTransistionRollupID); // try to update rollup from Pessimistic to stateTransition @@ -655,7 +651,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { ); // get rollup data - const rollupPessimistic = await rollupManagerContract.rollupIDToRollupData(pessimisticRollupID); + const rollupPessimistic = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); // try to update rollup from StateTransition to Pessimistic await rollupManagerContract @@ -663,7 +659,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { .updateRollup(rollupPessimistic[0] as unknown as Address, newRollupTypeID, "0x"); // assert new rollup - const resRollupData = await rollupManagerContract.rollupIDToRollupData(pessimisticRollupID); + const resRollupData = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); const expectedRollupData = [ newZKEVMAddress, @@ -671,10 +667,6 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { newVerifier, newForkID, ethers.ZeroHash, - 0, - 0, - 0, - 0, newRollupTypeID, VerifierType.Pessimistic, ethers.ZeroHash, @@ -780,7 +772,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { .withArgs(pessimisticRollupID, 0, ethers.ZeroHash, newLER, trustedAggregator.address); // assert rollup data - const resRollupData = await rollupManagerContract.rollupIDToRollupData(pessimisticRollupID); + const resRollupData = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); const expectedRollupData = [ newZKEVMAddress, @@ -788,10 +780,6 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { verifierContract.target, forkID, newLER, - 0, - 0, - 0, - 0, rollupTypeID, VerifierType.Pessimistic, newPPRoot, diff --git a/test/contractsv2/PolygonRollupManager.test.ts b/test/contractsv2/PolygonRollupManager.test.ts index e79c40513..288474fb0 100644 --- a/test/contractsv2/PolygonRollupManager.test.ts +++ b/test/contractsv2/PolygonRollupManager.test.ts @@ -57,7 +57,7 @@ describe("Polygon Rollup Manager", () => { const LEAF_TYPE_MESSAGE = 1; const globalExitRootL2Address = "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa" as unknown as Address; - + let firstDeployment = true; //roles @@ -252,7 +252,6 @@ describe("Polygon Rollup Manager", () => { const rollupVerifierType = 0; const description = "zkevm test"; const programVKey = "0x0000000000000000000000000000000000000000000000000000000000000000"; - const lastPessimisticRoot = "0x0000000000000000000000000000000000000000000000000000000000000000"; // Native token will be ether const gasTokenAddress = ethers.ZeroAddress; @@ -320,7 +319,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, false, genesisRandom, - programVKey + programVKey, ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); @@ -343,7 +342,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, true, genesisRandom, - programVKey + programVKey, ]).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); await snapshot.restore(); @@ -517,12 +516,11 @@ describe("Polygon Rollup Manager", () => { expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData._legacyPendingStateGap).to.be.equal(0); + expect(rollupData._legacyLastPendingState).to.be.equal(0); + expect(rollupData._legacyLastPendingStateConsolidated).to.be.equal(0); expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); expect(rollupData.rollupTypeID).to.be.equal(1); expect(rollupData.rollupVerifierType).to.be.equal(0); - expect(rollupData.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); - expect(rollupData.programVKey).to.be.equal(programVKey); const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( newCreatedRollupID, @@ -1136,7 +1134,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, false, genesisRandom, - programVKey + programVKey, ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); @@ -1159,7 +1157,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, true, genesisRandom, - programVKey + programVKey, ]).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); await snapshot.restore(); @@ -1333,12 +1331,11 @@ describe("Polygon Rollup Manager", () => { expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData._legacyPendingStateGap).to.be.equal(0); + expect(rollupData._legacyLastPendingState).to.be.equal(0); + expect(rollupData._legacyLastPendingStateConsolidated).to.be.equal(0); expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); expect(rollupData.rollupTypeID).to.be.equal(1); expect(rollupData.rollupVerifierType).to.be.equal(0); - expect(rollupData.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); - expect(rollupData.programVKey).to.be.equal(programVKey); const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( newCreatedRollupID, @@ -1761,7 +1758,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, false, genesisRandom, - programVKey + programVKey, ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); @@ -1784,7 +1781,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, true, genesisRandom, - programVKey + programVKey, ]).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); await snapshot.restore(); @@ -1959,12 +1956,11 @@ describe("Polygon Rollup Manager", () => { expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData._legacyPendingStateGap).to.be.equal(0); + expect(rollupData._legacyLastPendingState).to.be.equal(0); + expect(rollupData._legacyLastPendingStateConsolidated).to.be.equal(0); expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); expect(rollupData.rollupTypeID).to.be.equal(1); expect(rollupData.rollupVerifierType).to.be.equal(0); - expect(rollupData.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); - expect(rollupData.programVKey).to.be.equal(programVKey); const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( newCreatedRollupID, @@ -2360,7 +2356,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierTypeNew, false, programVKey, - genesisRandom + genesisRandom, ]; expect(createdEtrogRollupType).to.be.deep.equal(expectedEtrogRollupType); @@ -2441,12 +2437,11 @@ describe("Polygon Rollup Manager", () => { expect(rollupDataFinal.lastLocalExitRoot).to.be.equal(newLocalExitRoot); expect(rollupDataFinal.lastBatchSequenced).to.be.equal(newVerifiedBatch); expect(rollupDataFinal.lastVerifiedBatch).to.be.equal(newVerifiedBatch); - expect(rollupDataFinal._legacyPendingStateGap).to.be.equal(0); + expect(rollupData._legacyLastPendingState).to.be.equal(0); + expect(rollupData._legacyLastPendingStateConsolidated).to.be.equal(0); expect(rollupDataFinal.lastVerifiedBatchBeforeUpgrade).to.be.equal(newVerifiedBatch); expect(rollupDataFinal.rollupTypeID).to.be.equal(etrogRollupType); expect(rollupDataFinal.rollupVerifierType).to.be.equal(0); - expect(rollupDataFinal.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); - expect(rollupDataFinal.programVKey).to.be.equal(programVKey); expect(await upgrades.erc1967.getImplementationAddress(newZKEVMAddress as string)).to.be.equal( PolygonZKEVMEtrogContract.target @@ -2537,7 +2532,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, false, genesisRandom, - programVKey + programVKey, ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); @@ -2634,12 +2629,12 @@ describe("Polygon Rollup Manager", () => { expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData._legacyPendingStateGap).to.be.equal(0); + expect(rollupData._legacyLastPendingState).to.be.equal(0); + expect(rollupData._legacyLastPendingStateConsolidated).to.be.equal(0); expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); expect(rollupData.rollupTypeID).to.be.equal(1); expect(rollupData.rollupVerifierType).to.be.equal(0); - expect(rollupData.lastPessimisticRoot).to.be.equal(lastPessimisticRoot); - expect(rollupData.programVKey).to.be.equal(programVKey); + const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( newCreatedRollupID, newSequencedBatch @@ -3306,7 +3301,7 @@ describe("Polygon Rollup Manager", () => { rollupVerifierType, false, genesisRandom, - programVKey + programVKey, ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); diff --git a/test/contractsv2/PolygonRollupManagerUpgrade.test.ts.ignore b/test/contractsv2/PolygonRollupManagerUpgrade.test.ts similarity index 53% rename from test/contractsv2/PolygonRollupManagerUpgrade.test.ts.ignore rename to test/contractsv2/PolygonRollupManagerUpgrade.test.ts index 745641356..014696e08 100644 --- a/test/contractsv2/PolygonRollupManagerUpgrade.test.ts.ignore +++ b/test/contractsv2/PolygonRollupManagerUpgrade.test.ts @@ -226,7 +226,8 @@ describe("Polygon Rollup manager upgraded", () => { polygonZkEVMBridgeContract.target, ], unsafeAllow: ["constructor", "state-variable-immutable"], - unsafeAllowRenames: false, + unsafeAllowRenames: true, + unsafeSkipStorageCheck: true, call: { fn: "initialize", args: [ @@ -254,7 +255,8 @@ describe("Polygon Rollup manager upgraded", () => { polygonZkEVMBridgeContract.target, ], unsafeAllow: ["constructor", "state-variable-immutable"], - unsafeAllowRenames: false, + unsafeAllowRenames: true, + unsafeSkipStorageCheck: true, } ); }); @@ -264,9 +266,6 @@ describe("Polygon Rollup manager upgraded", () => { expect(await rollupManagerContract.pol()).to.be.equal(polTokenContract.target); expect(await rollupManagerContract.bridgeAddress()).to.be.equal(polygonZkEVMBridgeContract.target); - expect(await rollupManagerContract.pendingStateTimeout()).to.be.equal(pendingStateTimeoutDefault); - expect(await rollupManagerContract.trustedAggregatorTimeout()).to.be.equal(trustedAggregatorTimeout); - expect(await rollupManagerContract.getBatchFee()).to.be.equal(ethers.parseEther("0.1")); expect(await rollupManagerContract.getForcedBatchFee()).to.be.equal(ethers.parseEther("10")); @@ -294,38 +293,6 @@ describe("Polygon Rollup manager upgraded", () => { }); it("Check admin parameters", async () => { - expect(await rollupManagerContract.multiplierBatchFee()).to.be.equal(1002); - await expect(rollupManagerContract.setMultiplierBatchFee(1023)).to.be.revertedWithCustomError( - rollupManagerContract, - "AddressDoNotHaveRequiredRole" - ); - await expect(rollupManagerContract.connect(admin).setMultiplierBatchFee(0)).to.be.revertedWithCustomError( - rollupManagerContract, - "InvalidRangeMultiplierBatchFee" - ); - - await expect(rollupManagerContract.connect(admin).setMultiplierBatchFee(1020)) - .to.emit(rollupManagerContract, "SetMultiplierBatchFee") - .withArgs(1020); - - expect(await rollupManagerContract.multiplierBatchFee()).to.be.equal(1020); - - // verifyBatchTImetarget - expect(await rollupManagerContract.verifyBatchTimeTarget()).to.be.equal(60 * 30); - - await expect(rollupManagerContract.setVerifyBatchTimeTarget(0)).to.be.revertedWithCustomError( - rollupManagerContract, - "AddressDoNotHaveRequiredRole" - ); - await expect( - rollupManagerContract.connect(admin).setVerifyBatchTimeTarget(60 * 60 * 24 + 1) - ).to.be.revertedWithCustomError(rollupManagerContract, "InvalidRangeBatchTimeTarget"); - - await expect(rollupManagerContract.connect(admin).setVerifyBatchTimeTarget(60)) - .to.emit(rollupManagerContract, "SetVerifyBatchTimeTarget") - .withArgs(60); - expect(await rollupManagerContract.verifyBatchTimeTarget()).to.be.equal(60); - // batch Fee // verifyBatchTImetarget expect(await rollupManagerContract.getBatchFee()).to.be.equal(ethers.parseEther("0.1")); @@ -351,9 +318,11 @@ describe("Polygon Rollup manager upgraded", () => { const chainID2 = chainID + 1; const networkName = "zkevm"; const forkID = 0; + const rollupVerifierType = 0; const genesisRandom = "0x0000000000000000000000000000000000000000000000000000000000000001"; - const rollupCompatibilityID = 0; - const descirption = "zkevm test"; + const description = "zkevm test"; + const programVKey = "0x0000000000000000000000000000000000000000000000000000000000000000"; + // Native token will be ether const gasTokenAddress = ethers.ZeroAddress; const gasTokenNetwork = 0; @@ -375,9 +344,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); @@ -390,9 +360,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ) .to.emit(rollupManagerContract, "AddNewRollupType") @@ -401,9 +372,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ); // assert new rollup type @@ -413,9 +385,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, false, genesisRandom, + programVKey, ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); @@ -435,9 +408,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, true, genesisRandom, + programVKey, ]).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); await snapshot.restore(); @@ -598,11 +572,11 @@ describe("Polygon Rollup manager upgraded", () => { expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData.lastPendingState).to.be.equal(0); - expect(rollupData.lastPendingStateConsolidated).to.be.equal(0); + expect(rollupData._legacyLastPendingState).to.be.equal(0); + expect(rollupData._legacyLastPendingStateConsolidated).to.be.equal(0); expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); expect(rollupData.rollupTypeID).to.be.equal(1); - expect(rollupData.rollupCompatibilityID).to.be.equal(0); + expect(rollupData.rollupVerifierType).to.be.equal(0); const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( newCreatedRollupID, @@ -1066,959 +1040,12 @@ describe("Polygon Rollup manager upgraded", () => { .withArgs(deployer.address); }); - it("should check full flow no trusted aggreagtor", async () => { - const urlSequencer = "http://zkevm-json-rpc:8123"; - const chainID2 = chainID + 1; - const networkName = "zkevm"; - const forkID = 0; - const genesisRandom = "0x0000000000000000000000000000000000000000000000000000000000000001"; - const rollupCompatibilityID = 0; - const descirption = "zkevm test"; - // Native token will be ether - const gasTokenAddress = ethers.ZeroAddress; - const gasTokenNetwork = 0; - - // In order to create a new rollup type, create an implementation of the contract - - // Create zkEVM implementation - const PolygonZKEVMV2Factory = await ethers.getContractFactory("PolygonZkEVMEtrog"); - const PolygonZKEVMV2Contract = await PolygonZKEVMV2Factory.deploy( - polygonZkEVMGlobalExitRoot.target, - polTokenContract.target, - polygonZkEVMBridgeContract.target, - rollupManagerContract.target - ); - await PolygonZKEVMV2Contract.waitForDeployment(); - - // Try to add a new rollup type - await expect( - rollupManagerContract.addNewRollupType( - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - rollupCompatibilityID, - genesisRandom, - descirption - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); - - // Add a new rollup type with timelock - const newRollupTypeID = 1; - await expect( - rollupManagerContract - .connect(timelock) - .addNewRollupType( - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - rollupCompatibilityID, - genesisRandom, - descirption - ) - ) - .to.emit(rollupManagerContract, "AddNewRollupType") - .withArgs( - newRollupTypeID, - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - rollupCompatibilityID, - genesisRandom, - descirption - ); - - // assert new rollup type - const createdRollupType = await rollupManagerContract.rollupTypeMap(newRollupTypeID); - - const expectedRollupType = [ - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - rollupCompatibilityID, - false, - genesisRandom, - ]; - expect(createdRollupType).to.be.deep.equal(expectedRollupType); - - // obsoleteRollupType, take snapshot for it - const snapshot = await takeSnapshot(); - - await expect(rollupManagerContract.obsoleteRollupType(newRollupTypeID)).to.be.revertedWithCustomError( - rollupManagerContract, - "AddressDoNotHaveRequiredRole" - ); - - await expect(rollupManagerContract.connect(admin).obsoleteRollupType(newRollupTypeID)) - .to.emit(rollupManagerContract, "ObsoleteRollupType") - .withArgs(newRollupTypeID); - - expect([ - PolygonZKEVMV2Contract.target, - verifierContract.target, - forkID, - rollupCompatibilityID, - true, - genesisRandom, - ]).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); - await snapshot.restore(); - - expect(expectedRollupType).to.be.deep.equal(await rollupManagerContract.rollupTypeMap(newRollupTypeID)); - // Create a - - // Only admin can create new zkEVMs - await expect( - rollupManagerContract.createNewRollup( - newRollupTypeID, - chainID2, - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); - - // UNexisting rollupType - await expect( - rollupManagerContract - .connect(admin) - .createNewRollup( - 0, - chainID2, - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "RollupTypeDoesNotExist"); - - // Obsolete rollup type and test that fails - const snapshot2 = await takeSnapshot(); - await expect(rollupManagerContract.connect(admin).obsoleteRollupType(newRollupTypeID)) - .to.emit(rollupManagerContract, "ObsoleteRollupType") - .withArgs(newRollupTypeID); - - await expect( - rollupManagerContract - .connect(admin) - .createNewRollup( - newRollupTypeID, - chainID2, - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "RollupTypeObsolete"); - await snapshot2.restore(); - - const newCreatedRollupID = 2; // 1 is zkEVM - const newZKEVMAddress = ethers.getCreateAddress({ - from: rollupManagerContract.target as string, - nonce: 1, - }); - - const newZkEVMContract = PolygonZKEVMV2Factory.attach(newZKEVMAddress) as PolygonZkEVMEtrog; - const newSequencedBatch = 1; - - await expect( - rollupManagerContract - .connect(admin) - .createNewRollup( - newRollupTypeID, - chainID2, - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName - ) - ) - .to.emit(rollupManagerContract, "CreateNewRollup") - .withArgs(newCreatedRollupID, newRollupTypeID, newZKEVMAddress, chainID2, gasTokenAddress) - .to.emit(newZkEVMContract, "InitialSequenceBatches") - .to.emit(rollupManagerContract, "OnSequenceBatches") - .withArgs(newCreatedRollupID, newSequencedBatch); - - const blockCreatedRollup = await ethers.provider.getBlock("latest"); - - // Assert new rollup created - const timestampCreatedRollup = blockCreatedRollup?.timestamp; - expect(await newZkEVMContract.admin()).to.be.equal(admin.address); - expect(await newZkEVMContract.trustedSequencer()).to.be.equal(trustedSequencer.address); - expect(await newZkEVMContract.trustedSequencerURL()).to.be.equal(urlSequencer); - expect(await newZkEVMContract.networkName()).to.be.equal(networkName); - expect(await newZkEVMContract.forceBatchTimeout()).to.be.equal(FORCE_BATCH_TIMEOUT); - - // Cannot create 2 chains with the same chainID2 - await expect( - rollupManagerContract - .connect(admin) - .createNewRollup( - newRollupTypeID, - chainID2, - admin.address, - trustedSequencer.address, - gasTokenAddress, - urlSequencer, - networkName - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "ChainIDAlreadyExist"); - - const transaction = await newZkEVMContract.generateInitializeTransaction( - newCreatedRollupID, - gasTokenAddress, - gasTokenNetwork, - "0x" // empty metadata - ); - - // Check transaction - const bridgeL2Factory = await ethers.getContractFactory("PolygonZkEVMBridgeV2"); - const encodedData = bridgeL2Factory.interface.encodeFunctionData("initialize", [ - newCreatedRollupID, - gasTokenAddress, - gasTokenNetwork, - globalExitRootL2Address, - ethers.ZeroAddress, - "0x", - ]); - - const rawTx = processorUtils.customRawTxToRawTx(transaction); - const tx = ethers.Transaction.from(rawTx); - const rlpSignData = transaction.slice(0, -(SIGNATURE_BYTES * 2 + EFFECTIVE_PERCENTAGE_BYTES * 2)); - expect(rlpSignData).to.be.equal(tx.unsignedSerialized); - - expect(tx.to).to.be.equal(polygonZkEVMBridgeContract.target); - expect(tx.value).to.be.equal(0); - expect(tx.data).to.be.equal(encodedData); - expect(tx.gasPrice).to.be.equal(0); - expect(tx.gasLimit).to.be.equal(30000000); - expect(tx.nonce).to.be.equal(0); - expect(tx.chainId).to.be.equal(0); - - const expectedAccInputHash = calculateAccInputHashetrog( - ethers.ZeroHash, - ethers.keccak256(transaction), - await polygonZkEVMGlobalExitRoot.getLastGlobalExitRoot(), - timestampCreatedRollup, - trustedSequencer.address, - blockCreatedRollup?.parentHash - ); - // calcualte accINputHash - expect(await newZkEVMContract.lastAccInputHash()).to.be.equal(expectedAccInputHash); - - // Check mapping on rollup Manager - const rollupData = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); - expect(rollupData.rollupContract).to.be.equal(newZKEVMAddress); - expect(rollupData.chainID).to.be.equal(chainID2); - expect(rollupData.verifier).to.be.equal(verifierContract.target); - expect(rollupData.forkID).to.be.equal(forkID); - expect(rollupData.lastLocalExitRoot).to.be.equal(ethers.ZeroHash); - expect(rollupData.lastBatchSequenced).to.be.equal(newSequencedBatch); - expect(rollupData.lastVerifiedBatch).to.be.equal(0); - expect(rollupData.lastPendingState).to.be.equal(0); - expect(rollupData.lastPendingStateConsolidated).to.be.equal(0); - expect(rollupData.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); - expect(rollupData.rollupTypeID).to.be.equal(1); - expect(rollupData.rollupCompatibilityID).to.be.equal(0); - - const sequencedBatchData = await rollupManagerContract.getRollupSequencedBatches( - newCreatedRollupID, - newSequencedBatch - ); - - expect(sequencedBatchData.accInputHash).to.be.equal(expectedAccInputHash); - expect(sequencedBatchData.sequencedTimestamp).to.be.equal(timestampCreatedRollup); - expect(sequencedBatchData.previousLastBatchSequenced).to.be.equal(0); - - // try verify batches - const l2txData = "0x123456"; - const maticAmount = await rollupManagerContract.getBatchFee(); - const currentTimestamp = (await ethers.provider.getBlock("latest"))?.timestamp; - - const sequence = { - transactions: l2txData, - forcedGlobalExitRoot: ethers.ZeroHash, - forcedTimestamp: 0, - forcedBlockHashL1: ethers.ZeroHash, - } as BatchDataStructEtrog; - - // Approve tokens - await expect(polTokenContract.connect(trustedSequencer).approve(newZkEVMContract.target, maticAmount)).to.emit( - polTokenContract, - "Approval" - ); - - // Sequence Batches - const currentTime = Number((await ethers.provider.getBlock("latest"))?.timestamp); - const currentLastBatchSequenced = 1; - - const height = 32; - const merkleTreeGLobalExitRoot = new MerkleTreeBridge(height); - - const rootSC = await polygonZkEVMGlobalExitRoot.getRoot(); - const rootJS = merkleTreeGLobalExitRoot.getRoot(); - const indexL1infoRoot = 0; - - expect(rootSC).to.be.equal(rootJS); - - const expectedAccInputHash2 = calculateAccInputHashetrog( - expectedAccInputHash, - ethers.keccak256(l2txData), - rootSC, - currentTime, - trustedSequencer.address, - ethers.ZeroHash - ); - - await expect( - newZkEVMContract - .connect(trustedSequencer) - .sequenceBatches( - [sequence], - indexL1infoRoot, - currentTime, - expectedAccInputHash2, - trustedSequencer.address - ) - ).to.emit(newZkEVMContract, "SequenceBatches"); - - const currnetRollup = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); - expect(currnetRollup.lastBatchSequenced).to.be.equal(2); - - // calcualte accINputHash - expect(await newZkEVMContract.lastAccInputHash()).to.be.equal(expectedAccInputHash2); - - // Create a new local exit root mocking some bridge - const tokenName = "Matic Token"; - const tokenSymbol = "MATIC"; - const decimals = 18; - const metadataToken = ethers.AbiCoder.defaultAbiCoder().encode( - ["string", "string", "uint8"], - [tokenName, tokenSymbol, decimals] - ); - - const originNetwork = networkIDRollup; - const tokenAddress = ethers.getAddress(ethers.hexlify(ethers.randomBytes(20))); - const amount = ethers.parseEther("10"); - const destinationNetwork = networkIDMainnet; - const destinationAddress = beneficiary.address; - const metadata = metadataToken; // since we are inserting in the exit root can be anything - const metadataHash = ethers.solidityPackedKeccak256(["bytes"], [metadata]); - - // compute root merkle tree in Js - const merkleTreezkEVM = new MerkleTreeBridge(height); - const leafValue = getLeafValue( - LEAF_TYPE_ASSET, - originNetwork, - tokenAddress, - destinationNetwork, - destinationAddress, - amount, - metadataHash - ); - - // Add 2 leafs - merkleTreezkEVM.add(leafValue); - merkleTreezkEVM.add(leafValue); - - // check merkle root with SC - const rootzkEVM = merkleTreezkEVM.getRoot(); - - // trustedAggregator forge the batch - const pendingState = 0; - const newLocalExitRoot = rootzkEVM; - const newStateRoot = "0x0000000000000000000000000000000000000000000000000000000000000123"; - const newVerifiedBatch = newSequencedBatch; - const zkProofFFlonk = new Array(24).fill(ethers.ZeroHash); - const currentVerifiedBatch = 0; - - const initialAggregatorMatic = await polTokenContract.balanceOf(beneficiary.address); - - await expect( - rollupManagerContract.getInputSnarkBytes( - newCreatedRollupID, - 3, - 4, - newLocalExitRoot, - ethers.ZeroHash, - newStateRoot - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "OldAccInputHashDoesNotExist"); - - await expect( - rollupManagerContract.getInputSnarkBytes( - newCreatedRollupID, - 2, - 3, - newLocalExitRoot, - ethers.ZeroHash, - newStateRoot - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "NewAccInputHashDoesNotExist"); - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .verifyBatches( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "TrustedAggregatorTimeoutNotExpired"); - - await rollupManagerContract.connect(admin).setTrustedAggregatorTimeout(0); - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .verifyBatches( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - currentVerifiedBatch + _MAX_VERIFY_BATCHES + 1, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "ExceedMaxVerifyBatches"); - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .verifyBatches( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - currentVerifiedBatch, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "FinalNumBatchBelowLastVerifiedBatch"); - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - 3, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "NewAccInputHashDoesNotExist"); - - // Calcualte new globalExitroot - const merkleTreeRollups = new MerkleTreeBridge(height); - merkleTreeRollups.add(ethers.ZeroHash); - merkleTreeRollups.add(newLocalExitRoot); - const rootRollups = merkleTreeRollups.getRoot(); - - // Verify batch - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ) - .to.emit(rollupManagerContract, "VerifyBatches") - .withArgs(newCreatedRollupID, newVerifiedBatch, newStateRoot, newLocalExitRoot, deployer.address); - - const timestampVerifyBatches = (await ethers.provider.getBlock("latest"))?.timestamp; - const finalAggregatorMatic = await polTokenContract.balanceOf(beneficiary.address); - expect(finalAggregatorMatic).to.equal(((initialAggregatorMatic + maticAmount) * 1n) / 3n); - const createdPendingState = 1; - - const snapshotVerify = await takeSnapshot(); - await rollupManagerContract.connect(admin).setPendingStateTimeout(0); - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - 0, - 5, - 6, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "OldStateRootDoesNotExist"); - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - 0, - newVerifiedBatch, - 0, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.reverted; - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - createdPendingState + 1, - currentVerifiedBatch, - newVerifiedBatch + 1, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "PendingStateDoesNotExist"); - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - createdPendingState, - currentVerifiedBatch, - newVerifiedBatch + 1, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "InitNumBatchDoesNotMatchPendingState"); - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - createdPendingState, - newVerifiedBatch, - newVerifiedBatch + 1, - newLocalExitRoot, - ethers.toQuantity(ethers.MaxUint256), - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "NewStateRootNotInsidePrime"); - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - createdPendingState, - newVerifiedBatch, - newVerifiedBatch + 1, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ) - .to.emit(rollupManagerContract, "VerifyBatches") - .withArgs(newCreatedRollupID, newVerifiedBatch + 1, newStateRoot, newLocalExitRoot, deployer.address); - - let rollupDataV = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); - expect(rollupDataV.lastPendingState).to.be.equal(0); - expect(rollupDataV.lastLocalExitRoot).to.be.equal(newLocalExitRoot); - expect(rollupDataV.lastBatchSequenced).to.be.equal(2); - expect(rollupDataV.lastVerifiedBatch).to.be.equal(newVerifiedBatch + 1); - expect(rollupDataV.lastPendingState).to.be.equal(0); - expect(rollupDataV.lastPendingStateConsolidated).to.be.equal(0); - expect(rollupDataV.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .verifyBatchesTrustedAggregator( - newCreatedRollupID, - 0, - 0, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "FinalNumBatchBelowLastVerifiedBatch"); - - await snapshotVerify.restore(); - await rollupManagerContract.connect(admin).setPendingStateTimeout(1); - - await expect( - rollupManagerContract.verifyBatches( - newCreatedRollupID, - createdPendingState, - newVerifiedBatch, - newVerifiedBatch + 1, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ) - .to.emit(rollupManagerContract, "VerifyBatches") - .withArgs(newCreatedRollupID, newVerifiedBatch + 1, newStateRoot, newLocalExitRoot, deployer.address); - - rollupDataV = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); - expect(rollupDataV.lastPendingState).to.be.equal(2); - expect(rollupDataV.lastLocalExitRoot).to.be.equal(newLocalExitRoot); - expect(rollupDataV.lastBatchSequenced).to.be.equal(2); - expect(rollupDataV.lastVerifiedBatch).to.be.equal(newVerifiedBatch); - expect(rollupDataV.lastPendingStateConsolidated).to.be.equal(1); - expect(rollupDataV.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); - - await snapshotVerify.restore(); - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .verifyBatchesTrustedAggregator( - newCreatedRollupID, - pendingState, - currentVerifiedBatch, - newVerifiedBatch + 1, - newLocalExitRoot, - newStateRoot, - beneficiary.address, - zkProofFFlonk - ) - ) - .to.emit(rollupManagerContract, "VerifyBatchesTrustedAggregator") - .withArgs( - newCreatedRollupID, - newVerifiedBatch + 1, - newStateRoot, - newLocalExitRoot, - trustedAggregator.address - ); - - rollupDataV = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); - expect(rollupDataV.lastPendingState).to.be.equal(0); - expect(rollupDataV.lastLocalExitRoot).to.be.equal(newLocalExitRoot); - expect(rollupDataV.lastBatchSequenced).to.be.equal(2); - expect(rollupDataV.lastVerifiedBatch).to.be.equal(newVerifiedBatch + 1); - expect(rollupDataV.lastPendingState).to.be.equal(0); - expect(rollupDataV.lastPendingStateConsolidated).to.be.equal(0); - expect(rollupDataV.lastVerifiedBatchBeforeUpgrade).to.be.equal(0); - - await snapshotVerify.restore(); - await expect( - rollupManagerContract.proveNonDeterministicPendingState( - newCreatedRollupID, - 0, - createdPendingState, - 0, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "StoredRootMustBeDifferentThanNewRoot"); - - await expect( - rollupManagerContract.proveNonDeterministicPendingState( - newCreatedRollupID, - 0, - createdPendingState, - 5, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "OldStateRootDoesNotExist"); - - await expect( - rollupManagerContract.proveNonDeterministicPendingState( - newCreatedRollupID, - 3, // init pending state - 2, - 0, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "PendingStateDoesNotExist"); - - await expect( - rollupManagerContract.proveNonDeterministicPendingState( - newCreatedRollupID, - createdPendingState, - createdPendingState, - 0, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "InitNumBatchDoesNotMatchPendingState"); - - await expect( - rollupManagerContract.proveNonDeterministicPendingState( - newCreatedRollupID, - createdPendingState, - createdPendingState, - newVerifiedBatch, - newVerifiedBatch, - newLocalExitRoot, - newStateRoot, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "FinalPendingStateNumInvalid"); - - await expect( - rollupManagerContract.proveNonDeterministicPendingState( - newCreatedRollupID, - 0, - createdPendingState, - 0, - newVerifiedBatch + 1, - newLocalExitRoot, - ethers.ZeroHash, - zkProofFFlonk - ) - ).to.be.revertedWithCustomError(rollupManagerContract, "FinalNumBatchDoesNotMatchPendingState"); - - await expect( - rollupManagerContract.proveNonDeterministicPendingState( - newCreatedRollupID, - 0, - createdPendingState, - 0, - newVerifiedBatch, - newLocalExitRoot, - ethers.ZeroHash, - zkProofFFlonk - ) - ) - .to.emit(rollupManagerContract, "ProveNonDeterministicPendingState") - .withArgs(newStateRoot, ethers.ZeroHash); - - expect(await rollupManagerContract.isEmergencyState()).to.be.equal(true); - - await snapshotVerify.restore(); - - const randomSTateRoot = ethers.hexlify(ethers.randomBytes(32)); - const randomlocalRoot = ethers.hexlify(ethers.randomBytes(32)); - - await expect( - rollupManagerContract.connect(trustedAggregator).overridePendingState( - newCreatedRollupID, - 0, - createdPendingState, - 0, - newVerifiedBatch, - randomlocalRoot, // local exit root - randomSTateRoot, // state root - zkProofFFlonk - ) - ) - .to.emit(rollupManagerContract, "OverridePendingState") - .withArgs( - newCreatedRollupID, - newVerifiedBatch, - randomSTateRoot, - randomlocalRoot, - trustedAggregator.address - ); - - expect( - await rollupManagerContract.getRollupBatchNumToStateRoot(newCreatedRollupID, newVerifiedBatch) - ).to.be.equal(randomSTateRoot); - - rollupDataV = await rollupManagerContract.rollupIDToRollupData(newCreatedRollupID); - expect(rollupDataV.lastPendingState).to.be.equal(0); - expect(rollupDataV.lastLocalExitRoot).to.be.equal(randomlocalRoot); - expect(rollupDataV.lastBatchSequenced).to.be.equal(2); - expect(rollupDataV.lastVerifiedBatch).to.be.equal(newVerifiedBatch); - expect(rollupDataV.lastPendingState).to.be.equal(0); - expect(rollupDataV.lastPendingStateConsolidated).to.be.equal(0); - - expect(await rollupManagerContract.isEmergencyState()).to.be.equal(false); - expect(await rollupManagerContract.trustedAggregatorTimeout()).to.be.equal(_HALT_AGGREGATION_TIMEOUT); - - await snapshotVerify.restore(); - - const pendingStateNum = 1; - // check revert reasons: - - expect( - await rollupManagerContract.isPendingStateConsolidable(newCreatedRollupID, createdPendingState) - ).to.be.equal(false); - - const currentPendingStateTransition = await rollupManagerContract.getRollupPendingStateTransitions( - newCreatedRollupID, - createdPendingState - ); - - expect(currentPendingStateTransition.timestamp).to.be.equal(timestampVerifyBatches); - expect(currentPendingStateTransition.lastVerifiedBatch).to.be.equal(newVerifiedBatch); - expect(currentPendingStateTransition.exitRoot).to.be.equal(newLocalExitRoot); - expect(currentPendingStateTransition.stateRoot).to.be.equal(newStateRoot); - - await expect( - rollupManagerContract.consolidatePendingState(newCreatedRollupID, pendingStateNum) - ).to.be.revertedWithCustomError(rollupManagerContract, "PendingStateNotConsolidable"); - - // try emergency - await rollupManagerContract.connect(emergencyCouncil).activateEmergencyState(); - await rollupManagerContract.connect(admin).setPendingStateTimeout(0); - - await expect( - rollupManagerContract.consolidatePendingState(newCreatedRollupID, pendingStateNum) - ).to.be.revertedWithCustomError(rollupManagerContract, "OnlyNotEmergencyState"); - await snapshotVerify.restore(); - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .consolidatePendingState(newCreatedRollupID, pendingStateNum + 1) - ).to.be.revertedWithCustomError(rollupManagerContract, "PendingStateInvalid"); - - await expect( - rollupManagerContract - .connect(trustedAggregator) - .consolidatePendingState(newCreatedRollupID, pendingStateNum) - ) - .to.emit(rollupManagerContract, "ConsolidatePendingState") - .withArgs(newCreatedRollupID, newVerifiedBatch, newStateRoot, newLocalExitRoot, pendingStateNum); - - // Assert new root - expect( - await rollupManagerContract.getRollupBatchNumToStateRoot(newCreatedRollupID, newVerifiedBatch) - ).to.be.equal(newStateRoot); - - // Assert global exit root - expect(await polygonZkEVMGlobalExitRoot.lastRollupExitRoot()).to.be.equal(rootRollups); - expect(await polygonZkEVMGlobalExitRoot.lastMainnetExitRoot()).to.be.equal(ethers.ZeroHash); - - expect(await polygonZkEVMGlobalExitRoot.getLastGlobalExitRoot()).to.be.equal( - calculateGlobalExitRoot(ethers.ZeroHash, rootRollups) - ); - - const indexLeaf = 0; - const indexRollup = 1; - const proofZkEVM = merkleTreezkEVM.getProofTreeByIndex(indexLeaf); - const proofRollups = merkleTreeRollups.getProofTreeByIndex(indexRollup); - - // verify merkle proof - expect(verifyMerkleProof(leafValue, proofZkEVM, indexLeaf, rootzkEVM)).to.be.equal(true); - expect(verifyMerkleProof(rootzkEVM, proofRollups, indexRollup, rootRollups)).to.be.equal(true); - - expect( - await polygonZkEVMBridgeContract.verifyMerkleProof(leafValue, proofZkEVM, indexLeaf, rootzkEVM) - ).to.be.equal(true); - - expect( - await polygonZkEVMBridgeContract.verifyMerkleProof(newLocalExitRoot, proofRollups, indexRollup, rootRollups) - ).to.be.equal(true); - - // claim - const tokenWrappedFactory = await ethers.getContractFactory("TokenWrapped"); - // create2 parameters - const salt = ethers.solidityPackedKeccak256(["uint32", "address"], [networkIDRollup, tokenAddress]); - const minimalBytecodeProxy = await polygonZkEVMBridgeContract.BASE_INIT_BYTECODE_WRAPPED_TOKEN(); - const hashInitCode = ethers.solidityPackedKeccak256(["bytes", "bytes"], [minimalBytecodeProxy, metadataToken]); - const precalculateWrappedErc20 = await ethers.getCreate2Address( - polygonZkEVMBridgeContract.target as string, - salt, - hashInitCode - ); - const newWrappedToken = tokenWrappedFactory.attach(precalculateWrappedErc20) as TokenWrapped; - - // Use precalculatedWrapperAddress and check if matches - expect( - await polygonZkEVMBridgeContract.precalculatedWrapperAddress( - networkIDRollup, - tokenAddress, - tokenName, - tokenSymbol, - decimals - ) - ).to.be.equal(precalculateWrappedErc20); - - // index leaf is 0 bc, does not have mainnet flag, and it's rollup 0 on leaf 0 - const globalIndex = computeGlobalIndex(indexLeaf, indexRollup, false); - await expect( - polygonZkEVMBridgeContract.claimAsset( - proofZkEVM, - proofRollups, - globalIndex, - ethers.ZeroHash, - rootRollups, - originNetwork, - tokenAddress, - destinationNetwork, - destinationAddress, - amount, - metadata - ) - ) - .to.emit(polygonZkEVMBridgeContract, "ClaimEvent") - .withArgs(globalIndex, originNetwork, tokenAddress, destinationAddress, amount) - .to.emit(polygonZkEVMBridgeContract, "NewWrappedToken") - .withArgs(originNetwork, tokenAddress, precalculateWrappedErc20, metadata) - .to.emit(newWrappedToken, "Transfer") - .withArgs(ethers.ZeroAddress, beneficiary.address, amount); - - // Assert maps created - const newTokenInfo = await polygonZkEVMBridgeContract.wrappedTokenToTokenInfo(precalculateWrappedErc20); - - expect(newTokenInfo.originNetwork).to.be.equal(networkIDRollup); - expect(newTokenInfo.originTokenAddress).to.be.equal(tokenAddress); - expect(await polygonZkEVMBridgeContract.getTokenWrappedAddress(networkIDRollup, tokenAddress)).to.be.equal( - precalculateWrappedErc20 - ); - expect(await polygonZkEVMBridgeContract.getTokenWrappedAddress(networkIDRollup, tokenAddress)).to.be.equal( - precalculateWrappedErc20 - ); - - expect(await polygonZkEVMBridgeContract.tokenInfoToWrappedToken(salt)).to.be.equal(precalculateWrappedErc20); - - // Check the wrapper info - expect(await newWrappedToken.name()).to.be.equal(tokenName); - expect(await newWrappedToken.symbol()).to.be.equal(tokenSymbol); - expect(await newWrappedToken.decimals()).to.be.equal(decimals); - - // Can't claim because nullifier - await expect( - polygonZkEVMBridgeContract.claimAsset( - proofZkEVM, - proofRollups, - globalIndex, - ethers.ZeroHash, - rootRollups, - originNetwork, - tokenAddress, - destinationNetwork, - destinationAddress, - amount, - metadata - ) - ).to.be.revertedWithCustomError(polygonZkEVMBridgeContract, "AlreadyClaimed"); - - // Check new token - expect(await newWrappedToken.totalSupply()).to.be.equal(amount); - }); - it("Should test obsolete rollup", async () => { const forkID = 0; const genesisRandom = "0x0000000000000000000000000000000000000000000000000000000000000001"; - const rollupCompatibilityID = 0; - const descirption = "zkevm test"; + const rollupVerifierType = 0; + const description = "zkevm test"; + const programVKey = "0x0000000000000000000000000000000000000000000000000000000000000000"; // In order to create a new rollup type, create an implementation of the contract @@ -2041,9 +1068,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ) ) .to.emit(rollupManagerContract, "AddNewRollupType") @@ -2052,9 +1080,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, genesisRandom, - descirption + description, + programVKey ); // assert new rollup type @@ -2064,9 +1093,10 @@ describe("Polygon Rollup manager upgraded", () => { PolygonZKEVMV2Contract.target, verifierContract.target, forkID, - rollupCompatibilityID, + rollupVerifierType, false, genesisRandom, + programVKey, ]; expect(createdRollupType).to.be.deep.equal(expectedRollupType); From 469774f0191d1b90756b0dc7be576075cb225e83 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Tue, 30 Jul 2024 10:12:26 +0200 Subject: [PATCH 06/16] rename _legacy... to _ --- contracts/v2/PolygonRollupManager.sol | 36 +++++++++---------- .../v2/mocks/PolygonRollupManagerMock.sol | 2 +- .../PolygonGlobalExitRootV2.test.ts | 1 + .../PolygonRollupManagerUpgrade.test.ts | 4 +-- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/contracts/v2/PolygonRollupManager.sol b/contracts/v2/PolygonRollupManager.sol index b732a27a4..ec5581187 100644 --- a/contracts/v2/PolygonRollupManager.sol +++ b/contracts/v2/PolygonRollupManager.sol @@ -243,7 +243,7 @@ contract PolygonRollupManager is // Rollups ID mapping /// @custom:oz-renamed-from rollupIDToRollupData - mapping(uint32 rollupID => RollupData) internal legacyRollupIDToRollupData; + mapping(uint32 rollupID => RollupData) internal _rollupIDToRollupData; // Rollups address mapping mapping(address rollupAddress => uint32 rollupID) public rollupAddressToID; @@ -527,7 +527,7 @@ contract PolygonRollupManager is // Store rollup data rollupAddressToID[rollupAddress] = rollupID; - RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; + RollupData storage rollup = _rollupIDToRollupData[rollupID]; rollup.rollupContract = IPolygonRollupBase(rollupAddress); rollup.forkID = rollupType.forkID; @@ -602,7 +602,7 @@ contract PolygonRollupManager is // Store rollup data rollupAddressToID[address(rollupAddress)] = rollupID; - RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; + RollupData storage rollup = _rollupIDToRollupData[rollupID]; rollup.rollupContract = rollupAddress; rollup.forkID = forkID; rollup.verifier = verifier; @@ -645,7 +645,7 @@ contract PolygonRollupManager is } // Check all sequences are verified before upgrading - RollupData storage rollup = legacyRollupIDToRollupData[ + RollupData storage rollup = _rollupIDToRollupData[ rollupAddressToID[address(rollupContract)] ]; @@ -698,7 +698,7 @@ contract PolygonRollupManager is revert RollupMustExist(); } - RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; + RollupData storage rollup = _rollupIDToRollupData[rollupID]; // The update must be to a new rollup type if (rollup.rollupTypeID == newRollupTypeID) { @@ -760,7 +760,7 @@ contract PolygonRollupManager is } // Load rollup - RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; + RollupData storage rollup = _rollupIDToRollupData[rollupID]; if (rollup.rollupVerifierType != VerifierType.StateTransition) { revert OnlyStateTransitionChains(); @@ -840,7 +840,7 @@ contract PolygonRollupManager is revert MustSequenceSomeBatch(); } - RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; + RollupData storage rollup = _rollupIDToRollupData[rollupID]; // Update total sequence parameters totalSequencedBatches += newSequencedBatches; @@ -889,7 +889,7 @@ contract PolygonRollupManager is revert PendingStateNumExist(); } - RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; + RollupData storage rollup = _rollupIDToRollupData[rollupID]; if (rollup.rollupVerifierType != VerifierType.StateTransition) { revert OnlyStateTransitionChains(); @@ -937,7 +937,7 @@ contract PolygonRollupManager is bytes32 newPessimisticRoot, bytes calldata proof ) external onlyRole(_TRUSTED_AGGREGATOR_ROLE) { - RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; + RollupData storage rollup = _rollupIDToRollupData[rollupID]; // Only for pessimistic verifiers if (rollup.rollupVerifierType != VerifierType.Pessimistic) { @@ -1167,8 +1167,7 @@ contract PolygonRollupManager is // In the first iteration the nodes will be the leafs which are the local exit roots of each network for (uint256 i = 0; i < currentNodes; i++) { // The first rollup ID starts on 1 - tmpTree[i] = legacyRollupIDToRollupData[uint32(i + 1)] - .lastLocalExitRoot; + tmpTree[i] = _rollupIDToRollupData[uint32(i + 1)].lastLocalExitRoot; } // This variable will keep track of the zero hashes @@ -1223,7 +1222,7 @@ contract PolygonRollupManager is function getLastVerifiedBatch( uint32 rollupID ) public view returns (uint64) { - return _getLastVerifiedBatch(legacyRollupIDToRollupData[rollupID]); + return _getLastVerifiedBatch(_rollupIDToRollupData[rollupID]); } /** @@ -1280,7 +1279,7 @@ contract PolygonRollupManager is ) public view returns (bytes memory) { return _getInputPessimisticBytes( - legacyRollupIDToRollupData[rollupID], + _rollupIDToRollupData[rollupID], selectedGlobalExitRoot, newLocalExitRoot, newPessimisticRoot @@ -1335,7 +1334,7 @@ contract PolygonRollupManager is ) public view returns (bytes memory) { return _getInputSnarkBytes( - legacyRollupIDToRollupData[rollupID], + _rollupIDToRollupData[rollupID], initNumBatch, finalNewBatch, newLocalExitRoot, @@ -1428,8 +1427,7 @@ contract PolygonRollupManager is uint32 rollupID, uint64 batchNum ) public view returns (bytes32) { - return - legacyRollupIDToRollupData[rollupID].batchNumToStateRoot[batchNum]; + return _rollupIDToRollupData[rollupID].batchNumToStateRoot[batchNum]; } /** @@ -1441,7 +1439,7 @@ contract PolygonRollupManager is uint32 rollupID, uint64 batchNum ) public view returns (SequencedBatchData memory) { - return legacyRollupIDToRollupData[rollupID].sequencedBatches[batchNum]; + return _rollupIDToRollupData[rollupID].sequencedBatches[batchNum]; } /** @@ -1451,7 +1449,7 @@ contract PolygonRollupManager is function rollupIDToRollupData( uint32 rollupID ) public view returns (RollupDataReturnStateTransistion memory rollupData) { - RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; + RollupData storage rollup = _rollupIDToRollupData[rollupID]; if (rollup.rollupVerifierType != VerifierType.StateTransition) { revert InvalidVerifierType(); @@ -1480,7 +1478,7 @@ contract PolygonRollupManager is function rollupIDToRollupDataPessimistic( uint32 rollupID ) public view returns (RollupDataReturnPessimistic memory rollupData) { - RollupData storage rollup = legacyRollupIDToRollupData[rollupID]; + RollupData storage rollup = _rollupIDToRollupData[rollupID]; if (rollup.rollupVerifierType != VerifierType.Pessimistic) { revert InvalidVerifierType(); diff --git a/contracts/v2/mocks/PolygonRollupManagerMock.sol b/contracts/v2/mocks/PolygonRollupManagerMock.sol index 87190f306..0f072ec01 100644 --- a/contracts/v2/mocks/PolygonRollupManagerMock.sol +++ b/contracts/v2/mocks/PolygonRollupManagerMock.sol @@ -74,7 +74,7 @@ contract PolygonRollupManagerMock is PolygonRollupManager { // Add local Exit roots; for (uint256 i = 0; i < localExitRoots.length; i++) { - legacyRollupIDToRollupData[uint32(i + 1)] + _rollupIDToRollupData[uint32(i + 1)] .lastLocalExitRoot = localExitRoots[i]; } } diff --git a/test/contractsv2/PolygonGlobalExitRootV2.test.ts b/test/contractsv2/PolygonGlobalExitRootV2.test.ts index 102fc32a7..e03740c1b 100644 --- a/test/contractsv2/PolygonGlobalExitRootV2.test.ts +++ b/test/contractsv2/PolygonGlobalExitRootV2.test.ts @@ -99,6 +99,7 @@ describe("Polygon Global exit root v2", () => { const currentL1InfoRoot = await polygonZkEVMGlobalExitRootV2.getRoot(); // Retrieve depositCount const depositCount = await polygonZkEVMGlobalExitRootV2.depositCount(); + // Retrieve parentHash and timestamp const blockInfo = await ethers.provider.getBlock(updateExitRoot?.blockHash as any); diff --git a/test/contractsv2/PolygonRollupManagerUpgrade.test.ts b/test/contractsv2/PolygonRollupManagerUpgrade.test.ts index 014696e08..5fa9aec0d 100644 --- a/test/contractsv2/PolygonRollupManagerUpgrade.test.ts +++ b/test/contractsv2/PolygonRollupManagerUpgrade.test.ts @@ -254,9 +254,9 @@ describe("Polygon Rollup manager upgraded", () => { polTokenContract.target, polygonZkEVMBridgeContract.target, ], - unsafeAllow: ["constructor", "state-variable-immutable"], + unsafeAllow: ["constructor", "state-variable-immutable", "enum-definition", "struct-definition"], unsafeAllowRenames: true, - unsafeSkipStorageCheck: true, + unsafeAllowCustomTypes: true, } ); }); From 27a8f82c5e07574e25e1ac2f238270f9c1aac152 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Tue, 30 Jul 2024 13:27:06 +0200 Subject: [PATCH 07/16] increase coverage --- contracts/v2/PolygonZkEVMGlobalExitRootV2.sol | 6 +- .../v2/mocks/PolygonRollupManagerMock.sol | 6 + .../PolygonRollupManager-Pessimistic.test.ts | 148 +++++++++++++++++- test/contractsv2/PolygonRollupManager.test.ts | 55 +++++++ .../PolygonRollupManagerUpgrade.test.ts | 6 + 5 files changed, 217 insertions(+), 4 deletions(-) diff --git a/contracts/v2/PolygonZkEVMGlobalExitRootV2.sol b/contracts/v2/PolygonZkEVMGlobalExitRootV2.sol index fab8d77c4..c904686b5 100644 --- a/contracts/v2/PolygonZkEVMGlobalExitRootV2.sol +++ b/contracts/v2/PolygonZkEVMGlobalExitRootV2.sol @@ -23,7 +23,7 @@ contract PolygonZkEVMGlobalExitRootV2 is address public immutable rollupManager; // Store every l1InfoLeaf - mapping(uint32 leafIndex => bytes32 l1InfoRoot) public l1InfoRootMap; + mapping(uint32 leafCount => bytes32 l1InfoRoot) public l1InfoRootMap; /** * @dev Emitted when the global exit root is updated @@ -38,7 +38,7 @@ contract PolygonZkEVMGlobalExitRootV2 is */ event UpdateL1InfoTreeV2( bytes32 currentL1InfoRoot, - uint32 indexed leafIndex, + uint32 indexed leafCount, uint256 blockhash, uint64 minTimestamp ); @@ -46,7 +46,7 @@ contract PolygonZkEVMGlobalExitRootV2 is /** * @dev Emitted when the global exit root manager starts adding leafs to the L1InfoRootMap */ - event InitL1InfoRootMap(uint32 leafIndex, bytes32 currentL1InfoRoot); + event InitL1InfoRootMap(uint32 leafCount, bytes32 currentL1InfoRoot); /** * @param _rollupManager Rollup manager contract address diff --git a/contracts/v2/mocks/PolygonRollupManagerMock.sol b/contracts/v2/mocks/PolygonRollupManagerMock.sol index 0f072ec01..574f24095 100644 --- a/contracts/v2/mocks/PolygonRollupManagerMock.sol +++ b/contracts/v2/mocks/PolygonRollupManagerMock.sol @@ -78,4 +78,10 @@ contract PolygonRollupManagerMock is PolygonRollupManager { .lastLocalExitRoot = localExitRoots[i]; } } + + function exposed_checkStateRootInsidePrime( + uint256 newStateRoot + ) public pure returns (bool) { + return _checkStateRootInsidePrime(newStateRoot); + } } diff --git a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts index 58ae7684d..e356d8d05 100644 --- a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts +++ b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts @@ -357,6 +357,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { const urlSequencer = "https://pessimistic:8545"; const networkName = "testPessimistic"; const newCreatedRollupID = 1; + const nonExistentRollupID = 4; // Only admin can create new zkEVMs await expect( @@ -371,6 +372,21 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { ) ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); + // rollupTypeID does not exist + await expect( + rollupManagerContract + .connect(admin) + .createNewRollup( + nonExistentRollupID, + chainID, + admin.address, + trustedSequencer.address, + gasTokenAddress, + urlSequencer, + networkName + ) + ).to.be.revertedWithCustomError(rollupManagerContract, "RollupTypeDoesNotExist"); + // create new pessimistic const newZKEVMAddress = ethers.getCreateAddress({ from: rollupManagerContract.target as string, @@ -572,6 +588,20 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { .connect(timelock) .updateRollup(rollupStateTransition[0] as unknown as Address, 1, "0x") ).to.be.revertedWithCustomError(rollupManagerContract, "UpdateNotCompatible"); + + // try to update rollup with rollupType = 0 + await expect( + rollupManagerContract + .connect(timelock) + .updateRollup(rollupStateTransition[0] as unknown as Address, 0, "0x") + ).to.be.revertedWithCustomError(rollupManagerContract, "RollupTypeDoesNotExist"); + + // try to update rollup with a greater rollupType that the last created + await expect( + rollupManagerContract + .connect(timelock) + .updateRollup(rollupStateTransition[0] as unknown as Address, 4, "0x") + ).to.be.revertedWithCustomError(rollupManagerContract, "RollupTypeDoesNotExist"); }); it("should update rollup: pessismsitic type", async () => { @@ -676,7 +706,68 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { expect(expectedRollupData).to.be.deep.equal(resRollupData); }); - it("should verify pessimistic proof: pessismsitic type", async () => { + it("should not allow rollback sequences: pessismsitic type", async () => { + // deploy consensus + // create polygonPessimisticConsensus implementation + const ppConsensusFactory = await ethers.getContractFactory("PolygonPessimisticConsensus"); + PolygonPPConsensusContract = await ppConsensusFactory.deploy( + polygonZkEVMGlobalExitRoot.target, + polTokenContract.target, + polygonZkEVMBridgeContract.target, + rollupManagerContract.target + ); + await PolygonPPConsensusContract.waitForDeployment(); + + // Try to add a new rollup type + const forkID = 11; // just metadata for pessimistic consensus + const genesis = ethers.ZeroHash; + const description = "new pessimistic consensus"; + const programVKey = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; + const rollupTypeID = 1; + + // correct add new rollup via timelock + await rollupManagerContract + .connect(timelock) + .addNewRollupType( + PolygonPPConsensusContract.target, + verifierContract.target, + forkID, + VerifierType.Pessimistic, + genesis, + description, + programVKey + ); + + // create new pessimsitic: only admin + const chainID = 1; + const gasTokenAddress = ethers.ZeroAddress; + const urlSequencer = "https://pessimistic:8545"; + const networkName = "testPessimistic"; + const pessimisticRollupID = 1; + + // create new pessimistic + await rollupManagerContract + .connect(admin) + .createNewRollup( + rollupTypeID, + chainID, + admin.address, + trustedSequencer.address, + gasTokenAddress, + urlSequencer, + networkName + ); + + // get rollup data + const rollupPessimistic = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); + + // try to rollback sequences + await expect( + rollupManagerContract.connect(admin).rollbackBatches(rollupPessimistic[0] as unknown as Address, 2) + ).to.be.revertedWithCustomError(rollupManagerContract, "OnlyStateTransitionChains"); + }); + + it("should verify pessimistic proof: pessimistic type", async () => { // deploy consensus // create polygonPessimisticConsensus implementation const ppConsensusFactory = await ethers.getContractFactory("PolygonPessimisticConsensus"); @@ -739,6 +830,18 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { const newPPRoot = "0x0000000000000000000000000000000000000000000000000000000000000002"; const proofPP = "0x00"; + // not trusted aggregator + await expect( + rollupManagerContract.verifyPessimisticTrustedAggregator( + pessimisticRollupID, + unexistentGER, + newLER, + newPPRoot, + proofPP + ) + ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); + + // global exit root does not exist await expect( rollupManagerContract .connect(trustedAggregator) @@ -772,6 +875,12 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { .withArgs(pessimisticRollupID, 0, ethers.ZeroHash, newLER, trustedAggregator.address); // assert rollup data + // try to get stateTransistion data from pessimsitic rollup + await expect(rollupManagerContract.rollupIDToRollupData(pessimisticRollupID)).to.be.revertedWithCustomError( + rollupManagerContract, + "InvalidVerifierType" + ); + const resRollupData = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); const expectedRollupData = [ @@ -787,6 +896,38 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { ]; expect(expectedRollupData).to.be.deep.equal(resRollupData); + + // not allow verifyBatchesTrustedAggregator from a Pessimistic chain + await expect( + rollupManagerContract + .connect(trustedAggregator) + .verifyBatchesTrustedAggregator( + pessimisticRollupID, + 0, + 0, + 0, + newLER, + newPPRoot, + beneficiary.address, + new Array(24).fill(ethers.ZeroHash) + ) + ).to.be.revertedWithCustomError(rollupManagerContract, "OnlyStateTransitionChains"); + + // pendingstate != 0 + await expect( + rollupManagerContract + .connect(trustedAggregator) + .verifyBatchesTrustedAggregator( + pessimisticRollupID, + 42, + 0, + 0, + newLER, + newPPRoot, + beneficiary.address, + new Array(24).fill(ethers.ZeroHash) + ) + ).to.be.revertedWithCustomError(rollupManagerContract, "PendingStateNumExist"); }); it("should not verify pessimistic proof from stateTransistion chain", async () => { @@ -849,5 +990,10 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { .connect(trustedAggregator) .verifyPessimisticTrustedAggregator(stateTransistionRollupID, unexistentGER, newLER, newPPRoot, proofPP) ).to.be.revertedWithCustomError(rollupManagerContract, "OnlyChainsWithPessimisticProofs"); + + // tro get pessimistic info from stateTransistion chain + await expect( + rollupManagerContract.rollupIDToRollupDataPessimistic(stateTransistionRollupID) + ).to.be.revertedWithCustomError(rollupManagerContract, "InvalidVerifierType"); }); }); diff --git a/test/contractsv2/PolygonRollupManager.test.ts b/test/contractsv2/PolygonRollupManager.test.ts index 288474fb0..5f4173d6f 100644 --- a/test/contractsv2/PolygonRollupManager.test.ts +++ b/test/contractsv2/PolygonRollupManager.test.ts @@ -243,6 +243,39 @@ describe("Polygon Rollup Manager", () => { expect(await polygonZkEVMBridgeContract.isEmergencyState()).to.be.equal(false); }); + it("should check _checkStateRootInsidePrime", async () => { + let stateRoot = "0x0000000000000000000000000000000000000000000000000000000000000000"; + expect(await rollupManagerContract.exposed_checkStateRootInsidePrime(stateRoot)).to.be.equal(true); + + // goldilocks - 1 + stateRoot = "0x000000000000000000000000000000000000000000000000ffffffff00000000"; + expect(await rollupManagerContract.exposed_checkStateRootInsidePrime(stateRoot)).to.be.equal(true); + + // goldilocks + stateRoot = "0x000000000000000000000000000000000000000000000000ffffffff00000001"; + expect(await rollupManagerContract.exposed_checkStateRootInsidePrime(stateRoot)).to.be.equal(false); + + // goldilocks + 1 + stateRoot = "0x000000000000000000000000000000000000000000000000ffffffff00000002"; + expect(await rollupManagerContract.exposed_checkStateRootInsidePrime(stateRoot)).to.be.equal(false); + + // goldilocks 2nd element + stateRoot = "0x00000000000000000000000000000000ffffffff00000001ffffffff00000000"; + expect(await rollupManagerContract.exposed_checkStateRootInsidePrime(stateRoot)).to.be.equal(false); + + // goldilocks 3rd element + stateRoot = "0x0000000000000000ffffffff00000001ffffffff00000000ffffffff00000000"; + expect(await rollupManagerContract.exposed_checkStateRootInsidePrime(stateRoot)).to.be.equal(false); + + // goldilocks 4rt element + stateRoot = "0xffffffff00000001ffffffff00000000ffffffff00000000ffffffff00000000"; + expect(await rollupManagerContract.exposed_checkStateRootInsidePrime(stateRoot)).to.be.equal(false); + + // all goldilocks - 1 + stateRoot = "0xffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000"; + expect(await rollupManagerContract.exposed_checkStateRootInsidePrime(stateRoot)).to.be.equal(true); + }); + it("should check full flow etrog", async () => { const urlSequencer = "http://zkevm-json-rpc:8123"; const chainID = 1000; @@ -448,6 +481,10 @@ describe("Polygon Rollup Manager", () => { expect(await newZkEVMContract.networkName()).to.be.equal(networkName); expect(await newZkEVMContract.forceBatchTimeout()).to.be.equal(FORCE_BATCH_TIMEOUT); + // Retrieve rollup batch info + const genesisStateRoot = await rollupManagerContract.getRollupBatchNumToStateRoot(newCreatedRollupID, 0); + expect(genesisStateRoot).to.be.equal(genesisRandom); + // Cannot create 2 chains with the same chainID await expect( rollupManagerContract @@ -707,6 +744,8 @@ describe("Polygon Rollup Manager", () => { zkProofFFlonk ); + // Retrieve rollup batch info + // const rollupStateRoot = await rollupManagerContract.getRollupBatchNumToStateRoot(); // Retrieve l1InfoRoot const currentL1InfoRoot = await polygonZkEVMGlobalExitRoot.getRoot(); // Retrieve depositCount @@ -722,6 +761,13 @@ describe("Polygon Rollup Manager", () => { .to.emit(polygonZkEVMGlobalExitRoot, "UpdateL1InfoTreeV2") .withArgs(currentL1InfoRoot, depositCount, blockInfo?.parentHash, blockInfo?.timestamp); + // Retrieve rollup batch info + const batchStateRoot = await rollupManagerContract.getRollupBatchNumToStateRoot( + newCreatedRollupID, + newVerifiedBatch + ); + expect(batchStateRoot).to.be.equal(newStateRoot); + const finalAggregatorMatic = await polTokenContract.balanceOf(beneficiary.address); expect(finalAggregatorMatic).to.equal(initialAggregatorMatic + maticAmount); @@ -1003,6 +1049,11 @@ describe("Polygon Rollup Manager", () => { "NotAllowedAddress" ); + await expect( + rollupManagerContract.connect(timelock).rollbackBatches(admin.address, 0) + ).to.be.revertedWithCustomError(rollupManagerContract, "RollupMustExist"); + + // doe snot implement admin() method await expect(rollupManagerContract.connect(admin).rollbackBatches(admin.address, 0)).to.be.reverted; await expect( @@ -2877,6 +2928,10 @@ describe("Polygon Rollup Manager", () => { .to.emit(rollupManagerContract, "AddExistingRollup") .withArgs(RollupID, forkID, PolygonZKEVMV2Contract.target, chainID, rollupVerifierType, 0, programVKey); + // Retrieve rollup batch info + const genesisStateRoot = await rollupManagerContract.getRollupBatchNumToStateRoot(RollupID, 0); + expect(genesisStateRoot).to.be.equal(genesisRandom); + await expect( rollupManagerContract .connect(timelock) diff --git a/test/contractsv2/PolygonRollupManagerUpgrade.test.ts b/test/contractsv2/PolygonRollupManagerUpgrade.test.ts index 5fa9aec0d..a2159f3fd 100644 --- a/test/contractsv2/PolygonRollupManagerUpgrade.test.ts +++ b/test/contractsv2/PolygonRollupManagerUpgrade.test.ts @@ -257,6 +257,7 @@ describe("Polygon Rollup manager upgraded", () => { unsafeAllow: ["constructor", "state-variable-immutable", "enum-definition", "struct-definition"], unsafeAllowRenames: true, unsafeAllowCustomTypes: true, + unsafeSkipStorageCheck: true, } ); }); @@ -301,11 +302,16 @@ describe("Polygon Rollup manager upgraded", () => { rollupManagerContract, "AddressDoNotHaveRequiredRole" ); + await expect(rollupManagerContract.connect(admin).setBatchFee(0)).to.be.revertedWithCustomError( rollupManagerContract, "BatchFeeOutOfRange" ); + await expect( + rollupManagerContract.connect(admin).setBatchFee(ethers.parseEther("1001")) + ).to.be.revertedWithCustomError(rollupManagerContract, "BatchFeeOutOfRange"); + await expect(rollupManagerContract.connect(admin).setBatchFee(ethers.parseEther("10"))) .to.emit(rollupManagerContract, "SetBatchFee") .withArgs(ethers.parseEther("10")); From e5d646db9d44103910387c3e1977cfe0c8d9a432 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Tue, 30 Jul 2024 18:11:43 +0200 Subject: [PATCH 08/16] add edge case --- test/contractsv2/PolygonRollupManager.test.ts | 95 ++++++++++++++++++- 1 file changed, 92 insertions(+), 3 deletions(-) diff --git a/test/contractsv2/PolygonRollupManager.test.ts b/test/contractsv2/PolygonRollupManager.test.ts index 5f4173d6f..033a10d52 100644 --- a/test/contractsv2/PolygonRollupManager.test.ts +++ b/test/contractsv2/PolygonRollupManager.test.ts @@ -695,6 +695,21 @@ describe("Polygon Rollup Manager", () => { ) ).to.be.revertedWithCustomError(rollupManagerContract, "AddressDoNotHaveRequiredRole"); + await expect( + rollupManagerContract + .connect(trustedAggregator) + .verifyBatchesTrustedAggregator( + newCreatedRollupID, + pendingState, + 1, + currentVerifiedBatch, + newLocalExitRoot, + newStateRoot, + beneficiary.address, + zkProofFFlonk + ) + ).to.be.revertedWithCustomError(rollupManagerContract, "OldStateRootDoesNotExist"); + await expect( rollupManagerContract .connect(trustedAggregator) @@ -1076,16 +1091,73 @@ describe("Polygon Rollup Manager", () => { // compare accINputHash expect(await newZkEVMContract.lastAccInputHash()).not.to.be.equal(expectedAccInputHash2); + const snapshotRollback = await takeSnapshot(); + await expect(rollupManagerContract.connect(admin).rollbackBatches(newZkEVMContract.target, 2)) .to.emit(rollupManagerContract, "RollbackBatches") .withArgs(newCreatedRollupID, 2, expectedAccInputHash2); // compare accINputHash expect(await newZkEVMContract.lastAccInputHash()).to.be.equal(expectedAccInputHash2); + await snapshotRollback.restore(); await expect(newZkEVMContract.connect(deployer).acceptAdminRole()) .to.emit(newZkEVMContract, "AcceptAdminRole") .withArgs(deployer.address); + + // get last accInputHash + const rollupDataRes = await rollupManagerContract.rollupIDToRollupData(networkIDRollup); + const lastAccInputHash = await rollupManagerContract.getRollupSequencedBatches( + networkIDRollup, + rollupDataRes[5] + ); + + // Sequence two batches + // fund deployer with Matic tokens + await polTokenContract.transfer(deployer.address, ethers.parseEther("1000")); + // Approve tokens + await expect(polTokenContract.approve(newZkEVMContract.target, ethers.parseEther("1000"))).to.emit( + polTokenContract, + "Approval" + ); + + const currentTime2 = Number((await ethers.provider.getBlock("latest"))?.timestamp); + const indexL1InfoRoot = 0; + const l1InfoTreeRootSelected = await polygonZkEVMGlobalExitRoot.l1InfoRootMap(indexL1InfoRoot); + + const accInputHash4 = calculateAccInputHashetrog( + lastAccInputHash[0], + ethers.keccak256(l2txData), + l1InfoTreeRootSelected, + currentTime2, + trustedSequencer.address, + ethers.ZeroHash + ); + + const accInputHash5 = calculateAccInputHashetrog( + accInputHash4, + ethers.keccak256(l2txData), + l1InfoTreeRootSelected, + currentTime2, + trustedSequencer.address, + ethers.ZeroHash + ); + + await expect( + newZkEVMContract.sequenceBatches( + [sequence, sequence], + indexL1InfoRoot, + currentTime2, + accInputHash5, + trustedSequencer.address + ) + ).to.emit(newZkEVMContract, "SequenceBatches"); + + // try to rollback batches to a non finish sequence + await expect(rollupManagerContract.rollbackBatches(newZkEVMContract.target, 4)).to.be.revertedWithCustomError( + rollupManagerContract, + "RollbackBatchIsNotEndOfSequence" + ); }); it("should check full flow with gas Token etrog", async () => { @@ -2497,6 +2569,23 @@ describe("Polygon Rollup Manager", () => { expect(await upgrades.erc1967.getImplementationAddress(newZKEVMAddress as string)).to.be.equal( PolygonZKEVMEtrogContract.target ); + + // try to verify a batch smaller than the lastVerifiedBatchBeforeUpgrade + // Verify batch + await expect( + rollupManagerContract + .connect(trustedAggregator) + .verifyBatchesTrustedAggregator( + newCreatedRollupID, + pendingState, + currentVerifiedBatch, + newVerifiedBatch, + newLocalExitRoot, + newStateRoot, + beneficiary.address, + zkProofFFlonk + ) + ).to.be.revertedWithCustomError(rollupManagerContract, "InitBatchMustMatchCurrentForkID"); }); it("should check full flow upgrading validium storage migration", async () => { @@ -3417,7 +3506,7 @@ describe("Polygon Rollup Manager", () => { }); /** - * Compute accumulateInputHash = Keccak256(oldAccInputHash, batchHashData, globalExitRoot, timestamp, seqAddress) + * Compute accumulateInputHash = Keccak256(oldAccInputHash, batchHashData, l1InfoTreeRoot, timestamp, seqAddress) * @param {String} oldAccInputHash - old accumulateInputHash * @param {String} batchHashData - Batch hash data * @param {String} globalExitRoot - Global Exit Root @@ -3428,14 +3517,14 @@ describe("Polygon Rollup Manager", () => { function calculateAccInputHashetrog( oldAccInputHash: any, batchHashData: any, - globalExitRoot: any, + l1InfoTreeRoot: any, timestamp: any, sequencerAddress: any, forcedBlockHash: any ) { const hashKeccak = ethers.solidityPackedKeccak256( ["bytes32", "bytes32", "bytes32", "uint64", "address", "bytes32"], - [oldAccInputHash, batchHashData, globalExitRoot, timestamp, sequencerAddress, forcedBlockHash] + [oldAccInputHash, batchHashData, l1InfoTreeRoot, timestamp, sequencerAddress, forcedBlockHash] ); return hashKeccak; From 262faa900469a215531b04620c0f4aecedb0bc03 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 31 Jul 2024 15:54:33 +0200 Subject: [PATCH 09/16] all coverage --- contracts/v2/PolygonRollupManager.sol | 1 + src/pessimistic-utils.js | 58 +++++++++ .../PolygonRollupManager-Pessimistic.test.ts | 33 ++++-- test/contractsv2/PolygonRollupManager.test.ts | 112 +++++++++++++++++- 4 files changed, 193 insertions(+), 11 deletions(-) create mode 100644 src/pessimistic-utils.js diff --git a/contracts/v2/PolygonRollupManager.sol b/contracts/v2/PolygonRollupManager.sol index ec5581187..609f889e2 100644 --- a/contracts/v2/PolygonRollupManager.sol +++ b/contracts/v2/PolygonRollupManager.sol @@ -40,6 +40,7 @@ contract PolygonRollupManager is * @param rollupVerifierType Rollup compatibility ID, to check upgradability between rollup types * @param obsolete Indicates if the rollup type is obsolete * @param genesis Genesis block of the rollup, note that will only be used on creating new rollups, not upgrade them + * @param programVKey Hashed program that will be executed in case of using a "general porpuse ZK verifier" e.g SP1 */ struct RollupType { address consensusImplementation; diff --git a/src/pessimistic-utils.js b/src/pessimistic-utils.js new file mode 100644 index 000000000..802aee8fc --- /dev/null +++ b/src/pessimistic-utils.js @@ -0,0 +1,58 @@ +const VerifierType = { + StateTransition: 0, + Pessimistic: 1 +} + +const ConsensusTypes = { + Ecdsa: 0 +} + +/** + * Compute input for SNARK circuit: sha256( + * initStateRoot, initBlobStateRoot, initBlobAccInputHash, initNumBlob, chainId, forkID + * finalStateRoot, finalBlobStateRoot, finalBlobAccInputHash, finalNumBlob, finalLocalExitRoot + * aggregatorAddress + * ) % FrSNARK + * @param {String} lastLocalExitRoot - old LER + * @param {String} lastPessimisticRoot - old pessimistic root. pessRoor = Poseidon(LBR # nullifierRoot) + * @param {String} selectedGlobalExitRoot - selected GER + * @param {Number} consensusHash - consensus hash. consensusHash = Sha(consensusType # consensusPayload) + * @param {Number} newLocalExitRoot - new LER + * @param {Number} newPessimisticRoot - new pessimistic root + */ +function computeInputPessimisticBytes( + lastLocalExitRoot, + lastPessimisticRoot, + selectedGlobalExitRoot, + consensusHash, + newLocalExitRoot, + newPessimisticRoot +) { + return ethers.solidityPacked( + ["bytes32", "bytes32", "bytes32", "bytes32", "bytes32", "bytes32"], + [ + lastLocalExitRoot, + lastPessimisticRoot, + selectedGlobalExitRoot, + consensusHash, + newLocalExitRoot, + newPessimisticRoot, + ] + ); +} + +/** + * Computes consensus hash + * @param address - Signer of the message in the pessimsistic proof + * @returns consensus hash + */ +function computeConsensusHashEcdsa(address) { + return ethers.solidityPackedKeccak256(["uint32", "address"], [ConsensusTypes.Ecdsa, address]); +} + +module.exports = { + VerifierType, + ConsensusTypes, + computeInputPessimisticBytes, + computeConsensusHashEcdsa, +}; \ No newline at end of file diff --git a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts index e356d8d05..7a131264e 100644 --- a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts +++ b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts @@ -15,11 +15,7 @@ import { PolygonPessimisticConsensus, } from "../../typechain-types"; import {takeSnapshot, time} from "@nomicfoundation/hardhat-network-helpers"; - -enum VerifierType { - StateTransition = 0, - Pessimistic = 1, -} +const {VerifierType, computeInputPessimisticBytes, computeConsensusHashEcdsa} = require("../../src/pessimistic-utils"); describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { let deployer: any; @@ -848,8 +844,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { .verifyPessimisticTrustedAggregator(pessimisticRollupID, unexistentGER, newLER, newPPRoot, proofPP) ).to.be.revertedWithCustomError(rollupManagerContract, "GlobalExitRootNotExist"); - // create a bridge to genenew rate a GER - // Just to have the metric of a low cost bridge Asset + // create a bridge to generate a new GER const tokenAddress = ethers.ZeroAddress; const amount = ethers.parseEther("1"); await polygonZkEVMBridgeContract.bridgeAsset( @@ -866,6 +861,30 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { const existingGER = await polygonZkEVMGlobalExitRoot.getLastGlobalExitRoot(); + // check JS function computeInputPessimisticBytes + const inputPessimisticBytes = await rollupManagerContract.getInputPessimisticBytes( + pessimisticRollupID, + existingGER, + newLER, + newPPRoot + ); + + const infoRollup = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); + + const consensusHash = computeConsensusHashEcdsa(trustedSequencer.address); + + const expectedInputPessimsiticBytes = computeInputPessimisticBytes( + infoRollup[4], + infoRollup[7], + existingGER, + consensusHash, + newLER, + newPPRoot + ); + + expect(inputPessimisticBytes).to.be.equal(expectedInputPessimsiticBytes); + + // verify pessimistic await expect( rollupManagerContract .connect(trustedAggregator) diff --git a/test/contractsv2/PolygonRollupManager.test.ts b/test/contractsv2/PolygonRollupManager.test.ts index 033a10d52..7c2e51768 100644 --- a/test/contractsv2/PolygonRollupManager.test.ts +++ b/test/contractsv2/PolygonRollupManager.test.ts @@ -14,7 +14,7 @@ import { PolygonDataCommittee, } from "../../typechain-types"; import {takeSnapshot, time} from "@nomicfoundation/hardhat-network-helpers"; -import {processorUtils, contractUtils, MTBridge, mtBridgeUtils} from "@0xpolygonhermez/zkevm-commonjs"; +import {processorUtils, contractUtils, MTBridge, mtBridgeUtils, utils} from "@0xpolygonhermez/zkevm-commonjs"; const {calculateSnarkInput, calculateAccInputHash, calculateBatchHashData} = contractUtils; type BatchDataStructEtrog = PolygonRollupBaseEtrog.BatchDataStruct; @@ -48,6 +48,7 @@ describe("Polygon Rollup Manager", () => { const pendingStateTimeoutDefault = 100; const trustedAggregatorTimeout = 100; const FORCE_BATCH_TIMEOUT = 60 * 60 * 24 * 5; // 5 days + const HALT_AGGREGATION_TIMEOUT = 60 * 60 * 24 * 7; // 7 days // BRidge constants const networkIDMainnet = 0; @@ -616,6 +617,25 @@ describe("Polygon Rollup Manager", () => { ethers.ZeroHash ); + // try to sequence in an emergency state + // snapshot emergency + const snapshotEmergencyStateSequence = await takeSnapshot(); + await rollupManagerContract.connect(emergencyCouncil).activateEmergencyState(); + + await expect( + newZkEVMContract + .connect(trustedSequencer) + .sequenceBatches( + [sequence], + indexL1infoRoot, + currentTime, + expectedAccInputHash2, + trustedSequencer.address + ) + ).to.be.revertedWithCustomError(rollupManagerContract, "OnlyNotEmergencyState"); + + await snapshotEmergencyStateSequence.restore(); + await expect( newZkEVMContract .connect(trustedSequencer) @@ -745,6 +765,55 @@ describe("Polygon Rollup Manager", () => { merkleTreeRollups.add(newLocalExitRoot); const rootRollups = merkleTreeRollups.getRoot(); + // get input snark bytes + const oldSeqData = await rollupManagerContract.getRollupSequencedBatches( + newCreatedRollupID, + currentVerifiedBatch + ); + const oldStateRoot = await rollupManagerContract.getRollupBatchNumToStateRoot( + newCreatedRollupID, + currentVerifiedBatch + ); + const newSeqData = await rollupManagerContract.getRollupSequencedBatches(newCreatedRollupID, newVerifiedBatch); + + const expectedHashInputSnarkBytes = await contractUtils.calculateSnarkInput( + oldStateRoot, + newStateRoot, + newLocalExitRoot, + oldSeqData[0], + newSeqData[0], + currentVerifiedBatch, + newVerifiedBatch, + chainID, + deployer.address, + forkID + ); + + // check newStateroot inside golilocks + const failNewSR = "0x000000000000000000000000000000000000000000000000ffffffff00000001"; + await expect( + rollupManagerContract.getInputSnarkBytes( + newCreatedRollupID, + currentVerifiedBatch, + newVerifiedBatch, + newLocalExitRoot, + oldStateRoot, + failNewSR + ) + ).to.be.revertedWithCustomError(rollupManagerContract, "NewStateRootNotInsidePrime"); + + const inputSnark = await rollupManagerContract.getInputSnarkBytes( + newCreatedRollupID, + currentVerifiedBatch, + newVerifiedBatch, + newLocalExitRoot, + oldStateRoot, + newStateRoot + ); + + const hashInputSnark = utils.sha256Snark(inputSnark.substring(2)); + expect(hashInputSnark).to.be.equal(expectedHashInputSnarkBytes); + // Verify batch const verifyBatchesTrustedAggregator = await rollupManagerContract .connect(trustedAggregator) @@ -759,8 +828,6 @@ describe("Polygon Rollup Manager", () => { zkProofFFlonk ); - // Retrieve rollup batch info - // const rollupStateRoot = await rollupManagerContract.getRollupBatchNumToStateRoot(); // Retrieve l1InfoRoot const currentL1InfoRoot = await polygonZkEVMGlobalExitRoot.getRoot(); // Retrieve depositCount @@ -776,6 +843,42 @@ describe("Polygon Rollup Manager", () => { .to.emit(polygonZkEVMGlobalExitRoot, "UpdateL1InfoTreeV2") .withArgs(currentL1InfoRoot, depositCount, blockInfo?.parentHash, blockInfo?.timestamp); + // try to set emergency state + await expect(rollupManagerContract.activateEmergencyState()).to.be.revertedWithCustomError( + rollupManagerContract, + "HaltTimeoutNotExpired" + ); + + // enter emergency state when timeout has passed + const enterEmergencyState = await takeSnapshot(); + // Increment timestamp + const blockTime = (await ethers.provider.getBlock("latest"))?.timestamp as any; + await ethers.provider.send("evm_setNextBlockTimestamp", [blockTime + HALT_AGGREGATION_TIMEOUT + 1]); + // activate + await rollupManagerContract.connect(trustedAggregator).activateEmergencyState(); + await enterEmergencyState.restore(); + + // try to enter emergency state when: timeout has passed but it has been an deactivated emergency state + const snapshotEmergencyTimeout = await takeSnapshot(); + // Increment timestamp + const currentTimestamp = (await ethers.provider.getBlock("latest"))?.timestamp as any; + await ethers.provider.send("evm_setNextBlockTimestamp", [currentTimestamp + HALT_AGGREGATION_TIMEOUT / 2 - 1]); + // activate + await rollupManagerContract.connect(emergencyCouncil).activateEmergencyState(); + // deactivate + await rollupManagerContract.connect(admin).deactivateEmergencyState(); + // Increment timestamp + const currentTimestampA = (await ethers.provider.getBlock("latest"))?.timestamp as any; + await ethers.provider.send("evm_setNextBlockTimestamp", [currentTimestampA + HALT_AGGREGATION_TIMEOUT / 2 + 2]); + + // try to set emergency state + await expect(rollupManagerContract.activateEmergencyState()).to.be.revertedWithCustomError( + rollupManagerContract, + "HaltTimeoutNotExpired" + ); + + await snapshotEmergencyTimeout.restore(); + // Retrieve rollup batch info const batchStateRoot = await rollupManagerContract.getRollupBatchNumToStateRoot( newCreatedRollupID, @@ -922,9 +1025,10 @@ describe("Polygon Rollup Manager", () => { newZkEVMContract.connect(admin).setForceBatchAddress(deployer.address) ).to.be.revertedWithCustomError(newZkEVMContract, "ForceBatchesDecentralized"); - //snapshot emergency + // snapshot emergency const snapshotEmergencyState = await takeSnapshot(); await rollupManagerContract.connect(emergencyCouncil).activateEmergencyState(); + await expect(newZkEVMContract.forceBatch("0x", 0)).to.be.revertedWithCustomError( newZkEVMContract, "ForceBatchesNotAllowedOnEmergencyState" From 3f3b029f7481a4092f10d0693c3783df0738f618 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 31 Jul 2024 16:10:46 +0200 Subject: [PATCH 10/16] fix eslint --- src/pessimistic-utils.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/pessimistic-utils.js b/src/pessimistic-utils.js index 802aee8fc..7b4111e48 100644 --- a/src/pessimistic-utils.js +++ b/src/pessimistic-utils.js @@ -1,11 +1,13 @@ +const ethers = require('ethers'); + const VerifierType = { StateTransition: 0, - Pessimistic: 1 -} + Pessimistic: 1, +}; const ConsensusTypes = { - Ecdsa: 0 -} + Ecdsa: 0, +}; /** * Compute input for SNARK circuit: sha256( @@ -26,10 +28,10 @@ function computeInputPessimisticBytes( selectedGlobalExitRoot, consensusHash, newLocalExitRoot, - newPessimisticRoot + newPessimisticRoot, ) { return ethers.solidityPacked( - ["bytes32", "bytes32", "bytes32", "bytes32", "bytes32", "bytes32"], + ['bytes32', 'bytes32', 'bytes32', 'bytes32', 'bytes32', 'bytes32'], [ lastLocalExitRoot, lastPessimisticRoot, @@ -37,7 +39,7 @@ function computeInputPessimisticBytes( consensusHash, newLocalExitRoot, newPessimisticRoot, - ] + ], ); } @@ -47,7 +49,7 @@ function computeInputPessimisticBytes( * @returns consensus hash */ function computeConsensusHashEcdsa(address) { - return ethers.solidityPackedKeccak256(["uint32", "address"], [ConsensusTypes.Ecdsa, address]); + return ethers.solidityPackedKeccak256(['uint32', 'address'], [ConsensusTypes.Ecdsa, address]); } module.exports = { @@ -55,4 +57,4 @@ module.exports = { ConsensusTypes, computeInputPessimisticBytes, computeConsensusHashEcdsa, -}; \ No newline at end of file +}; From 2bcabb6efeeb9af31e5c55bf51be1a9e19d044f8 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Thu, 1 Aug 2024 13:40:03 +0200 Subject: [PATCH 11/16] add rollupID as a public input --- .github/workflows/build-docker.yml | 41 +------------ .github/workflows/build-push-docker.yml | 60 +++++++++++++++++++ contracts/v2/PolygonRollupManager.sol | 5 ++ src/pessimistic-utils.js | 11 ++-- .../PolygonRollupManager-Pessimistic.test.ts | 1 + 5 files changed, 76 insertions(+), 42 deletions(-) create mode 100644 .github/workflows/build-push-docker.yml diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 5ebfa474d..90eefd319 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -5,7 +5,9 @@ name: Build-Docker image on: push: - branches: [main] + branches: [main, develop, feature/ongoingPP] + pull_request: + branches: [main, develop, feature/ongoingPP] jobs: build: runs-on: ubuntu-latest @@ -19,42 +21,5 @@ jobs: uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - - name: Set int-bot SSH key - run: | - touch /tmp/ssh-key - echo "${{ secrets.INT_BOT_SSH_KEY }}" > /tmp/ssh-key - chmod 400 /tmp/ssh-key - eval "$(ssh-agent -s)" - ssh-add /tmp/ssh-key - - name: Checkout code - uses: actions/checkout@v3 - - name: setup - run: | - eval "$(ssh-agent -s)" - ssh-add /tmp/ssh-key - npm i - sudo curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose - sudo chmod +x /usr/local/bin/docker-compose - - name: Login to DockerHub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build docker run: npm run docker:contracts - - name: Push docker image - run: npm run push:docker:contracts - # Steps to push multi-platform image, it relies on the previous step: - # npm run docker:contracts - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v1 - - name: Build and push - uses: docker/build-push-action@v2 - with: - platforms: linux/amd64,linux/arm64 - push: true - tags: hermeznetwork/geth-zkevm-contracts:1.5-integration - file: docker/Dockerfile - context: . diff --git a/.github/workflows/build-push-docker.yml b/.github/workflows/build-push-docker.yml new file mode 100644 index 000000000..e434c236b --- /dev/null +++ b/.github/workflows/build-push-docker.yml @@ -0,0 +1,60 @@ +# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Build-Docker image and push it + +on: + push: + branches: [main] +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16.x] + + steps: + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - name: Set int-bot SSH key + run: | + touch /tmp/ssh-key + echo "${{ secrets.INT_BOT_SSH_KEY }}" > /tmp/ssh-key + chmod 400 /tmp/ssh-key + eval "$(ssh-agent -s)" + ssh-add /tmp/ssh-key + - name: Checkout code + uses: actions/checkout@v3 + - name: setup + run: | + eval "$(ssh-agent -s)" + ssh-add /tmp/ssh-key + npm i + sudo curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker-compose + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Build docker + run: npm run docker:contracts + - name: Push docker image + run: npm run push:docker:contracts + # Steps to push multi-platform image, it relies on the previous step: + # npm run docker:contracts + - name: Set up QEMU + uses: docker/setup-qemu-action@v1 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + - name: Build and push + uses: docker/build-push-action@v2 + with: + platforms: linux/amd64,linux/arm64 + push: true + tags: hermeznetwork/geth-zkevm-contracts:1.5-integration + file: docker/Dockerfile + context: . diff --git a/contracts/v2/PolygonRollupManager.sol b/contracts/v2/PolygonRollupManager.sol index 609f889e2..ab731145b 100644 --- a/contracts/v2/PolygonRollupManager.sol +++ b/contracts/v2/PolygonRollupManager.sol @@ -953,6 +953,7 @@ contract PolygonRollupManager is } bytes memory inputPessimisticBytes = _getInputPessimisticBytes( + rollupID, rollup, selectedGlobalExitRoot, newLocalExitRoot, @@ -1280,6 +1281,7 @@ contract PolygonRollupManager is ) public view returns (bytes memory) { return _getInputPessimisticBytes( + rollupID, _rollupIDToRollupData[rollupID], selectedGlobalExitRoot, newLocalExitRoot, @@ -1289,12 +1291,14 @@ contract PolygonRollupManager is /** * @notice Function to calculate the input snark bytes + * @param rollupID Rollup identifier * @param rollup Rollup data storage pointer * @param selectedGlobalExitRoot Selected global exit root to proof imported bridges * @param newLocalExitRoot New local exit root * @param newPessimisticRoot New pessimistic information, Hash(localBalanceTreeRoot, nullifierTreeRoot) */ function _getInputPessimisticBytes( + uint32 rollupID, RollupData storage rollup, bytes32 selectedGlobalExitRoot, bytes32 newLocalExitRoot, @@ -1310,6 +1314,7 @@ contract PolygonRollupManager is rollup.lastLocalExitRoot, rollup.lastPessimisticRoot, selectedGlobalExitRoot, + rollupID, // networkID = rollupID - 1 consensusHash, newLocalExitRoot, newPessimisticRoot diff --git a/src/pessimistic-utils.js b/src/pessimistic-utils.js index 7b4111e48..18f6c9867 100644 --- a/src/pessimistic-utils.js +++ b/src/pessimistic-utils.js @@ -18,24 +18,27 @@ const ConsensusTypes = { * @param {String} lastLocalExitRoot - old LER * @param {String} lastPessimisticRoot - old pessimistic root. pessRoor = Poseidon(LBR # nullifierRoot) * @param {String} selectedGlobalExitRoot - selected GER - * @param {Number} consensusHash - consensus hash. consensusHash = Sha(consensusType # consensusPayload) - * @param {Number} newLocalExitRoot - new LER - * @param {Number} newPessimisticRoot - new pessimistic root + * @param {Number} rollupID - rollup identifier (networkID = rollupID - 1) + * @param {String} consensusHash - consensus hash. consensusHash = Sha(consensusType # consensusPayload) + * @param {String} newLocalExitRoot - new LER + * @param {String} newPessimisticRoot - new pessimistic root */ function computeInputPessimisticBytes( lastLocalExitRoot, lastPessimisticRoot, selectedGlobalExitRoot, + rollupID, consensusHash, newLocalExitRoot, newPessimisticRoot, ) { return ethers.solidityPacked( - ['bytes32', 'bytes32', 'bytes32', 'bytes32', 'bytes32', 'bytes32'], + ['bytes32', 'bytes32', 'bytes32', 'uint32', 'bytes32', 'bytes32', 'bytes32'], [ lastLocalExitRoot, lastPessimisticRoot, selectedGlobalExitRoot, + rollupID, consensusHash, newLocalExitRoot, newPessimisticRoot, diff --git a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts index 7a131264e..1da4067be 100644 --- a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts +++ b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts @@ -877,6 +877,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { infoRollup[4], infoRollup[7], existingGER, + pessimisticRollupID, consensusHash, newLER, newPPRoot From 155199c2344f2690b95be92f71cf8f7ce840ba22 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Thu, 1 Aug 2024 15:16:04 +0200 Subject: [PATCH 12/16] remove incorrect comment --- contracts/v2/PolygonRollupManager.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/v2/PolygonRollupManager.sol b/contracts/v2/PolygonRollupManager.sol index ab731145b..fd3012bd1 100644 --- a/contracts/v2/PolygonRollupManager.sol +++ b/contracts/v2/PolygonRollupManager.sol @@ -1314,7 +1314,7 @@ contract PolygonRollupManager is rollup.lastLocalExitRoot, rollup.lastPessimisticRoot, selectedGlobalExitRoot, - rollupID, // networkID = rollupID - 1 + rollupID, consensusHash, newLocalExitRoot, newPessimisticRoot From 2130a9f2e9a749e31122e52b2445a64e224dcd60 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Fri, 2 Aug 2024 10:18:51 +0200 Subject: [PATCH 13/16] missing checkout on gha docker-build --- .github/workflows/build-docker.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 90eefd319..9b66b7ad8 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -21,5 +21,7 @@ jobs: uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} + - name: Checkout code + uses: actions/checkout@v3 - name: Build docker run: npm run docker:contracts From e52515f162a21bf6fcaa9cc2db15f7b7bf9dd47d Mon Sep 17 00:00:00 2001 From: krlosMata Date: Fri, 2 Aug 2024 15:25:11 +0200 Subject: [PATCH 14/16] returnData V2 --- contracts/v2/PolygonRollupManager.sol | 30 ++++++++-------- .../PolygonRollupManager-Pessimistic.test.ts | 36 +++++++++---------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/contracts/v2/PolygonRollupManager.sol b/contracts/v2/PolygonRollupManager.sol index fd3012bd1..72c6f5d6c 100644 --- a/contracts/v2/PolygonRollupManager.sol +++ b/contracts/v2/PolygonRollupManager.sol @@ -114,7 +114,7 @@ contract PolygonRollupManager is * @param rollupTypeID Rollup type ID, can be 0 if it was added as an existing rollup * @param rollupVerifierType Rollup ID used for compatibility checks when upgrading */ - struct RollupDataReturnStateTransistion { + struct RollupDataReturn { IPolygonRollupBase rollupContract; uint64 chainID; address verifier; @@ -130,24 +130,30 @@ contract PolygonRollupManager is } /** - * @notice Struct to return all the necessary rollup info: VerifierType Pessimistic + * @notice Struct which to store the rollup data of each chain * @param rollupContract Rollup consensus contract, which manages everything * related to sequencing transactions * @param chainID Chain ID of the rollup * @param verifier Verifier contract * @param forkID ForkID of the rollup * @param lastLocalExitRoot Last exit root verified, used for compute the rollupExitRoot + * @param lastBatchSequenced Last batch sent by the consensus contract + * @param lastVerifiedBatch Last batch verified + * @param lastVerifiedBatchBeforeUpgrade Last batch verified before the last upgrade * @param rollupTypeID Rollup type ID, can be 0 if it was added as an existing rollup * @param rollupVerifierType Rollup ID used for compatibility checks when upgrading * @param lastPessimisticRoot Pessimistic info, currently contains the local balance tree and the local nullifier tree hashed * @param programVKey Hashed program that will be executed in case of using a "general porpuse ZK verifier" e.g SP1 */ - struct RollupDataReturnPessimistic { + struct RollupDataReturnV2 { IPolygonRollupBase rollupContract; uint64 chainID; address verifier; uint64 forkID; bytes32 lastLocalExitRoot; + uint64 lastBatchSequenced; + uint64 lastVerifiedBatch; + uint64 lastVerifiedBatchBeforeUpgrade; uint64 rollupTypeID; VerifierType rollupVerifierType; bytes32 lastPessimisticRoot; @@ -1454,13 +1460,9 @@ contract PolygonRollupManager is */ function rollupIDToRollupData( uint32 rollupID - ) public view returns (RollupDataReturnStateTransistion memory rollupData) { + ) public view returns (RollupDataReturn memory rollupData) { RollupData storage rollup = _rollupIDToRollupData[rollupID]; - if (rollup.rollupVerifierType != VerifierType.StateTransition) { - revert InvalidVerifierType(); - } - rollupData.rollupContract = rollup.rollupContract; rollupData.chainID = rollup.chainID; rollupData.verifier = rollup.verifier; @@ -1481,20 +1483,20 @@ contract PolygonRollupManager is * @notice Get rollup data: VerifierType Pessimistic * @param rollupID Rollup identifier */ - function rollupIDToRollupDataPessimistic( + function rollupIDToRollupDataV2( uint32 rollupID - ) public view returns (RollupDataReturnPessimistic memory rollupData) { + ) public view returns (RollupDataReturnV2 memory rollupData) { RollupData storage rollup = _rollupIDToRollupData[rollupID]; - if (rollup.rollupVerifierType != VerifierType.Pessimistic) { - revert InvalidVerifierType(); - } - rollupData.rollupContract = rollup.rollupContract; rollupData.chainID = rollup.chainID; rollupData.verifier = rollup.verifier; rollupData.forkID = rollup.forkID; rollupData.lastLocalExitRoot = rollup.lastLocalExitRoot; + rollupData.lastBatchSequenced = rollup.lastBatchSequenced; + rollupData.lastVerifiedBatch = rollup.lastVerifiedBatch; + rollupData.lastVerifiedBatchBeforeUpgrade = rollup + .lastVerifiedBatchBeforeUpgrade; rollupData.rollupTypeID = rollup.rollupTypeID; rollupData.rollupVerifierType = rollup.rollupVerifierType; rollupData.lastPessimisticRoot = rollup.lastPessimisticRoot; diff --git a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts index 1da4067be..133b2d309 100644 --- a/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts +++ b/test/contractsv2/PolygonRollupManager-Pessimistic.test.ts @@ -413,7 +413,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { expect(await newZkEVMContract.networkName()).to.be.equal(networkName); // assert new rollup - const resRollupData = await rollupManagerContract.rollupIDToRollupDataPessimistic(newCreatedRollupID); + const resRollupData = await rollupManagerContract.rollupIDToRollupDataV2(newCreatedRollupID); const expectedRollupData = [ newZKEVMAddress, @@ -421,6 +421,9 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { verifierContract.target, forkID, ethers.ZeroHash, + 0, + 0, + 0, newRollupTypeID, VerifierType.Pessimistic, ethers.ZeroHash, @@ -570,7 +573,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { ); // get rollup data - const rollupPessimistic = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); + const rollupPessimistic = await rollupManagerContract.rollupIDToRollupDataV2(pessimisticRollupID); const rollupStateTransition = await rollupManagerContract.rollupIDToRollupData(stateTransistionRollupID); // try to update rollup from Pessimistic to stateTransition @@ -677,7 +680,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { ); // get rollup data - const rollupPessimistic = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); + const rollupPessimistic = await rollupManagerContract.rollupIDToRollupDataV2(pessimisticRollupID); // try to update rollup from StateTransition to Pessimistic await rollupManagerContract @@ -685,7 +688,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { .updateRollup(rollupPessimistic[0] as unknown as Address, newRollupTypeID, "0x"); // assert new rollup - const resRollupData = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); + const resRollupData = await rollupManagerContract.rollupIDToRollupDataV2(pessimisticRollupID); const expectedRollupData = [ newZKEVMAddress, @@ -693,6 +696,9 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { newVerifier, newForkID, ethers.ZeroHash, + 0, + 0, + 0, newRollupTypeID, VerifierType.Pessimistic, ethers.ZeroHash, @@ -755,7 +761,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { ); // get rollup data - const rollupPessimistic = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); + const rollupPessimistic = await rollupManagerContract.rollupIDToRollupDataV2(pessimisticRollupID); // try to rollback sequences await expect( @@ -869,13 +875,13 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { newPPRoot ); - const infoRollup = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); + const infoRollup = await rollupManagerContract.rollupIDToRollupDataV2(pessimisticRollupID); const consensusHash = computeConsensusHashEcdsa(trustedSequencer.address); const expectedInputPessimsiticBytes = computeInputPessimisticBytes( infoRollup[4], - infoRollup[7], + infoRollup[10], existingGER, pessimisticRollupID, consensusHash, @@ -895,13 +901,7 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { .withArgs(pessimisticRollupID, 0, ethers.ZeroHash, newLER, trustedAggregator.address); // assert rollup data - // try to get stateTransistion data from pessimsitic rollup - await expect(rollupManagerContract.rollupIDToRollupData(pessimisticRollupID)).to.be.revertedWithCustomError( - rollupManagerContract, - "InvalidVerifierType" - ); - - const resRollupData = await rollupManagerContract.rollupIDToRollupDataPessimistic(pessimisticRollupID); + const resRollupData = await rollupManagerContract.rollupIDToRollupDataV2(pessimisticRollupID); const expectedRollupData = [ newZKEVMAddress, @@ -909,6 +909,9 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { verifierContract.target, forkID, newLER, + 0, + 0, + 0, rollupTypeID, VerifierType.Pessimistic, newPPRoot, @@ -1010,10 +1013,5 @@ describe("Polygon Rollup Manager with Polygon Pessimistic Consensus", () => { .connect(trustedAggregator) .verifyPessimisticTrustedAggregator(stateTransistionRollupID, unexistentGER, newLER, newPPRoot, proofPP) ).to.be.revertedWithCustomError(rollupManagerContract, "OnlyChainsWithPessimisticProofs"); - - // tro get pessimistic info from stateTransistion chain - await expect( - rollupManagerContract.rollupIDToRollupDataPessimistic(stateTransistionRollupID) - ).to.be.revertedWithCustomError(rollupManagerContract, "InvalidVerifierType"); }); }); From 8942b02399e1f9a744f00a324161328e5280fd23 Mon Sep 17 00:00:00 2001 From: krlosMata Date: Fri, 2 Aug 2024 17:09:24 +0200 Subject: [PATCH 15/16] fix build docker --- .github/workflows/build-docker.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 9b66b7ad8..c3f4432f5 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: - node-version: [16.x] + node-version: [18.x] steps: - name: Use Node.js ${{ matrix.node-version }} @@ -23,5 +23,10 @@ jobs: node-version: ${{ matrix.node-version }} - name: Checkout code uses: actions/checkout@v3 + - name: Setup docker + run: | + npm i + sudo curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker-compose - name: Build docker run: npm run docker:contracts From 8f06eb7614bb8d58e62ce600543eb68197b45eef Mon Sep 17 00:00:00 2001 From: invocamanman Date: Mon, 5 Aug 2024 19:39:49 +0200 Subject: [PATCH 16/16] mini thingds --- contracts/v2/PolygonRollupManager.sol | 6 ++- ...r.sol => PolygonRollupManagerPrevious.sol} | 0 package-lock.json | 43 +++++++++---------- package.json | 4 +- .../PolygonRollupManagerUpgrade.test.ts | 1 - 5 files changed, 27 insertions(+), 27 deletions(-) rename contracts/v2/previousVersions/{PolygonRollupManager.sol => PolygonRollupManagerPrevious.sol} (100%) diff --git a/contracts/v2/PolygonRollupManager.sol b/contracts/v2/PolygonRollupManager.sol index 72c6f5d6c..0aade8ce1 100644 --- a/contracts/v2/PolygonRollupManager.sol +++ b/contracts/v2/PolygonRollupManager.sol @@ -46,6 +46,7 @@ contract PolygonRollupManager is address consensusImplementation; address verifier; uint64 forkID; + /// @custom:oz-renamed-from rollupCompatibilityID /// @custom:oz-retyped-from uint8 VerifierType rollupVerifierType; bool obsolete; @@ -92,6 +93,7 @@ contract PolygonRollupManager is uint64 _legacyLastPendingStateConsolidated; uint64 lastVerifiedBatchBeforeUpgrade; uint64 rollupTypeID; + /// @custom:oz-renamed-from rollupCompatibilityID /// @custom:oz-retyped-from uint8 VerifierType rollupVerifierType; bytes32 lastPessimisticRoot; @@ -242,14 +244,14 @@ contract PolygonRollupManager is uint32 public rollupTypeCount; // Rollup type mapping - // @custom:oz-retyped-from PolygonRollupManagerPrevious.RollupType + /// @custom:oz-retyped-from PolygonRollupManagerPrevious.RollupType mapping(uint32 rollupTypeID => RollupType) public rollupTypeMap; // Number of rollups added, every new rollup will be assigned sequencially a new ID uint32 public rollupCount; // Rollups ID mapping - /// @custom:oz-renamed-from rollupIDToRollupData + /// @custom:oz-retyped-from PolygonRollupManagerPrevious.RollupData mapping(uint32 rollupID => RollupData) internal _rollupIDToRollupData; // Rollups address mapping diff --git a/contracts/v2/previousVersions/PolygonRollupManager.sol b/contracts/v2/previousVersions/PolygonRollupManagerPrevious.sol similarity index 100% rename from contracts/v2/previousVersions/PolygonRollupManager.sol rename to contracts/v2/previousVersions/PolygonRollupManagerPrevious.sol diff --git a/package-lock.json b/package-lock.json index 667fa57ae..3361ba818 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@openzeppelin/contracts": "4.8.2", "@openzeppelin/contracts-upgradeable": "4.8.2", "@openzeppelin/contracts5": "npm:@openzeppelin/contracts@^5.0.0", - "@openzeppelin/hardhat-upgrades": "2.5.0", + "@openzeppelin/hardhat-upgrades": "^2.5.1", "@types/yargs": "^17.0.28", "circomlibjs": "0.1.1", "dotenv": "^8.6.0", @@ -3155,9 +3155,9 @@ } }, "node_modules/@openzeppelin/defender-sdk-base-client": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-base-client/-/defender-sdk-base-client-1.7.0.tgz", - "integrity": "sha512-tNT/uaAS37I+EZUVcH6AyM6gfvxiiBQ+tdY8Jk73XKtEdiYd0pJnKyaeeUHIlvKCNS/wyxX6hlPVjeC4hy59Nw==", + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-base-client/-/defender-sdk-base-client-1.14.3.tgz", + "integrity": "sha512-4yG9E8N1c/ZP2jNR+Ah19wi7SBKpauAV/VcYcm7rg1dltDbzbH/oZnnXJlymT7IfjTPXkKHW8TPsaqz3EjS7tA==", "dev": true, "dependencies": { "amazon-cognito-identity-js": "^6.3.6", @@ -3165,27 +3165,26 @@ } }, "node_modules/@openzeppelin/defender-sdk-deploy-client": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-deploy-client/-/defender-sdk-deploy-client-1.7.0.tgz", - "integrity": "sha512-eu/1khO5R0IdHio3BXlzUWZdr0Rgodoi49Djqtl3N78G8yN7t4RijfGrJm9rSqjrDFsjM41eWNHYGjc+KKyhKg==", + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-deploy-client/-/defender-sdk-deploy-client-1.14.3.tgz", + "integrity": "sha512-51WIZJz251lndK7uQU4gBE0gBX+2ZNTgf+hemtJUEPCpHtkooBRFFMID3EPGMKXVqf872pU8K3Huu9PyYQu6bw==", "dev": true, "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@openzeppelin/defender-sdk-base-client": "^1.7.0", - "axios": "^1.4.0", + "@openzeppelin/defender-sdk-base-client": "1.14.3", + "axios": "^1.7.2", "lodash": "^4.17.21" } }, "node_modules/@openzeppelin/hardhat-upgrades": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-2.5.0.tgz", - "integrity": "sha512-pRsqyRbp8LX9sTSMbL7jx4NjqjN/4PlKngmuAyRQIheYTGbRIs3FW3WyLuiCjkDlTETfmOsmzrnZxJmxDmxZIA==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-2.5.1.tgz", + "integrity": "sha512-wRwq9f2PqlfIdNGFApsqRpqptqy98exSFp8SESb6Brgw4L07sExySInNJhscM/tWVSnR1Qnuws9Ck6Fs5zIxvg==", "dev": true, "dependencies": { "@openzeppelin/defender-admin-client": "^1.52.0", "@openzeppelin/defender-base-client": "^1.52.0", - "@openzeppelin/defender-sdk-base-client": "^1.5.0", - "@openzeppelin/defender-sdk-deploy-client": "^1.5.0", + "@openzeppelin/defender-sdk-base-client": "^1.8.0", + "@openzeppelin/defender-sdk-deploy-client": "^1.8.0", "@openzeppelin/upgrades-core": "^1.31.2", "chalk": "^4.1.0", "debug": "^4.1.1", @@ -4652,12 +4651,12 @@ "dev": true }, "node_modules/axios": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", - "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz", + "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==", "dev": true, "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -7202,9 +7201,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true, "funding": [ { diff --git a/package.json b/package.json index b0a7d1785..b776c2f8d 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@openzeppelin/contracts": "4.8.2", "@openzeppelin/contracts-upgradeable": "4.8.2", "@openzeppelin/contracts5": "npm:@openzeppelin/contracts@^5.0.0", - "@openzeppelin/hardhat-upgrades": "2.5.0", + "@openzeppelin/hardhat-upgrades": "^2.5.1", "@types/yargs": "^17.0.28", "circomlibjs": "0.1.1", "dotenv": "^8.6.0", @@ -111,4 +111,4 @@ "verify:upgradeV2:mainnet": "npx hardhat run upgrade/upgradeToV2/verifyContracts.ts --network mainnet", "saveUpgradeV2:mainnet": "mkdir -p upgrade/upgradeToV2/mainnet_$(date +%s) && cp -r upgrade/upgradeToV2/upgrade_*.json upgrade/upgradeToV2/mainnet_$(date +%s) && cp -r upgrade/upgradeToV2/deploy_*.json upgrade/upgradeToV2/mainnet_$(date +%s) && cp .openzeppelin/mainnet.json upgrade/upgradeToV2/mainnet_$(date +%s)" } -} \ No newline at end of file +} diff --git a/test/contractsv2/PolygonRollupManagerUpgrade.test.ts b/test/contractsv2/PolygonRollupManagerUpgrade.test.ts index a2159f3fd..b3c7f5592 100644 --- a/test/contractsv2/PolygonRollupManagerUpgrade.test.ts +++ b/test/contractsv2/PolygonRollupManagerUpgrade.test.ts @@ -227,7 +227,6 @@ describe("Polygon Rollup manager upgraded", () => { ], unsafeAllow: ["constructor", "state-variable-immutable"], unsafeAllowRenames: true, - unsafeSkipStorageCheck: true, call: { fn: "initialize", args: [