Skip to content

Commit

Permalink
Merge pull request 0xPolygonHermez#9 from hermeznetwork/feature/addDo…
Browse files Browse the repository at this point in the history
…ckers

Small changes + dockers
  • Loading branch information
krlosMata authored Dec 10, 2021
2 parents 9b87288 + 8ae03ca commit d3b56b3
Show file tree
Hide file tree
Showing 16 changed files with 405 additions and 61 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
MNEMONIC="test test test test test test test test test test test test"
MNEMONIC="test test test test test test test test test test test junk"
INFURA_PROJECT_ID=""
ETHERSCAN_API_KEY=""
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ coverage
artifacts/
docs/interfaces
docs/mocks
.vscode/launch.json
.vscode/launch.json
deploy_output.json
29 changes: 16 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,20 @@

Smart contract implementation which will be used by the zkEVM


## Requirements

- node version: 14.x
- npm version: 7.x

## Repository structure

- `contracts`: zkEVM contracts
- `docs`: specs and useful links
- `js`: complementary code in javascript
- `test`: test all repository code

## Install

```
git config --local core.hooksPath .githooks/
```

## Activate github hook
- `src`: js code to interact with the zkEVM, executor, zkEVMDB, sequencer and aggregator.
- `test`: test of all repository

```
npm run i
npm i
```

## Run tests
Expand All @@ -43,7 +35,7 @@ npm run lint
Autofix errors:

```
npm run lintFix
npm run lint:fix
```

## Deploy on hardhat
Expand All @@ -52,6 +44,17 @@ npm run lintFix
npm run deploy:PoE:hardhat
```

## Build dockers

```
npm run docker:contracts
```

A new docker `hermez-geth1.3:latest` will be created
This docker will contain a geth node with the deployed contracts
The deployment output can be found in: `docker/deploymentOutput/deploy_output.json`
To run the docker you can use: `docker run -p 8545:8545 hermez-geth1.3:latest`

## License

`hermeznetwork/hez-matic-merge` is part of the Hermez project copyright 2020 HermezDAO and published with GPL-3 license. Please check the LICENSE file for more details.
61 changes: 35 additions & 26 deletions contracts/ProofOfEfficiency.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ contract ProofOfEfficiency is Ownable {

struct Sequencer {
string sequencerURL;
uint256 chainID;
uint32 chainID;
}

struct BatchData {
Expand All @@ -30,12 +30,8 @@ contract ProofOfEfficiency is Ownable {
// bytes4(keccak256(bytes("permit(address,address,uint256,uint256,uint8,bytes32,bytes32)")));
bytes4 private constant _PERMIT_SIGNATURE = 0xd505accf;

// Modulus zkSNARK
uint256 private constant _RFIELD =
21888242871839275222246405745257275088548364400416034343698204186575808495617;

// Default chainID
uint256 public constant CHAIN_ID_DEFAULT = 10000;
uint32 public constant DEFAULT_CHAIN_ID = 10000;

// MATIC token address
IERC20 public immutable matic;
Expand All @@ -44,16 +40,16 @@ contract ProofOfEfficiency is Ownable {
mapping(address => Sequencer) public sequencers;

// Current registered sequencers
uint256 public numSequencers;
uint32 public numSequencers;

// Last batch sent by the sequencers
uint256 public lastBatchSent;
uint32 public lastBatchSent;

// Mapping of sent batches with their associated data
mapping(uint256 => BatchData) public sentBatches;
mapping(uint32 => BatchData) public sentBatches;

// Last batch verified by the aggregators
uint256 public lastVerifiedBatch;
uint32 public lastVerifiedBatch;

// Bridge address
BridgeInterface public bridge;
Expand All @@ -69,17 +65,21 @@ contract ProofOfEfficiency is Ownable {
/**
* @dev Emitted when a sequencer is registered or updated
*/
event RegisterSequencer(address sequencerAddress, string sequencerURL, uint256 chainID);
event RegisterSequencer(
address sequencerAddress,
string sequencerURL,
uint32 chainID
);

/**
* @dev Emitted when a sequencer sends a new batch of transactions
*/
event SendBatch(uint256 indexed batchNum, address indexed sequencer);
event SendBatch(uint32 indexed batchNum, address indexed sequencer);

/**
* @dev Emitted when a aggregator verifies a new batch
*/
event VerifyBatch(uint256 indexed batchNum, address indexed aggregator);
event VerifyBatch(uint32 indexed batchNum, address indexed aggregator);

/**
* @param _bridge Bridge contract address
Expand Down Expand Up @@ -110,12 +110,16 @@ contract ProofOfEfficiency is Ownable {
// New sequencer is registered
numSequencers++;
sequencers[msg.sender].sequencerURL = sequencerURL;
sequencers[msg.sender].chainID = CHAIN_ID_DEFAULT + numSequencers;
sequencers[msg.sender].chainID = DEFAULT_CHAIN_ID + numSequencers;
} else {
// Sequencer already exist, update the URL
sequencers[msg.sender].sequencerURL = sequencerURL;
}
emit RegisterSequencer(msg.sender, sequencerURL, sequencers[msg.sender].chainID);
emit RegisterSequencer(
msg.sender,
sequencerURL,
sequencers[msg.sender].chainID
);
}

/**
Expand All @@ -141,11 +145,7 @@ contract ProofOfEfficiency is Ownable {
abi.encodePacked(transactions, bridge.getLastGlobalExitRoot())
);
sentBatches[lastBatchSent].maticCollateral = maticCollateral;

// Check if the sequencer is registered, if not, no one will claim the fees
if (sequencers[msg.sender].chainID != 0) {
sentBatches[lastBatchSent].sequencerAddress = msg.sender;
}
sentBatches[lastBatchSent].sequencerAddress = msg.sender;

emit SendBatch(lastBatchSent, msg.sender);
}
Expand All @@ -162,7 +162,7 @@ contract ProofOfEfficiency is Ownable {
function verifyBatch(
bytes32 newLocalExitRoot,
bytes32 newStateRoot,
uint256 batchNum,
uint32 batchNum,
uint256[2] calldata proofA,
uint256[2][2] calldata proofB,
uint256[2] calldata proofC
Expand All @@ -175,21 +175,30 @@ contract ProofOfEfficiency is Ownable {

// Calculate Circuit Input
BatchData memory currentBatch = sentBatches[batchNum];
address sequencerAddress = currentBatch.sequencerAddress; // could be 0, if sequencer is not registered
uint256 batchChainID = sequencers[sequencerAddress].chainID; // could be 0, if sequencer is not registered
address sequencerAddress = currentBatch.sequencerAddress;

uint32 batchChainID;
if (sequencers[sequencerAddress].chainID != 0) {
batchChainID = sequencers[sequencerAddress].chainID;
} else {
// If the sequencer is not registered use the default chainID
batchChainID = DEFAULT_CHAIN_ID;
}

uint256 input = uint256(
sha256(
keccak256(
abi.encodePacked(
currentStateRoot,
currentLocalExitRoot,
newStateRoot,
newLocalExitRoot,
sequencerAddress,
currentBatch.batchL2HashData,
batchChainID
batchChainID,
batchNum
)
)
) % _RFIELD;
);

// Verify proof
require(
Expand Down
108 changes: 108 additions & 0 deletions contracts/mocks/ProofOfEfficiencyMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.9;

import "../ProofOfEfficiency.sol";
import "hardhat/console.sol";

/**
* Contract responsible for managing the state and the updates of it of the L2 Hermez network.
* There will be sequencer, wich 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 {
/**
* @param _bridge Bridge contract address
* @param _matic MATIC token address
* @param _rollupVerifier rollup verifier address
*/
constructor(
BridgeInterface _bridge,
IERC20 _matic,
VerifierRollupInterface _rollupVerifier
) ProofOfEfficiency(_bridge, _matic, _rollupVerifier) {}

/**
* @notice Calculate the circuit input
* @param currentStateRoot Current state Root
* @param currentLocalExitRoot Current local exit root
* @param newStateRoot New State root once the batch is processed
* @param newLocalExitRoot New local exit root once the batch is processed
* @param sequencerAddress Sequencer address
* @param batchL2HashData Batch hash data
* @param batchChainID Batch chain ID
* @param batchNum Batch number that the aggregator intends to verify, used as a sanity check
*/
function calculateCircuitInput(
bytes32 currentStateRoot,
bytes32 currentLocalExitRoot,
bytes32 newStateRoot,
bytes32 newLocalExitRoot,
address sequencerAddress,
bytes32 batchL2HashData,
uint32 batchChainID,
uint32 batchNum
) public pure returns (uint256) {
uint256 input = uint256(
keccak256(
abi.encodePacked(
currentStateRoot,
currentLocalExitRoot,
newStateRoot,
newLocalExitRoot,
sequencerAddress,
batchL2HashData,
batchChainID,
batchNum
)
)
);
return input;
}

/**
* @notice Calculate the circuit input
* @param newStateRoot New State root once the batch is processed
* @param newLocalExitRoot New local exit root once the batch is processed
* @param batchNum Batch number that the aggregator intends to verify, used as a sanity check
*/
function getNextCircuitInput(
bytes32 newStateRoot,
bytes32 newLocalExitRoot,
uint32 batchNum
) public view returns (uint256) {
// sanity check
require(
batchNum == lastVerifiedBatch + 1,
"ProofOfEfficiency::verifyBatch: BATCH_DOES_NOT_MATCH"
);

// Calculate Circuit Input
BatchData memory currentBatch = sentBatches[batchNum];
address sequencerAddress = currentBatch.sequencerAddress;

uint32 batchChainID;
if (sequencers[sequencerAddress].chainID != 0) {
batchChainID = sequencers[sequencerAddress].chainID;
} else {
// If the sequencer is not registered use the default chainID
batchChainID = DEFAULT_CHAIN_ID;
}

uint256 input = uint256(
keccak256(
abi.encodePacked(
currentStateRoot,
currentLocalExitRoot,
newStateRoot,
newLocalExitRoot,
sequencerAddress,
currentBatch.batchL2HashData,
batchChainID,
batchNum
)
)
);
return input;
}
}
2 changes: 1 addition & 1 deletion deployment/testnet/checkDeployment.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async function checkDeployment() {

// Check public constants
expect(await proofOfEfficiencyContract.matic()).to.equal(maticTokenContract.address);
expect(await proofOfEfficiencyContract.CHAIN_ID_DEFAULT()).to.equal(ethers.BigNumber.from(10000));
expect(await proofOfEfficiencyContract.DEFAULT_CHAIN_ID()).to.equal(ethers.BigNumber.from(10000));
expect(await proofOfEfficiencyContract.numSequencers()).to.equal(ethers.BigNumber.from(0));
expect(await proofOfEfficiencyContract.lastBatchSent()).to.equal(ethers.BigNumber.from(0));
expect(await proofOfEfficiencyContract.lastVerifiedBatch()).to.equal(ethers.BigNumber.from(0));
Expand Down
8 changes: 8 additions & 0 deletions docker/Dockerfile.geth
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM ethereum/client-go

EXPOSE 8545

COPY docker/gethData /

ENTRYPOINT ["geth"]
CMD ["--http", "--http.addr", "0.0.0.0","--http.corsdomain", "*", "--http.vhosts" ,"*", "--ws", "--ws.origins", "*", "--ws.addr", "0.0.0.0", "--dev", "--datadir", "/geth_data"]
28 changes: 28 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Docker deployment

By default the following mnemonic will be used to deploy the smart contracts `MNEMONIC="test test test test test test test test test test test junk"`.
Also the first 20 accounts of this mnemonic will be funded with ether.
The first account of the mnemonic will be the deployer of the smart contracts and therefore the holder of all the MATIC test tokens, which are necessary to pay the `sendBatch` transactions.
You can change the deployment `mnemonic` creating a `.env` file in the project root with the following variable:
`MNEMONIC=<YOUR_MENMONIC>`

## Requirements

- node version: 14.x
- npm version: 7.x
- docker
- docker-compose

## Build dockers

In project root execute:

```
npm i
npm run dockerContracts
```

A new docker `hermez-geth1.3:latest` will be created
This docker will contain a geth node with the deployed contracts
The deployment output can be found in: `docker/deploymentOutput/deploy_output.json`
To run the docker you can use: `docker run -p 8545:8545 hermez-geth1.3:latest`
20 changes: 20 additions & 0 deletions docker/docker-compose.geth.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version: "3.3"
services:
geth:
image: ethereum/client-go
environment:
- DEV_PERIOD
ports:
- "8545:8545"
volumes:
- ./gethData/geth_data:/geth_data
entrypoint:
- geth
- --http
- --http.addr
- "0.0.0.0"
- --dev
- --dev.period
- $DEV_PERIOD
- --datadir
- /geth_data
Loading

0 comments on commit d3b56b3

Please sign in to comment.