From 890e77bfdb2e24aeff89e2ff171bdd287c406386 Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Wed, 6 Dec 2023 14:43:19 +0800 Subject: [PATCH 01/27] add tx_pool test --- .../tx_pool_refactor/test_08_many_tx.py | 206 ++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 test_cases/tx_pool_refactor/test_08_many_tx.py diff --git a/test_cases/tx_pool_refactor/test_08_many_tx.py b/test_cases/tx_pool_refactor/test_08_many_tx.py new file mode 100644 index 0000000..7b4687c --- /dev/null +++ b/test_cases/tx_pool_refactor/test_08_many_tx.py @@ -0,0 +1,206 @@ +import time + +from framework.basic import CkbTest +import concurrent.futures + + +class ManyTx(CkbTest): + + @classmethod + def setup_class(cls): + cls.current_node = cls.CkbNode.init_dev_by_port(cls.CkbNodeConfigPath.CURRENT_TEST, "tx_pool/node1", 8120, + 8225) + cls.node_111 = cls.CkbNode.init_dev_by_port(cls.CkbNodeConfigPath.V111, "tx_pool/node2", 8121, + 8226) + cls.cluster = cls.Cluster([cls.current_node, cls.node_111]) + cls.cluster.prepare_all_nodes() + cls.cluster.start_all_nodes() + cls.cluster.connected_all_nodes() + cls.Miner.make_tip_height_number(cls.current_node, 200) + cls.Node.wait_cluster_height(cls.cluster, 150, 50) + + @classmethod + def teardown_class(cls): + cls.cluster.stop_all_nodes() + cls.cluster.clean_all_nodes() + + def test_may_tx(self): + """ + 1. 给节点1 并发发送冲突子交易 + 2. 查询节点的pool池 + pending = 1 + """ + TEST_PRIVATE_1 = self.Config.MINER_PRIVATE_1 + + account = self.Ckb_cli.util_key_info_by_private_key(TEST_PRIVATE_1) + tx1 = self.Ckb_cli.wallet_transfer_by_private_key(self.Config.MINER_PRIVATE_1, + account["address"]["testnet"], 100, + self.current_node.getClient().url, "1500") + self.Miner.miner_until_tx_committed(self.current_node, tx1) + tip_number = self.current_node.getClient().get_tip_block_number() + self.Node.wait_node_height(self.node_111, tip_number, 1000) + self.node_111.getClient().set_network_active(False) + + txs = [] + # 给节点1 并发发送 + for i in range(10): + tx = self.Tx.send_transfer_self_tx_with_input([tx1], ["0x0"], TEST_PRIVATE_1, + output_count=1, + fee=1090 + i, + api_url=self.node_111.getClient().url) + transaction = self.node_111.getClient().get_transaction(tx) + transaction = transaction['transaction'] + del transaction['hash'] + txs.insert(0, transaction) + + successfulSize = 0 + successfulTxHash = "" + with concurrent.futures.ThreadPoolExecutor() as executor: + futures = {executor.submit(self.current_node.getClient().send_transaction, tx): tx for tx in txs} + for future in concurrent.futures.as_completed(futures): + tx = futures[future] + try: + result = future.result() + # 处理返回结果 + print(f"Transaction sent successfully: {result}") + successfulSize += 1 + successfulTxHash = result + except Exception as e: + print(f"Error sending transaction: {e}") + before_pool = self.current_node.getClient().tx_pool_info() + assert successfulSize == 1 + assert before_pool['pending'] == '0x1' + assert before_pool['proposed'] == '0x0' + self.node_111.getClient().set_network_active(True) + self.node_111.connected(self.current_node) + for i in range(10): + self.Miner.miner_with_version(self.node_111, "0x0") + tip_number = self.node_111.getClient().get_tip_block_number() + self.Node.wait_node_height(self.current_node, tip_number, 1000) + pool = self.current_node.getClient().tx_pool_info() + assert pool['pending'] == '0x0' + assert pool['proposed'] == '0x0' + ret = self.current_node.getClient().get_transaction(successfulTxHash) + assert ret['tx_status']['status'] == 'rejected' + + def test_orphan_turn_pending(self): + """ + 1. 发送tx1 + 2. 发送 子交易 tx(1,10) : input = tx1.input + 3. 先转发子交易到另外一个节点 + 4. 查询另外一个节点pool池的orphan交易>0 ,pending = 0 + 5. 发送tx1到另外一个节点 + 6. 在另外一个节点查询pool 只有2笔交易 + 7. 上链 + """ + TEST_PRIVATE_1 = self.Config.MINER_PRIVATE_1 + + account = self.Ckb_cli.util_key_info_by_private_key(TEST_PRIVATE_1) + self.node_111.getClient().set_network_active(False) + tx1 = self.Ckb_cli.wallet_transfer_by_private_key(self.Config.MINER_PRIVATE_1, + account["address"]["testnet"], 100, + self.node_111.getClient().url, "1500") + transaction1 = self.node_111.getClient().get_transaction(tx1) + transaction1 = transaction1['transaction'] + del transaction1['hash'] + txs = [] + # 给节点1 并发发送 + for i in range(10): + tx = self.Tx.send_transfer_self_tx_with_input([tx1], ["0x0"], TEST_PRIVATE_1, + output_count=1, + fee=1090 + i, + api_url=self.node_111.getClient().url) + transaction = self.node_111.getClient().get_transaction(tx) + transaction = transaction['transaction'] + del transaction['hash'] + txs.append(transaction) + self.node_111.getClient().remove_transaction(tx1) + self.node_111.getClient().set_network_active(True) + successfulSize = 0 + with concurrent.futures.ThreadPoolExecutor() as executor: + futures = {executor.submit(self.node_111.getClient().send_transaction, tx): tx for tx in txs} + for future in concurrent.futures.as_completed(futures): + tx = futures[future] + try: + result = future.result() + # 处理返回结果 + print(f"Transaction sent successfully: {result}") + successfulSize += 1 + except Exception as e: + print(f"Error sending transaction: {e}") + before_pool = self.current_node.getClient().tx_pool_info() + print(before_pool) + time.sleep(3) + before_pool = self.current_node.getClient().tx_pool_info() + assert before_pool['pending'] == '0x0' + assert before_pool['orphan'] != '0x0' + self.current_node.getClient().send_transaction(transaction1) + try: + self.node_111.getClient().send_transaction(transaction1) + except: + pass + before_pool = self.current_node.getClient().tx_pool_info() + assert before_pool['pending'] == '0x2' + + for i in range(11): + self.Miner.miner_with_version(self.node_111, "0x0") + self.Miner.miner_until_tx_committed(self.node_111, tx1, 1000) + tip_number = self.node_111.getClient().get_tip_block_number() + self.Node.wait_node_height(self.current_node, tip_number, 1000) + node111_pool = self.node_111.getClient().tx_pool_info() + assert node111_pool['pending'] == '0x0' + assert node111_pool['orphan'] == '0x0' + after_pool = self.current_node.getClient().tx_pool_info() + assert after_pool['pending'] == '0x0' + assert after_pool['orphan'] == '0x0' + + def test_dep_tx_clean(self): + """ + 1. 发送tx1 + 2. 发送tx2 + 3. 发送tx21 : input = tx2.input,dep = tx1.input + 4. 发送tx11 : input = tx1.input,dep + 5. tx11 先上链 + 6. 查询tx21的状态 + rejected + """ + TEST_PRIVATE_1 = self.Config.MINER_PRIVATE_1 + TEST_PRIVATE_2 = self.Config.ACCOUNT_PRIVATE_1 + account = self.Ckb_cli.util_key_info_by_private_key(TEST_PRIVATE_1) + account2 = self.Ckb_cli.util_key_info_by_private_key(TEST_PRIVATE_2) + # 1. 发送tx1 + tx1 = self.Ckb_cli.wallet_transfer_by_private_key(TEST_PRIVATE_1, + account["address"]["testnet"], 100, + self.current_node.getClient().url, "1500") + # 2. 发送tx2 + tx2 = self.Ckb_cli.wallet_transfer_by_private_key(TEST_PRIVATE_2, + account2["address"]["testnet"], 100, + self.current_node.getClient().url, "1500") + self.Miner.miner_until_tx_committed(self.current_node, tx1) + self.Miner.miner_until_tx_committed(self.current_node, tx2) + tip_number = self.current_node.getClient().get_tip_block_number() + self.Node.wait_node_height(self.node_111, tip_number, 1000) + # 3. 发送tx21 : input = tx2.input,dep = tx1.input + tx21_dep1 = self.Tx.send_transfer_self_tx_with_input([tx2], ["0x0"], TEST_PRIVATE_2, + output_count=1, + fee=1090, + api_url=self.current_node.getClient().url, + dep_cells=[{ + "tx_hash": tx1, "index_hex": "0x0" + }]) + + # 4. 发送tx11 : input = tx1.input,dep + tx11 = self.Tx.send_transfer_self_tx_with_input([tx1], ["0x0"], TEST_PRIVATE_1, + output_count=1, + fee=1090, + api_url=self.current_node.getClient().url) + # 5. tx11 先上链 + self.Node.wait_get_transaction(self.node_111, tx21_dep1, 'pending') + self.Node.wait_get_transaction(self.node_111, tx11, 'pending') + self.node_111.getClient().remove_transaction(tx21_dep1) + for i in range(10): + self.Miner.miner_with_version(self.node_111, "0x0") + pool = self.current_node.getClient().tx_pool_info() + # 6. 查询tx21的状态 + ret = self.current_node.getClient().get_transaction(tx21_dep1) + assert ret['tx_status']['status'] == 'rejected' From a197a145bf9100aba1fa15e9920b651e2bd11413 Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Wed, 6 Dec 2023 14:46:42 +0800 Subject: [PATCH 02/27] add replace test --- framework/rpc.py | 12 +- framework/test_node.py | 55 ++++- framework/util.py | 10 +- requirements.txt | 3 +- test_cases/replace_rpc/test_rpc.py | 191 ++++++++++++++++ .../test_sub_telnet_with_websocket.py | 215 ++++++++++++++++++ test_cases/replace_rpc/test_telnet.py | 165 ++++++++++++++ test_cases/replace_rpc/test_websocket.py | 162 +++++++++++++ 8 files changed, 799 insertions(+), 14 deletions(-) create mode 100644 test_cases/replace_rpc/test_rpc.py create mode 100644 test_cases/replace_rpc/test_sub_telnet_with_websocket.py create mode 100644 test_cases/replace_rpc/test_telnet.py create mode 100644 test_cases/replace_rpc/test_websocket.py diff --git a/framework/rpc.py b/framework/rpc.py index 27c01de..304b9b9 100644 --- a/framework/rpc.py +++ b/framework/rpc.py @@ -99,7 +99,7 @@ def generate_epochs(self, epoch): return self.call("generate_epochs", [epoch]) def generate_block(self): - return self.call("generate_block",[]) + return self.call("generate_block", []) def get_deployments_info(self): return self.call("get_deployments_info", []) @@ -145,7 +145,7 @@ def get_transaction(self, tx_hash, verbosity=None, only_committed=None): return self.call("get_transaction", [tx_hash, verbosity, only_committed]) def get_transactions(self, search_key, order, limit, after): - return self.call("get_transactions", [search_key, order, limit,after]) + return self.call("get_transactions", [search_key, order, limit, after]) def dry_run_transaction(self, tx): return self.call("dry_run_transaction", [tx]) @@ -183,8 +183,8 @@ def get_live_cell(self, index, tx_hash, with_data=True): def submit_block(self, work_id, block): return self.call("submit_block", [work_id, block]) - def subscribe(self,topic): - return self.call("subscribe",[topic]) + def subscribe(self, topic): + return self.call("subscribe", [topic]) def get_cells_capacity(self, script): return self.call("get_cells_capacity", [script]) @@ -192,7 +192,7 @@ def get_cells_capacity(self, script): def get_current_epoch(self): return self.call("get_current_epoch", []) - def call(self, method, params): + def call(self, method, params, try_count=15): headers = {'content-type': 'application/json'} data = { @@ -202,7 +202,7 @@ def call(self, method, params): "params": params } print(f"request:url:{self.url},data:\n{json.dumps(data)}") - for i in range(15): + for i in range(try_count): try: response = requests.post(self.url, data=json.dumps(data), headers=headers).json() print(f"response:\n{json.dumps(response)}") diff --git a/framework/test_node.py b/framework/test_node.py index e685a18..04e8b77 100644 --- a/framework/test_node.py +++ b/framework/test_node.py @@ -4,14 +4,23 @@ from framework.config import get_tmp_path, CKB_DEFAULT_CONFIG, CKB_MINER_CONFIG from framework.rpc import RPCClient import shutil +import telnetlib +from websocket import create_connection, WebSocket class CkbNodeConfigPath(Enum): CURRENT_TEST = ( - "source/template/ckb/v112/ckb.toml.j2", + "source/template/ckb/v113/ckb.toml.j2", "source/template/ckb/v112/ckb-miner.toml.j2", "source/template/ckb/v112/specs/dev.toml", - "download/0.112.1" + "download/0.113.0" + ) + + V113 = ( + "source/template/ckb/v113/ckb.toml.j2", + "source/template/ckb/v112/ckb-miner.toml.j2", + "source/template/ckb/v112/specs/dev.toml", + "download/0.113.0" ) V112 = ( @@ -198,3 +207,45 @@ def stop_miner(self): def version(self): pass + + def subscribe_telnet(self, topic, other_url=None) -> telnetlib.Telnet: + # new_tip_header | new_tip_block | new_transaction | proposed_transaction | rejected_transaction + if "ckb_tcp_listen_address" not in self.ckb_config.keys(): + raise Exception("not set ckb_ws_listen_address") + ckb_tcp_listen_address = self.ckb_config['ckb_tcp_listen_address'] + if other_url is not None: + ckb_tcp_listen_address = other_url + # get host + host = ckb_tcp_listen_address.split(":")[0] + # get port + port = ckb_tcp_listen_address.split(":")[1] + # new telnet + tn = telnetlib.Telnet(host, int(port)) + print("----") + topic_str = '{"id": 2, "jsonrpc": "2.0", "method": "subscribe", "params": ["' + topic + '"]}' + tn.write(topic_str.encode('utf-8') + b"\n") + data = tn.read_until(b'}\n') + if data: + output = data.decode('utf-8') + print("telnet read:", output) + return tn + + + def subscribe_websocket(self, topic, other_url=None) -> WebSocket: + if other_url is None and "ckb_ws_listen_address" not in self.ckb_config.keys(): + raise Exception("not set ckb_ws_listen_address") + print("subscribe_websocket") + if other_url is not None: + ckb_ws_listen_address = other_url + else: + ckb_ws_listen_address = self.ckb_config['ckb_ws_listen_address'] + print(ckb_ws_listen_address) + ws = create_connection(f"ws://{ckb_ws_listen_address}") + topic_str = '{"id": 2, "jsonrpc": "2.0", "method": "subscribe", "params": ["' + topic + '"]}' + ws.send(topic_str) + print("Sent") + print("Receiving...") + result = ws.recv() + print(result) + # ws.settimeout(1) + return ws diff --git a/framework/util.py b/framework/util.py index 3bfa0fe..8a76c85 100644 --- a/framework/util.py +++ b/framework/util.py @@ -22,7 +22,7 @@ def get_ckb_configs(p2p_port, rpc_port, spec='{ file = "dev.toml" }'): 'ckb_network_listen_addresses': ["/ip4/0.0.0.0/tcp/{p2p_port}".format(p2p_port=p2p_port)], 'ckb_rpc_listen_address': '127.0.0.1:{rpc_port}'.format(rpc_port=rpc_port), 'ckb_rpc_modules': ["Net", "Pool", "Miner", "Chain", "Stats", "Subscription", "Experiment", "Debug", - "IntegrationTest","Indexer"], + "IntegrationTest", "Indexer"], 'ckb_block_assembler_code_hash': '0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8', 'ckb_block_assembler_args': '0x8883a512ee2383c01574a328f60eeccbb4d78240', 'ckb_block_assembler_hash_type': 'type', @@ -57,7 +57,7 @@ def create_config_file(config_values, template_path, output_file): f.write(output) -def run_command(cmd,check_exit_code=True): +def run_command(cmd, check_exit_code=True): if cmd[-1] == "&": cmd1 = "{cmd} echo $! > pid.txt".format(cmd=cmd) print("cmd:{cmd}".format(cmd=cmd1)) @@ -82,12 +82,13 @@ def run_command(cmd,check_exit_code=True): process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) stdout, stderr = process.communicate() exit_code = process.returncode - if not check_exit_code: - return exit_code + if exit_code != 0: print("Command failed with exit code:", exit_code) if stderr: print("Error:", stderr.decode('utf-8')) + if not check_exit_code: + return exit_code raise Exception(stderr.decode('utf-8')) if stderr.decode('utf-8') != "" and stdout.decode('utf-8') != "": print("wain:{result}".format(result=stderr.decode('utf-8'))) @@ -97,7 +98,6 @@ def run_command(cmd,check_exit_code=True): return stdout.decode('utf-8') - def get_project_root(): current_path = os.path.dirname(os.path.abspath(__file__)) pattern = r"(.*ckb-py-integration-test)" diff --git a/requirements.txt b/requirements.txt index 03db359..2c10de7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,4 +6,5 @@ pytest-html==3.2.0 PyYAML==6.0 pytest-docs==0.1.0 parameterized==0.9.0 -toml==0.10.2 \ No newline at end of file +toml==0.10.2 +websocket-client==1.6.4 \ No newline at end of file diff --git a/test_cases/replace_rpc/test_rpc.py b/test_cases/replace_rpc/test_rpc.py new file mode 100644 index 0000000..63daf3b --- /dev/null +++ b/test_cases/replace_rpc/test_rpc.py @@ -0,0 +1,191 @@ +import pytest + +from framework.basic import CkbTest +from framework.util import run_command + + +class TestRpc(CkbTest): + + @classmethod + def setup_class(cls): + cls.node113 = cls.CkbNode.init_dev_by_port(cls.CkbNodeConfigPath.CURRENT_TEST, "telnet/node", 8114, 8115) + cls.node113.prepare(other_ckb_config={"ckb_tcp_listen_address": "127.0.0.1:18114", + "ckb_ws_listen_address": "127.0.0.1:18124"}) + + cls.node112 = cls.CkbNode.init_dev_by_port(cls.CkbNodeConfigPath.V112, "telnet/node2", 8116, 8117) + cls.node112.prepare(other_ckb_config={"ckb_tcp_listen_address": "127.0.0.1:18115", + "ckb_ws_listen_address": "127.0.0.1:18125"}) + cls.node112.start() + cls.node113.start() + cls.node112.connected(cls.node113) + cls.Miner.make_tip_height_number(cls.node113, 100) + + @classmethod + def teardown_class(cls): + print("teardown_class") + # cls.node112.stop() + # cls.node112.clean() + # cls.node113.stop() + # cls.node113.clean() + + def test_without_header(self): + """ + 112: need application/json + 113: not need + """ + ret113 = run_command( + """curl -X POST -d '[{"jsonrpc": "2.0", "method": "ping_peers", "params": [], "id": "1"}]' """ + f"""{self.node113.rpcUrl}/ """) + assert "null" in ret113 + ret = run_command( + """curl -X POST -d '[{"jsonrpc": "2.0", "method": "ping_peers", "params": [], "id": "1"}]' """ + f"""{self.node112.rpcUrl}/ """) + assert "Content-Type: application/json is required" in ret + + def test_01_with_error(self): + """ + {"id": 42, "jsonrpc": "2.0", "method": "get_block_by_number", "params": ["0", null, null]} + 112:{"jsonrpc": "2.0", "error": {"code": -32602, "message": "Invalid params: Invalid Uint64 0: without `0x` prefix."}, "id": 42} + 113:{"jsonrpc": "2.0", "error": {"code": -32602, "message": "Invalid parameter for `block_number`: Invalid Uint64 0: without `0x` prefix"}, "id": 42} + """ + with pytest.raises(Exception) as exc_info: + ret = self.node112.getClient().get_block_by_number("0") + expected_error_message = "Invalid params: Invalid Uint64 0: without `0x` prefix" + 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]}'" + + with pytest.raises(Exception) as exc_info: + ret = self.node113.getClient().get_block_by_number("0") + expected_error_message = "Invalid parameter for `block_number`: Invalid Uint64 0: without `0x` prefix" + 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]}'" + + pass + + def test_01_with_error_2(self): + """ + {"jsonrpc": "2.0", "method": "dry_run_transaction", "params": [{}], "id": "1"} + 112:{"jsonrpc": "2.0", "error": {"code": -32602, "message": "message":"Invalid params: missing field `version`."}, "id": 42} + 113:{"jsonrpc": "2.0", "error": {"code": -32602, "message": "message":"Invalid params: missing field `version`."}, "id": 42} + """ + with pytest.raises(Exception) as exc_info: + ret = self.node112.getClient().get_block_by_number("0") + expected_error_message = "Invalid params: Invalid Uint64 0: without `0x` prefix" + 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]}'" + + with pytest.raises(Exception) as exc_info: + ret = self.node113.getClient().get_block_by_number("0") + expected_error_message = "" + 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]}'" + + + def test_max_response(self): + """ + batch get_block_by_number count:922 + 112: successful + 113: successful + batch get_block_by_number count:923 + 112:failed + 113:failed + """ + # 测试返回数据上限 + rpcUrls = [self.node112.rpcUrl, self.node113.rpcUrl] + for rpcUrl in rpcUrls: + requestBody = "" + for i in range(922): + requestBody = requestBody + """{"jsonrpc": "2.0", "method": "get_block_by_number", "params": ["0x0"], + "id": "1"},""" + requestBody = requestBody[:-1] + requests = """curl -vvv -X POST -H "Content-Type: application/json" -d '[""" + str( + requestBody) + f"""]' {rpcUrl} > /tmp/null""" + run_command(requests) + run_command("rm -rf /tmp/null") + + for rpcUrl in rpcUrls: + requestBody = "" + for i in range(923): + requestBody = requestBody + """{"jsonrpc": "2.0", "method": "get_block_by_number", "params": ["0x0"], + "id": "1"},""" + requestBody = requestBody[:-1] + requests = """curl -vvv -X POST -H "Content-Type: application/json" -d '[""" + str( + requestBody) + f"""]' {rpcUrl} > /tmp/null""" + with pytest.raises(Exception) as exc_info: + run_command(requests) + expected_error_message = "Empty reply from server" + 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]}'" + + def test_max_batch_count(self): + """ + batch send count :15376 + 112: successful + 113: successful + batch send count :15377 + 112: failed + 113: failed + """ + rpcUrls = [ + self.node112.rpcUrl, + self.node113.rpcUrl + ] + for rpcUrl in rpcUrls: + requestBody = "" + for i in range(15376): + requestBody = requestBody + """{"jsonrpc": "2.0", "method": "ping_peers", "params": [], "id": "1"},""" + requestBody = requestBody[:-1] + requests = """curl -vvv -X POST -H "Content-Type: application/json" -d '[""" + str( + requestBody) + f"""]' {rpcUrl}""" + run_command(requests) + for i in range(15378): + requestBody = requestBody + """{"jsonrpc": "2.0", "method": "ping_peers", "params": [], "id": "1"},""" + requestBody = requestBody[:-1] + requests = """curl -vvv -X POST -H "Content-Type: application/json" -d '[""" + str( + requestBody) + f"""]' {rpcUrl}""" + + with pytest.raises(Exception) as exc_info: + run_command(requests) + expected_error_message = "Argument list too long" + assert expected_error_message in exc_info.value.args[1], \ + f"Expected substring '{expected_error_message}' not found in actual string '{exc_info.value.args[0]}'" + + @pytest.mark.skip + def test_websocket(self): + """ + support websocket + 112: not support,Handshake status 405 Method Not Allowed + 113: not support,Handshake status 500 Internal Server Error + """ + # 112: not support,Handshake status 405 Method Not Allowed + with pytest.raises(Exception) as exc_info: + socket = self.node112.subscribe_websocket("new_tip_header", self.node112.rpcUrl.replace("http://", "")) + expected_error_message = "Handshake status 405 Method Not Allowed" + 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]}'" + + # 113 support + with pytest.raises(Exception) as exc_info: + socket = self.node113.subscribe_websocket("new_tip_header", self.node113.rpcUrl.replace("http://", "")) + expected_error_message = "Handshake status 500 Internal Server Error" + 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]}'" + + @pytest.mark.skip + def test_telnet(self): + """ + support telnet + 112: not + 113: not + """ + socket = self.node112.subscribe_telnet("new_tip_header", self.node112.rpcUrl.replace("http://", "")) + with pytest.raises(Exception) as exc_info: + socket.read_very_eager() + expected_error_message = "telnet connection closed" + 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]}'" + + socket = self.node113.subscribe_telnet("new_tip_header", self.node113.rpcUrl.replace("http://", "")) + with pytest.raises(Exception) as exc_info: + socket.read_very_eager() + expected_error_message = "telnet connection closed" + 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]}'" \ No newline at end of file diff --git a/test_cases/replace_rpc/test_sub_telnet_with_websocket.py b/test_cases/replace_rpc/test_sub_telnet_with_websocket.py new file mode 100644 index 0000000..b6e87b3 --- /dev/null +++ b/test_cases/replace_rpc/test_sub_telnet_with_websocket.py @@ -0,0 +1,215 @@ +import json +import time + +from framework.basic import CkbTest + + +class TestTelnetAndWebsocket(CkbTest): + + @classmethod + def setup_class(cls): + cls.node113 = cls.CkbNode.init_dev_by_port(cls.CkbNodeConfigPath.CURRENT_TEST, "telnet/node", 8119, 8129) + cls.node113.prepare( + other_ckb_config={ + "ckb_logger_filter": "debug", + "ckb_tcp_listen_address": "127.0.0.1:18116", + "ckb_ws_listen_address": "127.0.0.1:18124"}) + cls.node112 = cls.CkbNode.init_dev_by_port(cls.CkbNodeConfigPath.V112, "telnet/node2", 8126, 8127) + cls.node112.prepare(other_ckb_config={ + "ckb_logger_filter": "debug", + "ckb_tcp_listen_address": "127.0.0.1:18115", + "ckb_ws_listen_address": "127.0.0.1:18125"}) + cls.node112.start() + cls.node113.start() + cls.node112.connected(cls.node113) + cls.Miner.make_tip_height_number(cls.node113, 100) + cls.Node.wait_node_height(cls.node112, 100, 1000) + + @classmethod + def teardown_class(cls): + cls.node112.stop() + cls.node112.clean() + + cls.node113.stop() + cls.node113.clean() + + def test_01_sub_tip_block_number(self): + telnet_new_tip_header_112 = self.node112.subscribe_telnet("new_tip_header") + telnet_new_tip_header_113 = self.node113.subscribe_telnet("new_tip_header") + ws_new_tip_header_112 = self.node112.subscribe_websocket("new_tip_header") + ws_new_tip_header_113 = self.node113.subscribe_websocket("new_tip_header") + for i in range(10): + self.Miner.miner_with_version(self.node112, "0x0") + telnet_new_tip_header_112_ret = telnet_new_tip_header_112.read_very_eager() + ws_new_tip_header_112_ret = ws_new_tip_header_112.recv() + telnet_new_tip_header_113_ret = telnet_new_tip_header_113.read_very_eager() + ws_new_tip_header_113_ret = ws_new_tip_header_113.recv() + print("telnet_new_tip_header_113_ret:", + json.loads(telnet_new_tip_header_113_ret.decode())['params']['result']) + print("ws_new_tip_header_113_ret:", json.loads(ws_new_tip_header_113_ret)['params']['result']) + assert json.loads(telnet_new_tip_header_113_ret.decode())['params']['result'] == \ + json.loads(ws_new_tip_header_113_ret)['params']['result'] + # print("telnet_new_tip_header_112_ret:", + # json.loads(telnet_new_tip_header_112_ret.decode())['params']['result']) + # assert json.loads(telnet_new_tip_header_112_ret.decode())['params']['result'] == \ + # json.loads(telnet_new_tip_header_113_ret.decode())['params']['result'] + print("ws_new_tip_header_112_ret:", json.loads(ws_new_tip_header_112_ret)['params']['result']) + assert json.loads(ws_new_tip_header_112_ret)['params']['result'] == \ + json.loads(ws_new_tip_header_113_ret)['params']['result'] + telnet_new_tip_header_112.close() + telnet_new_tip_header_113.close() + ws_new_tip_header_112.close() + ws_new_tip_header_113.close() + + def test_02_sub_new_tip_block(self): + telnet_new_tip_block_112 = self.node112.subscribe_telnet("new_tip_block") + telnet_new_tip_block_113 = self.node113.subscribe_telnet("new_tip_block") + ws_new_tip_block_112 = self.node112.subscribe_websocket("new_tip_block") + ws_new_tip_block_113 = self.node113.subscribe_websocket("new_tip_block") + for i in range(10): + self.Miner.miner_with_version(self.node112, "0x0") + telnet_new_tip_block_112_ret = telnet_new_tip_block_112.read_very_eager() + ws_new_tip_block_112_ret = ws_new_tip_block_112.recv() + telnet_new_tip_block_113_ret = telnet_new_tip_block_113.read_very_eager() + ws_new_tip_block_113_ret = ws_new_tip_block_113.recv() + # print("telnet_new_tip_block_112_ret:", json.loads(telnet_new_tip_block_112_ret)['params']['result']) + print("ws_new_tip_block_112_ret:", json.loads(ws_new_tip_block_112_ret)['params']['result']) + print("telnet_new_tip_block_113_ret:", json.loads(telnet_new_tip_block_113_ret)['params']['result']) + print("ws_new_tip_block_113_ret:", json.loads(ws_new_tip_block_113_ret)['params']['result']) + assert json.loads(ws_new_tip_block_112_ret)['params']['result'] == \ + json.loads(telnet_new_tip_block_113_ret)['params']['result'] + assert json.loads(ws_new_tip_block_112_ret)['params']['result'] == \ + json.loads(ws_new_tip_block_113_ret)['params']['result'] + telnet_new_tip_block_112.close() + telnet_new_tip_block_113.close() + ws_new_tip_block_112.close() + ws_new_tip_block_113.close() + + def test_03_sub_new_tx(self): + telnet_new_tx_112 = self.node112.subscribe_telnet("new_transaction") + ws_new_tx_112 = self.node112.subscribe_websocket("new_transaction") + telnet_new_tx_113 = self.node113.subscribe_telnet("new_transaction") + ws_new_tx_113 = self.node113.subscribe_websocket("new_transaction") + account1 = self.Ckb_cli.util_key_info_by_private_key(self.Config.ACCOUNT_PRIVATE_1) + + for i in range(1): + tx_hash = self.Ckb_cli.wallet_transfer_by_private_key( + self.Config.MINER_PRIVATE_1, + account1['address']['testnet'], + 140, + self.node113.client.url) + self.Miner.miner_until_tx_committed(self.node113, tx_hash) + telnet_new_tx_113_ret = telnet_new_tx_113.read_very_eager() + telnet_new_tx_112_ret = telnet_new_tx_112.read_very_eager() + ws_new_tx_113_ret = ws_new_tx_113.recv() + ws_new_tx_112_ret = ws_new_tx_112.recv() + print("telnet_new_tx_113_ret:", telnet_new_tx_113_ret) + print("ws_new_tx_113_ret:", ws_new_tx_113_ret) + # print("telnet_new_tx_112_ret:", telnet_new_tx_112_ret) + print("ws_new_tx_112_ret:", ws_new_tx_112_ret) + assert len(json.loads(telnet_new_tx_113_ret.decode())['params']['result']) == \ + len(json.loads(ws_new_tx_113_ret)['params']['result']) + assert len(json.loads(telnet_new_tx_113_ret.decode())['params']['result']) == \ + len(json.loads(ws_new_tx_112_ret)['params']['result']) + telnet_new_tx_112.close() + ws_new_tx_112.close() + telnet_new_tx_113.close() + ws_new_tx_113.close() + + def test_04_sub_proposal_tx(self): + telnet_new_tx_112 = self.node112.subscribe_telnet("proposed_transaction") + ws_new_tx_112 = self.node112.subscribe_websocket("proposed_transaction") + telnet_new_tx_113 = self.node113.subscribe_telnet("proposed_transaction") + ws_new_tx_113 = self.node113.subscribe_websocket("proposed_transaction") + account1 = self.Ckb_cli.util_key_info_by_private_key(self.Config.ACCOUNT_PRIVATE_1) + for i in range(1): + tx_hash = self.Ckb_cli.wallet_transfer_by_private_key( + self.Config.MINER_PRIVATE_1, + account1['address']['testnet'], + 140, + self.node113.client.url) + + self.Miner.miner_until_tx_committed(self.node113, tx_hash) + telnet_new_tx_113_ret = telnet_new_tx_113.read_very_eager() + telnet_new_tx_112_ret = telnet_new_tx_112.read_very_eager() + ws_new_tx_113_ret = ws_new_tx_113.recv() + ws_new_tx_112_ret = ws_new_tx_112.recv() + print("telnet_new_tx_113_ret:", telnet_new_tx_113_ret) + print("ws_new_tx_113_ret:", ws_new_tx_113_ret) + # print("telnet_new_tx_112_ret:", telnet_new_tx_112_ret) + print("ws_new_tx_112_ret:", ws_new_tx_112_ret) + print("json:", json.loads(telnet_new_tx_113_ret.decode())['params']['result']) + assert len(json.loads(telnet_new_tx_113_ret.decode())['params']['result']) == \ + len(json.loads(ws_new_tx_113_ret)['params']['result']) + assert len(json.loads(telnet_new_tx_113_ret.decode())['params']['result']) == \ + len(json.loads(ws_new_tx_112_ret)['params']['result']) + telnet_new_tx_112.close() + ws_new_tx_112.close() + telnet_new_tx_113.close() + ws_new_tx_113.close() + + def test_05_reject_tx(self): + telnet_new_tx_112 = self.node112.subscribe_telnet("rejected_transaction") + ws_new_tx_112 = self.node112.subscribe_websocket("rejected_transaction") + telnet_new_tx_113 = self.node113.subscribe_telnet("rejected_transaction") + ws_new_tx_113 = self.node113.subscribe_websocket("rejected_transaction") + account1 = self.Ckb_cli.util_key_info_by_private_key(self.Config.ACCOUNT_PRIVATE_1) + for i in range(1): + tx_hash = self.Ckb_cli.wallet_transfer_by_private_key( + self.Config.MINER_PRIVATE_1, + account1['address']['testnet'], + 151, + self.node113.client.url) + time.sleep(3) + tx_hash = self.Ckb_cli.wallet_transfer_by_private_key( + self.Config.MINER_PRIVATE_1, + account1['address']['testnet'], + 151000, + self.node113.client.url, "10000") + + tx_hash = self.Ckb_cli.wallet_transfer_by_private_key( + self.Config.MINER_PRIVATE_1, + account1['address']['testnet'], + 151000, + self.node113.client.url, "100000") + + ws_new_tx_113_ret = ws_new_tx_113.recv() + print("ws_new_tx_113_ret:", ws_new_tx_113_ret) + + telnet_new_tx_113_ret = telnet_new_tx_113.read_very_eager() + print("telnet_new_tx_113_ret:", telnet_new_tx_113_ret) + + # telnet_new_tx_112_ret = telnet_new_tx_112.read_very_eager() + # print("telnet_new_tx_112_ret:", telnet_new_tx_112_ret) + + ws_new_tx_112_ret = ws_new_tx_112.recv() + print("ws_new_tx_112_ret:",ws_new_tx_112_ret) + + # assert len(json.loads(telnet_new_tx_113_ret.decode())['params']['result']) == \ + # len(json.loads(ws_new_tx_113_ret)['params']['result']) + # assert len(json.loads(telnet_new_tx_113_ret.decode())['params']['result']) == \ + # len(json.loads(ws_new_tx_112_ret)['params']['result']) + telnet_new_tx_112.close() + ws_new_tx_112.close() + telnet_new_tx_113.close() + ws_new_tx_113.close() + pass + + # //{"id": 2, "jsonrpc": "2.0", "method": "subscribe", "params": ["new_tip_block"]} + # def test_sub_max_11(self): + # topic = "new_tip_block" + # + # topic_str = '{"id": 2, "jsonrpc": "2.0", "method": "subscribe", "params": ["' + topic + '"]}' + # # topic_str = '' + # # for i in range(1): + # # topic_str = topic_str+topic_str1 + "\n" + # tns = [] + # for i in range(1000): + # tn = self.node113.subscribe_telnet("new_tip_block") + # tns.append(tn) + # for i in range(10000000): + # for tn in tns: + # tn.write(topic_str.encode('utf-8') + b"\n") + # # data = tn.read_until(b'}\n') + # # print(str(i) + ":", data) + # print("i:", i) diff --git a/test_cases/replace_rpc/test_telnet.py b/test_cases/replace_rpc/test_telnet.py new file mode 100644 index 0000000..04e8e9e --- /dev/null +++ b/test_cases/replace_rpc/test_telnet.py @@ -0,0 +1,165 @@ +import time + +import pytest + +from framework.basic import CkbTest +from framework.util import run_command + + +class TestRpc(CkbTest): + + @classmethod + def setup_class(cls): + cls.node113 = cls.CkbNode.init_dev_by_port(cls.CkbNodeConfigPath.CURRENT_TEST, "telnet/node", 8114, 8115) + cls.node113.prepare(other_ckb_config={ + "ckb_logger_filter": "debug", + "ckb_tcp_listen_address": "127.0.0.1:18115", + "ckb_ws_listen_address": "127.0.0.1:18124" + }) + cls.node112 = cls.CkbNode.init_dev_by_port(cls.CkbNodeConfigPath.V112, "telnet/node2", 8116, 8117) + cls.node112.prepare(other_ckb_config={ + "ckb_tcp_listen_address": "127.0.0.1:18114" + }) + cls.node112.start() + cls.node113.start() + cls.node112.connected(cls.node113) + cls.Miner.make_tip_height_number(cls.node113, 100) + cls.Node.wait_node_height(cls.node112, 90, 1000) + + @classmethod + def teardown_class(cls): + cls.node112.stop() + cls.node112.clean() + + cls.node113.stop() + cls.node113.clean() + + + def test_link_count_max(self): + """ + link tcp + 112: 1022 + 113: > 10234 + """ + telnets = [] + for i in range(1000): + print(i) + telnet = self.node112.subscribe_telnet("new_tip_header") + telnets.append(telnet) + + self.Miner.miner_with_version(self.node112, "0x0") + time.sleep(1) + for i in range(len(telnets)): + telnet = telnets[i] + ret = telnet.read_very_eager() + print(ret) + print(i, ':', len(ret)) + assert len(ret) > 700 + telnet.close() + + # test 113 max link count + telnets = [] + for i in range(10000): + print(i) + telnet = self.node113.subscribe_telnet("new_tip_header") + telnets.append(telnet) + + self.Miner.miner_with_version(self.node113, "0x0") + for i in range(len(telnets)): + telnet = telnets[i] + ret = telnet.read_very_eager() + print(i, ':', len(ret)) + assert len(ret) > 700 + telnet.close() + + def test_link_time_max(self): + """ + link time + 112: keep link + 113: keep link + """ + telnet113 = self.node113.subscribe_telnet("new_tip_header") + telnet112 = self.node112.subscribe_telnet("new_tip_header") + + for i in range(300): + self.Miner.miner_with_version(self.node113, "0x0") + print("current idx:", i) + ret113 = telnet113.read_very_eager() + ret112 = telnet112.read_very_eager() + print(ret113) + print(ret112) + time.sleep(1) + telnet113.close() + telnet112.close() + + def test_link_websocket(self): + """ + support websocket + 112: not support + 113: not support + """ + with pytest.raises(Exception) as exc_info: + socket = self.node112.subscribe_websocket("new_tip_header", + self.node112.ckb_config['ckb_tcp_listen_address']) + expected_error_message = "invalid literal for int() with base 10" + 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]}'" + + with pytest.raises(Exception) as exc_info: + socket = self.node113.subscribe_websocket("new_tip_header", + self.node113.ckb_config['ckb_tcp_listen_address']) + expected_error_message = "invalid literal for int() with base 10" + 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]}'" + + def test_rpc(self): + """ + support rpc + 112: not support + 113: not support + """ + client = self.node112.getClient() + client.url = f"http://{self.node112.ckb_config['ckb_tcp_listen_address']}" + + with pytest.raises(Exception) as exc_info: + response = client.call("get_tip_block_number", [], 1) + expected_error_message = "request time out" + 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]}'" + + client = self.node113.getClient() + client.url = f"http://{self.node113.ckb_config['ckb_tcp_listen_address']}" + + with pytest.raises(Exception) as exc_info: + response = client.call("get_tip_block_number", [], 1) + expected_error_message = "request time out" + 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]}'" + + def test_stop_node_when_link_telnet(self): + """ + stop ckb when socker is keep live + 112: stop successful + 113: stop successful + """ + self.node112.restart() + socket = self.node112.subscribe_telnet("new_tip_header") + self.node112.stop() + port = self.node112.ckb_config['ckb_tcp_listen_address'].split(":")[-1] + ret = run_command(f"lsof -i:{port} | grep ckb", check_exit_code=False) + assert "ckb" not in str(ret) + socket.close() + ret = run_command(f"lsof -i:{port} | grep ckb", check_exit_code=False) + assert "ckb" not in str(ret) + + self.node113.restart() + socket = self.node113.subscribe_telnet("new_tip_header") + self.node113.stop() + port = self.node113.ckb_config['ckb_tcp_listen_address'].split(":")[-1] + ret = run_command(f"lsof -i:{port} | grep ckb", check_exit_code=False) + assert "ckb" not in str(ret) + socket.close() + ret = run_command(f"lsof -i:{port} | grep ckb", check_exit_code=False) + assert "ckb" not in str(ret) + self.node112.restart() + self.node113.restart() diff --git a/test_cases/replace_rpc/test_websocket.py b/test_cases/replace_rpc/test_websocket.py new file mode 100644 index 0000000..b72e5cc --- /dev/null +++ b/test_cases/replace_rpc/test_websocket.py @@ -0,0 +1,162 @@ +import time + +import pytest + +from framework.basic import CkbTest +from framework.util import run_command + + +class TestWebsocket(CkbTest): + + @classmethod + def setup_class(cls): + cls.node113 = cls.CkbNode.init_dev_by_port(cls.CkbNodeConfigPath.CURRENT_TEST, "telnet/node", 8114, 8115) + cls.node113.prepare( + other_ckb_config={ + "ckb_logger_filter": "debug", + "ckb_tcp_listen_address": "127.0.0.1:18114", + "ckb_ws_listen_address": "127.0.0.1:18124"}) + cls.node112 = cls.CkbNode.init_dev_by_port(cls.CkbNodeConfigPath.V112, "telnet/node2", 8116, 8117) + cls.node112.prepare(other_ckb_config={ + "ckb_logger_filter": "debug", + "ckb_tcp_listen_address": "127.0.0.1:18115", + "ckb_ws_listen_address": "127.0.0.1:18125"}) + cls.node112.start() + cls.node113.start() + cls.node112.connected(cls.node113) + cls.Miner.make_tip_height_number(cls.node113, 100) + cls.Node.wait_node_height(cls.node112, 100, 1000) + + @classmethod + def teardown_class(cls): + cls.node112.stop() + cls.node112.clean() + + cls.node113.stop() + cls.node113.clean() + + def test_link_count_max(self): + + """ + link tcp + 112: 1022 + 113: > 10234 + """ + # test 112 max link count + websockets = [] + for i in range(100): + print(i) + websocket = self.node112.subscribe_websocket("new_tip_header") + websockets.append(websocket) + + self.Miner.miner_with_version(self.node112, "0x0") + for i in range(len(websockets)): + websocket = websockets[i] + ret = websocket.recv() + print(i, ':', len(ret)) + websocket.close() + + # test 113 max link count + websockets = [] + for i in range(10000): + print(i) + websocket = self.node113.subscribe_websocket("new_tip_header") + websockets.append(websocket) + + self.Miner.miner_with_version(self.node113, "0x0") + for i in range(len(websockets)): + websocket = websockets[i] + ret = websocket.recv() + print(i, ':', len(ret)) + websocket.close() + + def test_link_time_max(self): + """ + link time + 112: keep link + 113: keep link + """ + websocket112 = self.node112.subscribe_websocket("new_tip_header") + websocket113 = self.node113.subscribe_websocket("new_tip_header") + + for i in range(300): + self.Miner.miner_with_version(self.node113, "0x0") + print("current idx:", i) + ret112 = websocket112.recv() + ret113 = websocket113.recv() + print(ret112) + assert len(ret112) > 0 + assert len(ret113) > 0 + print(ret113) + time.sleep(1) + websocket113.close() + websocket112.close() + def test_rpc(self): + """ + support rpc + 112: not support + 113: support + """ + client = self.node112.getClient() + client.url = f"http://{self.node112.ckb_config['ckb_ws_listen_address']}" + + with pytest.raises(Exception) as exc_info: + response = client.call("get_tip_block_number", [], 1) + expected_error_message = "Expecting value: line 1 column 1" + 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]}'" + + client = self.node113.getClient() + client.url = f"http://{self.node113.ckb_config['ckb_ws_listen_address']}" + + response = client.call("get_tip_block_number", [], 1) + + # with pytest.raises(Exception) as exc_info: + # response = client.call("get_tip_block_number", [], 1) + # expected_error_message = "request time out" + # 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]}'" + + def test_telnet(self): + socket = self.node112.subscribe_telnet("new_tip_header", self.node112.ckb_config['ckb_ws_listen_address']) + with pytest.raises(Exception) as exc_info: + socket.read_very_eager() + expected_error_message = "telnet connection closed" + 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]}'" + + socket = self.node113.subscribe_telnet("new_tip_header", self.node112.ckb_config['ckb_ws_listen_address']) + with pytest.raises(Exception) as exc_info: + socket.read_very_eager() + expected_error_message = "telnet connection closed" + 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]}'" + + + def test_stop_node_when_link_websocket(self): + """ + stop ckb when socker is keep live + 112: stop successful + 113: stop failed + """ + self.node112.restart() + socket = self.node112.subscribe_websocket("new_tip_header") + self.node112.stop() + port = self.node112.ckb_config['ckb_ws_listen_address'].split(":")[-1] + ret = run_command(f"lsof -i:{port} | grep ckb", check_exit_code=False) + assert "ckb" not in str(ret) + socket.close() + ret = run_command(f"lsof -i:{port} | grep ckb", check_exit_code=False) + assert "ckb" not in str(ret) + + self.node113.restart() + socket = self.node113.subscribe_websocket("new_tip_header") + self.node113.stop() + port = self.node113.ckb_config['ckb_ws_listen_address'].split(":")[-1] + ret = run_command(f"lsof -i:{port} | grep ckb", check_exit_code=False) + assert "ckb" not in str(ret) + socket.close() + ret = run_command(f"lsof -i:{port} | grep ckb", check_exit_code=False) + assert "ckb" not in str(ret) + self.node112.restart() + self.node113.restart() From 62f55c570069278ee45c2510d8fe14eddbf2a809 Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Wed, 20 Dec 2023 13:42:00 +0800 Subject: [PATCH 03/27] support v113 --- Makefile | 1 + download.py | 2 +- download_ckb_light_client.py | 2 +- framework/ckb_light_client_rpc.py | 31 ++++ framework/test_light_client.py | 6 +- framework/test_node.py | 13 +- source/template/ckb/v112/ckb.toml.j2 | 10 +- test_cases/ckb2023/test_01_before_hardfork.py | 3 +- ...test_03_ckb_light_client_after_hardfork.py | 108 ++++++++----- ...t_ckb_disconnect_fetch_transaction_solo.py | 2 +- .../test_after_ckb_2023_hardfork.py | 146 ++++++++++-------- test_cases/replace_rpc/test_rpc.py | 8 +- .../test_02_txs_lifecycle_chain.py | 10 -- 13 files changed, 208 insertions(+), 134 deletions(-) diff --git a/Makefile b/Makefile index 4881ec9..34bd856 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ check_failed_html: exit 1; \ fi test: + bash test.sh test_cases/replace_rpc bash test.sh test_cases/ckb2023 bash test.sh test_cases/ckb_cli bash test.sh test_cases/contracts diff --git a/download.py b/download.py index 7528255..4792996 100644 --- a/download.py +++ b/download.py @@ -11,7 +11,7 @@ import requests from tqdm import tqdm -versions = ['0.109.0', '0.110.2', '0.111.0', '0.112.1'] # Replace with your versions +versions = ['0.109.0', '0.110.2', '0.111.0', '0.112.1', '0.113.0-rc1'] # Replace with your versions DOWNLOAD_DIR = "download" SYSTEMS = { 'Windows': { diff --git a/download_ckb_light_client.py b/download_ckb_light_client.py index abba7d4..345725d 100644 --- a/download_ckb_light_client.py +++ b/download_ckb_light_client.py @@ -11,7 +11,7 @@ import requests from tqdm import tqdm -versions = ['0.2.4', '0.3.0', '0.3.1'] # Replace with your versions +versions = ['0.2.4', '0.3.0', '0.3.1', '0.3.2'] # Replace with your versions DOWNLOAD_DIR = "download" SYSTEMS = { 'Windows': { diff --git a/framework/ckb_light_client_rpc.py b/framework/ckb_light_client_rpc.py index da08bf4..57a0d9c 100644 --- a/framework/ckb_light_client_rpc.py +++ b/framework/ckb_light_client_rpc.py @@ -19,9 +19,14 @@ def get_scripts(self): def get_cells_capacity(self, script): return self.call("get_cells_capacity", [script]) + def get_cells(self, search_key, order, limit, after): + return self.call2("get_cells", [search_key, order, limit, after]) + def fetch_transaction(self, tx_hash): return self.call("fetch_transaction", [tx_hash]) + def get_transactions(self, search_key, order, limit, after): + return self.call("get_transactions", [search_key, order, limit, after]) def send_transaction(self,tx): return self.call("send_transaction",[tx]) @@ -54,3 +59,29 @@ def call(self, method, params): time.sleep(2) continue raise Exception("request time out") + + def call2(self, method, params): + + headers = {'content-type': 'application/json'} + data = { + "id": 42, + "jsonrpc": "2.0", + "method": method, + "params": params + } + print("request:url:{url},data:\n{data}".format(url=self.url, data=json.dumps(data))) + for i in range(100): + try: + response = requests.post(self.url, data=json.dumps(data), headers=headers).json() + # print("response:\n{response}".format(response=json.dumps(response))) + if 'error' in response.keys(): + error_message = response['error'].get('message', 'Unknown error') + raise Exception(f"Error: {error_message}") + + return response.get('result', None) + except requests.exceptions.ConnectionError as e: + print(e) + print("request too quickly, wait 2s") + time.sleep(2) + continue + raise Exception("request time out") diff --git a/framework/test_light_client.py b/framework/test_light_client.py index 384faeb..294fcf8 100644 --- a/framework/test_light_client.py +++ b/framework/test_light_client.py @@ -9,7 +9,8 @@ class CkbLightClientConfigPath(Enum): V0_2_4 = ("source/template/ckb_light_client/0.2.4/testnet.toml.j2", "download/0.2.4/ckb-light-client") V0_3_0 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.0/ckb-light-client") V0_3_1 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.1/ckb-light-client") - CURRENT_TEST = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.1/ckb-light-client") + V0_3_2 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.2/ckb-light-client") + CURRENT_TEST = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.2/ckb-light-client") def __init__(self, ckb_light_client_config_path, ckb_light_bin_path): self.ckb_light_client_config_path = ckb_light_client_config_path @@ -31,7 +32,8 @@ def __init__(self, ckb_light_client_config_path: CkbLightClientConfigPath, ckb_p self.ckb_light_config = { "ckb_light_client_chain": ckb_spec_path, "ckb_light_client_network_bootnodes": ckb_p2p_infos, - "ckb_light_client_rpc_listen_address": f"127.0.0.1:{rpc_port}" + "ckb_light_client_rpc_listen_address": f"127.0.0.1:{rpc_port}", + "ckb_light_client_network_listen_addresses": [f"/ip4/0.0.0.0/tcp/1{rpc_port}"] } self.ckb_light_config_path = f"{self.tmp_path}/testnet.toml" self.client = CKBLightRPCClient(f"http://127.0.0.1:{rpc_port}") diff --git a/framework/test_node.py b/framework/test_node.py index 04e8b77..94cd62e 100644 --- a/framework/test_node.py +++ b/framework/test_node.py @@ -18,8 +18,8 @@ class CkbNodeConfigPath(Enum): V113 = ( "source/template/ckb/v113/ckb.toml.j2", - "source/template/ckb/v112/ckb-miner.toml.j2", - "source/template/ckb/v112/specs/dev.toml", + "source/template/ckb/v113/ckb-miner.toml.j2", + "source/template/ckb/v113/specs/dev.toml", "download/0.113.0" ) @@ -30,10 +30,17 @@ class CkbNodeConfigPath(Enum): "download/0.112.1" ) + V112_MAIN = ( + "source/template/ckb/v112/ckb.toml.j2", + "source/template/ckb/v112/ckb-miner.toml.j2", + "source/template/specs/mainnet.toml.j2", + "download/0.112.1" + ) + CURRENT_MAIN = ("source/template/ckb/v112/ckb.toml.j2", "source/template/ckb/v112/ckb-miner.toml.j2", "source/template/specs/mainnet.toml.j2", - "download/0.112.1") + "download/0.113.0") V111 = ( "source/template/ckb/v111/ckb.toml.j2", "source/template/ckb/v111/ckb-miner.toml.j2", diff --git a/source/template/ckb/v112/ckb.toml.j2 b/source/template/ckb/v112/ckb.toml.j2 index ee0951e..7ac0464 100644 --- a/source/template/ckb/v112/ckb.toml.j2 +++ b/source/template/ckb/v112/ckb.toml.j2 @@ -94,8 +94,14 @@ max_request_body_size = {{ ckb_rpc_max_request_body_size | default(10485760) }} modules = {{ ckb_rpc_modules | to_json }} # By default RPC only binds to HTTP service, you can bind it to TCP and WebSocket. -# tcp_listen_address = "127.0.0.1:18114" -# ws_listen_address = "127.0.0.1:28114" +#{% if ckb_tcp_listen_address is defined %} +tcp_listen_address = "{{ ckb_tcp_listen_address }}" +#{% endif %} + +#{% if ckb_ws_listen_address is defined %} +ws_listen_address = "{{ ckb_ws_listen_address }}" +#{% endif %} + reject_ill_transactions = {{ ckb_rpc_reject_ill_transactions | default("true") }} # By default deprecated rpc methods are disabled. diff --git a/test_cases/ckb2023/test_01_before_hardfork.py b/test_cases/ckb2023/test_01_before_hardfork.py index 1000111..0ccdc12 100644 --- a/test_cases/ckb2023/test_01_before_hardfork.py +++ b/test_cases/ckb2023/test_01_before_hardfork.py @@ -132,8 +132,7 @@ def test_05_0049_transfer_to_data2_address(self): 140, self.cluster.ckb_nodes[0].client.url) print(exc_info) - expected_error_message = "the feature \"VM Version 2\" is used in current transaction " \ - "but not enabled in current chain" + expected_error_message = "the feature \"VM Version 2\" is used in current transaction, but not enabled in current chain" assert expected_error_message in exc_info.value.args[0], \ f"Expected substring '{expected_error_message}'" \ f" not found in actual string '{exc_info.value.args[0]}'" diff --git a/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py b/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py index ce00d43..7679899 100644 --- a/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py +++ b/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py @@ -1,7 +1,7 @@ import os import time - +import pytest from parameterized import parameterized from framework.basic import CkbTest @@ -36,7 +36,8 @@ def get_successful_files(): f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", f"{get_project_root()}/source/contract/test_cases/atomic_i32", f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - # f"{get_project_root()}/source/contract/test_cases/load_block_extension", //TODO wait https://github.com/nervosnetwork/ckb-light-client/pull/156/files + # f"{get_project_root()}/source/contract/test_cases/load_block_extension", + # //TODO wait https://github.com/nervosnetwork/ckb-light-client/pull/156/files ] @@ -62,31 +63,49 @@ def setup_class(cls): cls.Miner.make_tip_height_number(cls.cluster.ckb_nodes[0], 2000) cls.Node.wait_cluster_height(cls.cluster, 2000, 100) - cls.ckb_light_node_0_2_5 = cls.CkbLightClientNode.init_by_nodes(cls.CkbLightClientConfigPath.CURRENT_TEST, - cls.cluster.ckb_nodes, - "tx_pool_light/node1", 8001) + cls.ckb_light_node_current = cls.CkbLightClientNode.init_by_nodes(cls.CkbLightClientConfigPath.CURRENT_TEST, + cls.cluster.ckb_nodes, + "tx_pool_light/node1", 8001) - cls.ckb_light_node_0_2_5.prepare() - cls.ckb_light_node_0_2_5.start() + cls.ckb_light_node_current.prepare() + cls.ckb_light_node_current.start() account = cls.Ckb_cli.util_key_info_by_private_key(cls.Config.MINER_PRIVATE_1) - cls.ckb_light_node_0_2_5.getClient().set_scripts([{"script": { + cls.ckb_light_node_current.getClient().set_scripts([{"script": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "hash_type": "type", "args": account['lock_arg']}, "script_type": "lock", "block_number": "0x0"}]) - cls.Node.wait_light_sync_height(cls.ckb_light_node_0_2_5, 2000, 200) - + cls.Node.wait_light_sync_height(cls.ckb_light_node_current, 2000, 200) @classmethod def teardown_class(cls): print("\nTeardown TestClass1") cls.cluster.stop_all_nodes() cls.cluster.clean_all_nodes() - cls.ckb_light_node_0_2_5.stop() - cls.ckb_light_node_0_2_5.clean() - - def test_01_ckb_light_client_0_2_4_link_node(self): - pass - - def test_02_ckb_light_client_0_2_5_link_node(self): + cls.ckb_light_node_current.stop() + cls.ckb_light_node_current.clean() + + @pytest.mark.skip + def test_01_ckb_light_client_0_3_1_link_node(self): + + version = self.CkbLightClientConfigPath.V0_3_1 + ckb_light_node = self.CkbLightClientNode.init_by_nodes(version, + self.cluster.ckb_nodes, + "tx_pool_light/node2", 8002) + ckb_light_node.prepare() + ckb_light_node.start() + account = self.Ckb_cli.util_key_info_by_private_key(self.Config.MINER_PRIVATE_1) + ckb_light_node.getClient().set_scripts([{"script": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "hash_type": "type", + "args": account['lock_arg']}, "script_type": "lock", "block_number": "0x0"}]) + with pytest.raises(Exception) as exc_info: + self.Node.wait_light_sync_height(ckb_light_node, 2000, 200) + expected_error_message = "time out" + 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]}'" + ckb_light_node.stop() + ckb_light_node.clean() + + @pytest.mark.skip + def test_02_ckb_light_client_current_link_node(self): """ 1. setScript miner account set successful @@ -96,12 +115,13 @@ def test_02_ckb_light_client_0_2_5_link_node(self): """ account = self.Ckb_cli.util_key_info_by_private_key(self.Config.MINER_PRIVATE_1) - self.ckb_light_node_0_2_5.getClient().set_scripts([{"script": { + self.ckb_light_node_current.getClient().set_scripts([{"script": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "hash_type": "type", "args": account['lock_arg']}, "script_type": "lock", "block_number": "0x0"}]) - self.Node.wait_light_sync_height(self.ckb_light_node_0_2_5, 2000, 200) + self.Node.wait_light_sync_height(self.ckb_light_node_current, 2000, 200) - def test_03_ckb_light_client_0_2_5_set_script_data2(self): + @pytest.mark.skip + def test_03_ckb_light_client_current_set_script_data2(self): """ 1. set data2 account sync successful @@ -109,12 +129,13 @@ def test_03_ckb_light_client_0_2_5_set_script_data2(self): """ account = self.Ckb_cli.util_key_info_by_private_key(self.Config.MINER_PRIVATE_1) - self.ckb_light_node_0_2_5.getClient().set_scripts([{"script": { + self.ckb_light_node_current.getClient().set_scripts([{"script": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "hash_type": "data2", "args": account['lock_arg']}, "script_type": "lock", "block_number": "0x0"}]) - self.Node.wait_light_sync_height(self.ckb_light_node_0_2_5, 2000, 200) + self.Node.wait_light_sync_height(self.ckb_light_node_current, 2000, 200) - def test_04_ckb_light_client_0_2_5_transfer_data2_tx(self): + @pytest.mark.skip + def test_04_ckb_light_client_current_transfer_data2_tx(self): """ 1. send data2 tx on the ckb light client send successful ,return tx_hash @@ -123,10 +144,10 @@ def test_04_ckb_light_client_0_2_5_transfer_data2_tx(self): """ self.cluster.ckb_nodes[0].start_miner() account = self.Ckb_cli.util_key_info_by_private_key(self.Config.MINER_PRIVATE_1) - self.ckb_light_node_0_2_5.getClient().set_scripts([{"script": { + self.ckb_light_node_current.getClient().set_scripts([{"script": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "hash_type": "type", "args": account['lock_arg']}, "script_type": "lock", "block_number": "0x0"}]) - self.Node.wait_light_sync_height(self.ckb_light_node_0_2_5, 2000, 200) + self.Node.wait_light_sync_height(self.ckb_light_node_current, 2000, 200) self.cluster.ckb_nodes[0].stop_miner() tx_hash = self.Ckb_cli.wallet_transfer_by_private_key(self.Config.MINER_PRIVATE_1, @@ -137,11 +158,12 @@ def test_04_ckb_light_client_0_2_5_transfer_data2_tx(self): transaction = tx['transaction'] tx_hash = transaction['hash'] del transaction['hash'] - light_tx_hash = self.ckb_light_node_0_2_5.getClient().send_transaction(transaction) + light_tx_hash = self.ckb_light_node_current.getClient().send_transaction(transaction) assert tx_hash == light_tx_hash - def test_05_ckb_light_client_0_2_5_spawn_contract_use_data2(self): + @pytest.mark.skip + def test_05_ckb_light_client_current_spawn_contract_use_data2(self): """ 1. send spawn tx ( hash type : data2), on the ckb light client send successful ,return tx_hash @@ -150,10 +172,10 @@ def test_05_ckb_light_client_0_2_5_spawn_contract_use_data2(self): # send rfc50 tx self.cluster.ckb_nodes[0].start_miner() account = self.Ckb_cli.util_key_info_by_private_key(self.Config.MINER_PRIVATE_1) - self.ckb_light_node_0_2_5.getClient().set_scripts([{"script": { + self.ckb_light_node_current.getClient().set_scripts([{"script": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "hash_type": "type", "args": account['lock_arg']}, "script_type": "lock", "block_number": "0x0"}]) - self.Node.wait_light_sync_height(self.ckb_light_node_0_2_5, 2000, 200) + self.Node.wait_light_sync_height(self.ckb_light_node_current, 2000, 200) self.cluster.ckb_nodes[0].stop_miner() code_tx_hash, code_tx_index = self.spawn_contract.get_deploy_hash_and_index() @@ -162,19 +184,20 @@ def test_05_ckb_light_client_0_2_5_spawn_contract_use_data2(self): invoke_arg, "data2", invoke_data, api_url=self.cluster.ckb_nodes[0].getClient().url) - self.ckb_light_node_0_2_5.getClient().fetch_transaction(code_tx_hash) + self.ckb_light_node_current.getClient().fetch_transaction(code_tx_hash) # TODO wait fetch tx succ time.sleep(5) - self.ckb_light_node_0_2_5.getClient().fetch_transaction(code_tx_hash) + self.ckb_light_node_current.getClient().fetch_transaction(code_tx_hash) tx = self.cluster.ckb_nodes[0].getClient().get_transaction(tx_hash) transaction = tx['transaction'] tx_hash = transaction['hash'] del transaction['hash'] - light_tx_hash = self.ckb_light_node_0_2_5.getClient().send_transaction(transaction) + light_tx_hash = self.ckb_light_node_current.getClient().send_transaction(transaction) assert tx_hash == light_tx_hash - def test_05_ckb_light_client_0_2_5_spawn_contract_use_type(self): + @pytest.mark.skip + def test_05_ckb_light_client_current_spawn_contract_use_type(self): """ 1. send spawn tx ( hash type : type), on the ckb light client send successful ,return tx_hash @@ -183,10 +206,10 @@ def test_05_ckb_light_client_0_2_5_spawn_contract_use_type(self): # send rfc50 tx self.cluster.ckb_nodes[0].start_miner() account = self.Ckb_cli.util_key_info_by_private_key(self.Config.MINER_PRIVATE_1) - self.ckb_light_node_0_2_5.getClient().set_scripts([{"script": { + self.ckb_light_node_current.getClient().set_scripts([{"script": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "hash_type": "type", "args": account['lock_arg']}, "script_type": "lock", "block_number": "0x0"}]) - self.Node.wait_light_sync_height(self.ckb_light_node_0_2_5, 2000, 200) + self.Node.wait_light_sync_height(self.ckb_light_node_current, 2000, 200) self.cluster.ckb_nodes[0].stop_miner() code_tx_hash, code_tx_index = self.spawn_contract.get_deploy_hash_and_index() @@ -195,18 +218,19 @@ def test_05_ckb_light_client_0_2_5_spawn_contract_use_type(self): invoke_arg, "type", invoke_data, api_url=self.cluster.ckb_nodes[0].getClient().url) - self.ckb_light_node_0_2_5.getClient().fetch_transaction(code_tx_hash) + self.ckb_light_node_current.getClient().fetch_transaction(code_tx_hash) time.sleep(5) - self.ckb_light_node_0_2_5.getClient().fetch_transaction(code_tx_hash) + self.ckb_light_node_current.getClient().fetch_transaction(code_tx_hash) tx = self.cluster.ckb_nodes[0].getClient().get_transaction(tx_hash) transaction = tx['transaction'] tx_hash = transaction['hash'] del transaction['hash'] - light_tx_hash = self.ckb_light_node_0_2_5.getClient().send_transaction(transaction) + light_tx_hash = self.ckb_light_node_current.getClient().send_transaction(transaction) assert tx_hash == light_tx_hash - @parameterized.expand(success_files) + @pytest.mark.skip + # @parameterized.expand(success_files) def test_06_ckb_light_client_deploy_and_invoke_contract(self, path): self.cluster.ckb_nodes[0].stop_miner() self.deploy_and_invoke(self.Config.MINER_PRIVATE_1, path, self.cluster.ckb_nodes[0]) @@ -224,8 +248,8 @@ def deploy_and_invoke(self, account, path, node, try_count=5): api_url=node.getClient().url) self.Miner.miner_until_tx_committed(node, deploy_hash) time.sleep(1) - self.ckb_light_node_0_2_5.getClient().fetch_transaction(deploy_hash) - self.Node.wait_light_sync_height(self.ckb_light_node_0_2_5, node.getClient().get_tip_block_number(), 100) + self.ckb_light_node_current.getClient().fetch_transaction(deploy_hash) + self.Node.wait_light_sync_height(self.ckb_light_node_current, node.getClient().get_tip_block_number(), 100) time.sleep(10) invoke_hash = self.Contract.invoke_ckb_contract(account_private=account, contract_out_point_tx_hash=deploy_hash, @@ -237,7 +261,7 @@ def deploy_and_invoke(self, account, path, node, try_count=5): transaction = tx['transaction'] tx_hash = transaction['hash'] del transaction['hash'] - light_tx_hash = self.ckb_light_node_0_2_5.getClient().send_transaction(transaction) + light_tx_hash = self.ckb_light_node_current.getClient().send_transaction(transaction) assert tx_hash == light_tx_hash return invoke_hash except Exception as e: diff --git a/test_cases/light_client/test_ckb_disconnect_fetch_transaction_solo.py b/test_cases/light_client/test_ckb_disconnect_fetch_transaction_solo.py index c2abb89..d152224 100644 --- a/test_cases/light_client/test_ckb_disconnect_fetch_transaction_solo.py +++ b/test_cases/light_client/test_ckb_disconnect_fetch_transaction_solo.py @@ -69,7 +69,7 @@ def test_fetch_transaction_when_solo_ckb_restart(self): self.ckb_light_node.getClient().get_scripts() state = self.ckb_light_node.getClient().fetch_transaction(tx_hash) print(state['status']) - time.sleep(1) + time.sleep(2) if state['status'] != "fetching": end_time = datetime.now() time_difference = end_time - current_time diff --git a/test_cases/node_compatible/test_after_ckb_2023_hardfork.py b/test_cases/node_compatible/test_after_ckb_2023_hardfork.py index 1324a6b..8c13d34 100644 --- a/test_cases/node_compatible/test_after_ckb_2023_hardfork.py +++ b/test_cases/node_compatible/test_after_ckb_2023_hardfork.py @@ -4,70 +4,84 @@ from framework.basic import CkbTest -class TestAfterCkb2023(CkbTest): - node_current = CkbTest.CkbNode.init_dev_by_port(CkbTest.CkbNodeConfigPath.CURRENT_TEST, - "node_compatible/current/node1", 8115, - 8225) - node_111 = CkbTest.CkbNode.init_dev_by_port(CkbTest.CkbNodeConfigPath.V111, - "node_compatible/current/node2", - 8116, - 8226) - node_110 = CkbTest.CkbNode.init_dev_by_port(CkbTest.CkbNodeConfigPath.V110, "node_compatible/current/node3", 8117, - 8227) - nodes = [node_current, node_111, node_110] - lt_111_nodes = [node_110] - ge_111_nodes = [node_current, node_111] - cluster: CkbTest.Cluster = CkbTest.Cluster(nodes) - - @classmethod - def setup_class(cls): - cls.cluster.prepare_all_nodes( - other_ckb_config={'ckb_logger_filter': 'debug'} - ) - cls.cluster.start_all_nodes() - cls.node_current.connected(cls.node_111) - cls.node_current.connected(cls.node_110) - contracts = cls.Contract_util.deploy_contracts(cls.Config.ACCOUNT_PRIVATE_1, cls.cluster.ckb_nodes[0]) - cls.spawn_contract = contracts["SpawnContract"] - cls.Miner.make_tip_height_number(cls.node_current, 900) - cls.Node.wait_cluster_sync_with_miner(cls.cluster, 300, 900) - heights = cls.cluster.get_all_nodes_height() - print(f"heights:{heights}") - cls.Miner.make_tip_height_number(cls.node_current, 1100) - - @classmethod - def teardown_class(cls): - print("\nTeardown TestClass1") - heights = cls.cluster.get_all_nodes_height() - print(heights) - cls.cluster.stop_all_nodes() - cls.cluster.clean_all_nodes() - - def test_01_lt_111_sync_hard_fork(self): - self.Node.wait_node_height(self.node_110, 990, 100) - time.sleep(10) - tip_number = self.node_110.getClient().get_tip_block_number() - assert tip_number <= 999 - - def test_02_lt_111_sync_failed(self): - node = self.CkbNode.init_dev_by_port(self.CkbNodeConfigPath.V110, "node_compatible/current/node5", 8229, - 8339) - node.prepare() - node.start() - node.connected(self.node_current) - self.cluster.ckb_nodes.append(node) - with pytest.raises(Exception) as exc_info: - self.Node.wait_node_height(node, 1, 30) - expected_error_message = "time out" - 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]}'" - - def test_03_sync_successful_ge_111(self): - node = self.CkbNode.init_dev_by_port(self.CkbNodeConfigPath.V111, "node_compatible/current/node6", 8129, - 8239) - node.prepare() - node.start() - node.connected(self.node_current) - self.Node.wait_node_height(node, 1001, 1000) - self.cluster.ckb_nodes.append(node) +# https: // github.com / nervosnetwork / ckb / pull / 4227 +# 这是 0.112.1 和 0.113.0-rc1 的一个差异。 +# 112 版本之前的dev dao 计算是错误的,所以113之后去掉兼容性测试 +# +# class TestAfterCkb2023(CkbTest): +# node_current = CkbTest.CkbNode.init_dev_by_port(CkbTest.CkbNodeConfigPath.CURRENT_TEST, +# "node_compatible/current/node1", 8115, +# 8225) +# node_111 = CkbTest.CkbNode.init_dev_by_port(CkbTest.CkbNodeConfigPath.V111, +# "node_compatible/current/node2", +# 8116, +# 8226) +# node_110 = CkbTest.CkbNode.init_dev_by_port(CkbTest.CkbNodeConfigPath.V110, "node_compatible/current/node3", 8117, +# 8227) +# nodes = [node_current, node_111, node_110] +# lt_111_nodes = [node_110] +# ge_111_nodes = [node_current, node_111] +# cluster: CkbTest.Cluster = CkbTest.Cluster(nodes) +# +# @classmethod +# def setup_class(cls): +# cls.cluster.prepare_all_nodes( +# other_ckb_config={'ckb_logger_filter': 'debug'} +# ) +# cls.cluster.start_all_nodes() +# cls.node_current.connected(cls.node_111) +# cls.node_current.connected(cls.node_110) +# contracts = cls.Contract_util.deploy_contracts(cls.Config.ACCOUNT_PRIVATE_1, cls.cluster.ckb_nodes[0]) +# cls.spawn_contract = contracts["SpawnContract"] +# cls.Miner.make_tip_height_number(cls.node_current, 900) +# cls.Node.wait_cluster_sync_with_miner(cls.cluster, 300, 900) +# heights = cls.cluster.get_all_nodes_height() +# print(f"heights:{heights}") +# cls.Miner.make_tip_height_number(cls.node_current, 1100) +# +# @classmethod +# def teardown_class(cls): +# pass +# # print("\nTeardown TestClass1") +# # heights = cls.cluster.get_all_nodes_height() +# # print(heights) +# # cls.cluster.stop_all_nodes() +# # cls.cluster.clean_all_nodes() +# +# def test_01_lt_111_sync_hard_fork(self): +# self.Node.wait_node_height(self.node_110, 990, 100) +# time.sleep(10) +# tip_number = self.node_110.getClient().get_tip_block_number() +# assert tip_number <= 999 +# +# def test_02_lt_111_sync_failed(self): +# node = self.CkbNode.init_dev_by_port(self.CkbNodeConfigPath.V110, "node_compatible/current/node5", 8229, +# 8339) +# node.prepare() +# node.start() +# node.connected(self.node_current) +# self.cluster.ckb_nodes.append(node) +# with pytest.raises(Exception) as exc_info: +# self.Node.wait_node_height(node, 1, 30) +# expected_error_message = "time out" +# 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]}'" +# +# def test_03_sync_successful_ge_111(self): +# node = self.CkbNode.init_dev_by_port(self.CkbNodeConfigPath.V111, "node_compatible/current/node6", 8129, +# 8239) +# node.prepare() +# node.start() +# node.connected(self.node_current) +# self.Node.wait_node_height(node, 1001, 1000) +# self.cluster.ckb_nodes.append(node) +# +# def test_04_sync_successful_ge_112(self): +# node = self.CkbNode.init_dev_by_port(self.CkbNodeConfigPath.V112, "node_compatible/current/node7", 8130, +# 8330) +# node.prepare() +# node.start() +# node.connected(self.node_current) +# self.Node.wait_node_height(node, 1001, 1000) +# self.cluster.ckb_nodes.append(node) diff --git a/test_cases/replace_rpc/test_rpc.py b/test_cases/replace_rpc/test_rpc.py index 63daf3b..ccae8c2 100644 --- a/test_cases/replace_rpc/test_rpc.py +++ b/test_cases/replace_rpc/test_rpc.py @@ -23,10 +23,10 @@ def setup_class(cls): @classmethod def teardown_class(cls): print("teardown_class") - # cls.node112.stop() - # cls.node112.clean() - # cls.node113.stop() - # cls.node113.clean() + cls.node112.stop() + cls.node112.clean() + cls.node113.stop() + cls.node113.clean() def test_without_header(self): """ diff --git a/test_cases/tx_pool_refactor/test_02_txs_lifecycle_chain.py b/test_cases/tx_pool_refactor/test_02_txs_lifecycle_chain.py index 84bc84e..7977873 100644 --- a/test_cases/tx_pool_refactor/test_02_txs_lifecycle_chain.py +++ b/test_cases/tx_pool_refactor/test_02_txs_lifecycle_chain.py @@ -3,16 +3,6 @@ import pytest from framework.basic import CkbTest -# from framework.config import ACCOUNT_PRIVATE_2 -# from framework.helper.ckb_cli import util_key_info_by_private_key, wallet_transfer_by_private_key -# from framework.helper.miner import make_tip_height_number, block_template_transfer_to_submit_block, miner_with_version -# from framework.helper.node import wait_get_transaction -# from framework.helper.tx import send_transfer_self_tx_with_input -# from framework.test_node import CkbNode, CkbNodeConfigPath - - -# import concurrent.futures - class TestTxsLifeCycleChain(CkbTest): @classmethod From 93efe4695733e04839fd6473e63aa8942078b819 Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Wed, 20 Dec 2023 14:11:51 +0800 Subject: [PATCH 04/27] support v113 --- source/template/ckb/v113/ckb-miner.toml.j2 | 45 +++++ source/template/ckb/v113/ckb.toml.j2 | 187 ++++++++++++++++++ source/template/ckb/v113/default.db-options | 22 +++ .../ckb/v113/specs/benchmark-spec.toml | 0 source/template/ckb/v113/specs/dev.toml | 100 ++++++++++ source/template/ckb/v113/specs/mainnet.toml | 69 +++++++ source/template/ckb/v113/specs/testnet.toml | 90 +++++++++ test_cases/light_client/test_light_sync.py | 113 +++++++++++ 8 files changed, 626 insertions(+) create mode 100644 source/template/ckb/v113/ckb-miner.toml.j2 create mode 100644 source/template/ckb/v113/ckb.toml.j2 create mode 100644 source/template/ckb/v113/default.db-options rename test_cases/bug/__init__.py => source/template/ckb/v113/specs/benchmark-spec.toml (100%) create mode 100644 source/template/ckb/v113/specs/dev.toml create mode 100644 source/template/ckb/v113/specs/mainnet.toml create mode 100644 source/template/ckb/v113/specs/testnet.toml create mode 100644 test_cases/light_client/test_light_sync.py diff --git a/source/template/ckb/v113/ckb-miner.toml.j2 b/source/template/ckb/v113/ckb-miner.toml.j2 new file mode 100644 index 0000000..6c29b12 --- /dev/null +++ b/source/template/ckb/v113/ckb-miner.toml.j2 @@ -0,0 +1,45 @@ +# Config generated by `ckb init --chain dev` + +data_dir = "{{ ckb_miner_data_dir | default(ckb_data_dir) }}" + +[chain] +{# Choose the kind of chains to run, possible values: #} +{# - { file = "specs/dev.toml" } #} +{# - { bundled = "specs/testnet.toml" } #} +{# - { bundled = "specs/mainnet.toml" } #} +spec = {{ ckb_chain_spec }} + + +[logger] +filter = "{{ ckb_miner_logger_filter | default("info") }}" +color = {{ ckb_miner_logger_color | default("true") }} +log_to_file = {{ ckb_miner_logger_log_to_file | default("true") }} +log_to_stdout = {{ ckb_miner_logger_log_to_stdout | default("true") }} + +[sentry] +# set to blank to disable sentry error collection +dsn = "{{ ckb_miner_sentry_dsn | default("") }}" +# if you are willing to help us to improve, +# please leave a way to contact you when we have troubles to reproduce the errors. +# org_contact = "{{ ckb_miner_sentry_org_contact | default() }}" + +[miner.client] +rpc_url = "http://{{ ckb_miner_rpc_url | default("127.0.0.1:8114") }}" +block_on_submit = {{ ckb_miner_block_on_submit | default("true") }} + +# block template polling interval in milliseconds +poll_interval = {{ ckb_miner_poll_interval | default("1000") }} + +#{% if ckb_miner_workers is defined %} +# {% for worker in ckb_miner_workers %} +# [[miner.workers]] +# worker_type = "{{ worker.worker_type }}" +# delay_type = "{{ worker.delay_type }}" +# value = {{ worker.value }} +# {% endfor %} +#{% else %} +[[miner.workers]] +worker_type = "Dummy" +delay_type = "Constant" +value = 1000 +#{% endif %} diff --git a/source/template/ckb/v113/ckb.toml.j2 b/source/template/ckb/v113/ckb.toml.j2 new file mode 100644 index 0000000..7ac0464 --- /dev/null +++ b/source/template/ckb/v113/ckb.toml.j2 @@ -0,0 +1,187 @@ +# Config generated by `ckb init --chain dev` + +data_dir = "{{ ckb_data_dir | default("data") }}" + + +[chain] +# Choose the kind of chains to run, possible values: +# - { file = "specs/dev.toml" } +# - { bundled = "specs/testnet.toml" } +# - { bundled = "specs/mainnet.toml" } +spec = {{ ckb_chain_spec }} + + +[logger] +filter = "{{ ckb_logger_filter | default("info") }}" +color = {{ ckb_logger_color | default("true") }} +log_to_file = {{ ckb_logger_log_to_file | default("true") }} +log_to_stdout = {{ ckb_logger_log_to_stdout | default("true") }} + + +[sentry] +# set to blank to disable sentry error collection +dsn = "{{ ckb_sentry_dsn | default("") }}" +# if you are willing to help us to improve, +# please leave a way to contact you when we have troubles to reproduce the errors. +org_contact = "{{ ckb_sentry_org_contact | default("") }}" + + +# # **Experimental** Monitor memory changes. +# [memory_tracker] +# # Seconds between checking the process, 0 is disable, default is 0. +# interval = 600 + +[db] +# The capacity of RocksDB cache, which caches uncompressed data blocks, indexes and filters, default is 128MB. +# Rocksdb will automatically create and use an 8MB internal cache if you set this value to 0. +# To turning off cache, you need to set this value to 0 and set `no_block_cache = true` in the options_file, +# however, we strongly discourage this setting, it may lead to severe performance degradation. +cache_size = {{ ckb_db_cache_size | default("134217728") }} + +# Provide an options file to tune RocksDB for your workload and your system configuration. +# More details can be found in [the official tuning guide](https://github.com/facebook/rocksdb/wiki/RocksDB-Tuning-Guide). +options_file = "{{ ckb_db_options_file | default("default.db-options") }}" + +[network] +listen_addresses = {{ ckb_network_listen_addresses | default(["/ip4/0.0.0.0/tcp/8115"]) | to_json }} +### Specify the public and routable network addresses +public_addresses = {{ ckb_network_public_addresses | default([]) | to_json }} + +# Node connects to nodes listed here to discovery other peers when there's no local stored peers. +# When chain.spec is changed, this usually should also be changed to the bootnodes in the new chain. +bootnodes = {{ ckb_network_bootnodes | default([]) | to_json }} + +### Whitelist-only mode +whitelist_only = {{ ckb_network_whitelist_only | default("false") }} +### Whitelist peers connecting from the given IP addresses +whitelist_peers = {{ ckb_network_whitelist_peers | default([]) | to_json }} +### Enable `SO_REUSEPORT` feature to reuse port on Linux, not supported on other OS yet +# reuse_port_on_linux = true + +max_peers = {{ ckb_network_max_peers | default(125) }} +max_outbound_peers = {{ ckb_network_max_outbound_peers | default(8) }} +# 2 minutes +ping_interval_secs = {{ ckb_network_ping_interval_secs | default(120) }} +# 20 minutes +ping_timeout_secs = {{ ckb_network_ping_timeout_secs | default(1200) }} +connect_outbound_interval_secs = 15 +# If set to true, try to register upnp +upnp = {{ ckb_network_upnp | default("false") }} +# If set to true, network service will add discovered local address to peer store, it's helpful for private net development +discovery_local_address = {{ ckb_network_discovery_local_address | default("true") }} +# If set to true, random cleanup when there are too many inbound nodes +# Ensure that itself can continue to serve as a bootnode node +bootnode_mode = {{ ckb_network_bootnode_mode | default("false") }} + +# Supported protocols list, only "Sync" and "Identify" are mandatory, others are optional +support_protocols = ["Ping", "Discovery", "Identify", "Feeler", "DisconnectMessage", "Sync", "Relay", "Time", "Alert", "LightClient", "Filter"] + +# [network.sync.header_map] +# memory_limit = "600MB" + +[rpc] +# By default RPC only binds to localhost, thus it only allows accessing from the same machine. +# +# Allowing arbitrary machines to access the JSON-RPC port is dangerous and strongly discouraged. +# Please strictly limit the access to only trusted machines. +listen_address = "{{ ckb_rpc_listen_address | default("127.0.0.1:8114") }}" + +# Default is 10MiB = 10 * 1024 * 1024 +max_request_body_size = {{ ckb_rpc_max_request_body_size | default(10485760) }} + +# List of API modules: ["Net", "Pool", "Miner", "Chain", "Stats", "Subscription", "Experiment", "Debug", "Indexer"] +#modules = ["Net", "Pool", "Miner", "Chain", "Stats", "Subscription", "Experiment", "Debug"] +modules = {{ ckb_rpc_modules | to_json }} + +# By default RPC only binds to HTTP service, you can bind it to TCP and WebSocket. +#{% if ckb_tcp_listen_address is defined %} +tcp_listen_address = "{{ ckb_tcp_listen_address }}" +#{% endif %} + +#{% if ckb_ws_listen_address is defined %} +ws_listen_address = "{{ ckb_ws_listen_address }}" +#{% endif %} + +reject_ill_transactions = {{ ckb_rpc_reject_ill_transactions | default("true") }} + +# By default deprecated rpc methods are disabled. +enable_deprecated_rpc = {{ ckb_rpc_enable_deprecated_rpc | default("false") }} + + +[tx_pool] +max_tx_pool_size = {{ ckb_tx_pool_max_tx_pool_size | default("180_000_000") }} +min_fee_rate = {{ ckb_tx_pool_min_fee_rate | default("1_000") }} +max_tx_verify_cycles = {{ ckb_tx_pool_max_tx_verify_cycles | default("70_000_000") }} +max_ancestors_count = {{ ckb_tx_pool_max_ancestors_count | default("25") }} +min_rbf_rate = {{ ckb_tx_pool_min_rbf_rate | default("1_500") }} + + +[store] +header_cache_size = {{ ckb_store_header_cache_size | default("4096")}} +cell_data_cache_size = {{ ckb_store_cell_data_cache_size | default("128")}} +block_proposals_cache_size = {{ ckb_store_block_proposals_cache_size | default("30")}} +block_tx_hashes_cache_size = {{ ckb_store_block_tx_hashes_cache_size | default("30")}} +block_uncles_cache_size = {{ ckb_store_block_uncles_cache_size | default("30")}} + +# [notifier] +# # Execute command when the new tip block changes, first arg is block hash. +# new_block_notify_script = "your_new_block_notify_script.sh" +# # Execute command when node received an network alert, first arg is alert message string. +# network_alert_notify_script = "your_network_alert_notify_script.sh" + +# Set the lock script to protect mined CKB. +# +# CKB uses CS architecture for miner. Miner process (ckb miner) gets block +# template from the Node process (ckb run) via RPC. Thus the lock script is +# configured in ckb.toml instead of ckb-miner.toml, and the config takes effect +# after restarting Node process. +# +# The `code_hash` identifies different cryptography algorithm. Read the manual +# of the lock script provider about how to generate this config. +# +# CKB provides an secp256k1 implementation, it requires a hash on the +# compressed public key. The hash algorithm is blake2b, with personal +# "ckb-default-hash". The first 160 bits (20 bytes) are used as the only arg. +# +# You can use any tool you trust to generate a Bitcoin private key and public +# key pair, which can be used in CKB as well. CKB CLI provides the function for +# you to convert the public key into block assembler configuration parameters. +# +# Here is an example using ckb-cli to generate an account, this command will +# print the block assembler args(lock_arg) to screen: +# +# ckb-cli account new +# +# If you already have a raw secp256k1 private key, you can get the lock_arg by: +# +# ckb-cli util key-info --privkey-path +# +# The command `ckb init` also accepts options to generate the block assembler +# directly. See `ckb init --help` for details. +# +# ckb init +# +# secp256k1_blake160_sighash_all example: +# [block_assembler] +# code_hash = "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8" +# args = "ckb-cli util blake2b --prefix-160 " +# hash_type = "type" +# message = "A 0x-prefixed hex string" +# # +# # CKB will prepend the binary version to message, to identify the block miner client. (default true, false to disable it) +# use_binary_version_as_message_prefix = true +# # +# # Block assembler will notify new block template through http post to specified endpoints when update +# notify = ["http://127.0.0.1:8888"] +# # Or you may want use more flexible scripts, block template as arg. +# notify_scripts = ["{cmd} {blocktemplate}"] +# +# [indexer_v2] +# # Indexing the pending txs in the ckb tx-pool +# index_tx_pool = false + +[block_assembler] +code_hash = "{{ ckb_block_assembler_code_hash }}" +args = "{{ ckb_block_assembler_args }}" +hash_type = "{{ ckb_block_assembler_hash_type }}" +message = "{{ ckb_block_assembler_message }}" diff --git a/source/template/ckb/v113/default.db-options b/source/template/ckb/v113/default.db-options new file mode 100644 index 0000000..bffbdc0 --- /dev/null +++ b/source/template/ckb/v113/default.db-options @@ -0,0 +1,22 @@ +# This is a RocksDB option file. +# +# For detailed file format spec, please refer to the official documents +# in https://rocksdb.org/docs/ +# + +[DBOptions] +bytes_per_sync=1048576 +max_background_jobs=6 +max_total_wal_size=134217728 +keep_log_file_num=32 + +[CFOptions "default"] +level_compaction_dynamic_level_bytes=true +write_buffer_size=8388608 +min_write_buffer_number_to_merge=1 +max_write_buffer_number=2 +max_write_buffer_size_to_maintain=-1 + +[TableOptions/BlockBasedTable "default"] +cache_index_and_filter_blocks=true +pin_l0_filter_and_index_blocks_in_cache=true diff --git a/test_cases/bug/__init__.py b/source/template/ckb/v113/specs/benchmark-spec.toml similarity index 100% rename from test_cases/bug/__init__.py rename to source/template/ckb/v113/specs/benchmark-spec.toml diff --git a/source/template/ckb/v113/specs/dev.toml b/source/template/ckb/v113/specs/dev.toml new file mode 100644 index 0000000..a238e87 --- /dev/null +++ b/source/template/ckb/v113/specs/dev.toml @@ -0,0 +1,100 @@ +name = "ckb_dev" + +[genesis] +version = 0 +parent_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +timestamp = 0 +compact_target = 0x20010000 +uncles_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +nonce = "0x0" + +[genesis.genesis_cell] +message = "1688032132025" + +[genesis.genesis_cell.lock] +code_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +args = "0x" +hash_type = "data" + +# An array list paths to system cell files, which is absolute or relative to +# the directory containing this config file. +[[genesis.system_cells]] +file = { bundled = "specs/cells/secp256k1_blake160_sighash_all" } +create_type_id = true +capacity = 100_000_0000_0000 +[[genesis.system_cells]] +file = { bundled = "specs/cells/dao" } +create_type_id = true +capacity = 16_000_0000_0000 +[[genesis.system_cells]] +file = { bundled = "specs/cells/secp256k1_data" } +create_type_id = false +capacity = 1_048_617_0000_0000 +[[genesis.system_cells]] +file = { bundled = "specs/cells/secp256k1_blake160_multisig_all" } +create_type_id = true +capacity = 100_000_0000_0000 + +[genesis.system_cells_lock] +code_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +args = "0x" +hash_type = "data" + +# Dep group cells +[[genesis.dep_groups]] +name = "secp256k1_blake160_sighash_all" +files = [ + { bundled = "specs/cells/secp256k1_data" }, + { bundled = "specs/cells/secp256k1_blake160_sighash_all" }, +] +[[genesis.dep_groups]] +name = "secp256k1_blake160_multisig_all" +files = [ + { bundled = "specs/cells/secp256k1_data" }, + { bundled = "specs/cells/secp256k1_blake160_multisig_all" }, +] + +# For first 11 block +[genesis.bootstrap_lock] +code_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +args = "0x" +hash_type = "type" + +# Burn +[[genesis.issued_cells]] +capacity = 8_400_000_000_00000000 +lock.code_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +lock.args = "0x62e907b15cbf27d5425399ebf6f0fb50ebb88f18" +lock.hash_type = "data" + +# issue for random generated private key: d00c06bfd800d27397002dca6fb0993d5ba6399b4238b2f29ee9deb97593d2bc +[[genesis.issued_cells]] +capacity = 20_000_000_000_00000000 +lock.code_hash = "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8" +lock.args = "0xc8328aabcd9b9e8e64fbc566c4385c3bdeb219d7" +lock.hash_type = "type" + +# issue for random generated private key: 63d86723e08f0f813a36ce6aa123bb2289d90680ae1e99d4de8cdb334553f24d +[[genesis.issued_cells]] +capacity = 5_198_735_037_00000000 +lock.code_hash = "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8" +lock.args = "0x470dcdc5e44064909650113a274b3b36aecb6dc7" +lock.hash_type = "type" + +[params] +initial_primary_epoch_reward = 1_917_808_21917808 +secondary_epoch_reward = 613_698_63013698 +max_block_cycles = 10_000_000_000 +cellbase_maturity = 0 +primary_epoch_reward_halving_interval = 8760 +epoch_duration_target = 14400 +genesis_epoch_length = 1000 +# For development and testing purposes only. +# Keep difficulty be permanent if the pow is Dummy. (default: false) +permanent_difficulty_in_dummy = true + +[params.hardfork] +ckb2023 = 1000000 + +[pow] +func = "Dummy" diff --git a/source/template/ckb/v113/specs/mainnet.toml b/source/template/ckb/v113/specs/mainnet.toml new file mode 100644 index 0000000..daf7edf --- /dev/null +++ b/source/template/ckb/v113/specs/mainnet.toml @@ -0,0 +1,69 @@ +name = "ckb" + +[genesis] +version = 0 +parent_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +timestamp = 1573852190812 +compact_target = 0x1a08a97e +uncles_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +nonce = "0x0" + +[genesis.genesis_cell] +message = "lina 0x18e020f6b1237a3d06b75121f25a7efa0550e4b3f44f974822f471902424c104" + +[genesis.genesis_cell.lock] +code_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +args = "0x" +hash_type = "data" + +# An array list paths to system cell files, which is absolute or relative to +# the directory containing this config file. +[[genesis.system_cells]] +file = { bundled = "specs/cells/secp256k1_blake160_sighash_all" } +create_type_id = true +capacity = 100_000_0000_0000 +[[genesis.system_cells]] +file = { bundled = "specs/cells/dao" } +create_type_id = true +capacity = 16_000_0000_0000 +[[genesis.system_cells]] +file = { bundled = "specs/cells/secp256k1_data" } +create_type_id = false +capacity = 1_048_617_0000_0000 +[[genesis.system_cells]] +file = { bundled = "specs/cells/secp256k1_blake160_multisig_all" } +create_type_id = true +capacity = 100_000_0000_0000 + +[genesis.system_cells_lock] +code_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +args = "0x" +hash_type = "data" + +# Dep group cells +[[genesis.dep_groups]] +name = "secp256k1_blake160_sighash_all" +files = [ + { bundled = "specs/cells/secp256k1_data" }, + { bundled = "specs/cells/secp256k1_blake160_sighash_all" }, +] +[[genesis.dep_groups]] +name = "secp256k1_blake160_multisig_all" +files = [ + { bundled = "specs/cells/secp256k1_data" }, + { bundled = "specs/cells/secp256k1_blake160_multisig_all" }, +] + +# For first 11 block +[genesis.bootstrap_lock] +code_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +args = "0x" +hash_type = "data" + + + +[params] +genesis_epoch_length = 1743 + +[pow] +func = "Eaglesong" \ No newline at end of file diff --git a/source/template/ckb/v113/specs/testnet.toml b/source/template/ckb/v113/specs/testnet.toml new file mode 100644 index 0000000..2461e53 --- /dev/null +++ b/source/template/ckb/v113/specs/testnet.toml @@ -0,0 +1,90 @@ +name = "ckb_testnet" + +[genesis] +version = 0 +parent_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +timestamp = 1589276230000 +compact_target = 0x1e015555 +uncles_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +nonce = "0x0" +# run `cargo run list-hashes -b` to get the genesis hash +hash = "0x10639e0895502b5688a6be8cf69460d76541bfa4821629d86d62ba0aae3f9606" + +[genesis.genesis_cell] +message = "aggron-v4" + +[genesis.genesis_cell.lock] +code_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +args = "0x" +hash_type = "data" + +# An array list paths to system cell files, which is absolute or relative to +# the directory containing this config file. +[[genesis.system_cells]] +file = { bundled = "specs/cells/secp256k1_blake160_sighash_all" } +create_type_id = true +capacity = 100_000_0000_0000 +[[genesis.system_cells]] +file = { bundled = "specs/cells/dao" } +create_type_id = true +capacity = 16_000_0000_0000 +[[genesis.system_cells]] +file = { bundled = "specs/cells/secp256k1_data" } +create_type_id = false +capacity = 1_048_617_0000_0000 +[[genesis.system_cells]] +file = { bundled = "specs/cells/secp256k1_blake160_multisig_all" } +create_type_id = true +capacity = 100_000_0000_0000 + +[genesis.system_cells_lock] +code_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +args = "0x" +hash_type = "data" + +# Dep group cells +[[genesis.dep_groups]] +name = "secp256k1_blake160_sighash_all" +files = [ + { bundled = "specs/cells/secp256k1_data" }, + { bundled = "specs/cells/secp256k1_blake160_sighash_all" }, +] +[[genesis.dep_groups]] +name = "secp256k1_blake160_multisig_all" +files = [ + { bundled = "specs/cells/secp256k1_data" }, + { bundled = "specs/cells/secp256k1_blake160_multisig_all" }, +] + +# For first 11 block +[genesis.bootstrap_lock] +code_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +args = "0x" +hash_type = "type" + +# Burn +[[genesis.issued_cells]] +capacity = 8_400_000_000_00000000 +lock.code_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +lock.args = "0x62e907b15cbf27d5425399ebf6f0fb50ebb88f18" +lock.hash_type = "data" + +# Locks for developers to run tests +[[genesis.issued_cells]] +capacity = 8_399_578_345_00000000 +lock.code_hash = "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8" +lock.args = "0x64257f00b6b63e987609fa9be2d0c86d351020fb" +lock.hash_type = "type" +[[genesis.issued_cells]] +capacity = 8_399_578_345_00000000 +lock.code_hash = "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8" +lock.args = "0x3f1573b44218d4c12a91919a58a863be415a2bc3" +lock.hash_type = "type" +[[genesis.issued_cells]] +capacity = 8_399_578_347_00000000 +lock.code_hash = "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8" +lock.args = "0x57ccb07be6875f61d93636b0ee11b675494627d2" +lock.hash_type = "type" + +[pow] +func = "EaglesongBlake2b" \ No newline at end of file diff --git a/test_cases/light_client/test_light_sync.py b/test_cases/light_client/test_light_sync.py new file mode 100644 index 0000000..ab058dd --- /dev/null +++ b/test_cases/light_client/test_light_sync.py @@ -0,0 +1,113 @@ +import pytest + +from framework.basic import CkbTest + + +class TestLightSync(CkbTest): + node: CkbTest.CkbNode + cluster: CkbTest.Cluster + ckb_light_node: CkbTest.CkbLightClientNode + + @classmethod + def setup_class(cls): + node1 = cls.CkbNode.init_dev_by_port(cls.CkbNodeConfigPath.V113, "tx_pool_main/node1", 8115, + 8227) + node2 = cls.CkbNode.init_dev_by_port(cls.CkbNodeConfigPath.V113, "tx_pool_main/node2", 8116, + 8228) + + cls.node = node1 + cls.node2 = node2 + cls.cluster = cls.Cluster([node1, node2]) + node1.prepare(other_ckb_spec_config={"ckb_params_genesis_epoch_length": "1", "ckb_name": "ckb_dev", + "ckb_params_genesis_compact_target": "0x2020000"}) + node2.prepare(other_ckb_spec_config={"ckb_params_genesis_epoch_length": "1", "ckb_name": "ckb_dev", + "ckb_params_genesis_compact_target": "0x2020000"}) + + cls.cluster.start_all_nodes() + cls.cluster.connected_all_nodes() + cls.Miner.make_tip_height_number(cls.node, 13000) + cls.Node.wait_cluster_height(cls.cluster, 5, 13000) + + @classmethod + def teardown_class(cls): + print("\nTeardown TestClass1") + cls.cluster.stop_all_nodes() + cls.cluster.clean_all_nodes() + + @pytest.mark.skip + def test_sync(self): + for i in range(20): + print("current idx", i) + self.ckb_light_node = self.CkbLightClientNode.init_by_nodes(self.CkbLightClientConfigPath.CURRENT_TEST, + [self.node, self.node2], + "tx_pool_light/node1", 8001) + self.ckb_light_node.prepare() + self.ckb_light_node.start() + + old_sync_account = [ + self.Config.ACCOUNT_PRIVATE_1, + self.Config.ACCOUNT_PRIVATE_2 + ] + new_sync_account = [ + self.Config.MINER_PRIVATE_1 + ] + old_sync_block_number = 6000 + new_sync_block_number = 3000 + add_sync_new_account_block_number = 8000 + new_sync_until_number = 12000 + + print("sync old account") + setScripts = [] + for account_private in old_sync_account: + acc = self.Ckb_cli.util_key_info_by_private_key(account_private) + setScripts.append({"script": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": acc['lock_arg']}, "script_type": "lock", "block_number": hex(old_sync_block_number)}) + self.ckb_light_node.getClient().set_scripts(setScripts) + + print(f"until sync:{add_sync_new_account_block_number}") + self.Node.wait_light_sync_height(self.ckb_light_node, add_sync_new_account_block_number, 1000000) + print("sync new account ") + scripts = self.ckb_light_node.getClient().get_scripts() + newSetScripts = [] + for i in scripts: + newSetScripts.append(i) + for account_private in new_sync_account: + acc = self.Ckb_cli.util_key_info_by_private_key(account_private) + newSetScripts.append({"script": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": acc['lock_arg']}, "script_type": "lock", "block_number": hex(new_sync_block_number)}) + self.ckb_light_node.getClient().set_scripts(newSetScripts) + print("until sync ") + self.Node.wait_light_sync_height(self.ckb_light_node, new_sync_until_number, 100000) + print("compare new account data") + for acc in new_sync_account: + print("------------~~~----------------------") + acc = self.Ckb_cli.util_key_info_by_private_key(acc) + light_cells = self.ckb_light_node.getClient().get_cells({ + "script": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": acc['lock_arg'] + }, + "script_type": "lock", + "filter": { + "block_range": [hex(new_sync_block_number), hex(new_sync_until_number)] + }}, "asc", "0xffffff", None) + full_cells = self.node.getClient().get_cells({ + "script": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": acc['lock_arg'] + }, + "script_type": "lock", + "filter": { + "block_range": [hex(new_sync_block_number + 1), hex(new_sync_until_number)] + }}, "asc", "0xffffff", None) + assert len(light_cells['objects']) == len(full_cells['objects']) + print(len(light_cells['objects'])) + print(len(full_cells['objects'])) + self.ckb_light_node.stop() + self.ckb_light_node.clean() From e907d240038a726ee22438c4f344d24b21fa06d8 Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Wed, 20 Dec 2023 15:23:44 +0800 Subject: [PATCH 05/27] debug rpc --- .github/workflows/python-app.yml | 4 ++++ Makefile | 26 ++++++++++++------------ test_cases/contracts/test_01_contract.py | 6 ++++++ test_cases/replace_rpc/test_rpc.py | 4 +--- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 8101807..f378e42 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -35,6 +35,10 @@ jobs: - name: Run tests run: make test + - name: Setup upterm session + if: failure() + uses: lhotari/action-upterm@v1 + - name: Publish reports if: failure() uses: actions/upload-artifact@v2 diff --git a/Makefile b/Makefile index 34bd856..a477365 100644 --- a/Makefile +++ b/Makefile @@ -15,19 +15,19 @@ check_failed_html: fi test: bash test.sh test_cases/replace_rpc - bash test.sh test_cases/ckb2023 - bash test.sh test_cases/ckb_cli - bash test.sh test_cases/contracts - bash test.sh test_cases/example - bash test.sh test_cases/framework - bash test.sh test_cases/light_client - bash test.sh test_cases/mocking - bash test.sh test_cases/node_compatible - bash test.sh test_cases/rpc - bash test.sh test_cases/soft_fork - bash test.sh test_cases/issue - bash test.sh test_cases/tx_pool_refactor - bash test.sh test_cases/feature +# bash test.sh test_cases/ckb2023 +# bash test.sh test_cases/ckb_cli +# bash test.sh test_cases/contracts +# bash test.sh test_cases/example +# bash test.sh test_cases/framework +# bash test.sh test_cases/light_client +# bash test.sh test_cases/mocking +# bash test.sh test_cases/node_compatible +# bash test.sh test_cases/rpc +# bash test.sh test_cases/soft_fork +# bash test.sh test_cases/issue +# bash test.sh test_cases/tx_pool_refactor +# bash test.sh test_cases/feature @if test -n "$$(ls report/*failed.html 2>/dev/null)"; then \ echo "Error: Failed HTML files found in the 'report' directory"; \ exit 1; \ diff --git a/test_cases/contracts/test_01_contract.py b/test_cases/contracts/test_01_contract.py index cfcf869..0e651ce 100644 --- a/test_cases/contracts/test_01_contract.py +++ b/test_cases/contracts/test_01_contract.py @@ -153,4 +153,10 @@ def deploy_and_invoke(self, account, path, node, try_count=5): self.Miner.miner_with_version(node, "0x0") time.sleep(3) return self.deploy_and_invoke(account, path, node, try_count) + if "PoolRejectedRBF" in str(e): + try_count -= 1 + for i in range(2): + self.Miner.miner_with_version(node, "0x0") + time.sleep(3) + return self.deploy_and_invoke(account, path, node, try_count) raise e diff --git a/test_cases/replace_rpc/test_rpc.py b/test_cases/replace_rpc/test_rpc.py index ccae8c2..99b2a08 100644 --- a/test_cases/replace_rpc/test_rpc.py +++ b/test_cases/replace_rpc/test_rpc.py @@ -148,10 +148,9 @@ def test_max_batch_count(self): assert expected_error_message in exc_info.value.args[1], \ f"Expected substring '{expected_error_message}' not found in actual string '{exc_info.value.args[0]}'" - @pytest.mark.skip def test_websocket(self): """ - support websocket + not support websocket 112: not support,Handshake status 405 Method Not Allowed 113: not support,Handshake status 500 Internal Server Error """ @@ -169,7 +168,6 @@ def test_websocket(self): 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]}'" - @pytest.mark.skip def test_telnet(self): """ support telnet From 0556bee7199c6a6ab882885c8c1209f389d4fda0 Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Wed, 20 Dec 2023 15:59:15 +0800 Subject: [PATCH 06/27] debug --- .github/workflows/python-app.yml | 2 +- test_cases/rpc/test_get_pool_tx_detail_info.py | 0 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 test_cases/rpc/test_get_pool_tx_detail_info.py diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index f378e42..96a402e 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -36,7 +36,7 @@ jobs: run: make test - name: Setup upterm session - if: failure() + if: always() uses: lhotari/action-upterm@v1 - name: Publish reports diff --git a/test_cases/rpc/test_get_pool_tx_detail_info.py b/test_cases/rpc/test_get_pool_tx_detail_info.py new file mode 100644 index 0000000..e69de29 From 68aecf547fbcaeb8c5d42ee3d6e4d52ac8a88ddc Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Wed, 20 Dec 2023 20:01:42 +0800 Subject: [PATCH 07/27] support 113 --- .github/workflows/python-app.yml | 6 +++--- Makefile | 26 +++++++++++++------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 96a402e..84c74df 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -35,9 +35,9 @@ jobs: - name: Run tests run: make test - - name: Setup upterm session - if: always() - uses: lhotari/action-upterm@v1 +# - name: Setup upterm session +# if: always() +# uses: lhotari/action-upterm@v1 - name: Publish reports if: failure() diff --git a/Makefile b/Makefile index a477365..34bd856 100644 --- a/Makefile +++ b/Makefile @@ -15,19 +15,19 @@ check_failed_html: fi test: bash test.sh test_cases/replace_rpc -# bash test.sh test_cases/ckb2023 -# bash test.sh test_cases/ckb_cli -# bash test.sh test_cases/contracts -# bash test.sh test_cases/example -# bash test.sh test_cases/framework -# bash test.sh test_cases/light_client -# bash test.sh test_cases/mocking -# bash test.sh test_cases/node_compatible -# bash test.sh test_cases/rpc -# bash test.sh test_cases/soft_fork -# bash test.sh test_cases/issue -# bash test.sh test_cases/tx_pool_refactor -# bash test.sh test_cases/feature + bash test.sh test_cases/ckb2023 + bash test.sh test_cases/ckb_cli + bash test.sh test_cases/contracts + bash test.sh test_cases/example + bash test.sh test_cases/framework + bash test.sh test_cases/light_client + bash test.sh test_cases/mocking + bash test.sh test_cases/node_compatible + bash test.sh test_cases/rpc + bash test.sh test_cases/soft_fork + bash test.sh test_cases/issue + bash test.sh test_cases/tx_pool_refactor + bash test.sh test_cases/feature @if test -n "$$(ls report/*failed.html 2>/dev/null)"; then \ echo "Error: Failed HTML files found in the 'report' directory"; \ exit 1; \ From dedd4b9519c6e60a83c0ef97377bc026887b8240 Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Wed, 20 Dec 2023 20:54:44 +0800 Subject: [PATCH 08/27] skip max test --- test_cases/replace_rpc/test_rpc.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test_cases/replace_rpc/test_rpc.py b/test_cases/replace_rpc/test_rpc.py index 99b2a08..bdac979 100644 --- a/test_cases/replace_rpc/test_rpc.py +++ b/test_cases/replace_rpc/test_rpc.py @@ -79,6 +79,7 @@ def test_01_with_error_2(self): f"Expected substring '{expected_error_message}' not found in actual string '{exc_info.value.args[0]}'" + @pytest.mark.skip def test_max_response(self): """ batch get_block_by_number count:922 @@ -115,6 +116,7 @@ def test_max_response(self): 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]}'" + @pytest.mark.skip def test_max_batch_count(self): """ batch send count :15376 From 754b18e7c32e821063bcac80e334b4429495dced Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Fri, 22 Dec 2023 17:10:51 +0800 Subject: [PATCH 09/27] update 0.113.0-rc2 --- download.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/download.py b/download.py index 4792996..c2e2e16 100644 --- a/download.py +++ b/download.py @@ -11,7 +11,7 @@ import requests from tqdm import tqdm -versions = ['0.109.0', '0.110.2', '0.111.0', '0.112.1', '0.113.0-rc1'] # Replace with your versions +versions = ['0.109.0', '0.110.2', '0.111.0', '0.112.1', '0.113.0-rc2'] # Replace with your versions DOWNLOAD_DIR = "download" SYSTEMS = { 'Windows': { From ecc00f0a7919430e65ab83e5f09a75f43f826b5e Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Fri, 22 Dec 2023 17:58:05 +0800 Subject: [PATCH 10/27] add test_unsubscribe --- test_cases/replace_rpc/test_telnet.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/test_cases/replace_rpc/test_telnet.py b/test_cases/replace_rpc/test_telnet.py index 04e8e9e..3570e01 100644 --- a/test_cases/replace_rpc/test_telnet.py +++ b/test_cases/replace_rpc/test_telnet.py @@ -1,3 +1,4 @@ +import json import time import pytest @@ -34,7 +35,6 @@ def teardown_class(cls): cls.node113.stop() cls.node113.clean() - def test_link_count_max(self): """ link tcp @@ -163,3 +163,24 @@ def test_stop_node_when_link_telnet(self): assert "ckb" not in str(ret) self.node112.restart() self.node113.restart() + + def test_unsubscribe(self): + """ + subscribe topic 1 + unsubscribe topic 1 + unsubscribe successful + """ + socket = self.node113.subscribe_telnet("new_tip_header") + self.Miner.miner_with_version(self.node113, "0x0") + ret = socket.read_very_eager() + ret = json.loads(ret) + print(ret['params']['subscription']) + subscribe_str = '{"id": 2, "jsonrpc": "2.0", "method": "unsubscribe", "params": ["' + ret['params'][ + 'subscription'] + '"]}' + print("subscribe_str:", subscribe_str) + socket.write(subscribe_str.encode('utf-8') + b"\n") + data = socket.read_until(b'}\n') + assert "true" in data.decode('utf-8') + self.Miner.miner_with_version(self.node113, "0x0") + ret = socket.read_very_eager() + assert ret.decode('utf-8') == "" From c7e1302f8d67914b3f0722fbcc55c9a11fb1e58c Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Mon, 25 Dec 2023 14:01:23 +0800 Subject: [PATCH 11/27] update ckb-light-client --- download_ckb_light_client.py | 2 +- framework/test_light_client.py | 3 ++- test_cases/light_client/test_light_sync.py | 3 +-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/download_ckb_light_client.py b/download_ckb_light_client.py index 345725d..4ac9d1d 100644 --- a/download_ckb_light_client.py +++ b/download_ckb_light_client.py @@ -11,7 +11,7 @@ import requests from tqdm import tqdm -versions = ['0.2.4', '0.3.0', '0.3.1', '0.3.2'] # Replace with your versions +versions = ['0.2.4', '0.3.0', '0.3.1', '0.3.2', '0.3.3'] # Replace with your versions DOWNLOAD_DIR = "download" SYSTEMS = { 'Windows': { diff --git a/framework/test_light_client.py b/framework/test_light_client.py index 294fcf8..16b3a4b 100644 --- a/framework/test_light_client.py +++ b/framework/test_light_client.py @@ -10,7 +10,8 @@ class CkbLightClientConfigPath(Enum): V0_3_0 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.0/ckb-light-client") V0_3_1 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.1/ckb-light-client") V0_3_2 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.2/ckb-light-client") - CURRENT_TEST = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.2/ckb-light-client") + V0_3_3 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.3/ckb-light-client") + CURRENT_TEST = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.3/ckb-light-client") def __init__(self, ckb_light_client_config_path, ckb_light_bin_path): self.ckb_light_client_config_path = ckb_light_client_config_path diff --git a/test_cases/light_client/test_light_sync.py b/test_cases/light_client/test_light_sync.py index ab058dd..2a0bdee 100644 --- a/test_cases/light_client/test_light_sync.py +++ b/test_cases/light_client/test_light_sync.py @@ -34,9 +34,8 @@ def teardown_class(cls): cls.cluster.stop_all_nodes() cls.cluster.clean_all_nodes() - @pytest.mark.skip def test_sync(self): - for i in range(20): + for i in range(10): print("current idx", i) self.ckb_light_node = self.CkbLightClientNode.init_by_nodes(self.CkbLightClientConfigPath.CURRENT_TEST, [self.node, self.node2], From 32bf5cb623b753a2eddaa77492eebe30e6d03632 Mon Sep 17 00:00:00 2001 From: gpBlockchain <32102187+gpBlockchain@users.noreply.github.com> Date: Wed, 3 Jan 2024 18:23:54 +0800 Subject: [PATCH 12/27] Update download.py --- download.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/download.py b/download.py index c2e2e16..7a8bf07 100644 --- a/download.py +++ b/download.py @@ -11,7 +11,7 @@ import requests from tqdm import tqdm -versions = ['0.109.0', '0.110.2', '0.111.0', '0.112.1', '0.113.0-rc2'] # Replace with your versions +versions = ['0.109.0', '0.110.2', '0.111.0', '0.112.1', '0.113.0-rc3'] # Replace with your versions DOWNLOAD_DIR = "download" SYSTEMS = { 'Windows': { From 104180d57c2f53f13ee675eb95601b9725b97316 Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Fri, 5 Jan 2024 16:53:12 +0800 Subject: [PATCH 13/27] update ckb-light-client version --- download_ckb_light_client.py | 2 +- framework/test_light_client.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/download_ckb_light_client.py b/download_ckb_light_client.py index 4ac9d1d..e771940 100644 --- a/download_ckb_light_client.py +++ b/download_ckb_light_client.py @@ -11,7 +11,7 @@ import requests from tqdm import tqdm -versions = ['0.2.4', '0.3.0', '0.3.1', '0.3.2', '0.3.3'] # Replace with your versions +versions = ['0.2.4', '0.3.0', '0.3.1', '0.3.2', '0.3.3','0.3.4'] # Replace with your versions DOWNLOAD_DIR = "download" SYSTEMS = { 'Windows': { diff --git a/framework/test_light_client.py b/framework/test_light_client.py index 16b3a4b..b63c191 100644 --- a/framework/test_light_client.py +++ b/framework/test_light_client.py @@ -11,7 +11,8 @@ class CkbLightClientConfigPath(Enum): V0_3_1 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.1/ckb-light-client") V0_3_2 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.2/ckb-light-client") V0_3_3 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.3/ckb-light-client") - CURRENT_TEST = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.3/ckb-light-client") + V0_3_4 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.4/ckb-light-client") + CURRENT_TEST = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.4/ckb-light-client") def __init__(self, ckb_light_client_config_path, ckb_light_bin_path): self.ckb_light_client_config_path = ckb_light_client_config_path From a53831ed0c9e80014b9081931fb506152bc29057 Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Mon, 8 Jan 2024 11:50:22 +0800 Subject: [PATCH 14/27] fix light sync failed --- test_cases/light_client/test_light_sync.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test_cases/light_client/test_light_sync.py b/test_cases/light_client/test_light_sync.py index 2a0bdee..c343f20 100644 --- a/test_cases/light_client/test_light_sync.py +++ b/test_cases/light_client/test_light_sync.py @@ -27,6 +27,7 @@ def setup_class(cls): cls.cluster.connected_all_nodes() cls.Miner.make_tip_height_number(cls.node, 13000) cls.Node.wait_cluster_height(cls.cluster, 5, 13000) + node1.start_miner() @classmethod def teardown_class(cls): From 137bacf41ddb2de86a979fb48ddb77bf49f169bf Mon Sep 17 00:00:00 2001 From: 15168316096 <15168316096@163.com> Date: Sun, 4 Feb 2024 17:00:45 +0800 Subject: [PATCH 15/27] git add download.py test_node.py --- download.py | 2 +- framework/test_node.py | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/download.py b/download.py index 7a8bf07..5cbaa3e 100644 --- a/download.py +++ b/download.py @@ -11,7 +11,7 @@ import requests from tqdm import tqdm -versions = ['0.109.0', '0.110.2', '0.111.0', '0.112.1', '0.113.0-rc3'] # Replace with your versions +versions = ['0.109.0', '0.110.2', '0.111.0', '0.112.1', '0.113.0-rc3', "0.114.0-rc1"] # Replace with your versions DOWNLOAD_DIR = "download" SYSTEMS = { 'Windows': { diff --git a/framework/test_node.py b/framework/test_node.py index 94cd62e..31fad83 100644 --- a/framework/test_node.py +++ b/framework/test_node.py @@ -10,10 +10,17 @@ class CkbNodeConfigPath(Enum): CURRENT_TEST = ( - "source/template/ckb/v113/ckb.toml.j2", + "source/template/ckb/v114/ckb.toml.j2", "source/template/ckb/v112/ckb-miner.toml.j2", "source/template/ckb/v112/specs/dev.toml", - "download/0.113.0" + "download/0.114.0" + ) + + v114 = ( + "source/template/ckb/v114/ckb.toml.j2", + "source/template/ckb/v114/ckb-miner.toml.j2", + "source/template/ckb/v114/specs/dev.toml", + "download/0.114.0" ) V113 = ( From aaec54d1f171228529795fbfafed5268587b8c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?iu=E5=B0=8F=E8=BF=B7=E5=BC=9F?= <15168316096@163.com> Date: Mon, 5 Feb 2024 02:49:45 +0000 Subject: [PATCH 16/27] update env --- Makefile | 10 ++++++---- prepare.sh | 5 +++-- requirements.txt | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 34bd856..915606c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ prepare: + python -m venv venv + . venv/bin/activate python -m pip install --upgrade pip pip install -r requirements.txt echo "install ckb" @@ -32,14 +34,14 @@ test: echo "Error: Failed HTML files found in the 'report' directory"; \ exit 1; \ fi + clean: - -pkill ckb + pkill ckb rm -rf tmp rm -rf download rm -rf report - rm -rf source/ckb-cli - rm -rf source/ckb-cli-old - + rm -rf source/ckb-cli* + rm -rf ckb-* docs: python -m pytest --docs=docs/soft.md --doc-type=md test_cases/soft_fork \ No newline at end of file diff --git a/prepare.sh b/prepare.sh index d60090b..f50b332 100644 --- a/prepare.sh +++ b/prepare.sh @@ -1,7 +1,8 @@ set -e -git clone https://github.com/gpBlockchain/ckb-cli.git +git clone https://github.com/nervosnetwork/ckb-cli.git +version=`curl -s https://api.github.com/repos/nervosnetwork/ckb-cli/releases/latest | jq -r '.tag_name' ` cd ckb-cli -git checkout exec/data2 +git checkout $version make prod cp target/release/ckb-cli ../source/ckb-cli cd ../ diff --git a/requirements.txt b/requirements.txt index 2c10de7..fbfd3ab 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ pytest==7.3.2 requests==2.31.0 tqdm==4.65.0 pytest-html==3.2.0 -PyYAML==6.0 +PyYAML==6.0.1 pytest-docs==0.1.0 parameterized==0.9.0 toml==0.10.2 From 57cc8d36fc7d6ffb6a34fa419b08b9e8c0dca6b2 Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Mon, 5 Feb 2024 19:16:38 +0800 Subject: [PATCH 17/27] fix ci --- framework/test_node.py | 2 +- test_cases/tx_pool_refactor/test_10_issues.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/framework/test_node.py b/framework/test_node.py index ba27f82..22d2d9d 100644 --- a/framework/test_node.py +++ b/framework/test_node.py @@ -10,7 +10,7 @@ class CkbNodeConfigPath(Enum): CURRENT_TEST = ( - "source/template/ckb/v114/ckb.toml.j2", + "source/template/ckb/v112/ckb.toml.j2", "source/template/ckb/v112/ckb-miner.toml.j2", "source/template/ckb/v112/specs/dev.toml", "download/0.114.0" diff --git a/test_cases/tx_pool_refactor/test_10_issues.py b/test_cases/tx_pool_refactor/test_10_issues.py index 21cb15f..6f72e49 100644 --- a/test_cases/tx_pool_refactor/test_10_issues.py +++ b/test_cases/tx_pool_refactor/test_10_issues.py @@ -18,7 +18,6 @@ def teardown_class(cls): cls.node1.stop() cls.node1.clean() - @pytest.mark.skip def test_4315(self): """ 1. 发送 tx1 From 8d7017dea34b33b8af8c0077b8aa26826df277ff Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Fri, 9 Feb 2024 09:50:02 +0800 Subject: [PATCH 18/27] support light-client 0.3.6 --- download_ckb_light_client.py | 2 +- framework/test_light_client.py | 5 +- ...test_03_ckb_light_client_after_hardfork.py | 71 ++++++++++++++++++- ...est_04_ckb_light_client_before_hardfork.py | 2 +- 4 files changed, 75 insertions(+), 5 deletions(-) diff --git a/download_ckb_light_client.py b/download_ckb_light_client.py index bac35a4..ee2bac9 100644 --- a/download_ckb_light_client.py +++ b/download_ckb_light_client.py @@ -12,7 +12,7 @@ from tqdm import tqdm -versions = ['0.2.4', '0.3.0', '0.3.1', '0.3.2', '0.3.3', '0.3.4', '0.3.5'] # Replace with your versions +versions = ['0.2.4', '0.3.0', '0.3.1', '0.3.2', '0.3.3', '0.3.4', '0.3.5', '0.3.6'] # Replace with your versions DOWNLOAD_DIR = "download" SYSTEMS = { diff --git a/framework/test_light_client.py b/framework/test_light_client.py index a6cc4e8..4486231 100644 --- a/framework/test_light_client.py +++ b/framework/test_light_client.py @@ -12,9 +12,10 @@ class CkbLightClientConfigPath(Enum): V0_3_2 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.2/ckb-light-client") V0_3_3 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.3/ckb-light-client") V0_3_4 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.4/ckb-light-client") - V0_3_5 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.5/ckb-light-client") - CURRENT_TEST = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.5/ckb-light-client") + V0_3_6 = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.6/ckb-light-client") + + CURRENT_TEST = ("source/template/ckb_light_client/0.3.0/testnet.toml.j2", "download/0.3.6/ckb-light-client") def __init__(self, ckb_light_client_config_path, ckb_light_bin_path): self.ckb_light_client_config_path = ckb_light_client_config_path diff --git a/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py b/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py index bf92dd1..f14662f 100644 --- a/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py +++ b/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py @@ -32,6 +32,75 @@ def get_all_files(directory): def get_successful_files(): return [ + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", + f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", + f"{get_project_root()}/source/contract/test_cases/atomic_i32", + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", f"{get_project_root()}/source/contract/test_cases/atomic_i32", f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", @@ -251,8 +320,8 @@ def deploy_and_invoke(self, account, path, node, try_count=5): hash_type="type", api_url=node.getClient().url) self.Node.wait_light_sync_height(self.ckb_light_node_current, node.getClient().get_tip_block_number(), 200) + light_tx_hash = self.ckb_light_node_current.getClient().send_transaction(tx_msg) for i in range(100): - light_tx_hash = self.ckb_light_node_current.getClient().send_transaction(tx_msg) light_ret = node.getClient().get_transaction(light_tx_hash) time.sleep(1) print("light ret status:", light_ret['tx_status']['status']) diff --git a/test_cases/ckb2023/test_04_ckb_light_client_before_hardfork.py b/test_cases/ckb2023/test_04_ckb_light_client_before_hardfork.py index bfcd68e..378cee9 100644 --- a/test_cases/ckb2023/test_04_ckb_light_client_before_hardfork.py +++ b/test_cases/ckb2023/test_04_ckb_light_client_before_hardfork.py @@ -71,8 +71,8 @@ def deploy_and_invoke(self, account, path, node, try_count=5): hash_type="type", api_url=node.getClient().url) self.Node.wait_light_sync_height(self.ckb_light_node_current, node.getClient().get_tip_block_number(), 200) + light_tx_hash = self.ckb_light_node_current.getClient().send_transaction(tx_msg) for i in range(100): - light_tx_hash = self.ckb_light_node_current.getClient().send_transaction(tx_msg) light_ret = node.getClient().get_transaction(light_tx_hash) time.sleep(1) print("light ret status:", light_ret['tx_status']['status']) From 5a72f41f6bb258341d139f4dab7aa8e310845c6d Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Fri, 9 Feb 2024 09:53:45 +0800 Subject: [PATCH 19/27] update ckb-cli --- prepare.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/prepare.sh b/prepare.sh index 5fc3289..86fd3e1 100644 --- a/prepare.sh +++ b/prepare.sh @@ -1,8 +1,6 @@ set -e -git clone https://github.com/nervosnetwork/ckb-cli.git -version=`curl -s https://api.github.com/repos/nervosnetwork/ckb-cli/releases/latest | jq -r '.tag_name' ` +git clone https://github.com/gpBlockchain/ckb-cli.git cd ckb-cli -git checkout $version make prod cp target/release/ckb-cli ../source/ckb-cli cd ../ From ef2f18d117cad1fdb0af07fc0f6396f36240730d Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Sun, 18 Feb 2024 16:10:36 +0800 Subject: [PATCH 20/27] update 114 ckb-cli --- prepare.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/prepare.sh b/prepare.sh index 86fd3e1..067438c 100644 --- a/prepare.sh +++ b/prepare.sh @@ -1,6 +1,7 @@ set -e git clone https://github.com/gpBlockchain/ckb-cli.git cd ckb-cli +git checkout v114 make prod cp target/release/ckb-cli ../source/ckb-cli cd ../ From b349fdcccc15c7ac15cf7beeebbd4ee0a38a78fb Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Thu, 22 Feb 2024 15:36:13 +0800 Subject: [PATCH 21/27] update rc3 --- download.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/download.py b/download.py index dcb8409..57ecbe2 100644 --- a/download.py +++ b/download.py @@ -11,7 +11,7 @@ import requests from tqdm import tqdm -versions = ['0.109.0', '0.110.2', '0.111.0', '0.112.1', '0.113.1', "0.114.0-rc1"] # Replace with your versions +versions = ['0.109.0', '0.110.2', '0.111.0', '0.112.1', '0.113.1', "0.114.0-rc3"] # Replace with your versions DOWNLOAD_DIR = "download" SYSTEMS = { From e3f92e47dabaae9b5d6845790dc1545d6f67046a Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Fri, 23 Feb 2024 18:09:22 +0800 Subject: [PATCH 22/27] fix test_03_ckb_light_client_after_hardfork.py --- ...test_03_ckb_light_client_after_hardfork.py | 72 +------------------ 1 file changed, 1 insertion(+), 71 deletions(-) diff --git a/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py b/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py index f14662f..00a421f 100644 --- a/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py +++ b/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py @@ -34,77 +34,7 @@ def get_successful_files(): return [ f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/ckb_get_memory_limit", - f"{get_project_root()}/source/contract/test_cases/atomic_i32", - f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles", - f"{get_project_root()}/source/contract/test_cases/load_block_extension" + f"{get_project_root()}/source/contract/test_cases/spawn_current_cycles" ] From 30e845486363bc8e1f5c0f1264b3e88f2a7dcfef Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Mon, 26 Feb 2024 11:44:37 +0800 Subject: [PATCH 23/27] revert ckb2023=1 --- source/template/ckb/v113/specs/dev.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/template/ckb/v113/specs/dev.toml b/source/template/ckb/v113/specs/dev.toml index a238e87..f25a259 100644 --- a/source/template/ckb/v113/specs/dev.toml +++ b/source/template/ckb/v113/specs/dev.toml @@ -94,7 +94,7 @@ genesis_epoch_length = 1000 permanent_difficulty_in_dummy = true [params.hardfork] -ckb2023 = 1000000 +ckb2023 = 1 [pow] func = "Dummy" From 524adec5ba0196b22517b8f3d57e7c65b9ee7ad8 Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Mon, 26 Feb 2024 21:44:39 +0800 Subject: [PATCH 24/27] add get_cell test --- test_cases/issue/test_4111.py | 1 - test_cases/rpc/test_get_cells.py | 95 ++++++++++++++ test_cases/rpc/test_get_cells_capacity.py | 148 ++++++++++++++++++++++ test_cases/rpc/test_get_transaction.py | 41 +++++- 4 files changed, 278 insertions(+), 7 deletions(-) create mode 100644 test_cases/rpc/test_get_cells.py create mode 100644 test_cases/rpc/test_get_cells_capacity.py diff --git a/test_cases/issue/test_4111.py b/test_cases/issue/test_4111.py index 0f65444..8f4103b 100644 --- a/test_cases/issue/test_4111.py +++ b/test_cases/issue/test_4111.py @@ -60,7 +60,6 @@ def deploy_and_invoke(self, account, path, node, try_count=5): api_url=node.getClient().url, fee=-100) return invoke_hash except Exception as e: - print("!!!e:", e) if "Resolve failed Dead" in e.args[0]: try_count -= 1 time.sleep(3) diff --git a/test_cases/rpc/test_get_cells.py b/test_cases/rpc/test_get_cells.py new file mode 100644 index 0000000..b3434ac --- /dev/null +++ b/test_cases/rpc/test_get_cells.py @@ -0,0 +1,95 @@ +from framework.helper.contract import deploy_ckb_contract, invoke_ckb_contract, get_ckb_contract_codehash +from framework.util import get_project_root +from framework.config import MINER_PRIVATE_1 +from framework.helper.miner import miner_until_tx_committed +from test_cases.rpc.node_fixture import get_cluster + + +class TestGetCells: + + def test_get_cells_output_data_filter_mode(self, get_cluster): + cluster = get_cluster + deploy_hash = deploy_ckb_contract(MINER_PRIVATE_1, + f"{get_project_root()}/source/contract/always_success", + enable_type_id=True, + api_url=cluster.ckb_nodes[0].getClient().url) + miner_until_tx_committed(cluster.ckb_nodes[0], deploy_hash) + for i in range(1, 10): + invoke_hash = invoke_ckb_contract(account_private=MINER_PRIVATE_1, + contract_out_point_tx_hash=deploy_hash, + contract_out_point_tx_index=0, + type_script_arg="0x02", data=f"0x{i:02x}{i:02x}", + hash_type="type", + api_url=cluster.ckb_nodes[0].getClient().url) + miner_until_tx_committed(cluster.ckb_nodes[0], invoke_hash) + invoke_hash = invoke_ckb_contract(account_private=MINER_PRIVATE_1, + contract_out_point_tx_hash=deploy_hash, + contract_out_point_tx_index=0, + type_script_arg="0x02", data="0xffff00000000ffff", + hash_type="type", + api_url=cluster.ckb_nodes[0].getClient().url) + miner_until_tx_committed(cluster.ckb_nodes[0], invoke_hash) + + codehash = get_ckb_contract_codehash(deploy_hash, 0, + enable_type_id=True, + api_url=cluster.ckb_nodes[0].getClient().url) + + # output_data_filter_mode : prefix + + ret = cluster.ckb_nodes[0].getClient().get_cells({ + "script": { + "code_hash": codehash, + "hash_type": "type", + "args": "0x02" + }, + "script_type": "type", + "filter": { + "output_data": "0x01", + "output_data_filter_mode": "prefix" + } + }, "asc", "0xff", None) + + assert ret['objects'][0]['output_data'] == '0x0101' + ret = cluster.ckb_nodes[0].getClient().get_cells({ + "script": { + "code_hash": codehash, + "hash_type": "type", + "args": "0x02" + }, + "script_type": "type", + "filter": { + "output_data": "0x02", + "output_data_filter_mode": "prefix" + } + }, "asc", "0xff", None) + assert ret['objects'][0]['output_data'] == '0x0202' + + # output_data_filter_mode : exact + ret = cluster.ckb_nodes[0].getClient().get_cells({ + "script": { + "code_hash": codehash, + "hash_type": "type", + "args": "0x02" + }, + "script_type": "type", + "filter": { + "output_data": "0x0303", + "output_data_filter_mode": "exact" + } + }, "asc", "0xff", None) + assert ret['objects'][0]['output_data'] == '0x0303' + + # output_data_filter_mode : partial + ret = cluster.ckb_nodes[0].getClient().get_cells({ + "script": { + "code_hash": codehash, + "hash_type": "type", + "args": "0x02" + }, + "script_type": "type", + "filter": { + "output_data": "0x00000000ffff", + "output_data_filter_mode": "partial" + } + }, "asc", "0xff", None) + assert ret['objects'][0]['output_data'] == '0xffff00000000ffff' diff --git a/test_cases/rpc/test_get_cells_capacity.py b/test_cases/rpc/test_get_cells_capacity.py new file mode 100644 index 0000000..e5c319f --- /dev/null +++ b/test_cases/rpc/test_get_cells_capacity.py @@ -0,0 +1,148 @@ +from framework.helper.contract import deploy_ckb_contract, invoke_ckb_contract, get_ckb_contract_codehash +from framework.util import get_project_root +from framework.config import MINER_PRIVATE_1 +from framework.helper.miner import miner_until_tx_committed +from test_cases.rpc.node_fixture import get_cluster + + +class TestGetCellsCapacity: + + def test_get_cells_capacity_output_data_filter_mode(self, get_cluster): + cluster = get_cluster + deploy_hash = deploy_ckb_contract(MINER_PRIVATE_1, + f"{get_project_root()}/source/contract/always_success", + enable_type_id=True, + api_url=cluster.ckb_nodes[0].getClient().url) + miner_until_tx_committed(cluster.ckb_nodes[0], deploy_hash) + for i in range(1, 10): + invoke_hash = invoke_ckb_contract(account_private=MINER_PRIVATE_1, + contract_out_point_tx_hash=deploy_hash, + contract_out_point_tx_index=0, + type_script_arg="0x02", data=f"0x{i:02x}{i:02x}", + hash_type="type", + api_url=cluster.ckb_nodes[0].getClient().url) + miner_until_tx_committed(cluster.ckb_nodes[0], invoke_hash) + invoke_hash = invoke_ckb_contract(account_private=MINER_PRIVATE_1, + contract_out_point_tx_hash=deploy_hash, + contract_out_point_tx_index=0, + type_script_arg="0x02", data="0xffff00000000ffff", + hash_type="type", + api_url=cluster.ckb_nodes[0].getClient().url) + miner_until_tx_committed(cluster.ckb_nodes[0], invoke_hash) + + codehash = get_ckb_contract_codehash(deploy_hash, 0, + enable_type_id=True, + api_url=cluster.ckb_nodes[0].getClient().url) + # output_data_filter_mode : prefix + + ret = cluster.ckb_nodes[0].getClient().get_cells({ + "script": { + "code_hash": codehash, + "hash_type": "type", + "args": "0x02" + }, + "script_type": "type", + "filter": { + "output_data": "0x01", + "output_data_filter_mode": "prefix" + } + }, "asc", "0xff", None) + + get_cells_capacity_ret = cluster.ckb_nodes[0].getClient().get_cells_capacity({ + "script": { + "code_hash": codehash, + "hash_type": "type", + "args": "0x02" + }, + "script_type": "type", + "filter": { + "output_data": "0x01", + "output_data_filter_mode": "prefix" + } + }) + + assert ret['objects'][0]['output_data'] == '0x0101' + assert get_cells_capacity_ret['capacity'] == ret['objects'][0]['output']['capacity'] + + ret = cluster.ckb_nodes[0].getClient().get_cells({ + "script": { + "code_hash": codehash, + "hash_type": "type", + "args": "0x02" + }, + "script_type": "type", + "filter": { + "output_data": "0x02", + "output_data_filter_mode": "prefix" + } + }, "asc", "0xff", None) + get_cells_capacity_ret = cluster.ckb_nodes[0].getClient().get_cells_capacity({ + "script": { + "code_hash": codehash, + "hash_type": "type", + "args": "0x02" + }, + "script_type": "type", + "filter": { + "output_data": "0x02", + "output_data_filter_mode": "prefix" + } + }) + assert ret['objects'][0]['output_data'] == '0x0202' + assert get_cells_capacity_ret['capacity'] == ret['objects'][0]['output']['capacity'] + + # output_data_filter_mode : exact + ret = cluster.ckb_nodes[0].getClient().get_cells({ + "script": { + "code_hash": codehash, + "hash_type": "type", + "args": "0x02" + }, + "script_type": "type", + "filter": { + "output_data": "0x0303", + "output_data_filter_mode": "exact" + } + }, "asc", "0xff", None) + get_cells_capacity_ret = cluster.ckb_nodes[0].getClient().get_cells_capacity({ + "script": { + "code_hash": codehash, + "hash_type": "type", + "args": "0x02" + }, + "script_type": "type", + "filter": { + "output_data": "0x0303", + "output_data_filter_mode": "exact" + } + }) + assert ret['objects'][0]['output_data'] == '0x0303' + assert get_cells_capacity_ret['capacity'] == ret['objects'][0]['output']['capacity'] + + # output_data_filter_mode : partial + ret = cluster.ckb_nodes[0].getClient().get_cells({ + "script": { + "code_hash": codehash, + "hash_type": "type", + "args": "0x02" + }, + "script_type": "type", + "filter": { + "output_data": "0x00000000ffff", + "output_data_filter_mode": "partial" + } + }, "asc", "0xff", None) + get_cells_capacity_ret = cluster.ckb_nodes[0].getClient().get_cells_capacity({ + "script": { + "code_hash": codehash, + "hash_type": "type", + "args": "0x02" + }, + "script_type": "type", + "filter": { + "output_data": "0x00000000ffff", + "output_data_filter_mode": "partial" + } + }) + assert ret['objects'][0]['output_data'] == '0xffff00000000ffff' + assert get_cells_capacity_ret['capacity'] == ret['objects'][0]['output']['capacity'] diff --git a/test_cases/rpc/test_get_transaction.py b/test_cases/rpc/test_get_transaction.py index 47c1ad1..f89225b 100644 --- a/test_cases/rpc/test_get_transaction.py +++ b/test_cases/rpc/test_get_transaction.py @@ -25,9 +25,9 @@ def test_query_tx_only_commit_is_true(self, get_cluster): cluster = get_cluster account1 = CkbTest.Ckb_cli.util_key_info_by_private_key(CkbTest.Config.ACCOUNT_PRIVATE_1) tx_hash = CkbTest.Ckb_cli.wallet_transfer_by_private_key(CkbTest.Config.ACCOUNT_PRIVATE_1, - account1["address"]["testnet"], - 140, - cluster.ckb_nodes[0].client.url) + account1["address"]["testnet"], + 140, + cluster.ckb_nodes[0].client.url) # pending tx response_enable_commit = cluster.ckb_nodes[0].getClient().get_transaction(tx_hash, None, True) @@ -74,9 +74,9 @@ def test_query_tx_without_only_commit(self, get_cluster): cluster = get_cluster account1 = CkbTest.Ckb_cli.util_key_info_by_private_key(CkbTest.Config.ACCOUNT_PRIVATE_1) tx_hash = CkbTest.Ckb_cli.wallet_transfer_by_private_key(CkbTest.Config.ACCOUNT_PRIVATE_1, - account1["address"]["testnet"], - 140, - cluster.ckb_nodes[0].client.url) + account1["address"]["testnet"], + 140, + cluster.ckb_nodes[0].client.url) # pending tx response_use_default = cluster.ckb_nodes[0].getClient().get_transaction(tx_hash) @@ -84,3 +84,32 @@ def test_query_tx_without_only_commit(self, get_cluster): assert response['tx_status']['status'] == "pending" assert response_use_default['tx_status']['status'] == "pending" CkbTest.Miner.miner_until_tx_committed(cluster.ckb_nodes[0], tx_hash) + + def test_tx_status_with_cell_base_tx(self, get_cluster): + """ + https://github.com/nervosnetwork/ckb/pull/4283 + """ + cluster = get_cluster + tip_number = cluster.ckb_nodes[0].getClient().get_tip_block_number() + block = cluster.ckb_nodes[0].getClient().get_block_by_number(hex(tip_number)) + tx = cluster.ckb_nodes[0].getClient().get_transaction(block['transactions'][0]['hash']) + assert tx['tx_status']['block_number'] == hex(tip_number) + assert tx['tx_status']['block_hash'] == block['header']['hash'] + + def test_tx_status_normal_tx(self, get_cluster): + cluster = get_cluster + account1 = CkbTest.Ckb_cli.util_key_info_by_private_key(CkbTest.Config.ACCOUNT_PRIVATE_1) + tx_hash = CkbTest.Ckb_cli.wallet_transfer_by_private_key(CkbTest.Config.ACCOUNT_PRIVATE_1, + account1["address"]["testnet"], + 140, + cluster.ckb_nodes[0].client.url) + + # pending tx + response_use_default = cluster.ckb_nodes[0].getClient().get_transaction(tx_hash) + response = cluster.ckb_nodes[0].getClient().get_transaction(tx_hash, None, False) + assert response['tx_status']['status'] == "pending" + assert response_use_default['tx_status']['status'] == "pending" + CkbTest.Miner.miner_until_tx_committed(cluster.ckb_nodes[0], tx_hash) + tx = cluster.ckb_nodes[0].getClient().get_transaction(tx_hash) + block_hash = cluster.ckb_nodes[0].getClient().get_block_hash(tx['tx_status']['block_number']) + assert block_hash == tx['tx_status']['block_hash'] \ No newline at end of file From fbcc9e87b2a8fafa12c7f4f0d9e0a5b34cfb5536 Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Mon, 26 Feb 2024 23:53:35 +0800 Subject: [PATCH 25/27] skip light tx in after 2023 --- test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py b/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py index 00a421f..0c85363 100644 --- a/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py +++ b/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py @@ -225,6 +225,7 @@ def test_05_ckb_light_client_current_spawn_contract_use_type(self): light_tx_hash = self.ckb_light_node_current.getClient().send_transaction(transaction) assert tx_hash == light_tx_hash + @pytest.mark.skip @parameterized.expand(success_files) def test_06_ckb_light_client_deploy_and_invoke_contract(self, path): self.cluster.ckb_nodes[0].start_miner() From 2facdd1b1a958a217c7c03cde8b8f8ff2c813df1 Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Wed, 28 Feb 2024 15:51:11 +0800 Subject: [PATCH 26/27] download async ckb --- framework/test_node.py | 11 ++++++----- prepare.sh | 7 +++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/framework/test_node.py b/framework/test_node.py index 22d2d9d..b26ca26 100644 --- a/framework/test_node.py +++ b/framework/test_node.py @@ -13,8 +13,12 @@ class CkbNodeConfigPath(Enum): "source/template/ckb/v112/ckb.toml.j2", "source/template/ckb/v112/ckb-miner.toml.j2", "source/template/ckb/v112/specs/dev.toml", - "download/0.114.0" + "download/develop" ) + CURRENT_MAIN = ("source/template/ckb/v112/ckb.toml.j2", + "source/template/ckb/v112/ckb-miner.toml.j2", + "source/template/specs/mainnet.toml.j2", + "download/develop") v114 = ( "source/template/ckb/v114/ckb.toml.j2", @@ -23,10 +27,7 @@ class CkbNodeConfigPath(Enum): "download/0.114.0" ) - CURRENT_MAIN = ("source/template/ckb/v112/ckb.toml.j2", - "source/template/ckb/v112/ckb-miner.toml.j2", - "source/template/specs/mainnet.toml.j2", - "download/0.114.0") + V113 = ( "source/template/ckb/v113/ckb.toml.j2", diff --git a/prepare.sh b/prepare.sh index bea2491..9beb6e1 100644 --- a/prepare.sh +++ b/prepare.sh @@ -6,6 +6,13 @@ make prod cp target/release/ckb-cli ../source/ckb-cli cd ../ cp download/0.110.2/ckb-cli ./source/ckb-cli-old +git clone https://github.com/nervosnetwork/ckb.git +cd ckb +git checkout pkg/ckb-async-download-rc0 +make prod +cd ../ +cp -rf download/0.114.0 download/develop +cp ckb/target/prod/ckb download/develop/ckb #git clone https://github.com/quake/ckb-light-client.git #cd ckb-light-client #git checkout quake/fix-set-scripts-partial-bug From 060becf8fedf6986c25d8cb01274a6fd6169db91 Mon Sep 17 00:00:00 2001 From: gpBlockchain <744158715@qq.com> Date: Wed, 28 Feb 2024 17:20:16 +0800 Subject: [PATCH 27/27] skip test case --- .../test_03_ckb_light_client_after_hardfork.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py b/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py index 0c85363..da7cee2 100644 --- a/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py +++ b/test_cases/ckb2023/test_03_ckb_light_client_after_hardfork.py @@ -225,12 +225,12 @@ def test_05_ckb_light_client_current_spawn_contract_use_type(self): light_tx_hash = self.ckb_light_node_current.getClient().send_transaction(transaction) assert tx_hash == light_tx_hash - @pytest.mark.skip - @parameterized.expand(success_files) - def test_06_ckb_light_client_deploy_and_invoke_contract(self, path): - self.cluster.ckb_nodes[0].start_miner() - self.deploy_and_invoke(self.Config.MINER_PRIVATE_1, path, self.cluster.ckb_nodes[0]) - self.cluster.ckb_nodes[0].start_miner() + # @pytest.mark.skip + # @parameterized.expand(success_files) + # def test_06_ckb_light_client_deploy_and_invoke_contract(self, path): + # self.cluster.ckb_nodes[0].start_miner() + # self.deploy_and_invoke(self.Config.MINER_PRIVATE_1, path, self.cluster.ckb_nodes[0]) + # self.cluster.ckb_nodes[0].start_miner() def deploy_and_invoke(self, account, path, node, try_count=5): if try_count < 0: