Skip to content
Merged

V202 #98

Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ test_cases := \
test_cases/config \
test_cases/miner \
test_cases/get_fee_rate_statistics \
test_cases/ws
test_cases/ws \
test_cases/memory


test:
Expand Down
1 change: 1 addition & 0 deletions download.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"0.121.0",
"0.200.0",
"0.201.0",
"0.202.0",
] # Replace with your versions

DOWNLOAD_DIR = "download"
Expand Down
2 changes: 2 additions & 0 deletions framework/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
ALWAYS_SUCCESS_CONTRACT_PATH = f"{get_project_root()}/source/contract/always_success"
SPAWN_CONTRACT_PATH = f"{get_project_root()}/source/contract/test_cases/spawn_demo"
UDT_CONTRACT_PATH = f"{get_project_root()}/source/contract/XUDTType"
SPAWN_ARG_PATH = f"{get_project_root()}/source/contract/spawn_arg_length"
EXEC_ARG_PATH = f"{get_project_root()}/source/contract/exec_arg_length"


def get_tmp_path():
Expand Down
4 changes: 2 additions & 2 deletions framework/helper/ckb_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ def tx_add_input(tx_hash, index, tx_file, api_url="http://127.0.0.1:8114"):

def tx_add_multisig_config(ckb_address, tx_file, api_url="http://127.0.0.1:8114"):
"""
./ckb-cli tx add-multisig-config --sighash-address ckt1qyqdfjzl8ju2vfwjtl4mttx6me09hayzfldq8m3a0y --tx-file tx.txt
./ckb-cli tx add-multisig-config --multisig-code-hash legacy --sighash-address ckt1qyqdfjzl8ju2vfwjtl4mttx6me09hayzfldq8m3a0y --tx-file tx.txt
status: success
MacBook-Pro-4 0.111.0 % cat tx.txt
{
Expand Down Expand Up @@ -421,7 +421,7 @@ def tx_add_multisig_config(ckb_address, tx_file, api_url="http://127.0.0.1:8114"

"""
cmd = (
f"export API_URL={api_url} && {cli_path} tx add-multisig-config --sighash-address {ckb_address} "
f"export API_URL={api_url} && {cli_path} tx add-multisig-config --multisig-code-hash legacy --sighash-address {ckb_address} "
f"--tx-file {tx_file}"
)
return run_command(cmd)
Expand Down
61 changes: 61 additions & 0 deletions framework/helper/exec_arg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from framework.config import EXEC_ARG_PATH
from framework.helper.contract import deploy_ckb_contract, CkbContract
from framework.helper.miner import miner_until_tx_committed
from framework.helper.ckb_cli import util_key_info_by_private_key
from framework.helper.contract import invoke_ckb_contract

from framework.test_node import CkbNode
from framework.util import (
ckb_hash_script,
to_big_uint128_le_compatible,
to_int_from_big_uint128_le,
)
from framework.helper.contract import get_ckb_contract_codehash


class ExecArgContract(CkbContract):

def __init__(self, contract_hash=None, contract_tx_index=None):
self.contract_hash = contract_hash
self.contract_tx_index = contract_tx_index
if contract_hash is None:
self.deployed = False
else:
self.deployed = True
self.contract_path = EXEC_ARG_PATH
self.method = {"demo": {"args": "0x", "data": "0x"}}

def deploy(self, account_private, node: CkbNode):
if self.deployed:
return
self.contract_hash = deploy_ckb_contract(
account_private, self.contract_path, api_url=node.getClient().url
)
self.contract_tx_index = 0
miner_until_tx_committed(node, self.contract_hash)
self.deployed = True

def get_deploy_hash_and_index(self) -> (str, int):
if not self.deployed:
raise Exception("pls deploy first")
return self.contract_hash, self.contract_tx_index

def get_code_hash(self, type_id, api):
return get_ckb_contract_codehash(
self.contract_hash, self.contract_tx_index, type_id, api
)

def get_owner_arg_by_lock_arg(self, lock_arg):
return ckb_hash_script(lock_arg)

@classmethod
def get_test_data(cls, mb_size, kb_size, byte_size) -> (str, str):
return "0x1234", to_big_uint128_le_compatible(
mb_size * 100000000 + kb_size * 10000 + byte_size
)

def get_arg_and_data(self, key) -> (str, str):
if key not in self.method.keys():
# return "0x0","0x0"
raise Exception("key not exist in method list")
return self.method[key]["args"], self.method[key]["data"]
61 changes: 61 additions & 0 deletions framework/helper/spawn_arg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from framework.config import SPAWN_ARG_PATH
from framework.helper.contract import deploy_ckb_contract, CkbContract
from framework.helper.miner import miner_until_tx_committed
from framework.helper.ckb_cli import util_key_info_by_private_key
from framework.helper.contract import invoke_ckb_contract

from framework.test_node import CkbNode
from framework.util import (
ckb_hash_script,
to_big_uint128_le_compatible,
to_int_from_big_uint128_le,
)
from framework.helper.contract import get_ckb_contract_codehash


class SpawnArgContract(CkbContract):

def __init__(self, contract_hash=None, contract_tx_index=None):
self.contract_hash = contract_hash
self.contract_tx_index = contract_tx_index
if contract_hash is None:
self.deployed = False
else:
self.deployed = True
self.contract_path = SPAWN_ARG_PATH
self.method = {"demo": {"args": "0x", "data": "0x"}}

def deploy(self, account_private, node: CkbNode):
if self.deployed:
return
self.contract_hash = deploy_ckb_contract(
account_private, self.contract_path, api_url=node.getClient().url
)
self.contract_tx_index = 0
miner_until_tx_committed(node, self.contract_hash)
self.deployed = True

def get_deploy_hash_and_index(self) -> (str, int):
if not self.deployed:
raise Exception("pls deploy first")
return self.contract_hash, self.contract_tx_index

def get_code_hash(self, type_id, api):
return get_ckb_contract_codehash(
self.contract_hash, self.contract_tx_index, type_id, api
)

def get_owner_arg_by_lock_arg(self, lock_arg):
return ckb_hash_script(lock_arg)

@classmethod
def get_test_data(cls, mb_size, kb_size, byte_size) -> (str, str):
return "0x1234", to_big_uint128_le_compatible(
mb_size * 100000000 + kb_size * 10000 + byte_size
)

def get_arg_and_data(self, key) -> (str, str):
if key not in self.method.keys():
# return "0x0","0x0"
raise Exception("key not exist in method list")
return self.method[key]["args"], self.method[key]["data"]
3 changes: 3 additions & 0 deletions framework/rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ def get_transaction_proof(self, tx_hash, block_hash):
def send_transaction(self, tx, outputs_validator="passthrough"):
return self.call("send_transaction", [tx, outputs_validator])

def send_test_transaction(self, tx, outputs_validator="passthrough"):
return self.call("send_test_transaction", [tx, outputs_validator])

def get_raw_tx_pool(self, verbose=None):
return self.call("get_raw_tx_pool", [verbose])

Expand Down
15 changes: 11 additions & 4 deletions framework/test_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,34 @@ class CkbNodeConfigPath(Enum):
"source/template/ckb/v200/ckb.toml.j2",
"source/template/ckb/v200/ckb-miner.toml.j2",
"source/template/ckb/v200/specs/dev.toml",
"download/0.201.0",
"download/0.202.0",
)
TESTNET = (
"source/template/ckb/v200/ckb.toml.j2",
"source/template/ckb/v200/ckb-miner.toml.j2",
"source/template/specs/testnet.toml.j2",
"download/0.201.0",
"download/0.202.0",
)

CURRENT_MAIN = (
"source/template/ckb/v200/ckb.toml.j2",
"source/template/ckb/v200/ckb-miner.toml.j2",
"source/template/specs/mainnet.toml.j2",
"download/0.201.0",
"download/0.202.0",
)

PREVIEW_DUMMY = (
"source/template/ckb/v200/ckb.toml.j2",
"source/template/ckb/v200/ckb-miner.toml.j2",
"source/template/specs/preview_dev.toml",
"download/0.201.0",
"download/0.202.0",
)

v202 = (
"source/template/ckb/v200/ckb.toml.j2",
"source/template/ckb/v200/ckb-miner.toml.j2",
"source/template/ckb/v200/specs/dev.toml",
"download/0.202.0",
)

v201 = (
Expand Down
Binary file added source/contract/exec_arg_length
Binary file not shown.
Binary file added source/contract/spawn_arg_length
Binary file not shown.
Binary file added source/contract/test_cases/exec_oom
Binary file not shown.
Binary file added source/contract/test_cases/spawn_oom
Binary file not shown.
29 changes: 29 additions & 0 deletions test_cases/config/test_listen_address.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from framework.basic import CkbTest


class TestListenAddress(CkbTest):

def test_listen_address(self):
"""
fix: fix multi-listen with tcp bind #4889
Returns:

"""
self.node = self.CkbNode.init_dev_by_port(
self.CkbNodeConfigPath.CURRENT_TEST, "node/node", 8118, 8119
)
self.node.prepare()
self.node.prepare(
other_ckb_config={
"ckb_network_listen_addresses": [
"/ip4/0.0.0.0/tcp/8115",
"/ip4/0.0.0.0/tcp/8116",
],
"ckb_network_reuse_tcp_with_ws": "true",
}
)
self.node.start()
local_node_info = self.node.getClient().local_node_info()
assert len(local_node_info["addresses"]) == 4
self.node.stop()
self.node.clean()
19 changes: 18 additions & 1 deletion test_cases/contracts/test_01_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def get_successful_files():
"loop_contract",
"exec_with_block_opcode",
"rfc49_atomic",
"exec_oom",
"spawn_oom",
]
return [s for s in files if not any(s.endswith(suffix) for suffix in files_list)]

Expand All @@ -50,6 +52,8 @@ def get_failed_files():
"loop_contract",
"exec_with_block_opcode",
"rfc49_atomic",
"exec_oom",
"spawn_oom",
]
# return [s for s in files if not any(s.endswith(suffix) for suffix in files_list)]
return [f"{project_root}/source/contract/test_cases/{x}" for x in files_list]
Expand All @@ -67,11 +71,20 @@ def setup_class(cls):
cls.node.prepare()
cls.node.start()
cls.Miner.make_tip_height_number(cls.node, 2000)
cls.node1 = cls.CkbNode.init_dev_by_port(
cls.CkbNodeConfigPath.v200, "contract/node1", 8116, 8117
)
cls.node1.prepare()
cls.node1.start()
cls.node1.connected(cls.node)
cls.Node.wait_node_height(cls.node1, 2000, 200)

@classmethod
def teardown_class(cls):
cls.node.stop()
cls.node.clean()
cls.node1.stop()
cls.node1.clean()

@parameterized.expand(success_files)
# @pytest.mark.skip
Expand All @@ -80,7 +93,9 @@ def test_01_deploy_and_invoke_demo(self, path):
1. Retrieve the paths of successful files from `project_root/source/contract/test_cases` by excluding the files specified in `files_list`.
2. deploy and invoke contract
"""
return self.deploy_and_invoke(self.Config.MINER_PRIVATE_1, path, self.node)
self.deploy_and_invoke(self.Config.MINER_PRIVATE_1, path, self.node)
tip_number = self.node.getClient().get_tip_block_number()
self.Node.wait_node_height(self.node1, tip_number, 200)

@parameterized.expand(failed_files)
def test_02_deploy_and_invoke_demo_failed(self, path):
Expand All @@ -94,6 +109,8 @@ def test_02_deploy_and_invoke_demo_failed(self, path):
self.fail("Did not raise an exception as expected!")
except Exception as e:
print(e)
tip_number = self.node.getClient().get_tip_block_number()
self.Node.wait_node_height(self.node1, tip_number, 200)

def deploy_and_invoke(self, account, path, node, try_count=5):
if try_count < 0:
Expand Down
52 changes: 52 additions & 0 deletions test_cases/contracts/test_exceeded_maximum_cycles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import time

import pytest

from framework.basic import CkbTest
from framework.util import get_project_root


class TestExceededMaximumCycles(CkbTest):
@classmethod
def setup_class(cls):
cls.node = cls.CkbNode.init_dev_by_port(
cls.CkbNodeConfigPath.CURRENT_TEST, "contract/node", 8114, 8115
)
cls.node.prepare()
cls.node.start()
cls.Miner.make_tip_height_number(cls.node, 2000)

@classmethod
def teardown_class(cls):
cls.node.stop()
cls.node.clean()

def test_01(self):
path = f"{get_project_root()}/source/contract/test_cases/spawn_loop_times"
account = self.Config.MINER_PRIVATE_1
node = self.node
deploy_hash = self.Contract.deploy_ckb_contract(
account, path, enable_type_id=True, api_url=node.getClient().url
)
self.Miner.miner_until_tx_committed(node, deploy_hash)
time.sleep(1)
tx = self.Contract.build_invoke_ckb_contract(
account_private=account,
contract_out_point_tx_hash=deploy_hash,
contract_out_point_tx_index=0,
type_script_arg="0x02",
data="0x1234",
hash_type="type",
api_url=node.getClient().url,
)
invoke_hash = self.node.getClient().send_test_transaction(tx, "passthrough")
self.node.getClient().get_transaction(invoke_hash)
self.Node.wait_get_transaction(self.node, invoke_hash, "rejected")

with pytest.raises(Exception) as exc_info:
invoke_hash = self.node.getClient().send_transaction(tx, "passthrough")

expected_error_message = "ExceededMaximumCycles"
assert (
expected_error_message in exc_info.value.args[0]
), f"Expected substring '{expected_error_message}' not found in actual string '{exc_info.value.args[0]}'"
Loading