Skip to content

Commit

Permalink
Merge pull request #61 from 0xPolygonHermez/feature/grapefruitVerifier
Browse files Browse the repository at this point in the history
Feature/grapefruit verifier
  • Loading branch information
krlosMata authored Sep 30, 2022
2 parents 6a1a9a1 + 5766b2f commit 05adaa2
Show file tree
Hide file tree
Showing 11 changed files with 2,186 additions and 120 deletions.
4 changes: 2 additions & 2 deletions compiled-contracts/ProofOfEfficiency.json

Large diffs are not rendered by default.

133 changes: 131 additions & 2 deletions compiled-contracts/ProofOfEfficiencyMock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions compiled-contracts/Verifier.json

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions contracts/ProofOfEfficiency.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@ contract ProofOfEfficiency is Initializable {
uint256 public constant TRUSTED_SEQUENCER_FEE = 0.1 ether; // TODO should be defined

// Max batch byte length
uint256 public constant MAX_BATCH_LENGTH = type(uint256).max; // TODO should be defined
// Max keccaks circuit = (2**23 / 158418) * 9 = 468
// Bytes per keccak = 136
// Minimum Static keccaks batch = 4
// Max bytes allowed = (468 - 4) * 136 = 63104 bytes - 1 byte padding
// Rounded to 60000 bytes
uint256 public constant MAX_BATCH_LENGTH = 60000;

// Force batch timeout
uint64 public constant FORCE_BATCH_TIMEOUT = 7 days;
Expand Down Expand Up @@ -180,7 +185,7 @@ contract ProofOfEfficiency is Initializable {
address _trustedSequencer,
bool _forceBatchAllowed,
string memory _trustedSequencerURL
) public initializer {
) public virtual initializer {
globalExitRootManager = _globalExitRootManager;
matic = _matic;
rollupVerifier = _rollupVerifier;
Expand Down
97 changes: 93 additions & 4 deletions contracts/mocks/ProofOfEfficiencyMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,43 @@
pragma solidity 0.8.15;

import "../ProofOfEfficiency.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

/**
* Contract responsible for managing the state and the updates of the L2 network
* There will be sequencer, which are able to send transactions. That transactions will be stored in the contract.
* The aggregators are forced to process and validate the sequencers transactions in the same order by using a verifier.
* To enter and exit of the L2 network will be used a Bridge smart contract
*/
contract ProofOfEfficiencyMock is ProofOfEfficiency {
contract ProofOfEfficiencyMock is ProofOfEfficiency, OwnableUpgradeable {
/**
* @param _globalExitRootManager global exit root manager address
* @param _matic MATIC token address
* @param _rollupVerifier rollup verifier address
* @param genesisRoot rollup genesis root
* @param _trustedSequencer trusted sequencer address
* @param _forceBatchAllowed indicates wheather the force batch functionality is available
* @param _trustedSequencerURL trusted sequencer URL
*/
function initialize(
IGlobalExitRootManager _globalExitRootManager,
IERC20Upgradeable _matic,
IVerifierRollup _rollupVerifier,
bytes32 genesisRoot,
address _trustedSequencer,
bool _forceBatchAllowed,
string memory _trustedSequencerURL
) public override initializer {
globalExitRootManager = _globalExitRootManager;
matic = _matic;
rollupVerifier = _rollupVerifier;
currentStateRoot = genesisRoot;
trustedSequencer = _trustedSequencer;
forceBatchAllowed = _forceBatchAllowed;
trustedSequencerURL = _trustedSequencerURL;
__Ownable_init();
}

/**
* @notice Calculate the stark input
* @param currentStateRoot Current state Root
Expand Down Expand Up @@ -247,15 +276,75 @@ contract ProofOfEfficiencyMock is ProofOfEfficiency {
* @notice Set state root
* @param newStateRoot New State root ¡
*/
function setStateRoot(bytes32 newStateRoot) public {
function setStateRoot(bytes32 newStateRoot) public onlyOwner {
currentStateRoot = newStateRoot;
}

/**
* @notice Set Sequencer
* @notice Set Exit Root
* @param newLocalExitRoot New exit root ¡
*/
function setExitRoot(bytes32 newLocalExitRoot) public {
function setExitRoot(bytes32 newLocalExitRoot) public onlyOwner {
currentLocalExitRoot = newLocalExitRoot;
}

/**
* @notice Set Sequencer
* @param _rollupVerifier New verifier
*/
function setVerifier(IVerifierRollup _rollupVerifier) public onlyOwner {
rollupVerifier = _rollupVerifier;
}

/**
* @notice Set Sequencer
* @param _numBatch New verifier
*/
function setVerifiedBatch(uint64 _numBatch) public onlyOwner {
lastVerifiedBatch = _numBatch;
}

/**
* @notice Set Sequencer
* @param _numBatch New verifier
*/
function setSequencedBatch(uint64 _numBatch) public onlyOwner {
lastBatchSequenced = _numBatch;
}

/**
* @notice Allows an aggregator to verify a batch
* @param newLocalExitRoot New local exit root once the batch is processed
* @param newStateRoot New State root once the batch is processed
* @param numBatch Batch number that the aggregator intends to verify, used as a sanity check
*/
function verifyBatchMock(
bytes32 newLocalExitRoot,
bytes32 newStateRoot,
uint64 numBatch,
uint256[2] calldata proofA,
uint256[2][2] calldata proofB,
uint256[2] calldata proofC
) public onlyOwner {
// sanity check
require(
numBatch == lastVerifiedBatch + 1,
"ProofOfEfficiency::verifyBatch: batch does not match"
);

require(
numBatch <= lastBatchSequenced,
"ProofOfEfficiency::verifyBatch: batch does not have been sequenced"
);

// Update state
lastVerifiedBatch++;
currentStateRoot = newStateRoot;
currentLocalExitRoot = newLocalExitRoot;

// Interact with globalExitRoot
globalExitRootManager.updateExitRoot(currentLocalExitRoot);

emit VerifyBatch(numBatch, msg.sender);
}
}
16 changes: 8 additions & 8 deletions contracts/verifiers/Verifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -258,24 +258,24 @@ contract Verifier {
);
vk.delta2 = Pairing.G2Point(
[
8188133026889091027856087262423689337288537869553783670503523924435362871863,
18620400793702540571830888102060291015580892623749971407600191942375988811221
19750022496320240285101974197532631012549739392915452934998344141081741597788,
2223709129676094253803737952722506157817386693174598893579503973249984386700
],
[
261378424847058333545744776259397296033734994929076139782236430167356014909,
15862210727222112294249509989128349840464733037854829171142736285795705227424
8966856057114738640791797187844853032120821578531353489915389735279816674443,
11597187533467027019109289109090493384694314652469173795335699571419657895459
]
);
vk.IC = new Pairing.G1Point[](2);

vk.IC[0] = Pairing.G1Point(
16295726692751084026070338310517949640740817381066173380170000205205468334465,
9912718531730304020921134608687121537381161742676114483923962717303940463744
3627212711832259927366220037147556247655224844677697657011085160292772114693,
3868076051722587117964587681717552506747417383257761638118612049734072870316
);

vk.IC[1] = Pairing.G1Point(
19230317438752043671609520496064012189568042726418813709758990551030728674048,
9402561321447615383609311866863793168259761950949292469394516560760039553443
9897458465965570598905236047800806366352001136795638520287997492087260786366,
9992939189109259730671274431440102542613311982204982073059522006827208775593
);
}

Expand Down
67 changes: 54 additions & 13 deletions deployment/deployment_v2-0/deployPoE_v2-0.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const { ethers } = require('hardhat');
const path = require('path');
const fs = require('fs');
const { Scalar } = require('ffjavascript');
require('dotenv').config({ path: path.resolve(__dirname, '../../.env') })

const pathOutputJson = path.join(__dirname, './deploy_output.json');

Expand All @@ -10,13 +11,23 @@ const deployParameters = require('./deploy_parameters.json');
const genesis = require("./genesis.json")

async function main() {
const deployer = (await ethers.getSigners())[0];
const networkIDMainnet = 0;
const forceBatchAllowed = Boolean(deployParameters.forceBatchAllowed);
const trustedSequencer = deployParameters.trustedSequencerAddress;
const trustedSequencerURL = deployParameters.trustedSequencerURL || "http://zkevm-json-rpc:8123";
const realVerifier = deployParameters.realVerifier || false;
console.log("real Verifier:", realVerifier);
const atemptsDeployProxy = 20;

const deployer = (await ethers.getSigners())[0];
// Use this only if necessary, override the hardhat gas parameters
// const FEE_DATA = {
// maxFeePerGas: ethers.utils.parseUnits('10', 'gwei'),
// maxPriorityFeePerGas: ethers.utils.parseUnits('4', 'gwei'),
// };
// const currentProvider = new ethers.providers.JsonRpcProvider(`https://${process.env.HARDHAT_NETWORK}.infura.io/v3/${process.env.INFURA_PROJECT_ID}`);

// currentProvider.getFeeData = async () => FEE_DATA;
// const deployer = ethers.Wallet.fromMnemonic(process.env.MNEMONIC, `m/44'/60'/0'/0/0`).connect(currentProvider);

/*
Deployment MATIC
Expand All @@ -25,12 +36,12 @@ async function main() {
const maticTokenSymbol = 'MATIC';
const maticTokenInitialBalance = ethers.utils.parseEther('20000000');

const maticTokenFactory = await ethers.getContractFactory('ERC20PermitMock');
const maticTokenFactory = await ethers.getContractFactory('ERC20PermitMock', deployer);
const maticTokenContract = await maticTokenFactory.deploy(
maticTokenName,
maticTokenSymbol,
deployer.address,
maticTokenInitialBalance,
maticTokenInitialBalance
);
await maticTokenContract.deployed();

Expand All @@ -43,14 +54,14 @@ async function main() {
let verifierContract;
if (realVerifier === true) {
const VerifierRollup = await ethers.getContractFactory(
'Verifier',
'Verifier', deployer
);
verifierContract = await VerifierRollup.deploy();
await verifierContract.deployed();
}
else {
const VerifierRollupHelperFactory = await ethers.getContractFactory(
'VerifierRollupHelperMock',
'VerifierRollupHelperMock', deployer
);
verifierContract = await VerifierRollupHelperFactory.deploy();
await verifierContract.deployed();
Expand All @@ -61,21 +72,51 @@ async function main() {
/*
*Deployment Global exit root manager
*/

// deploy global exit root manager
const globalExitRootManagerFactory = await ethers.getContractFactory('GlobalExitRootManager');
globalExitRootManager = await upgrades.deployProxy(globalExitRootManagerFactory, [], { initializer: false });
const globalExitRootManagerFactory = await ethers.getContractFactory('GlobalExitRootManager', deployer);
let globalExitRootManager;
for (let i = 0; i < atemptsDeployProxy; i++) {
try {
globalExitRootManager = await upgrades.deployProxy(globalExitRootManagerFactory, [], { initializer: false });
break;
}
catch (error) {
console.log(`attempt ${atemptsDeployProxy}`);
console.log("upgrades.deployProxy of hermezAuctionProtocol ", error);
}
}

// deploy bridge
const bridgeFactory = await ethers.getContractFactory('Bridge');
bridgeContract = await upgrades.deployProxy(bridgeFactory, [], { initializer: false });
const bridgeFactory = await ethers.getContractFactory('Bridge', deployer);
let bridgeContract;
for (let i = 0; i < atemptsDeployProxy; i++) {
try {
bridgeContract = await upgrades.deployProxy(bridgeFactory, [], { initializer: false });
break;
}
catch (error) {
console.log(`attempt ${atemptsDeployProxy}`);
console.log("upgrades.deployProxy of hermezAuctionProtocol ", error);
}
}

// deploy PoE
const ProofOfEfficiencyFactory = await ethers.getContractFactory('ProofOfEfficiencyMock');
proofOfEfficiencyContract = await upgrades.deployProxy(ProofOfEfficiencyFactory, [], { initializer: false });
const ProofOfEfficiencyFactory = await ethers.getContractFactory('ProofOfEfficiencyMock', deployer);
let proofOfEfficiencyContract;
for (let i = 0; i < atemptsDeployProxy; i++) {
try {
proofOfEfficiencyContract = await upgrades.deployProxy(ProofOfEfficiencyFactory, [], { initializer: false });
break;
}
catch (error) {
console.log(`attempt ${atemptsDeployProxy}`);
console.log("upgrades.deployProxy of hermezAuctionProtocol ", error);
}
}

await globalExitRootManager.initialize(proofOfEfficiencyContract.address, bridgeContract.address);


console.log('#######################\n');
console.log('globalExitRootManager deployed to:', globalExitRootManager.address);

Expand Down
8 changes: 6 additions & 2 deletions test/contracts/real-prover/real-flow.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ describe('Real flow test', () => {
).to.emit(maticTokenContract, 'Approval');

// set timestamp for the sendBatch call
const lastBatchSequenced = await proofOfEfficiencyContract.lastBatchSequenced();
const sequence = {
transactions: inputJson.batchL2Data,
globalExitRoot: inputJson.globalExitRoot,
Expand All @@ -128,12 +127,17 @@ describe('Real flow test', () => {
await globalExitRootManager.setLastGlobalExitRootNum(1);
await globalExitRootManager.setLastGlobalExitRoot(sequence.globalExitRoot);

await proofOfEfficiencyContract.setVerifiedBatch(inputJson.numBatch - 1);
await proofOfEfficiencyContract.setSequencedBatch(inputJson.numBatch - 1);

const lastBatchSequenced = await proofOfEfficiencyContract.lastBatchSequenced();

await ethers.provider.send('evm_setNextBlockTimestamp', [sequence.timestamp]);

// Sequence Batches
await expect(proofOfEfficiencyContract.connect(trustedSequencer).sequenceBatches([sequence]))
.to.emit(proofOfEfficiencyContract, 'SequenceBatches')
.withArgs(lastBatchSequenced + 1);
.withArgs(Number(lastBatchSequenced) + 1);

// aggregator forge the batch
const { newLocalExitRoot } = inputJson;
Expand Down
Loading

0 comments on commit 05adaa2

Please sign in to comment.