Skip to content

Commit

Permalink
Merge pull request #3000 from darwintree/improve-contract
Browse files Browse the repository at this point in the history
refactor: improve contract test framework
  • Loading branch information
darwintree authored Dec 30, 2024
2 parents c243c27 + 68b195d commit fd1da3d
Show file tree
Hide file tree
Showing 25 changed files with 933 additions and 661 deletions.
2 changes: 1 addition & 1 deletion dev-support/dep_pip3.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

set -e

pip3 install cfx-account eth-utils py-ecc rlp trie coincurve safe-pysha3 web3==7.4.0 py-solc-x jsonrpcclient==3.3.6 asyncio websockets pyyaml numpy
pip3 install cfx-account eth-utils py-ecc rlp trie coincurve safe-pysha3 conflux-web3==1.4.0b5 web3 py-solc-x jsonrpcclient==3.3.6 asyncio websockets pyyaml numpy

python3 -m solcx.install v0.5.17

Expand Down
40 changes: 20 additions & 20 deletions tests/admin_at_creation_test.py
Original file line number Diff line number Diff line change
@@ -1,55 +1,55 @@
#!/usr/bin/env python3
from test_framework.block_gen_thread import BlockGenThread
from test_framework.contracts import ConfluxTestFrameworkForContract, ZERO_ADDRESS, Contract
from test_framework.test_framework import ConfluxTestFramework
from test_framework.mininode import *
from test_framework.util import *
from web3 import Web3

class ClearAdminTest(ConfluxTestFrameworkForContract):
class ClearAdminTest(ConfluxTestFramework):
def set_test_params(self):
super().set_test_params()
self.num_nodes = 8
self._add_genesis_secrets(1, "core")

def setup_network(self):
self.setup_nodes()
connect_sample_nodes(self.nodes, self.log)
sync_blocks(self.nodes)

def run_test(self):
block_gen_thread = BlockGenThread(self.nodes, self.log)
block_gen_thread.start()
self.start_block_gen()
self.deploy_create2()

genesis_addr = self.genesis_addr
test_account_key = self.genesis_key2
test_account_addr = self.genesis_addr2
genesis_addr = self.core_accounts[0].address
test_account = self.core_accounts[1]
test_account_addr = self.core_accounts[1].address
create2factory_addr = self.create2factory.address

# Clear admin by non-admin (fail)
self.log.info("Test unable to clear admin by non-admin.")
self.adminControl.functions.setAdmin(create2factory_addr, ZERO_ADDRESS).cfx_transact(priv_key=test_account_key)
assert_equal(self.client.get_admin(create2factory_addr), genesis_addr.lower())
self.internal_contract("AdminControl").functions.setAdmin(create2factory_addr, ZERO_ADDRESS).transact({
"from": test_account.address
})
assert_equal(self.cfx.get_admin(create2factory_addr), genesis_addr)


self.log.info("Test contract creation by itself")
clear_admin_test_contract: Contract = self.cfx_contract("AdminTestContract").deploy()
clear_admin_test_contract = self.deploy_contract("AdminTestContract")
self.log.info(" contract created at %s" % clear_admin_test_contract.address)

self.log.info("Test clear admin at contract creation through create2factory")
# Deploy the contract.
clear_admin_test_contract2: Contract = self.cfx_contract("AdminTestContract").deploy2(seed = 0)
assert_equal(self.client.get_admin(clear_admin_test_contract2.address), ZERO_ADDRESS)
clear_admin_test_contract2 = self.deploy_contract_2("AdminTestContract", 0)
assert_equal(self.cfx.get_admin(clear_admin_test_contract2.address).hex_address, ZERO_ADDRESS) # type: ignore
# The owner of create2factory_addr isn't hijacked.
self.log.info("Test unable to hijack set admin.")
assert_equal(self.client.get_admin(create2factory_addr), genesis_addr.lower())
assert_equal(self.cfx.get_admin(create2factory_addr), genesis_addr)

self.log.info("Test unable to hijack owner through deployAndHijackAdmin")
# Create a new contract through deployAndHijackAdmin.
create_data = self.cfx_contract("BlackHole").constructor().data()
create_data = self.cfx_contract("BlackHole").constructor()._encode_data_in_transaction()

fn_call = clear_admin_test_contract.functions.deployAndHijackAdmin(create_data)
created_address = fn_call.cfx_call(sender = test_account_addr)
fn_call.cfx_transact(priv_key = test_account_key, value = 123, decimals = 1)
assert_equal(self.client.get_admin(created_address), test_account_addr.lower())
created_address = fn_call.call({"from": test_account_addr})
fn_call.transact({"from": test_account.address, "value": 123}).executed()
assert_equal(self.cfx.get_admin(created_address), test_account_addr)

self.log.info("Pass")

Expand Down
91 changes: 56 additions & 35 deletions tests/admin_control_test.py
Original file line number Diff line number Diff line change
@@ -1,68 +1,89 @@
#!/usr/bin/env python3
from cfx_utils import CFX, Drip
from conflux.transactions import CONTRACT_DEFAULT_GAS, charged_of_huge_gas
from test_framework.contracts import ConfluxTestFrameworkForContract
from test_framework.test_framework import ConfluxTestFramework
from test_framework.util import assert_equal
from web3 import Web3
from web3.contract import Contract

class AdminControlTest(ConfluxTestFrameworkForContract):
class AdminControlTest(ConfluxTestFramework):
def set_test_params(self):
super().set_test_params()
self.num_nodes = 1

def run_test(self):
self.w3 = self.cw3
pay_contract = self.cfx_contract("CheckPay")
admin_control_contract = self.internal_contract("AdminControl")

self.log.info("Initializing contract")
client = self.client
gas = CONTRACT_DEFAULT_GAS


# Setup balance for node 0
(addr, priv_key) = client.rand_account()
self.log.info("addr=%s priv_key=%s", addr, priv_key)
self.cfx_transfer(addr, value = 5)
assert_equal(client.get_balance(addr), 5000000000000000000)
# Setup balance for node 0
acct1 = self.cfx.account.create()
self.log.info("addr=%s priv_key=%s", acct1.address, acct1.key.hex())
self.cfx_transfer(acct1.hex_address, value = 5)
assert_equal(self.cfx.get_balance(acct1.address).to("CFX"), CFX(5))
self.w3.wallet.add_account(acct1)


(addr2, priv_key2) = client.rand_account()
self.log.info("addr2=%s priv_key2=%s", addr2, priv_key2)
self.cfx_transfer(addr2, value = 5)
assert_equal(client.get_balance(addr2), 5000000000000000000)
acct2 = self.cfx.account.create()
self.log.info("addr2=%s priv_key2=%s", acct2.address, acct2.key.hex())
self.cfx_transfer(acct2.hex_address, value = 5)
assert_equal(self.cfx.get_balance(acct2.address).to("CFX"), CFX(5))
self.w3.wallet.add_account(acct2)

# deploy pay contract
pay_contract: Contract = self.cfx_contract("CheckPay").deploy(transact_args=dict(priv_key=priv_key, storage_limit=512, gas=gas))
pay_contract = self.deploy_contract(name="CheckPay", transact_args={
"from": acct1.address,
"storageLimit": 512,
"gas": gas,
"gasPrice": 1
})
contract_addr = pay_contract.address
self.log.info("contract_addr={}".format(pay_contract.address))
assert_equal(client.get_collateral_for_storage(addr), 512 * 976562500000000)
assert_equal(client.get_balance(contract_addr), 0)
assert_equal(self.cfx.get_collateral_for_storage(acct1.address), 512 * 976562500000000)
assert_equal(self.cfx.get_balance(contract_addr), 0)


# deposit 10**18
b0 = client.get_balance(addr)
pay_contract.functions.recharge().cfx_transact(priv_key=priv_key, value = 1, gas=gas)
assert_equal(client.get_balance(contract_addr), 10 ** 18)
assert_equal(client.get_balance(addr), b0 - 10 ** 18 - charged_of_huge_gas(gas))
assert_equal(client.get_admin(contract_addr), addr.lower())
b0 = self.cfx.get_balance(acct1.address)
pay_contract.functions.recharge().transact({
"from": acct1.address,
"value": CFX(1),
"gas": gas,
"gasPrice": 1,
}).executed()
assert_equal(self.cfx.get_balance(contract_addr), CFX(1))
assert_equal(self.cfx.get_balance(acct1.address), b0 - CFX(1) - Drip(charged_of_huge_gas(gas)))
assert_equal(self.cfx.get_admin(contract_addr), acct1.address.lower())


# transfer admin (fail)
admin_control_contract.functions.setAdmin(contract_addr, addr2).cfx_transact(priv_key=priv_key2, gas=gas)
assert_equal(client.get_admin(contract_addr), addr.lower())
assert_equal(client.get_balance(addr2), 5 * 10 ** 18 - charged_of_huge_gas(gas))
admin_control_contract.functions.setAdmin(contract_addr, acct2.address).transact({
"from": acct2.address,
"gas": gas,
"gasPrice": 1
}).executed()
assert_equal(self.cfx.get_admin(contract_addr), acct1.address.lower())
assert_equal(self.cfx.get_balance(acct2.address), CFX(5) - Drip(charged_of_huge_gas(gas)))

# transfer admin (success)
admin_control_contract.functions.setAdmin(contract_addr, addr2).cfx_transact(priv_key=priv_key, gas=gas)
assert_equal(client.get_admin(contract_addr), addr2.lower())
admin_control_contract.functions.setAdmin(contract_addr, acct2.address).transact({
"from": acct1.address,
"gas": gas,
"gasPrice": 1,
}).executed()
assert_equal(self.cfx.get_admin(contract_addr), acct2.address.lower())

# destroy
b0 = client.get_balance(addr)
admin_control_contract.functions.destroy(contract_addr).cfx_transact(priv_key=priv_key2, gas=gas)
assert_equal(client.get_balance(contract_addr), 0)
assert_equal(client.get_balance(addr2), 6 * 10 ** 18 - charged_of_huge_gas(gas) * 2)
assert_equal(client.get_collateral_for_storage(addr), 0)
assert_equal(client.get_balance(addr), b0 + 512 * 976562500000000)
b0 = self.cfx.get_balance(acct1.address)
admin_control_contract.functions.destroy(contract_addr).transact({
"from": acct2.address,
"gas": gas,
"gasPrice": 1,
}).executed()
assert_equal(self.cfx.get_balance(contract_addr), 0)
assert_equal(self.cfx.get_balance(acct2.address), CFX(6) - Drip(charged_of_huge_gas(gas) * 2))
assert_equal(self.cfx.get_collateral_for_storage(acct1.address), 0)
assert_equal(self.cfx.get_balance(acct1.address), b0 + Drip(512 * 976562500000000))

self.log.info("Pass")

Expand Down
19 changes: 11 additions & 8 deletions tests/blockhash_test.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,33 @@
from conflux.utils import *
from test_framework.contracts import ConfluxTestFrameworkForContract
from test_framework.test_framework import ConfluxTestFramework
from test_framework.util import *
from test_framework.mininode import *


class BlockHashFromStateTest(ConfluxTestFrameworkForContract):
class BlockHashFromStateTest(ConfluxTestFramework):
def set_test_params(self):
self.num_nodes = 1

def run_test(self):
genesis_hash = self.client.block_by_epoch(0)["hash"]
for _ in range(5):
self.client.generate_block_with_parent(genesis_hash)

self.wait_for_block(1000)

test_contract = self.cfx_contract("BlockHash").deploy()
context_contract = self.internal_contract("ConfluxContext");
test_contract = self.deploy_contract("BlockHash")
context_contract = self.internal_contract("ConfluxContext")
for i in range(100, 1001, 100):
assert_equal(test_contract.functions.getBlockHash(i).cfx_call().hex(), self.client.block_by_block_number(i)["hash"][2:])
assert_equal(context_contract.functions.epochHash(i).cfx_call().hex(), self.client.block_by_epoch(i)["hash"][2:])
assert_equal(test_contract.functions.getBlockHash(i).call().hex(), self.client.block_by_block_number(i)["hash"][2:])
assert_equal(context_contract.functions.epochHash(i).call().hex(), self.client.block_by_epoch(i)["hash"][2:])

self.log.info("Generate 65536+ blocks")
for i in range(5000, 66000, 5000):
self.wait_for_block(i)
self.wait_for_block(66000)

assert_equal(test_contract.functions.getBlockHash(100).cfx_call().hex(), "0" * 64)
assert_equal(context_contract.functions.epochHash(100).cfx_call().hex(), "0" * 64)
assert_equal(test_contract.functions.getBlockHash(100).call().hex(), "0" * 64)
assert_equal(context_contract.functions.epochHash(100).call().hex(), "0" * 64)


def wait_for_block(self, block_number, have_not_reach=False):
Expand Down
Loading

0 comments on commit fd1da3d

Please sign in to comment.