Skip to content

Commit

Permalink
Merge pull request #264 from matter-labs/dvush/commit-block-contract-…
Browse files Browse the repository at this point in the history
…refactor

Block commit contract refactor
  • Loading branch information
dvush authored Mar 11, 2020
2 parents 2d2b4da + 4066e24 commit dc0cfa7
Show file tree
Hide file tree
Showing 37 changed files with 1,072 additions and 553 deletions.
2 changes: 1 addition & 1 deletion bin/contracts-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ set -e

echo contracts-test
cd contracts
yarn test || true # FIXME: after test merges done
yarn unit-test
cd ..
2 changes: 0 additions & 2 deletions bin/deploy-contracts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ ERC20_ADDR_NEW_VALUE=`grep "TEST_ERC20" deploy.log`
GOVERNANCE_GENESIS_TX_HASH_NEW_VALUE=`grep "GOVERNANCE_GENESIS_TX_HASH" deploy.log`
GOVERNANCE_ADDR_NEW_VALUE=`grep "GOVERNANCE_ADDR" deploy.log`
VERIFIER_ADDR_NEW_VALUE=`grep "VERIFIER_ADDR" deploy.log`
PRIORITY_QUEUE_ADDR_NEW_VALUE=`grep "PRIORITY_QUEUE_ADDR" deploy.log`
if [[ ! -z "$CONTRACT_ADDR_NEW_VALUE" ]]
then
export LABEL=$ZKSYNC_ENV-Contract_deploy-`date +%Y-%m-%d-%H%M%S`
Expand All @@ -37,7 +36,6 @@ then
python3 bin/replace-env-variable.py ./$ENV_FILE $GOVERNANCE_GENESIS_TX_HASH_NEW_VALUE
python3 bin/replace-env-variable.py ./$ENV_FILE $GOVERNANCE_ADDR_NEW_VALUE
python3 bin/replace-env-variable.py ./$ENV_FILE $VERIFIER_ADDR_NEW_VALUE
python3 bin/replace-env-variable.py ./$ENV_FILE $PRIORITY_QUEUE_ADDR_NEW_VALUE
else
echo "Contract deployment failed"
exit 1
Expand Down
4 changes: 0 additions & 4 deletions bin/prepare-test-contracts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,17 @@ OUT_DIR=./contracts/contracts/generated
rm -rf $OUT_DIR
mkdir -p $OUT_DIR
cp $IN_DIR/Governance.sol $OUT_DIR/GovernanceTest.sol
cp $IN_DIR/PriorityQueue.sol $OUT_DIR/PriorityQueueTest.sol
cp $IN_DIR/Verifier.sol $OUT_DIR/VerifierTest.sol
cp $IN_DIR/Franklin.sol $OUT_DIR/FranklinTest.sol
cp $IN_DIR/Storage.sol $OUT_DIR/StorageTest.sol
cp $IN_DIR/Config.sol $OUT_DIR/ConfigTest.sol

# Rename contracts
ssed 's/Governance/GovernanceTest/' -i $OUT_DIR/*.sol
ssed 's/PriorityQueue/PriorityQueueTest/' -i $OUT_DIR/*.sol
ssed 's/Verifier/VerifierTest/' -i $OUT_DIR/*.sol
ssed 's/Franklin/FranklinTest/' -i $OUT_DIR/*.sol
ssed 's/Storage/StorageTest/' -i $OUT_DIR/*.sol
ssed 's/Config/ConfigTest/' -i $OUT_DIR/*.sol
# Workaround -> priority queue has FranklinTest in method names.
ssed 's/FranklinTest/Franklin/' -i $OUT_DIR/PriorityQueueTest.sol


# Changes solidity constant to provided value
Expand Down
20 changes: 20 additions & 0 deletions contracts/contracts/Bytes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,24 @@ library Bytes {
return tempBytes;
}

// Helper function for hex conversion.
function halfByteToHex(byte _byte) internal pure returns (byte _hexByte) {
uint8 numByte = uint8(_byte);
if (numByte >= 0 && numByte <= 9) {
return byte(0x30 + numByte); // ASCII 0-9
} else if (numByte <= 15) {
return byte(0x57 + numByte); // ASCII a-f
}
}

// Convert bytes to ASCII hex representation
function bytesToHexASCIIBytes(bytes memory _input) internal pure returns (bytes memory _output) {
bytes memory outStringBytes = new bytes(_input.length * 2);
for (uint i = 0; i < _input.length; ++i) {
outStringBytes[i*2] = halfByteToHex(_input[i] >> 4);
outStringBytes[i*2+1] = halfByteToHex(_input[i] & 0x0f);
}
return outStringBytes;
}

}
6 changes: 3 additions & 3 deletions contracts/contracts/Config.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ contract Config {
uint256 constant BASE_FULL_EXIT_GAS = 170000;

/// @notice ETH blocks verification expectation
uint256 constant EXPECT_VERIFICATION_IN = 8 * 60 * 100;
uint256 constant EXPECT_VERIFICATION_IN = 2 * 4 * 60 * 24; // Two days

/// @notice Max number of unverified blocks. To make sure that all reverted blocks can be copied under block gas limit!
uint256 constant MAX_UNVERIFIED_BLOCKS = 4 * 60 * 100;
Expand All @@ -55,6 +55,6 @@ contract Config {
uint256 constant CHANGE_PUBKEY_BYTES = 6 * 8;

/// @notice Expiration delta for priority request to be satisfied (in ETH blocks)
uint256 constant PRIORITY_EXPIRATION = 4 * 60 * 24; // One day

/// NOTE: Priority expiration should be > EXPECT_VERIFICATION_IN, otherwise incorrect block with priority op could not be reverted.
uint256 constant PRIORITY_EXPIRATION = 3 * 4 * 60 * 24; // Two days
}
227 changes: 103 additions & 124 deletions contracts/contracts/Franklin.sol

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion contracts/contracts/Governance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ contract Governance is Config {
/// @param _tokenId Token id
/// @return bool flag that indicates if token id is less than total tokens amount
function isValidTokenId(uint16 _tokenId) external view returns (bool) {
return _tokenId < totalTokens + 1;
return _tokenId <= totalTokens;
}

/// @notice Validate token address
Expand Down
18 changes: 0 additions & 18 deletions contracts/contracts/PriorityQueue.sol

This file was deleted.

3 changes: 1 addition & 2 deletions contracts/contracts/Storage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import "../node_modules/openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";

import "./Governance.sol";
import "./Verifier.sol";
import "./PriorityQueue.sol";

import "./Operations.sol";

/// @title zkSync storage contract
/// @author Matter Labs
Expand Down
6 changes: 5 additions & 1 deletion contracts/contracts/test/BytesTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ contract BytesTest {
bytes memory buf = Bytes.toBytesFromUInt24(x);
(offset, r) = Bytes.readUInt24(buf, 0);
}


function bytesToHexConvert(bytes calldata _in) external pure returns (string memory) {
return string(Bytes.bytesToHexASCIIBytes(_in));
}

}

12 changes: 0 additions & 12 deletions contracts/contracts/test/DummyVerifier.sol

This file was deleted.

14 changes: 13 additions & 1 deletion contracts/contracts/test/OperationsTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ contract OperationsTest {
require(x.tokenId == r.tokenId, "tokenId mismatch");
require(x.amount == r.amount, "amount mismatch");
}


function parseDepositFromPubdata(bytes calldata _pubdata) external pure returns (uint16 tokenId, uint128 amount, address owner) {
(, Operations.Deposit memory r) = Operations.readDepositPubdata(_pubdata, 0);
return (r.tokenId, r.amount, r.owner);
}

function parseFullExitFromPubdata(bytes calldata _pubdata) external pure returns (uint24 accountId, address owner, uint16 tokenId, uint128 amount) {
Operations.FullExit memory r = Operations.readFullExitPubdata(_pubdata, 0);
accountId = r.accountId;
owner = r.owner;
tokenId = r.tokenId;
amount = r.amount;
}
}

41 changes: 41 additions & 0 deletions contracts/contracts/test/ZKSyncUnitTest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
pragma solidity 0.5.16;

import "../generated/FranklinTest.sol";


contract ZKSyncUnitTest is FranklinTest {

constructor(
address _governanceAddress,
address _verifierAddress,
address _genesisAccAddress,
bytes32 _genesisRoot
) FranklinTest(_governanceAddress, _verifierAddress, _genesisAccAddress, _genesisRoot) public{}

function changePubkeySignatureCheck(bytes calldata _signature, bytes calldata _newPkHash, uint32 _nonce, address _ethAddress) external pure returns (bool) {
return verifyChangePubkeySignature(_signature, _newPkHash, _nonce, _ethAddress);
}

function setBalanceToWithdraw(address _owner, uint16 _token, uint128 _amount) external {
balancesToWithdraw[_owner][_token] = _amount;
}

function () payable external{}

function addPendingWithdrawal(address _to, uint16 _tokenId, uint128 _amount) external {
storeWithdrawalAsPending(_to, _tokenId, _amount);
}

function testProcessNextOperation(
uint256 _pubdataOffset,
bytes calldata _publicData,
bytes calldata _currentEthWitness,
uint256 _expectedBytesProcessed
) external {
require(processNextOperation(_pubdataOffset, _publicData, _currentEthWitness) == _expectedBytesProcessed, "bytes processed incorrect");
}

function testVerifyEthereumSignature(bytes calldata _signature, bytes calldata _message) external pure returns (address) {
return verifyEthereumSignature(_signature, _message);
}
}
5 changes: 3 additions & 2 deletions contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@
"ts-node": "^8.3.0",
"tslint": "^5.18.0",
"typescript": "^3.5.3",
"zksync": "^0.3.9"
"zksync": "link:../js/zksync.js"
},
"scripts": {
"build": "waffle .waffle.json",
"test": "yarn build && mocha -r ts-node/register test/**/*.ts",
"itest": "yarn build && mocha -r ts-node/register test/unit_tests/**/*.js test/fails_tests.ts",
"unit-test": "yarn build && mocha test/unit_tests/**/*.js",
"unit-test": "yarn build && mocha -r ts-node/register test/unit_tests/**/*",
"unit-test-watch": "waffle .waffle.json && mocha -r ts-node/register test/unit_tests/**/* --watch --watch-extensions ts --watch-extensions 'js'",
"deploy": "yarn build && ts-node scripts/testnet-deploy.ts --deploy --publish",
"deploy-no-build": "ts-node scripts/testnet-deploy.ts --deploy --publish",
"deploy-test-no-build": "ts-node scripts/testnet-deploy.ts --deploy --test",
Expand Down
6 changes: 1 addition & 5 deletions contracts/scripts/revert-reason.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import {ethers} from "ethers";
import {franklinContractCode, governanceContractCode, priorityQueueContractCode} from "../src.ts/deploy";
import {franklinContractCode, governanceContractCode} from "../src.ts/deploy";
import {Interface} from "ethers/utils";
const provider = new ethers.providers.JsonRpcProvider(process.env.WEB3_URL);
const wallet = ethers.Wallet.fromMnemonic(process.env.MNEMONIC, "m/44'/60'/0'/0/1").connect(provider);
const franklinInterface = new Interface(franklinContractCode.interface);
const priorityQueueInterface = new Interface(priorityQueueContractCode.interface);
const governanceInterface = new Interface(governanceContractCode.interface);

function hex_to_ascii(str1) {
Expand Down Expand Up @@ -53,9 +52,6 @@ async function reason() {

for (let log of receipt.logs){
let parsedLog = franklinInterface.parseLog(log);
if (!parsedLog) {
parsedLog = priorityQueueInterface.parseLog(log);
}
if (!parsedLog) {
parsedLog = governanceInterface.parseLog(log);
}
Expand Down
19 changes: 9 additions & 10 deletions contracts/scripts/testnet-deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,26 @@ async function main() {

if (args.deploy) {
let timer = Date.now();
await deployer.deployGovernance();
const governance = await deployer.deployGovernance();
console.log(`GOVERNANCE_GENESIS_TX_HASH=${governance.deployTransaction.hash}`);
console.log(`GOVERNANCE_ADDR=${governance.address}`);
console.log(`Governance contract deployed, time: ${(Date.now() - timer) / 1000} secs`);

timer = Date.now();
await deployer.deployPriorityQueue();
console.log(`Priority queue contract deployed, time: ${(Date.now() - timer) / 1000} secs`);

timer = Date.now();
await deployer.deployVerifier();
const verifier = await deployer.deployVerifier();
console.log(`VERIFIER_ADDR=${verifier.address}`);
console.log(`Verifier contract deployed, time: ${(Date.now() - timer) / 1000} secs`);

timer = Date.now();
await deployer.deployFranklin();
const mainContract = await deployer.deployFranklin();
console.log(`CONTRACT_GENESIS_TX_HASH=${mainContract.deployTransaction.hash}`);
console.log(`CONTRACT_ADDR=${mainContract.address}`);
console.log(`Main contract deployed, time: ${(Date.now() - timer) / 1000} secs`);

const governance = await deployer.getDeployedContract('Governance');
await governance.setValidator(process.env.OPERATOR_ETH_ADDRESS, true);

const erc20 = await addTestERC20Token(wallet, governance);
console.log("TEST_ERC20=" + erc20.address);
await mintTestERC20Token(testWallet, erc20);
}

Expand All @@ -60,14 +61,12 @@ async function main() {
if (process.env.ETH_NETWORK === 'localhost') {
await Promise.all([
deployer.postContractToTesseracts("Governance"),
deployer.postContractToTesseracts("PriorityQueue"),
deployer.postContractToTesseracts("Verifier"),
deployer.postContractToTesseracts("Franklin"),
]);
} else {
// sequentially, since etherscan has request limit
await deployer.publishSourceCodeToEtherscan("Governance");
await deployer.publishSourceCodeToEtherscan("PriorityQueue");
await deployer.publishSourceCodeToEtherscan("Verifier");
await deployer.publishSourceCodeToEtherscan("Franklin");
}
Expand Down
24 changes: 0 additions & 24 deletions contracts/src.ts/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ export const ERC20MintableContract = function () {
export const franklinContractCode = require(`../build/Franklin`);
export const verifierContractCode = require(`../build/Verifier`);
export const governanceContractCode = require(`../build/Governance`);
export const priorityQueueContractCode = require(`../build/PriorityQueue`);

export const franklinTestContractCode = require('../build/FranklinTest');
export const verifierTestContractCode = require('../build/VerifierTest');
export const governanceTestContractCode = require('../build/GovernanceTest');
export const priorityQueueTestContractCode = require('../build/PriorityQueueTest');

import { ImportsFsEngine } from '@resolver-engine/imports-fs';
import { gatherSources } from '@resolver-engine/imports';
Expand Down Expand Up @@ -65,14 +63,12 @@ export class Deployer {
constructor(public wallet: ethers.Wallet, isTest: boolean) {
this.bytecodes = {
Governance: isTest ? governanceTestContractCode : governanceContractCode,
PriorityQueue: isTest ? priorityQueueTestContractCode : priorityQueueContractCode,
Verifier: isTest ? verifierTestContractCode : verifierContractCode,
Franklin: isTest ? franklinTestContractCode : franklinContractCode,
};

this.addresses = {
Governance: process.env.GOVERNANCE_ADDR,
PriorityQueue: process.env.PRIORITY_QUEUE_ADDR,
Verifier: process.env.VERIFIER_ADDR,
Franklin: process.env.CONTRACT_ADDR,
};
Expand All @@ -94,7 +90,6 @@ export class Deployer {
'Franklin': [
this.addresses.Governance,
this.addresses.Verifier,
this.addresses.PriorityQueue,
process.env.OPERATOR_FRANKLIN_ADDRESS,
process.env.GENESIS_ROOT || ethers.constants.HashZero,
]
Expand Down Expand Up @@ -123,32 +118,17 @@ export class Deployer {
this.constructorArgs('Governance'),
{ gasLimit: 3000000 }
);
console.log(`GOVERNANCE_GENESIS_TX_HASH=${governance.deployTransaction.hash}`);
console.log(`GOVERNANCE_ADDR=${governance.address}`);
this.addresses.Governance = governance.address;
return governance;
}

async deployPriorityQueue() {
let priorityQueue = await deployContract(
this.wallet,
this.bytecodes.PriorityQueue,
this.constructorArgs('PriorityQueue'),
{ gasLimit: 5000000 }
);
console.log(`PRIORITY_QUEUE_ADDR=${priorityQueue.address}`);
this.addresses.PriorityQueue = priorityQueue.address;
return priorityQueue;
}

async deployVerifier() {
let verifier = await deployContract(
this.wallet,
this.bytecodes.Verifier,
this.constructorArgs('Verifier'),
{ gasLimit: 2000000 }
);
console.log(`VERIFIER_ADDR=${verifier.address}`);
this.addresses.Verifier = verifier.address;
return verifier;
}
Expand All @@ -160,8 +140,6 @@ export class Deployer {
this.constructorArgs('Franklin'),
{ gasLimit: 6000000}
);
console.log(`CONTRACT_GENESIS_TX_HASH=${franklin.deployTransaction.hash}`);
console.log(`CONTRACT_ADDR=${franklin.address}`);
this.addresses.Franklin = franklin.address;
return franklin;
}
Expand Down Expand Up @@ -241,7 +219,6 @@ export async function addTestERC20Token(wallet, governance) {
try {
let erc20 = await deployContract(wallet, ERC20MintableContract, []);
await erc20.mint(wallet.address, parseEther("3000000000"));
console.log("TEST_ERC20=" + erc20.address);
await (await governance.addToken(erc20.address)).wait();
return erc20;
} catch (err) {
Expand All @@ -262,7 +239,6 @@ export async function addTestNotApprovedERC20Token(wallet) {
try {
let erc20 = await deployContract(wallet, ERC20MintableContract, []);
await erc20.mint(wallet.address, bigNumberify("1000000000"));
console.log("TEST_ERC20=" + erc20.address);
return erc20
} catch (err) {
console.log("Add token error:" + err);
Expand Down
Loading

0 comments on commit dc0cfa7

Please sign in to comment.