From 306c43c9dca6645da56c37f3337b08f39eb30cfa Mon Sep 17 00:00:00 2001 From: Chenxing Li Date: Thu, 14 Mar 2024 13:56:17 +0800 Subject: [PATCH] Migrate to the new contract interfaces (#29) * Fix compile warning & Search contract by name automatically Migrate to the new contract interfaces * Fix compile * Fix lint --- 0g-storage-contracts | 2 +- Cargo.toml | 5 ++- common/contract-interface/build.rs | 57 ++++++++++++++----------- node/storage/Cargo.toml | 5 +-- tests/test_framework/blockchain_node.py | 57 ++++++++++++------------- tests/test_framework/bsc_node.py | 4 -- tests/test_framework/conflux_node.py | 4 -- tests/test_framework/contracts.py | 14 ++++++ tests/test_framework/test_framework.py | 34 +-------------- 9 files changed, 79 insertions(+), 103 deletions(-) create mode 100644 tests/test_framework/contracts.py diff --git a/0g-storage-contracts b/0g-storage-contracts index 951c029..1f3f759 160000 --- a/0g-storage-contracts +++ b/0g-storage-contracts @@ -1 +1 @@ -Subproject commit 951c02992e2a03eb47e41eb840392ec824639640 +Subproject commit 1f3f759236b48dd8682deba91011292cb5966f4c diff --git a/Cargo.toml b/Cargo.toml index 9d15452..98e7d43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,4 +29,7 @@ resolver = "2" [patch.crates-io] discv5 = { path = "version-meld/discv5" } eth2_ssz = { path = "version-meld/eth2_ssz" } -enr = { path = "version-meld/enr" } \ No newline at end of file +enr = { path = "version-meld/enr" } + +[profile.bench.package.'storage'] +debug = true \ No newline at end of file diff --git a/common/contract-interface/build.rs b/common/contract-interface/build.rs index 923f860..048e407 100644 --- a/common/contract-interface/build.rs +++ b/common/contract-interface/build.rs @@ -1,30 +1,35 @@ -// use std::process::Command; +use std::process::Command; -// const INSTALL_ERROR_MESSAGE: &str = -// "Install dependencies for contract fail, try to run `yarn` in folder '0g-storage-contracts'"; -// const COMPILE_ERROR_MESSAGE: &str = -// "Compile solidity contracts fail, try to run `yarn compile` in folder '0g-storage-contracts'"; +const INSTALL_ERROR_MESSAGE: &str = + "Install dependencies for contract fail, try to run `yarn` in folder '0g-storage-contracts'"; +const COMPILE_ERROR_MESSAGE: &str = + "Compile solidity contracts fail, try to run `yarn compile` in folder '0g-storage-contracts'"; + +#[allow(dead_code)] +fn compile_contracts() { + println!("cargo:rerun-if-changed=../../0g-storage-contracts/contracts/"); + println!("cargo:rerun-if-changed=../../0g-storage-contracts/hardhat.config.ts"); + + let output = Command::new("yarn") + .arg("--cwd") + .arg("../../0g-storage-contracts") + .status() + .expect(INSTALL_ERROR_MESSAGE); + assert!(output.success(), "{}", INSTALL_ERROR_MESSAGE); + + let output = Command::new("yarn") + .arg("--cwd") + .arg("../../0g-storage-contracts") + .arg("compile") + .status() + .expect(COMPILE_ERROR_MESSAGE); + assert!(output.success(), "{}", COMPILE_ERROR_MESSAGE); +} fn main() { - // if cfg!(feature = "compile-contracts") { - // println!("cargo:rerun-if-changed=../../0g-storage-contracts/contracts/"); - // println!("cargo:rerun-if-changed=../../0g-storage-contracts/hardhat.config.ts"); - - // let output = Command::new("yarn") - // .arg("--cwd") - // .arg("../../0g-storage-contracts") - // .status() - // .expect(INSTALL_ERROR_MESSAGE); - // assert!(output.success(), "{}", INSTALL_ERROR_MESSAGE); - - // let output = Command::new("yarn") - // .arg("--cwd") - // .arg("../../0g-storage-contracts") - // .arg("compile") - // .status() - // .expect(COMPILE_ERROR_MESSAGE); - // assert!(output.success(), "{}", COMPILE_ERROR_MESSAGE); - // } else { - // println!("cargo:rerun-if-changed=../../0g-storage-contracts/artifacts/"); - // } + if cfg!(feature = "compile-contracts") { + // compile_contracts(); + // return; + } + println!("cargo:rerun-if-changed=../../0g-storage-contracts/artifacts/"); } diff --git a/node/storage/Cargo.toml b/node/storage/Cargo.toml index 765f4d6..fa3fb8f 100644 --- a/node/storage/Cargo.toml +++ b/node/storage/Cargo.toml @@ -35,7 +35,4 @@ criterion = "0.4" [[bench]] name = "benchmark" -harness = false - -[profile.bench] -debug = true \ No newline at end of file +harness = false \ No newline at end of file diff --git a/tests/test_framework/blockchain_node.py b/tests/test_framework/blockchain_node.py index be4674a..f2d7d0d 100644 --- a/tests/test_framework/blockchain_node.py +++ b/tests/test_framework/blockchain_node.py @@ -3,8 +3,9 @@ import os import subprocess import tempfile import time +import rlp -from eth_utils import decode_hex +from eth_utils import decode_hex, keccak from web3 import Web3, HTTPProvider from web3.middleware import construct_sign_and_send_raw_middleware from enum import Enum, unique @@ -22,6 +23,7 @@ from utility.utils import ( initialize_config, wait_until, ) +from test_framework.contracts import load_contract_metadata @unique @@ -218,15 +220,11 @@ class BlockchainNode(TestNode): binary, local_conf, contract_path, - token_contract_path, - mine_contract_path, log, blockchain_node_type, rpc_timeout=10, ): self.contract_path = contract_path - self.token_contract_path = token_contract_path - self.mine_contract_path = mine_contract_path self.blockchain_node_type = blockchain_node_type @@ -261,14 +259,15 @@ class BlockchainNode(TestNode): # account = w3.eth.account.from_key(GENESIS_PRIV_KEY1) # w3.middleware_onion.add(construct_sign_and_send_raw_middleware(account)) - def deploy_contract(path, args=None): + def deploy_contract(name, args=None): if args is None: args = [] - contract_interface = json.load(open(path, "r")) + contract_interface = load_contract_metadata(base_path=self.contract_path, name=name) contract = w3.eth.contract( abi=contract_interface["abi"], bytecode=contract_interface["bytecode"], ) + tx_params = TX_PARAMS.copy() del tx_params["gas"] tx_hash = contract.constructor(*args).transact(tx_params) @@ -278,38 +277,36 @@ class BlockchainNode(TestNode): abi=contract_interface["abi"], ) return contract, tx_hash + + def predict_contract_address(offset): + nonce = w3.eth.get_transaction_count(account1.address) + rlp_encoded = rlp.encode([decode_hex(account1.address), nonce + offset]) + contract_address_bytes = keccak(rlp_encoded)[-20:] + contract_address = '0x' + contract_address_bytes.hex() + return Web3.to_checksum_address(contract_address) + + + flowAddress = predict_contract_address(1) + mineAddress = predict_contract_address(2) + + ZERO = "0x0000000000000000000000000000000000000000" self.log.debug("Start deploy contracts") - token_contract, _ = deploy_contract(self.token_contract_path) - self.log.debug("ERC20 deployed") + book, _ = deploy_contract("AddressBook", [flowAddress, ZERO, ZERO, mineAddress]); + self.log.debug("AddressBook deployed") + flow_contract, flow_contract_hash = deploy_contract( - self.contract_path, ["0x0000000000000000000000000000000000000000", 100, 0] + "Flow", [book.address, 100, 0] ) self.log.debug("Flow deployed") + mine_contract, _ = deploy_contract( - self.mine_contract_path, - [flow_contract.address, "0x0000000000000000000000000000000000000000", 7], + "PoraMineTest", + [book.address, 3], ) self.log.debug("Mine deployed") self.log.info("All contracts deployed") - tx_hash = token_contract.functions.approve( - flow_contract.address, int(1e9) - ).transact(TX_PARAMS) - self.wait_for_transaction_receipt(w3, tx_hash) - - # setup second account - amount = int(1e8) - tx_hash = token_contract.functions.transfer(account2.address, amount).transact( - TX_PARAMS - ) - self.wait_for_transaction_receipt(w3, tx_hash) - - tx_hash = token_contract.functions.approve( - flow_contract.address, amount - ).transact(TX_PARAMS1) - self.wait_for_transaction_receipt(w3, tx_hash) - tx_hash = mine_contract.functions.setMiner(decode_hex(MINER_ID)).transact(TX_PARAMS) self.wait_for_transaction_receipt(w3, tx_hash) @@ -324,7 +321,7 @@ class BlockchainNode(TestNode): construct_sign_and_send_raw_middleware([account1, account2]) ) - contract_interface = json.load(open(self.contract_path, "r")) + contract_interface = load_contract_metadata(self.contract_path, "Flow") return w3.eth.contract(address=contract_address, abi=contract_interface["abi"]) def wait_for_transaction(self, tx_hash): diff --git a/tests/test_framework/bsc_node.py b/tests/test_framework/bsc_node.py index e615780..3eaae7a 100644 --- a/tests/test_framework/bsc_node.py +++ b/tests/test_framework/bsc_node.py @@ -26,8 +26,6 @@ class BSCNode(BlockchainNode): binary, updated_config, contract_path, - token_contract_path, - mine_contract_path, log, rpc_timeout=10, ): @@ -71,8 +69,6 @@ class BSCNode(BlockchainNode): binary, local_conf, contract_path, - token_contract_path, - mine_contract_path, log, BlockChainNodeType.BSC, rpc_timeout, diff --git a/tests/test_framework/conflux_node.py b/tests/test_framework/conflux_node.py index 3be502a..fc55fe6 100644 --- a/tests/test_framework/conflux_node.py +++ b/tests/test_framework/conflux_node.py @@ -29,8 +29,6 @@ class ConfluxNode(BlockchainNode): binary, updated_config, contract_path, - token_contract_path, - mine_contract_path, log, rpc_timeout=10, ): @@ -76,8 +74,6 @@ class ConfluxNode(BlockchainNode): binary, local_conf, contract_path, - token_contract_path, - mine_contract_path, log, BlockChainNodeType.Conflux, rpc_timeout, diff --git a/tests/test_framework/contracts.py b/tests/test_framework/contracts.py new file mode 100644 index 0000000..457478e --- /dev/null +++ b/tests/test_framework/contracts.py @@ -0,0 +1,14 @@ +from os.path import join +from pathlib import Path +import json +from web3 import Web3 + + +def load_contract_metadata(base_path: str, name: str): + path = Path(join(base_path, "artifacts")) + try: + found_file = next(path.rglob(f"{name}.json")) + return json.loads(open(found_file, "r").read()) + except StopIteration: + raise Exception(f"Cannot found contract {name}'s metadata") + diff --git a/tests/test_framework/test_framework.py b/tests/test_framework/test_framework.py index e84d394..fd90068 100644 --- a/tests/test_framework/test_framework.py +++ b/tests/test_framework/test_framework.py @@ -74,8 +74,6 @@ class TestFramework: self.blockchain_binary, updated_config, self.contract_path, - self.token_contract_path, - self.mine_contract_path, self.log, 60, ) @@ -86,8 +84,6 @@ class TestFramework: self.blockchain_binary, updated_config, self.contract_path, - self.token_contract_path, - self.mine_contract_path, self.log, ) else: @@ -212,27 +208,7 @@ class TestFramework: dest="contract", default=os.path.join( __file_path__, - "../../0g-storage-contracts/artifacts/contracts/dataFlow/Flow.sol/Flow.json", - ), - type=str, - ) - - parser.add_argument( - "--token-contract-path", - dest="token_contract", - default=os.path.join( - __file_path__, - "../config/MockToken.json", - ), - type=str, - ) - - parser.add_argument( - "--mine-contract-path", - dest="mine_contract", - default=os.path.join( - __file_path__, - "../../0g-storage-contracts/artifacts/contracts/test/PoraMineTest.sol/PoraMineTest.json", + "../../0g-storage-contracts/", ), type=str, ) @@ -414,18 +390,10 @@ class TestFramework: self.zgs_binary = os.path.abspath(self.options.zerog_storage) self.cli_binary = os.path.abspath(self.options.cli) self.contract_path = os.path.abspath(self.options.contract) - self.token_contract_path = os.path.abspath(self.options.token_contract) - self.mine_contract_path = os.path.abspath(self.options.mine_contract) assert os.path.exists(self.contract_path), ( "%s should be exist" % self.contract_path ) - assert os.path.exists(self.token_contract_path), ( - "%s should be exist" % self.token_contract_path - ) - assert os.path.exists(self.mine_contract_path), ( - "%s should be exist" % self.mine_contract_path - ) if self.options.random_seed is not None: random.seed(self.options.random_seed)