Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: improve contract test framework #3000

Merged
merged 27 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
41d0a5e
refactor: test framework for contracts
darwintree Dec 6, 2024
076d396
refactor(tests): admin_ad_creation_test
darwintree Dec 6, 2024
c9d95b3
refactor(tests): admin_control_test.py
darwintree Dec 9, 2024
527246b
refactor: improve contract framework
darwintree Dec 13, 2024
17d5466
refactor: blockhash_test.py
darwintree Dec 13, 2024
a576b83
refactor: enable cfx_maxPriorityFeePerGas when node starts
darwintree Dec 13, 2024
86ef2e9
refactor: cip97_test.py
darwintree Dec 13, 2024
beafd36
refactor: cip107_test.py
darwintree Dec 13, 2024
74f1fd1
refactor: cip118_activation_test.py
darwintree Dec 13, 2024
9092dd4
refactor: commission_privilege_test.py
darwintree Dec 13, 2024
9edc374
refactor: contract_remove_test.py
darwintree Dec 13, 2024
e38e09c
refactor: overlay_account_storage_test.py
darwintree Dec 13, 2024
debdbd9
refactor: sponsored_tx_test
darwintree Dec 13, 2024
4bf763a
refactor: storage_value_unchange_test.py
darwintree Dec 13, 2024
6f99fb6
refactor: vote_token_test
darwintree Dec 13, 2024
156142c
resolve test issues
darwintree Dec 13, 2024
59b1bf5
chore: update test dependency
darwintree Dec 13, 2024
511f683
chore: clean code
darwintree Dec 13, 2024
6828093
fix(test): cip107_test issues
darwintree Dec 16, 2024
5d45ee3
refactor: move common features in ConfluxTestFrameworkForContract to …
darwintree Dec 20, 2024
935d3d8
refactor: remove dataclass Account
darwintree Dec 20, 2024
6e839a8
refactor: remove util func from ConfluxTestFrameworkForContract
darwintree Dec 20, 2024
6908b95
refactor: remove ConfluxTestFrameworkForConflux
darwintree Dec 20, 2024
9c2f05f
refactor(tests): use encode_transactioin_data instead of _encode_tran…
darwintree Dec 20, 2024
54b7d7f
refactor(tests): use semantic value format
darwintree Dec 20, 2024
546c5b3
chore: restore tests/test_all.py
darwintree Dec 23, 2024
68b195d
resolve comments
darwintree Dec 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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