Skip to content

Commit

Permalink
Calldata generation and making tests pass
Browse files Browse the repository at this point in the history
  • Loading branch information
StanislavBreadless committed May 31, 2021
1 parent 07270b1 commit 0bf20c4
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 49 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 4 additions & 7 deletions contracts/contracts/RegenesisMultisig.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,11 @@ contract RegenesisMultisig is Ownable {
gnosisAddress = _gnosisAddress;
}

function submitHash(
bytes32 _oldRootHash,
bytes32 _newRootHash
) external {
// Only gnosis multisig of the security council can submit
function submitHash(bytes32 _oldRootHash, bytes32 _newRootHash) external {
// Only gnosis multisig of the security council can submit
// the new root hash
require(msg.sender == gnosisAddress, "1");
require(msg.sender == gnosisAddress, "1");

oldRootHash = _oldRootHash;
newRootHash = _newRootHash;
}
Expand Down
3 changes: 1 addition & 2 deletions contracts/scripts/upgrade-testnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ async function main() {
});
parser.addArgument('--initArgs', {
required: false,
help:
'Upgrade function parameters comma-separated, RLP serialized in hex (Governance,Verifier,ZkSync): 0xaa..aa,0xbb..bb,0xcc..c or zero by default.',
help: 'Upgrade function parameters comma-separated, RLP serialized in hex (Governance,Verifier,ZkSync): 0xaa..aa,0xbb..bb,0xcc..c or zero by default.',
defaultValue: '0x,0x,0x'
});
parser.addArgument('--cancelPreviousUpgrade', {
Expand Down
9 changes: 1 addition & 8 deletions contracts/src.ts/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,17 +313,10 @@ export class Deployer {
console.log('Deploying Regenesis Multisig contract');
}

const partners = process.env.MISC_REGENESIS_PARTNERS.split(',');
const numberOfNeededSignatures = +process.env.MISC_REGENESIS_NEEDED_SIGNATURES;

if (partners.length < numberOfNeededSignatures) {
throw new Error('Number of required signatures for Genesis is higher than the number of partners');
}

const regenesisMultisigContract = await deployContract(
this.deployWallet,
this.contracts.regenesisMultisig,
[partners, numberOfNeededSignatures],
[process.env.MISC_REGENESIS_GNOSIS_ADDRESS],
{
gasLimit: 6000000,
...ethTxOptions
Expand Down
60 changes: 37 additions & 23 deletions contracts/test/unit_tests/regenesis_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,35 +55,14 @@ describe('Regenesis test', function () {
'PreparationStart'
);

// Submitting signatures to the multisig
expect(await regenesisMultisigContract.numberOfPartners()).to.eq(4, 'The test is aimed at 4 partners');
expect(await regenesisMultisigContract.requiredNumberOfSignatures()).to.eq(
3,
'The test is aimed at 3 required signatures'
);

const oldRootHash = process.env.CONTRACTS_GENESIS_ROOT;
expect(oldRootHash).to.eq(
'0x2d5ab622df708ab44944bb02377be85b6f27812e9ae520734873b7a193898ba4',
'The test requires a specific GENESIS_ROOT'
);
const newRootHash = '0x2a9b50e17ece607c8c88b1833426fd9e60332685b94a1534fcf26948e373604c';
const signatures = [
// Correct signature for 0x374Ac2A10cBCaE93d2aBBe468f0EDEF6768e65eE
'0xeae499cb52c214e998ec9311e883f9362d8f0e2448e1c2275ebacd2ad92679751e79d8e9f7ed6ff513afc55ac5acf09bd4f1b6b893e0fb849c89cf3d25d091341c',
// Correct signature for 0xB991c776AedacfA5a7e8CF3e7aD6CB6C1AcB9227
'0x23e85b70fdbcb1eaeacf83a3a62c5bbfb604bd34f8ef9798f05fe915ad5d3cc6661c7f941dc7656c63ee28bbec760b32cbb893cc04560ff433eacc92aecec60a1c',
// Incorrect signature
'0x4843ef9f8e9bb01c883b4df5b99a5287d4602e6340f9d4207900af5a333b5d90186cb5267f8789e6364d2fa737778e13c129b295fdc5f220d4bfa03e948f262e1b',
// Correct signature for 0x093Cf8450c5eE506aB865F68F5f8EB8C4C2073C2
'0xb0b6e1efbca8abd97a4cb96c19ef59f6640c10b9369e2d89111a8f0622a0b0c249a0bef1d4479a98c85832926ef04072ff2e9f51fde53967ce235971995629001c'
];

const submitSignaturesTx = await regenesisMultisigContract.submitSignatures(
oldRootHash,
newRootHash,
signatures
);

const submitSignaturesTx = await regenesisMultisigContract.submitHash(oldRootHash, newRootHash);
await submitSignaturesTx.wait();

// After the new root hash has been submitted to the multisig,
Expand Down Expand Up @@ -123,4 +102,39 @@ describe('Regenesis test', function () {
'The additional zkSync address has been changed wrongly'
);
});

it('Test data submission', async () => {
const [hardhatWallet]: ethers.Wallet[] = await hardhat.ethers.getSigners();
const fundingWalletTx = await hardhatWallet.sendTransaction({
to: wallet.address,
value: utils.parseEther('3.0')
});
await fundingWalletTx.wait();

const contracts = readProductionContracts();
const deployer = new Deployer({ deployWallet: wallet, contracts });
await deployer.deployRegenesisMultisig({ gasLimit: 6500000 });
await deployer.deployAll({ gasLimit: 6500000 });

const regenesisMultisigContract = RegenesisMultisigFactory.connect(
deployer.addresses.RegenesisMultisig,
wallet
);

const tx = await wallet.sendTransaction({
to: regenesisMultisigContract.address,
// The calldata was retrieved from the regen-root-hash tool
data: '0x905717402f59c906954c0445843de5e33ceb41d60b5ed5d3d78f0575bc345bd3514ea0910c0c243023dce4bb411344d572dcc24bd77d393ef5a02ef4f5ffd12649634d5e'
});
await tx.wait();

expect(await regenesisMultisigContract.oldRootHash()).to.eq(
'0x2f59c906954c0445843de5e33ceb41d60b5ed5d3d78f0575bc345bd3514ea091',
'The old root hash was not set correctly'
);
expect(await regenesisMultisigContract.newRootHash()).to.eq(
'0x0c0c243023dce4bb411344d572dcc24bd77d393ef5a02ef4f5ffd12649634d5e',
'The new root hash was not set correctly'
);
});
});
1 change: 1 addition & 0 deletions core/bin/regen-root-hash/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ zksync_types = { path = "../../lib/types", version = "1.0" }
zksync_utils = { path = "../../lib/utils", version = "1.0" }
zksync_circuit = { path = "../../lib/circuit", version = "1.0" }
zksync_storage = { path = "../../lib/storage", version = "1.0" }
ethabi = "12.0.0"

once_cell = "1.4"
anyhow = "1.0"
Expand Down
8 changes: 7 additions & 1 deletion core/bin/regen-root-hash/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use account::{
};

use structopt::StructOpt;
use utils::fr_to_hex;
use utils::{fr_to_hex, get_tx_data};
use zksync_circuit::witness::utils::fr_from_bytes;

use hasher::{get_state, verify_accounts_equal, verify_identical_trees};
Expand Down Expand Up @@ -108,6 +108,12 @@ async fn main() -> anyhow::Result<()> {
if params.db_migrate {
println!("Migrating the database to enable NFTs");
migrage_db_for_nft(old_hash, new_tree).await?;
} else {
let calldata = get_tx_data(old_hash, new_hash);
println!(
"The calldata of the call to regenesis multisig is 0x{}",
calldata
);
}

Ok(())
Expand Down
45 changes: 45 additions & 0 deletions core/bin/regen-root-hash/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
use ethabi::{Contract, Hash};
use std::fs;
use std::io;
use std::str::FromStr;
use zksync_crypto::{
ff::{PrimeField, PrimeFieldRepr},
Fr,
};

const REGEN_MULTISIG_CONTRACT: &str =
"contracts/artifacts/cache/solpp-generated-contracts/RegenesisMultisig.sol/RegenesisMultisig.json";

fn read_file_to_json_value(path: &str) -> io::Result<serde_json::Value> {
let zksync_home = std::env::var("ZKSYNC_HOME").unwrap_or_else(|_| ".".into());
println!("{}", zksync_home);
let path = std::path::Path::new(&zksync_home).join(path);
let contents = fs::read_to_string(path).unwrap();
let val = serde_json::Value::from_str(&contents).unwrap();
Ok(val)
}

pub fn fr_to_bytes(scalar: Fr) -> Vec<u8> {
let mut be_bytes = [0u8; 32];
scalar
Expand All @@ -18,3 +34,32 @@ pub fn fr_to_hex(scalar: Fr) -> String {

hex::encode(be_bytes)
}

pub fn regen_multisig_contract() -> Contract {
let abi_string = read_file_to_json_value(REGEN_MULTISIG_CONTRACT)
.expect("couldn't read REGEN_MULTISIG_CONTRACT")
.get("abi")
.expect("couldn't get abi from REGEN_MULTISIG_CONTRACT")
.to_string();
Contract::load(abi_string.as_bytes()).expect("regenesis multiisg contract abi")
}

// Returns hex-encoded tx data for contract call
pub fn get_tx_data(old_hash: Fr, new_hash: Fr) -> String {
let regen_multisig_contract = regen_multisig_contract();

let function = regen_multisig_contract
.function("submitHash")
.expect("no submitHash function");

let input_tokens = vec![
ethabi::Token::FixedBytes(fr_to_bytes(old_hash)),
ethabi::Token::FixedBytes(fr_to_bytes(new_hash)),
];

let calldata = function
.encode_input(&input_tokens)
.expect("Failed to encode bytes");

hex::encode(&calldata)
}
10 changes: 2 additions & 8 deletions etc/env/base/misc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,8 @@ log_format="plain"

sentry_url="unset"

# The address of the regenesis multisig smart contract
regenesis_multisig_address="0xAA7113B9de498556dC76eDFEFc57681083c861C1"

# The number of signatures needed for the regenesis to complete
regenesis_needed_signatures=3

# The list of partners signatures of which will be collected for the regenesis
regenesis_partners="0xB991c776AedacfA5a7e8CF3e7aD6CB6C1AcB9227,0x093Cf8450c5eE506aB865F68F5f8EB8C4C2073C2,0x0d2200E8Ff14516397E86Ad63670516D371Dc862,0x374Ac2A10cBCaE93d2aBBe468f0EDEF6768e65eE"
# The address of the regenesis gnosis smart contract
regenesis_gnosis_address="0xbD5Ca6f189111A1befd4ffAa6F17f62D4535F254"

# The address of the new additional zkSync
new_additional_zksync_address="0x7fbaD9d9C9a1204F45FA38CcbF732B0930F8B582"

0 comments on commit 0bf20c4

Please sign in to comment.