diff --git a/.github/workflows/fiber-testnet.yml b/.github/workflows/fiber-testnet.yml index b18e3306..815bac71 100644 --- a/.github/workflows/fiber-testnet.yml +++ b/.github/workflows/fiber-testnet.yml @@ -53,6 +53,7 @@ jobs: GitBranch: '${{ github.event.inputs.GitBranch }}' BuildFIBER: '${{ github.event.inputs.BuildFIBER }}' + - name: Run tests run: make fiber_testnet_test diff --git a/.github/workflows/fiber.yml b/.github/workflows/fiber.yml index 9fe7fc41..1a0e1e99 100644 --- a/.github/workflows/fiber.yml +++ b/.github/workflows/fiber.yml @@ -2,46 +2,332 @@ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python name: fiber test - on: push: - branches: [ "fiber" ] + branches: ["fiber"] pull_request: - branches: [ "fiber" ] + branches: ["fiber"] permissions: contents: read jobs: - build: + prepare: + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + + - name: Run make prepare + run: make prepare + + - name: Tar backup + run: | + tar -czf prepare-backup.tar.gz \ + download \ + source/ckb-cli \ + source/ckb-cli-old + + - name: Backup data + uses: actions/upload-artifact@v4 + with: + name: prepare-backup-${{ runner.os }} + path: prepare-backup.tar.gz + + fiber_test_open_channel: + needs: prepare + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + + - name: Download prepare backup + uses: actions/download-artifact@v4 + with: + name: prepare-backup-${{ runner.os }} + path: ./ + + - name: Extract tarball and restore permissions + run: | + tar -xzf prepare-backup.tar.gz + + - name: Run fiber_test_demo + run: make fiber_test_demo FIBER_TEST_DEMO=test_cases/fiber/devnet/open_channel + + - name: Publish reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: jfoa-open_channel-reports-${{ runner.os }} + path: ./report + + fiber_test_accept_channel_cancel_invoice_connect_peer_disconnect_peer: + needs: prepare + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + + - name: Download prepare backup + uses: actions/download-artifact@v4 + with: + name: prepare-backup-${{ runner.os }} + path: ./ + + - name: Extract tarball and restore permissions + run: | + tar -xzf prepare-backup.tar.gz + + - name: Run fiber_test_demo + run: make fiber_test_demo FIBER_TEST_DEMO="test_cases/fiber/devnet/accept_channel test_cases/fiber/devnet/cancel_invoice test_cases/fiber/devnet/connect_peer test_cases/fiber/devnet/disconnect_peer" + + - name: Publish reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: jfoa-accept_channel_to_disconnect_peer-reports-${{ runner.os }} + path: ./report + + fiber_test_get_invoice_graph_channels_graph_nodes_list_channels_new_invoice: + needs: prepare + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + + - name: Download prepare backup + uses: actions/download-artifact@v4 + with: + name: prepare-backup-${{ runner.os }} + path: ./ + + - name: Extract tarball and restore permissions + run: | + tar -xzf prepare-backup.tar.gz + + - name: Run fiber_test_demo + run: make fiber_test_demo FIBER_TEST_DEMO="test_cases/fiber/devnet/get_invoice test_cases/fiber/devnet/graph_channels test_cases/fiber/devnet/graph_nodes test_cases/fiber/devnet/list_channels test_cases/fiber/devnet/new_invoice" + + - name: Publish reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: jfoa-accept_channel_to_disconnect_peer-reports-${{ runner.os }} + path: ./report + + fiber_test_send_payment_module_offline: + needs: prepare + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + + - name: Download prepare backup + uses: actions/download-artifact@v4 + with: + name: prepare-backup-${{ runner.os }} + path: ./ + + - name: Extract tarball and restore permissions + run: | + tar -xzf prepare-backup.tar.gz + + - name: Run fiber_test_demo + run: make fiber_test_demo FIBER_TEST_DEMO="test_cases/fiber/devnet/send_payment/module test_cases/fiber/devnet/send_payment/offline" + + - name: Publish reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: jfoa-send_payment-module-offline-reports-${{ runner.os }} + path: ./report + + fiber_test_send_payment_params_path: + needs: prepare + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + + - name: Download prepare backup + uses: actions/download-artifact@v4 + with: + name: prepare-backup-${{ runner.os }} + path: ./ + + - name: Extract tarball and restore permissions + run: | + tar -xzf prepare-backup.tar.gz + + - name: Run fiber_test_demo + run: make fiber_test_demo FIBER_TEST_DEMO="test_cases/fiber/devnet/send_payment/params test_cases/fiber/devnet/send_payment/path" + + - name: Publish reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: jfoa-send_payment-params-path-reports-${{ runner.os }} + path: ./report + + fiber_test_shutdown_channel_update_channel_issue: + needs: prepare runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 - - name: Set up Python 3.10 - uses: actions/setup-python@v3 - with: - python-version: "3.10" + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" - - name: Install dependencies - run: | - python -m pip install --upgrade pip - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + + - name: Download prepare backup + uses: actions/download-artifact@v4 + with: + name: prepare-backup-${{ runner.os }} + path: ./ + + - name: Extract tarball and restore permissions + run: | + tar -xzf prepare-backup.tar.gz + + - name: Run fiber_test_demo + run: make fiber_test_demo FIBER_TEST_DEMO="test_cases/fiber/devnet/shutdown_channel test_cases/fiber/devnet/update_channel test_cases/fiber/devnet/issue" + + - name: Publish reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: jfoa-send_payment-reports-${{ runner.os }} + path: ./report + + + fiber_test_watch_tower: + needs: prepare + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + + - name: Download prepare backup + uses: actions/download-artifact@v4 + with: + name: prepare-backup-${{ runner.os }} + path: ./ + + - name: Extract tarball and restore permissions + run: | + tar -xzf prepare-backup.tar.gz + + - name: Run fiber_test_demo + run: make fiber_test_demo FIBER_TEST_DEMO="test_cases/fiber/devnet/watch_tower" + - name: Publish reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: jfoa-watch_tower-reports-${{ runner.os }} + path: ./report + + + fiber_test_watch_tower_tlc: + needs: prepare + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" - - name: Install dependencies - run: make prepare + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - name: Run tests - run: make fiber_test + - name: Download prepare backup + uses: actions/download-artifact@v4 + with: + name: prepare-backup-${{ runner.os }} + path: ./ -# - name: Setup upterm session -# if: always() -# uses: lhotari/action-upterm@v1 + - name: Extract tarball and restore permissions + run: | + tar -xzf prepare-backup.tar.gz - - name: Publish reports - if: failure() - uses: actions/upload-artifact@v4 - with: - name: jfoa-build-reports-${{ runner.os }} - path: ./report + - name: Run fiber_test_demo + run: make fiber_test_demo FIBER_TEST_DEMO="test_cases/fiber/devnet/watch_tower_wit_tlc" + - name: Publish reports + if: failure() + uses: actions/upload-artifact@v4 + with: + name: jfoa-watch_tower-reports-${{ runner.os }} + path: ./report diff --git a/Makefile b/Makefile index 0fe8ada3..50447be8 100644 --- a/Makefile +++ b/Makefile @@ -89,7 +89,6 @@ fiber_test_cases := \ test_cases/fiber/devnet/shutdown_channel \ test_cases/fiber/devnet/update_channel \ test_cases/fiber/devnet/issue \ - test_cases/fiber/devnet/compatibility \ test_cases/fiber/devnet/watch_tower fiber_testnet_cases := \ @@ -139,6 +138,21 @@ fiber_test: exit 1; \ fi +fiber_test_demo: + @failed_cases=; \ + echo "Running tests for $$FIBER_TEST_DEMO"; \ + for test_case in $(FIBER_TEST_DEMO); do \ + echo "Running tests for $$test_case"; \ + if ! bash test.sh "$$test_case"; then \ + echo "$$test_case" >> failed_test_cases.txt; \ + fi \ + done; \ + if [ -s failed_test_cases.txt ]; then \ + echo "Some test cases failed: $$(cat failed_test_cases.txt)"; \ + rm -f failed_test_cases.txt; \ + exit 1; \ + fi + develop_test: @failed_cases=; \ for test_case in $(TestCases); do \ diff --git a/download_ckb_light_client.py b/download_ckb_light_client.py index 90fc152f..f5876a86 100644 --- a/download_ckb_light_client.py +++ b/download_ckb_light_client.py @@ -36,7 +36,7 @@ }, "arm64": { "url": "https://github.com/nervosnetwork/fiber/releases/download/v{version}/fnn_v{" - "version}-x86_64-darwin.tar.gz", + "version}-x86_64-darwin-portable.tar.gz", "ext": ".tar.gz", }, }, diff --git a/download_fiber.py b/download_fiber.py index 25cae650..f9262bde 100644 --- a/download_fiber.py +++ b/download_fiber.py @@ -11,7 +11,15 @@ import requests from tqdm import tqdm -versions = ["0.2.0", "0.2.1", "0.3.0", "0.3.1"] # Replace with your versions +versions = [ + "0.2.0", + "0.2.1", + "0.3.0", + "0.3.1", + "0.4.0", + "0.4.2", + "0.5.0", +] # Replace with your versions DOWNLOAD_DIR = "download/fiber" SYSTEMS = { @@ -35,7 +43,7 @@ }, "arm64": { "url": "https://github.com/nervosnetwork/fiber/releases/download/v{version}/fnn_v{" - "version}-x86_64-darwin.tar.gz", + "version}-x86_64-darwin-portable.tar.gz", "ext": ".tar.gz", }, }, diff --git a/framework/basic_fiber.py b/framework/basic_fiber.py index 0a7707d6..745e6298 100644 --- a/framework/basic_fiber.py +++ b/framework/basic_fiber.py @@ -22,6 +22,7 @@ class FiberTest(CkbTest): debug = False first_debug = False logger = logging.getLogger(__name__) + start_fiber_config = {} @classmethod def setup_class(cls): @@ -113,31 +114,21 @@ def setup_method(cls, method): cls.node.start_miner() # deploy fiber # start 2 fiber with xudt + update_config = { + "ckb_rpc_url": cls.node.rpcUrl, + "ckb_udt_whitelist": True, + "xudt_script_code_hash": cls.Contract.get_ckb_contract_codehash( + deploy_hash, deploy_index, True, cls.node.rpcUrl + ), + "xudt_cell_deps_tx_hash": deploy_hash, + "xudt_cell_deps_index": deploy_index, + } + update_config.update(cls.start_fiber_config) - cls.fiber1.prepare( - update_config={ - "ckb_rpc_url": cls.node.rpcUrl, - "ckb_udt_whitelist": True, - "xudt_script_code_hash": cls.Contract.get_ckb_contract_codehash( - deploy_hash, deploy_index, True, cls.node.rpcUrl - ), - "xudt_cell_deps_tx_hash": deploy_hash, - "xudt_cell_deps_index": deploy_index, - } - ) + cls.fiber1.prepare(update_config=update_config) cls.fiber1.start(cls.node) - cls.fiber2.prepare( - update_config={ - "ckb_rpc_url": cls.node.rpcUrl, - "ckb_udt_whitelist": True, - "xudt_script_code_hash": cls.Contract.get_ckb_contract_codehash( - deploy_hash, deploy_index, True, cls.node.rpcUrl - ), - "xudt_cell_deps_tx_hash": deploy_hash, - "xudt_cell_deps_index": deploy_index, - } - ) + cls.fiber2.prepare(update_config=update_config) cls.fiber2.start(cls.node) before_balance1 = cls.Ckb_cli.wallet_get_capacity( cls.account1["address"]["testnet"], api_url=cls.node.getClient().url @@ -246,6 +237,7 @@ def start_new_fiber( "xudt_cell_deps_tx_hash": deploy_hash, "xudt_cell_deps_index": deploy_index, } + update_config.update(self.start_fiber_config) i = len(self.new_fibers) # start fiber3 @@ -307,6 +299,7 @@ def open_channel( fiber2_balance, fiber1_fee=1000, fiber2_fee=1000, + udt=None, ): fiber1.connect_peer(fiber2) time.sleep(1) @@ -343,6 +336,7 @@ def open_channel( "funding_amount": hex(fiber1_balance + fiber2_balance + 62 * 100000000), "tlc_fee_proportional_millionths": hex(fiber1_fee), "public": True, + "funding_udt_type_script": udt, } ) self.wait_for_channel_state( @@ -356,7 +350,7 @@ def open_channel( # "keysend": True, # } # ) - self.send_payment(fiber1, fiber2, fiber2_balance, True, None, 10) + self.send_payment(fiber1, fiber2, fiber2_balance, True, udt, 10) fiber2.get_client().update_channel( { "channel_id": channels["channels"][0]["channel_id"], @@ -407,14 +401,14 @@ def get_account_script(self, account_private_key): "args": account1["lock_arg"], } - def wait_payment_state(self, client, payment_hash, status="Success", timeout=120): + def wait_payment_state(self, client, payment_hash, status="Success", timeout=360): for i in range(timeout): result = client.get_client().get_payment({"payment_hash": payment_hash}) if result["status"] == status: return time.sleep(1) raise TimeoutError( - f"status did not reach state {expected_state} within timeout period." + f"status did not reach state: {status} within timeout period." ) def wait_payment_finished(self, client, payment_hash, timeout=120): @@ -436,22 +430,31 @@ def get_fibers_balance_message(self): def get_fiber_balance(self, fiber): channels = fiber.get_client().list_channels({}) + balance_map = {} + channels_balance = 0 channels_offered_tlc_balance = 0 channels_received_tlc_balance = 0 for i in range(len(channels["channels"])): channel = channels["channels"][i] if channel["state"]["state_name"] == "CHANNEL_READY": - channels_balance += int(channel["local_balance"], 16) - channels_offered_tlc_balance += int(channel["offered_tlc_balance"], 16) - channels_received_tlc_balance += int( + key = "ckb" + if channel["funding_udt_type_script"] is not None: + key = channel["funding_udt_type_script"]["args"] + if balance_map.get(key) is None: + balance_map[key] = { + "local_balance": 0, + "offered_tlc_balance": 0, + "received_tlc_balance": 0, + } + balance_map[key]["local_balance"] += int(channel["local_balance"], 16) + balance_map[key]["offered_tlc_balance"] += int( + channel["offered_tlc_balance"], 16 + ) + balance_map[key]["received_tlc_balance"] += int( channel["received_tlc_balance"], 16 ) - return { - "local_balance": channels_balance, - "offered_tlc_balance": channels_offered_tlc_balance, - "received_tlc_balance": channels_received_tlc_balance, - } + return balance_map def calculate_tx_fee(self, balance, fee_list): """ @@ -484,19 +487,22 @@ def wait_tx_pool(self, pending_size, try_size=100): f"status did not reach state {expected_state} within timeout period." ) - def wait_and_check_tx_pool_fee(self, fee_rate, check=True, try_size=120): + def wait_and_check_tx_pool_fee( + self, fee_rate, check=True, try_size=120, up_and_down_rate=0.1 + ): self.wait_tx_pool(1, try_size) pool = self.node.getClient().get_raw_tx_pool() pool_tx_detail_info = self.node.getClient().get_pool_tx_detail_info( pool["pending"][0] ) if check: - assert ( - int(pool_tx_detail_info["score_sortkey"]["fee"], 16) - * 1000 - / int(pool_tx_detail_info["score_sortkey"]["weight"], 16) - == fee_rate - ) + assert int(pool_tx_detail_info["score_sortkey"]["fee"], 16) * 1000 / int( + pool_tx_detail_info["score_sortkey"]["weight"], 16 + ) <= fee_rate * (1 + up_and_down_rate) + + assert int(pool_tx_detail_info["score_sortkey"]["fee"], 16) * 1000 / int( + pool_tx_detail_info["score_sortkey"]["weight"], 16 + ) >= fee_rate * (1 - up_and_down_rate) return pool["pending"][0] def wait_invoice_state( @@ -576,7 +582,16 @@ def get_tx_message(self, tx_hash): } ) print({"input_cells": input_cells, "output_cells": output_cells}) - return {"input_cells": input_cells, "output_cells": output_cells} + input_cap = 0 + for i in range(len(input_cells)): + input_cap = input_cap + input_cells[i]["capacity"] + for i in range(len(output_cells)): + input_cap = input_cap - output_cells[i]["capacity"] + return { + "input_cells": input_cells, + "output_cells": output_cells, + "fee": input_cap, + } def get_fiber_env(self, new_fiber_count=0): # self.logger.debug ckb tip number diff --git a/framework/fiber_rpc.py b/framework/fiber_rpc.py index da833438..c56d3d37 100644 --- a/framework/fiber_rpc.py +++ b/framework/fiber_rpc.py @@ -16,6 +16,15 @@ def __init__(self, url): def send_btc(self, btc_pay_req): return self.call("send_btc", [btc_pay_req]) + def build_router(self, param): + return self.call("build_router", [param]) + + def send_payment_with_router(self, param): + return self.call("send_payment_with_router", [param]) + + def abandon_channel(self, param): + return self.call("abandon_channel", [param]) + def open_channel(self, param): """ curl --location 'http://127.0.0.1:8227' --header 'Content-Type: application/json' --data '{ @@ -193,9 +202,15 @@ def graph_channels(self, param={}): """ return self.call("graph_channels", [param]) + def remove_watch_channel(self, param): + return self.call("remove_watch_channel", [param]) + def get_peer_id(self): return self.node_info()["addresses"][0].split("/")[-1] + def list_peers(self): + return self.call("list_peers", []) + def call(self, method, params): headers = {"content-type": "application/json"} data = {"id": 42, "jsonrpc": "2.0", "method": method, "params": params} @@ -204,7 +219,7 @@ def call(self, method, params): url=self.url, data=json.dumps(data, indent=4) ) ) - for i in range(100): + for i in range(200): try: response = requests.post( self.url, data=json.dumps(data), headers=headers diff --git a/framework/helper/miner.py b/framework/helper/miner.py index 3de02d35..6b27d7d3 100644 --- a/framework/helper/miner.py +++ b/framework/helper/miner.py @@ -55,10 +55,16 @@ def miner_until_tx_committed(node, tx_hash, with_unknown=False): # support > 0x0 when ckb2023 active def miner_with_version(node, version): # get_block_template - block = node.getClient().get_block_template() - node.getClient().submit_block( - block["work_id"], block_template_transfer_to_submit_block(block, version) - ) + for i in range(10): + try: + block = node.getClient().get_block_template() + node.getClient().submit_block( + block["work_id"], + block_template_transfer_to_submit_block(block, version), + ) + break + except Exception as e: + time.sleep(1) pool = node.getClient().tx_pool_info() header = node.getClient().get_tip_header() print( diff --git a/framework/helper/udt_contract.py b/framework/helper/udt_contract.py index d8cdb89a..223e9ab8 100644 --- a/framework/helper/udt_contract.py +++ b/framework/helper/udt_contract.py @@ -57,7 +57,11 @@ def transfer(cls, own_arg, amount) -> (str, str): return ckb_hash_script(own_arg), to_big_uint128_le_compatible(amount) def balance(self, client, own_arg, query_arg): - pass + cells = self.list_cell(client, own_arg, query_arg) + balance = 0 + for cell in cells: + balance += cell["balance"] + return balance def list_cell(self, client, own_arg, query_arg): code_hash = get_ckb_contract_codehash( diff --git a/framework/rpc.py b/framework/rpc.py index fd05172a..b14daaa1 100644 --- a/framework/rpc.py +++ b/framework/rpc.py @@ -99,9 +99,9 @@ def get_consensus(self): def get_fee_rate_statics(self, target=None): return self.call("get_fee_rate_statics", [target]) - def generate_epochs(self, epoch): + def generate_epochs(self, epoch, wait_time=2): response = self.call("generate_epochs", [epoch]) - time.sleep(1) + time.sleep(wait_time) return response def generate_block(self): diff --git a/framework/test_fiber.py b/framework/test_fiber.py index 21db4fcb..7b54d0ef 100644 --- a/framework/test_fiber.py +++ b/framework/test_fiber.py @@ -18,19 +18,22 @@ class FiberConfigPath(Enum): CURRENT_DEV = ( - "/source/template/fiber/dev_config.yml.j2", + "/source/template/fiber/dev_config_2.yml.j2", "download/fiber/current/fnn", ) CURRENT_TESTNET = ( - "/source/template/fiber/config.yml.j2", - "download/fiber/0.3.1/fnn", + "/source/template/fiber/testnet_config_2.yml.j2", + "download/fiber/0.5.0/fnn", ) + V042_TESTNET = ("/source/template/fiber/config.yml.j2", "download/fiber/0.4.2/fnn") + V040_TESTNET = ("/source/template/fiber/config.yml.j2", "download/fiber/0.4.0/fnn") V031_TESTNET = ("/source/template/fiber/config.yml.j2", "download/fiber/0.3.1/fnn") V030_TESTNET = ("/source/template/fiber/config.yml.j2", "download/fiber/0.3.0/fnn") V020_TESTNET = ("/source/template/fiber/config.yml.j2", "download/fiber/0.2.0/fnn") V010_TESTNET = ("/source/template/fiber/config.yml.j2", "download/fiber/0.1.0/fnn") + V040_DEV = ("/source/template/fiber/dev_config.yml.j2", "download/fiber/0.4.0/fnn") V031_DEV = ("/source/template/fiber/dev_config.yml.j2", "download/fiber/0.3.1/fnn") V030_DEV = ("/source/template/fiber/dev_config.yml.j2", "download/fiber/0.3.0/fnn") V021_DEV = ("/source/template/fiber/dev_config.yml.j2", "download/fiber/0.2.1/fnn") diff --git a/framework/test_node.py b/framework/test_node.py index 38bb63ae..889284a8 100644 --- a/framework/test_node.py +++ b/framework/test_node.py @@ -281,8 +281,10 @@ def stop(self): # run_command("kill {pid}".format(pid=self.ckb_pid)) # self.ckb_pid = -1 port = self.rpcUrl.split(":")[-1] - - run_command(f"kill $(lsof -t -i:{port})", check_exit_code=False) + run_command( + f"kill $(lsof -i:{port} | grep LISTEN | awk '{{print $2}}')", + check_exit_code=False, + ) self.ckb_pid = -1 time.sleep(3) @@ -318,7 +320,7 @@ def prepare( root_path=get_project_root(), spec_path=self.ckb_config_path.ckb_spec_path, ), - self.ckb_dir, + "{ckb_dir}/dev.toml".format(ckb_dir=self.ckb_dir), ) shutil.copy( diff --git a/prepare.sh b/prepare.sh index 013f1009..4d1c4bea 100644 --- a/prepare.sh +++ b/prepare.sh @@ -3,6 +3,7 @@ cp download/0.117.0/ckb-cli ./source/ckb-cli cp download/0.110.2/ckb-cli ./source/ckb-cli-old git clone https://github.com/nervosnetwork/fiber cd fiber +git checkout v0.5.0-rc1 cargo build cp target/debug/fnn ../download/fiber/current/fnn cd migrate diff --git a/source/contract/fiber/auth b/source/contract/fiber/auth index 726e4d8b..e59d00fb 100755 Binary files a/source/contract/fiber/auth and b/source/contract/fiber/auth differ diff --git a/source/contract/fiber/commitment-lock b/source/contract/fiber/commitment-lock old mode 100755 new mode 100644 index ac071386..6d264b8b Binary files a/source/contract/fiber/commitment-lock and b/source/contract/fiber/commitment-lock differ diff --git a/source/contract/fiber/funding-lock b/source/contract/fiber/funding-lock old mode 100755 new mode 100644 index ec974f32..22067027 Binary files a/source/contract/fiber/funding-lock and b/source/contract/fiber/funding-lock differ diff --git a/source/template/fiber/config.yml.j2 b/source/template/fiber/config.yml.j2 index 6816a59f..8981b8f9 100644 --- a/source/template/fiber/config.yml.j2 +++ b/source/template/fiber/config.yml.j2 @@ -13,11 +13,11 @@ fiber: args: 0x cell_deps: - out_point: - tx_hash: 0x89af398edc7ed0054506b33349b031097d94378e11e77bf0690ee69d82623a43 - index: 0x0 + tx_hash: 0x5a5288769cecde6451cb5d301416c297a6da43dc3ac2f3253542b4082478b19b + index: 0x1 dep_type: code - out_point: - tx_hash: 0xbfd6d68b328a02606f1f65ee0f79f8ed5f76dfe86998c7aaa9ee4720d53f4c49 # ckb_auth + tx_hash: 0x5a5288769cecde6451cb5d301416c297a6da43dc3ac2f3253542b4082478b19b # ckb_auth index: 0x0 dep_type: code - name: CommitmentLock @@ -27,14 +27,13 @@ fiber: args: 0x cell_deps: - out_point: - tx_hash: 0x89af398edc7ed0054506b33349b031097d94378e11e77bf0690ee69d82623a43 - index: 0x1 + tx_hash: 0x5a5288769cecde6451cb5d301416c297a6da43dc3ac2f3253542b4082478b19b + index: 0x2 dep_type: code - out_point: - tx_hash: 0xbfd6d68b328a02606f1f65ee0f79f8ed5f76dfe86998c7aaa9ee4720d53f4c49 #ckb_auth + tx_hash: 0x5a5288769cecde6451cb5d301416c297a6da43dc3ac2f3253542b4082478b19b #ckb_auth index: 0x0 dep_type: code - rpc: listening_addr: {{ rpc_listening_addr | default("127.0.0.1:8227") }} enabled_modules: diff --git a/source/template/fiber/dev_config.yml.j2 b/source/template/fiber/dev_config.yml.j2 index de40cf1a..467d7ea8 100644 --- a/source/template/fiber/dev_config.yml.j2 +++ b/source/template/fiber/dev_config.yml.j2 @@ -6,6 +6,8 @@ fiber: gossip_store_maintenance_interval_ms: 1000 gossip_network_maintenance_interval_ms: 1000 open_channel_auto_accept_min_ckb_funding_amount: {{ fiber_open_channel_auto_accept_min_ckb_funding_amount | default(10000000000)}} + watchtower_check_interval_seconds: {{ fiber_watchtower_check_interval_seconds | default(60) }} + tlc_expiry_delta: {{ fiber_tlc_expiry_delta | default(86400000) }} rpc: listening_addr: {{ rpc_listening_addr | default("127.0.0.1:8227") }} diff --git a/source/template/fiber/dev_config_2.yml.j2 b/source/template/fiber/dev_config_2.yml.j2 new file mode 100644 index 00000000..4f879049 --- /dev/null +++ b/source/template/fiber/dev_config_2.yml.j2 @@ -0,0 +1,44 @@ +fiber: + listening_addr: {{ fiber_listening_addr | default("/ip4/127.0.0.1/tcp/8228") }} + chain: dev.toml + announce_listening_addr: true + announce_private_addr: true + gossip_store_maintenance_interval_ms: 1000 + gossip_network_maintenance_interval_ms: 1000 + open_channel_auto_accept_min_ckb_funding_amount: {{ fiber_open_channel_auto_accept_min_ckb_funding_amount | default(10000000000)}} + watchtower_check_interval_seconds: {{ fiber_watchtower_check_interval_seconds | default(60) }} + tlc_expiry_delta: {{ fiber_tlc_expiry_delta | default(86400000) }} + +rpc: + listening_addr: {{ rpc_listening_addr | default("127.0.0.1:8227") }} + enabled_modules: + - cch + - channel + - payment + - graph + - info + - invoice + - peer + - dev +ckb: + rpc_url: {{ ckb_rpc_url | default("http://127.0.0.1:8114") }} + {% if ckb_udt_whitelist is defined %} + udt_whitelist: + - name: XUDT + + script: + code_hash: {{ xudt_script_code_hash }} + hash_type: type + args: 0x32e555f3ff8e135cece1351a6a2971518392c1e30375c1e006ad0ce8eac07947 + cell_deps: + - type_id: + code_hash: 0x00000000000000000000000000000000000000000000000000545950455f4944 + hash_type: type + args: 0xd0e6998c64e5e3ac7f04f1c05cc41c5c36af05db696333a762d4f1ef2f407468 + auto_accept_amount: {{ fiber_auto_accept_amount | default(1000000000)}} + {% endif %} + +services: + - fiber + - rpc + - ckb diff --git a/source/template/fiber/main_config.yml.j2 b/source/template/fiber/main_config.yml.j2 new file mode 100644 index 00000000..e5315b5c --- /dev/null +++ b/source/template/fiber/main_config.yml.j2 @@ -0,0 +1,71 @@ +# This configuration file only contains the necessary configurations for the mainnet deployment. +# All options' descriptions can be found via `fnn --help` and be overridden by command line arguments or environment variables. +fiber: + listening_addr: {{ fiber_listening_addr | default("/ip4/127.0.0.1/tcp/8228") }} + bootnode_addrs: + # - "/ip4/43.199.24.44/tcp/8228/p2p/" + # - "/ip4/54.255.71.126/tcp/8228/p2p/" + announce_listening_addr: true + announce_private_addr: true + announced_addrs: + # If you want to announce your fiber node public address to the network, you need to add the address here, please change the ip to your public ip accordingly. + # - "/ip4/YOUR-FIBER-NODE-PUBLIC-IP/tcp/8228" + chain: mainnet + # lock script configurations related to fiber network + # https://github.com/nervosnetwork/fiber-scripts/blob/main/deployment/mainnet/migrations/2025-02-28-114908.json + scripts: + - name: FundingLock + script: + code_hash: 0xe45b1f8f21bff23137035a3ab751d75b36a981deec3e7820194b9c042967f4f1 + hash_type: type + args: 0x + cell_deps: + - out_point: + tx_hash: 0x22ccb3018ca1aa7acd7b0ef7f5b01048be2525bb7364eafc8af04fd4d7279384 + index: 0x1 + dep_type: code + - out_point: + tx_hash: 0x22ccb3018ca1aa7acd7b0ef7f5b01048be2525bb7364eafc8af04fd4d7279384 # ckb_auth + index: 0x0 + dep_type: code + - name: CommitmentLock + script: + code_hash: 0x2d45c4d3ed3e942f1945386ee82a5d1b7e4bb16d7fe1ab015421174ab747406c + hash_type: type + args: 0x + cell_deps: + - out_point: + tx_hash: 0x22ccb3018ca1aa7acd7b0ef7f5b01048be2525bb7364eafc8af04fd4d7279384 + index: 0x2 + dep_type: code + - out_point: + tx_hash: 0x22ccb3018ca1aa7acd7b0ef7f5b01048be2525bb7364eafc8af04fd4d7279384 #ckb_auth + index: 0x0 + dep_type: code + +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. + listening_addr: {{ rpc_listening_addr | default("127.0.0.1:8227") }} + +ckb: + # Please use a trusted CKB RPC node, the node should be able to provide the correct data and should be stable. + rpc_url: "https://mainnet.ckbapp.dev/" + udt_whitelist: + ## https://github.com/CKBFansDAO/xudtlogos/blob/f2557839ecde0409ba674516a62ae6752bc0daa9/public/tokens/token_list.json#L548 + # - name: USDI + # script: + # code_hash: 0xbfa35a9c38a676682b65ade8f02be164d48632281477e36f8dc2f41f79e56bfc + # hash_type: type + # args: 0xd591ebdc69626647e056e13345fd830c8b876bb06aa07ba610479eb77153ea9f + # cell_deps: + # - tx_hash: 0xf6a5eef65101899db9709c8de1cc28f23c1bee90d857ebe176f6647ef109e20d + # index: 0 + # dep_type: code + # auto_accept_amount: 10000000 + +services: + - fiber + - rpc + - ckb \ No newline at end of file diff --git a/source/template/fiber/testnet_config_2.yml.j2 b/source/template/fiber/testnet_config_2.yml.j2 new file mode 100644 index 00000000..3f033864 --- /dev/null +++ b/source/template/fiber/testnet_config_2.yml.j2 @@ -0,0 +1,71 @@ +fiber: + listening_addr: {{ fiber_listening_addr | default("/ip4/127.0.0.1/tcp/8228") }} + chain: testnet + bootnode_addrs: + - "/ip4/54.179.226.154/tcp/8228/p2p/Qmes1EBD4yNo9Ywkfe6eRw9tG1nVNGLDmMud1xJMsoYFKy" + - "/ip4/54.179.226.154/tcp/18228/p2p/QmdyQWjPtbK4NWWsvy8s69NGJaQULwgeQDT5ZpNDrTNaeV" + announce_listening_addr: true + announce_private_addr: true + scripts: + - name: FundingLock + script: + code_hash: 0x6c67887fe201ee0c7853f1682c0b77c0e6214044c156c7558269390a8afa6d7c + hash_type: type + args: 0x + cell_deps: + - type_id: + code_hash: 0x00000000000000000000000000000000000000000000000000545950455f4944 + hash_type: type + args: 0x3cb7c0304fe53f75bb5727e2484d0beae4bd99d979813c6fc97c3cca569f10f6 + - cell_dep: + out_point: + tx_hash: 0x5a5288769cecde6451cb5d301416c297a6da43dc3ac2f3253542b4082478b19b # ckb_auth + index: 0x0 + dep_type: code + - name: CommitmentLock + script: + code_hash: 0x740dee83f87c6f309824d8fd3fbdd3c8380ee6fc9acc90b1a748438afcdf81d8 + hash_type: type + args: 0x + cell_deps: + - type_id: + code_hash: 0x00000000000000000000000000000000000000000000000000545950455f4944 + hash_type: type + args: 0xf7e458887495cf70dd30d1543cad47dc1dfe9d874177bf19291e4db478d5751b + - cell_dep: + out_point: + tx_hash: 0x5a5288769cecde6451cb5d301416c297a6da43dc3ac2f3253542b4082478b19b #ckb_auth + index: 0x0 + dep_type: code +rpc: + listening_addr: {{ rpc_listening_addr | default("127.0.0.1:8227") }} + enabled_modules: + - cch + - channel + - payment + - graph + - info + - invoice + - peer + - dev + +ckb: + rpc_url: "https://testnet.ckb.dev" + open_channel_auto_accept_min_ckb_funding_amount: {{ fiber_open_channel_auto_accept_min_ckb_funding_amount | default(10000000000)}} + udt_whitelist: + - name: RUSD + script: + code_hash: 0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a + hash_type: type + args: 0x878fcc6f1f08d48e87bb1c3b3d5083f23f8a39c5d5c764f253b55b998526439b + cell_deps: + - type_id: + code_hash: 0x00000000000000000000000000000000000000000000000000545950455f4944 + hash_type: type + args: 0x97d30b723c0b2c66e9cb8d4d0df4ab5d7222cbb00d4a9a2055ce2e5d7f0d8b0f + auto_accept_amount: {{ fiber_auto_accept_amount | default(1000000000)}} + +services: + - fiber + - rpc + - ckb diff --git a/test_cases/fiber/devnet/abandon_channel/test_abandon_channel.py b/test_cases/fiber/devnet/abandon_channel/test_abandon_channel.py new file mode 100644 index 00000000..bcab757b --- /dev/null +++ b/test_cases/fiber/devnet/abandon_channel/test_abandon_channel.py @@ -0,0 +1,149 @@ +import time + +import pytest + +from framework.basic_fiber import FiberTest + + +class TestAbandonChannel(FiberTest): + """ + abandon channel + 存在的chain id + tmp_id + channel 状态 + sign + await tx ready + ready + shutdown + close + 批量open_channel 随机abandon channel + 不存在的channel id + """ + + def test_tmp_id(self): + channel = self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1 + 62 * 100000000), + "public": True, + } + ) + time.sleep(1) + response = self.fiber1.get_client().abandon_channel( + {"channel_id": channel["temporary_channel_id"]} + ) + self.fiber2.get_client().accept_channel( + { + "temporary_channel_id": channel["temporary_channel_id"], + "funding_amount": hex(62 * 100000000), + } + ) + channel = self.fiber1.get_client().list_channels({}) + assert len(channel["channels"]) == 0 + channel = self.fiber2.get_client().list_channels({}) + assert len(channel["channels"]) == 0 + + def test_abandon_channel_accept(self): + channel = self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1 + 62 * 100000000), + "public": True, + } + ) + time.sleep(1) + self.fiber2.get_client().accept_channel( + { + "temporary_channel_id": channel["temporary_channel_id"], + "funding_amount": hex(62 * 100000000), + } + ) + # self.wait_and_check_tx_pool_fee(1000, False, 120) + time.sleep(1) + # Test AbandonChannel + channel_id = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + + with pytest.raises(Exception) as exc_info: + response = self.fiber1.get_client().abandon_channel( + {"channel_id": channel_id} + ) + expected_error_message = " our signature has been sent. It cannot be abandoned" + 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]}'" + ) + + def test_abandon_channel_when_tx_send(self): + channel = self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + } + ) + self.wait_and_check_tx_pool_fee(1000, False, 120) + with pytest.raises(Exception) as exc_info: + channel = self.fiber1.get_client().list_channels({}) + response = self.fiber1.get_client().abandon_channel( + {"channel_id": channel["channels"][0]["channel_id"]} + ) + + expected_error_message = "is in state AwaitingTxSignatures" + 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]}'" + ) + + def test_chain_status_ready_or_shutdown_close(self): + self.open_channel(self.fiber1, self.fiber2, 1000 * 100000000, 1) + channels = self.fiber1.get_client().list_channels({}) + + # Channel Ready + with pytest.raises(Exception) as exc_info: + response = self.fiber1.get_client().abandon_channel( + {"channel_id": channels["channels"][0]["channel_id"]} + ) + expected_error_message = ( + "cannot be abandoned, please shutdown the channel instead" + ) + 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]}'" + ) + + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": channels["channels"][0]["channel_id"], + "close_script": self.get_account_script(self.Config.ACCOUNT_PRIVATE_1), + "fee_rate": "0x3FC", + } + ) + with pytest.raises(Exception) as exc_info: + response = self.fiber1.get_client().abandon_channel( + {"channel_id": channels["channels"][0]["channel_id"]} + ) + expected_error_message = ( + "cannot be abandoned, please shutdown the channel instead" + ) + 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]}'" + ) + # closed + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CLOSED", 120, True + ) + with pytest.raises(Exception) as exc_info: + response = self.fiber1.get_client().abandon_channel( + {"channel_id": channels["channels"][0]["channel_id"]} + ) + expected_error_message = ( + "cannot be abandoned, please shutdown the channel instead" + ) + 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/fiber/devnet/accept_channel/test_max_tlc_number_in_flight.py b/test_cases/fiber/devnet/accept_channel/test_max_tlc_number_in_flight.py new file mode 100644 index 00000000..e6ede799 --- /dev/null +++ b/test_cases/fiber/devnet/accept_channel/test_max_tlc_number_in_flight.py @@ -0,0 +1,69 @@ +import time + +import pytest + +from framework.basic_fiber import FiberTest + + +class TestMaxTlcNumberInFlight(FiberTest): + + def test_max_tlc_number_in_flight(self): + """ + + Returns: + + """ + # 1. Open a new channel with fiber1 as the client and fiber2 as the peer + temporary_channel = self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(62 * 100000000), + "public": True, + } + ) + time.sleep(1) + # 2. Accept the channel with fiber2 as the client + self.fiber2.get_client().accept_channel( + { + "temporary_channel_id": temporary_channel["temporary_channel_id"], + "funding_amount": hex(1000 * 100000000), + "max_tlc_number_in_flight": hex(1), + } + ) + # 3. Wait for the channel state to be "CHANNEL_READY" + self.wait_for_channel_state( + self.fiber2.get_client(), self.fiber1.get_peer_id(), "CHANNEL_READY" + ) + # node1 send_payment to node2 + self.fiber2.get_client().add_tlc( + { + "channel_id": self.fiber2.get_client().list_channels({})["channels"][0][ + "channel_id" + ], + "amount": hex(100), + # "payment_hash": invoice_list[i]['invoice']['data']['payment_hash'], + "payment_hash": self.generate_random_preimage(), + "expiry": hex((int(time.time()) + 40) * 1000), + "hash_algorithm": "sha256", + } + ) + + with pytest.raises(Exception) as exc_info: + self.fiber2.get_client().add_tlc( + { + "channel_id": self.fiber2.get_client().list_channels({})[ + "channels" + ][0]["channel_id"], + "amount": hex(100), + # "payment_hash": invoice_list[i]['invoice']['data']['payment_hash'], + "payment_hash": self.generate_random_preimage(), + "expiry": hex((int(time.time()) + 40) * 1000), + "hash_algorithm": "sha256", + } + ) + + expected_error_message = "TemporaryChannelFailure" + 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/fiber/devnet/accept_channel/test_max_tlc_value_in_flight.py b/test_cases/fiber/devnet/accept_channel/test_max_tlc_value_in_flight.py new file mode 100644 index 00000000..2c9a3e81 --- /dev/null +++ b/test_cases/fiber/devnet/accept_channel/test_max_tlc_value_in_flight.py @@ -0,0 +1,42 @@ +import time + +from framework.basic_fiber import FiberTest + + +class TestMaxTlcValueInFlight(FiberTest): + + def test_max_tlc_value_in_flight_exist(self): + """ + max_tlc_value_in_flight = 1 ckb + Returns: + + """ + # 1. Open a new channel with fiber1 as the client and fiber2 as the peer + temporary_channel = self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(62 * 100000000), + "public": True, + } + ) + time.sleep(1) + # 2. Accept the channel with fiber2 as the client + self.fiber2.get_client().accept_channel( + { + "temporary_channel_id": temporary_channel["temporary_channel_id"], + "funding_amount": hex(1000 * 100000000), + "max_tlc_value_in_flight": hex(1 * 100000000), + } + ) + # 3. Wait for the channel state to be "CHANNEL_READY" + self.wait_for_channel_state( + self.fiber2.get_client(), self.fiber1.get_peer_id(), "CHANNEL_READY" + ) + # node1 send_payment to node2 + self.send_payment(self.fiber2, self.fiber1, 1 * 100000000) + self.send_payment(self.fiber2, self.fiber1, 1 * 100000000) + payment_hash = self.send_payment( + self.fiber2, self.fiber1, 1 * 100000000 + 1, False + ) + self.wait_payment_state(self.fiber2, payment_hash, "Failed") + self.send_payment(self.fiber1, self.fiber2, 1 * 100000000 + 1) diff --git a/test_cases/fiber/devnet/accept_channel/test_tlc_expiry_delta.py b/test_cases/fiber/devnet/accept_channel/test_tlc_expiry_delta.py new file mode 100644 index 00000000..ad5ed198 --- /dev/null +++ b/test_cases/fiber/devnet/accept_channel/test_tlc_expiry_delta.py @@ -0,0 +1,13 @@ +from framework.basic_fiber import FiberTest + + +class TestTlcExpiryDelta(FiberTest): + pass + + # def test_tlc_expiry_delta(self): + # """ + # todo + # Returns: + # + # """ + # 1. Open a new channel with fiber1 as the client and fiber2 as the peer diff --git a/test_cases/fiber/devnet/accept_channel/test_tlc_fee_proportional_millionths.py b/test_cases/fiber/devnet/accept_channel/test_tlc_fee_proportional_millionths.py new file mode 100644 index 00000000..1774ff4e --- /dev/null +++ b/test_cases/fiber/devnet/accept_channel/test_tlc_fee_proportional_millionths.py @@ -0,0 +1,41 @@ +import time + +from framework.basic_fiber import FiberTest + + +class TestTlcFeeProportionalMillionths(FiberTest): + + def test_tlc_fee_proportional_millionths(self): + # 1. Open a new channel with fiber1 as the client and fiber2 as the peer + temporary_channel = self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(62 * 100000000), + "public": True, + } + ) + time.sleep(1) + # 2. Accept the channel with fiber2 as the client + self.fiber2.get_client().accept_channel( + { + "temporary_channel_id": temporary_channel["temporary_channel_id"], + "funding_amount": hex(1000 * 100000000), + "tlc_fee_proportional_millionths": hex(1 * 100000000), + } + ) + # 3. Wait for the channel state to be "CHANNEL_READY" + self.wait_for_channel_state( + self.fiber2.get_client(), self.fiber1.get_peer_id(), "CHANNEL_READY" + ) + + self.fiber3 = self.start_new_fiber(self.generate_account(10000)) + self.open_channel(self.fiber3, self.fiber2, 1000 * 100000000, 1) + payment_hash = self.send_payment(self.fiber3, self.fiber1, 1 * 10000000) + payment = self.fiber3.get_client().get_payment( + { + "payment_hash": payment_hash, + } + ) + print("payment", payment) + fee = self.calculate_tx_fee(1 * 10000000, [100000000]) + assert int(payment["fee"], 16) == fee diff --git a/test_cases/fiber/devnet/accept_channel/test_tlc_min_value.py b/test_cases/fiber/devnet/accept_channel/test_tlc_min_value.py new file mode 100644 index 00000000..bf2a3305 --- /dev/null +++ b/test_cases/fiber/devnet/accept_channel/test_tlc_min_value.py @@ -0,0 +1,41 @@ +import time + +import pytest + +from framework.basic_fiber import FiberTest + + +class TestTlcMinValue(FiberTest): + + def test_tlc_min_value(self): + # 1. Open a new channel with fiber1 as the client and fiber2 as the peer + temporary_channel = self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(62 * 100000000), + "public": True, + } + ) + time.sleep(1) + # 2. Accept the channel with fiber2 as the client + self.fiber2.get_client().accept_channel( + { + "temporary_channel_id": temporary_channel["temporary_channel_id"], + "funding_amount": hex(1000 * 100000000), + "tlc_min_value": hex(1 * 100000000), + } + ) + # 3. Wait for the channel state to be "CHANNEL_READY" + self.wait_for_channel_state( + self.fiber2.get_client(), self.fiber1.get_peer_id(), "CHANNEL_READY" + ) + # node1 send_payment to node2 + self.send_payment(self.fiber2, self.fiber1, 1 * 100000000) + with pytest.raises(Exception) as exc_info: + self.send_payment(self.fiber2, self.fiber1, 1 * 100000000 - 1, False) + expected_error_message = "Failed to build route" + 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]}'" + ) + self.send_payment(self.fiber1, self.fiber2, 1 * 100000000 - 1) diff --git a/test_cases/fiber/devnet/build_router/test_build_router.py b/test_cases/fiber/devnet/build_router/test_build_router.py new file mode 100644 index 00000000..ef299140 --- /dev/null +++ b/test_cases/fiber/devnet/build_router/test_build_router.py @@ -0,0 +1,98 @@ +import time +from framework.basic_fiber import FiberTest + + +class TestBuildRouter(FiberTest): + """ + 测试 build_router RPC 的功能: + 1. 基本路由构建 + - 测试指定 amount 和不指定 amount 的情况 + - 测试指定和不指定 final_tlc_expiry_delta 的情况 + + 2. 通道指定测试 + - 测试指定 channel_outpoint 的情况 + - 测试不指定 channel_outpoint 的情况(让算法自动选择通道) + - 测试指定的 channel_outpoint 无效的情况 + + 3. 路径验证 + - 测试所有节点都存在的有效路径 + - 测试节点不存在的无效路径 + - 测试节点存在但无可用通道的情况 + + 4. 特殊情况 + - 测试空的 hops_info + - 测试只有一个 hop 的情况 + - 测试包含重复节点的情况 + + 5. UDT 支付路由(可选) + - 测试指定 udt 支付的情况 + - 测试 ckb 支付的情况 + """ + + def test_base_build_router(self): + """ + b-c-d-私-a网络 + 1. d-a建立了路由关系,查看构建的路由返回信息 + """ + self.start_new_fiber(self.generate_account(10000)) + self.start_new_fiber(self.generate_account(10000)) + + fiber1_balance = 1000 * 100000000 + fiber1_fee = 1000 + + self.open_channel(self.fibers[1], self.fibers[2], 1000 * 100000000, 1) # b-c + self.open_channel( + self.fibers[2], self.fibers[3], 1000 * 100000000, 1 + ) # c-d == b-c-d + + self.fibers[3].connect_peer(self.fibers[0]) # d-a + time.sleep(1) + self.fibers[3].get_client().open_channel( # d -a private channel + { + "peer_id": self.fibers[0].get_peer_id(), + "funding_amount": hex(fiber1_balance + 62 * 100000000), + "tlc_fee_proportional_millionths": hex(fiber1_fee), + "public": False, + } + ) + time.sleep(1) + self.wait_for_channel_state( + self.fibers[3].get_client(), self.fibers[0].get_peer_id(), "CHANNEL_READY" + ) + # 查看d-a的channeloutpoint + print(f"a peer_id:{self.fibers[0].get_peer_id()}") + print(f"d peer_id:{self.fibers[3].get_peer_id()}") + channels = ( + self.fibers[3] + .get_client() + .list_channels({"peer_id": self.fibers[0].get_peer_id()}) + ) + print(f"d-a,channel:{channels}") + da_channel_outpoint = channels["channels"][0]["channel_outpoint"] + print(f"d-a, channel_outpoint:{da_channel_outpoint}") + + router_hops = ( + self.fibers[3] + .get_client() + .build_router( + { + "amount": hex(1 + 62 * 100000000), + "udt_type_script": None, + "hops_info": [ + { + "pubkey": self.fibers[0] + .get_client() + .node_info()["node_id"], + "channel_outpoint": da_channel_outpoint, + }, + ], + "final_tlc_expiry_delta": None, + } + ) + ) + print(f"router_hops:{router_hops}") + hop = router_hops["router_hops"][0] + print(f"hop:{hop}") + assert hop["channel_outpoint"] == da_channel_outpoint + assert hop["target"] == self.fibers[0].get_client().node_info()["node_id"] + assert hop["amount_received"] == hex(1 + 62 * 100000000) diff --git a/test_cases/fiber/devnet/cancel_invoice/test_cancel_invoice.py b/test_cases/fiber/devnet/cancel_invoice/test_cancel_invoice.py index 870cf77c..cbf240dd 100644 --- a/test_cases/fiber/devnet/cancel_invoice/test_cancel_invoice.py +++ b/test_cases/fiber/devnet/cancel_invoice/test_cancel_invoice.py @@ -449,6 +449,7 @@ def test_cancel_invoice_that_statue_is_receive(self): int(before_channel["channels"][0]["local_balance"], 16) - invoice_balance ) + @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/654") def test_batch_cancel(self): """ Test case for batch canceling invoices. @@ -466,7 +467,8 @@ def test_batch_cancel(self): """ cancel_size = 50 channel_length = 4 - + # cancel_size = 5 + # channel_length = 3 # Step 1: Start new fibers for i in range(channel_length - 2): self.start_new_fiber(self.generate_account(10000)) diff --git a/test_cases/fiber/devnet/ckb/test_ckb_remove_tx.py b/test_cases/fiber/devnet/ckb/test_ckb_remove_tx.py new file mode 100644 index 00000000..530b1cb9 --- /dev/null +++ b/test_cases/fiber/devnet/ckb/test_ckb_remove_tx.py @@ -0,0 +1,79 @@ +import time + +import pytest + +from framework.basic_fiber import FiberTest + + +class TestCkbRemoveTx(FiberTest): + + @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/515") + def test_remove_open_tx_stuck_node1(self): + """ + 导致节点1 node_info 卡住 + + Returns: + + """ + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + } + ) + self.wait_tx_pool(pending_size=1, try_size=100) + self.node.client.clear_tx_pool() + # self.node.restart() + # self.node.start_miner() + time.sleep(3) + self.open_channel(self.fiber1, self.fiber2, 1000 * 100000000, 1) + # self.fiber1.get_client().open_channel({ + # "peer_id": self.fiber2.get_peer_id(), + # "funding_amount": hex(1000 * 100000000), + # "public": True, + # }) + # time.sleep(5) + # self.fiber1.get_client().node_info() + # self.fiber2.get_client().node_info() + + @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/515") + def test_remove_open_tx_stuck_node2(self): + """ + 导致节点2 node_info 卡住 + + Returns: + + """ + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + } + ) + self.wait_tx_pool(pending_size=1, try_size=100) + self.node.client.clear_tx_pool() + # self.node.restart() + # self.node.start_miner() + time.sleep(3) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + } + ) + time.sleep(5) + self.fiber2.get_client().node_info() + fiber3 = self.start_new_fiber(self.generate_account(10000)) + self.open_channel(fiber3, self.fiber2, 1000 * 100000000, 1) + # fiber3.connect_peer(self.fiber2) + # time.sleep(1) + # fiber3.get_client().open_channel({ + # "peer_id": self.fiber2.get_peer_id(), + # "funding_amount": hex(1000 * 100000000), + # "public": True, + # }) + # time.sleep(5) + # self.fiber2.get_client().node_info() diff --git a/test_cases/fiber/devnet/get_invoice/test_get_invoice.py b/test_cases/fiber/devnet/get_invoice/test_get_invoice.py index 4c6cb551..6295e124 100644 --- a/test_cases/fiber/devnet/get_invoice/test_get_invoice.py +++ b/test_cases/fiber/devnet/get_invoice/test_get_invoice.py @@ -42,7 +42,7 @@ def test_get_exist_new_invoice(self): # Step 3: Verify the node ID matches the PayeePublicKey in the invoice assert ( node_info["node_id"] - == result["invoice"]["data"]["attrs"][3]["PayeePublicKey"] + == result["invoice"]["data"]["attrs"][3]["payee_public_key"] ) # Step 4: Parse the invoice and verify the parsed result matches the original invoice @@ -53,11 +53,11 @@ def test_get_exist_new_invoice(self): assert invoice["invoice"]["currency"] == "Fibd" assert invoice["invoice"]["amount"] == "0x1" assert ( - invoice["invoice"]["data"]["attrs"][0]["Description"] + invoice["invoice"]["data"]["attrs"][0]["description"] == "test invoice generated by node2" ) - assert invoice["invoice"]["data"]["attrs"][1]["ExpiryTime"]["secs"] == 3600 - assert invoice["invoice"]["data"]["attrs"][2]["HashAlgorithm"] == "sha256" + assert invoice["invoice"]["data"]["attrs"][1]["expiry_time"] == hex(3600) + assert invoice["invoice"]["data"]["attrs"][2]["hash_algorithm"] == "sha256" # Step 5: Verify the timestamp of the invoice assert int(int(invoice["invoice"]["data"]["timestamp"], 16) / 1000) == int( diff --git a/test_cases/fiber/devnet/graph_channels/test_graph_channels.py b/test_cases/fiber/devnet/graph_channels/test_graph_channels.py index 142ac22b..15d1da17 100644 --- a/test_cases/fiber/devnet/graph_channels/test_graph_channels.py +++ b/test_cases/fiber/devnet/graph_channels/test_graph_channels.py @@ -276,33 +276,33 @@ def test_update_channel_info(self): node_info = self.fiber1.get_client().node_info() print("node1_channels:", node1_channels) key = ( - "fee_rate_of_node1" + "update_info_of_node1" if node3_channels["channels"][0]["node1"] == node_info["node_id"] - else "fee_rate_of_node2" + else "update_info_of_node2" ) print("key:", key) assert ( - node1_channels["channels"][0][key] + node1_channels["channels"][0][key]["fee_rate"] == update_channel_param["tlc_fee_proportional_millionths"] ) print("node2_channels", node2_channels) key = ( - "fee_rate_of_node1" + "update_info_of_node1" if node3_channels["channels"][0]["node1"] == node_info["node_id"] - else "fee_rate_of_node2" + else "update_info_of_node2" ) assert ( - node2_channels["channels"][0][key] + node2_channels["channels"][0][key]["fee_rate"] == update_channel_param["tlc_fee_proportional_millionths"] ) print("node3_channels", node3_channels) key = ( - "fee_rate_of_node1" + "update_info_of_node1" if node3_channels["channels"][0]["node1"] == node_info["node_id"] - else "fee_rate_of_node2" + else "update_info_of_node2" ) assert ( - node3_channels["channels"][0][key] + node3_channels["channels"][0][key]["fee_rate"] == update_channel_param["tlc_fee_proportional_millionths"] ) @@ -365,29 +365,29 @@ def test_channel_info_check(self): # created_timestamp # fee_rate_of_node2 assert ( - node1_channels["channels"][0]["fee_rate_of_node2"] + node1_channels["channels"][0]["update_info_of_node2"]["fee_rate"] == node2_info["tlc_fee_proportional_millionths"] ) assert ( - node2_channels["channels"][0]["fee_rate_of_node2"] + node2_channels["channels"][0]["update_info_of_node2"]["fee_rate"] == node2_info["tlc_fee_proportional_millionths"] ) assert ( - node3_channels["channels"][0]["fee_rate_of_node2"] + node3_channels["channels"][0]["update_info_of_node2"]["fee_rate"] == node2_info["tlc_fee_proportional_millionths"] ) # fee_rate_of_node1 assert ( - node1_channels["channels"][0]["fee_rate_of_node1"] + node1_channels["channels"][0]["update_info_of_node1"]["fee_rate"] == node1_info["tlc_fee_proportional_millionths"] ) assert ( - node2_channels["channels"][0]["fee_rate_of_node1"] + node2_channels["channels"][0]["update_info_of_node1"]["fee_rate"] == node1_info["tlc_fee_proportional_millionths"] ) assert ( - node3_channels["channels"][0]["fee_rate_of_node1"] + node3_channels["channels"][0]["update_info_of_node1"]["fee_rate"] == node1_info["tlc_fee_proportional_millionths"] ) diff --git a/test_cases/fiber/devnet/issue/test_force_stop.py b/test_cases/fiber/devnet/issue/test_force_stop.py new file mode 100644 index 00000000..e69de29b diff --git a/test_cases/fiber/devnet/issue/test_issue_640.py b/test_cases/fiber/devnet/issue/test_issue_640.py new file mode 100644 index 00000000..e69de29b diff --git a/test_cases/fiber/devnet/list_channels/test_list_channels.py b/test_cases/fiber/devnet/list_channels/test_list_channels.py index eb38cf65..35c999e5 100644 --- a/test_cases/fiber/devnet/list_channels/test_list_channels.py +++ b/test_cases/fiber/devnet/list_channels/test_list_channels.py @@ -169,8 +169,10 @@ def test_created_at(self): channels = self.fiber1.get_client().list_channels({}) created_at_hex = int(channels["channels"][0]["created_at"], 16) / 1000 - assert int(created_at_hex / 1000) == int( - int(datetime.datetime.now().timestamp()) / 1000 + assert ( + int(int(datetime.datetime.now().timestamp()) / 1000) + - int(created_at_hex / 1000) + < 10 ) def test_is_public(self): @@ -231,6 +233,9 @@ def test_check_channel_result(self): print("channel_outpoint:", channels["channels"][0]["channel_outpoint"]) assert open_tx_hash in channels["channels"][0]["channel_outpoint"] + # peer_id + assert channels["channels"][0]["peer_id"] == self.fiber2.get_peer_id() + # funding_udt_type_script assert channels["channels"][0][ "funding_udt_type_script" @@ -255,21 +260,35 @@ def test_check_channel_result(self): assert int(channels["channels"][0]["created_at"], 16) / 1000 > begin_time assert int(channels["channels"][0]["created_at"], 16) / 1000 < time.time() + # enabled + assert channels["channels"][0]["enabled"] is True + + # tlc_expiry_delta + assert channels["channels"][0]["tlc_expiry_delta"] == hex(86400000) + + # tlc_fee_proportional_millionths + assert channels["channels"][0]["tlc_fee_proportional_millionths"] == hex(1000) + # force shutdown latest_commitment_transaction_hash == hash self.fiber1.get_client().shutdown_channel( { "channel_id": channels["channels"][0]["channel_id"], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 120) assert tx_hash == channels["channels"][0]["latest_commitment_transaction_hash"] + # + channel = self.fiber1.get_client().list_channels( + { + "peer_id": self.fiber2.get_peer_id(), + } + ) + assert len(channel["channels"]) == 0 + channel = self.fiber1.get_client().list_channels( + {"peer_id": self.fiber2.get_peer_id(), "include_closed": True} + ) + assert len(channel["channels"]) == 1 def test_close_channels(self): temporary_channel_id = self.fiber1.get_client().open_channel( diff --git a/test_cases/fiber/devnet/list_peers/test_list_peers.py b/test_cases/fiber/devnet/list_peers/test_list_peers.py new file mode 100644 index 00000000..0607aa5b --- /dev/null +++ b/test_cases/fiber/devnet/list_peers/test_list_peers.py @@ -0,0 +1,19 @@ +from framework.basic_fiber import FiberTest + + +class TestListPeers(FiberTest): + + def test_01(self): + peer = self.fiber1.get_client().list_peers() + assert ( + peer["peers"][0]["pubkey"] + == self.fiber2.get_client().node_info()["node_id"] + ) + assert ( + peer["peers"][0]["addresses"] + == self.fiber2.get_client().node_info()["addresses"] + ) + assert ( + peer["peers"][0]["peer_id"] + == self.fiber2.get_client().node_info()["addresses"][0].split("/")[-1] + ) diff --git a/test_cases/fiber/devnet/new_invoice/test_description.py b/test_cases/fiber/devnet/new_invoice/test_description.py index b20c7e31..2376f6e9 100644 --- a/test_cases/fiber/devnet/new_invoice/test_description.py +++ b/test_cases/fiber/devnet/new_invoice/test_description.py @@ -140,7 +140,7 @@ def test_description_rd_str(self): {"payment_hash": payment["payment_hash"]} ) assert ( - invoice["invoice"]["data"]["attrs"][0]["Description"] + invoice["invoice"]["data"]["attrs"][0]["description"] == test_description_str[i] ) # 7. List channels after sending payment diff --git a/test_cases/fiber/devnet/node_info/test_node_info.py b/test_cases/fiber/devnet/node_info/test_node_info.py index b463b7d6..4e83ed6d 100644 --- a/test_cases/fiber/devnet/node_info/test_node_info.py +++ b/test_cases/fiber/devnet/node_info/test_node_info.py @@ -7,6 +7,7 @@ class TestNodeInfo(FiberTest): + @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/631") def test_commit_hash(self): """ @@ -69,6 +70,7 @@ def test_commit_hash(self): assert node_info["tlc_min_value"] == hex(0) # tlc_max_value + # https://github.com/nervosnetwork/fiber/issues/631 assert node_info["tlc_max_value"] == hex(0) # tlc_fee_proportional_millionths @@ -148,11 +150,11 @@ def test_channel_count(self): == int(after_node1_info["channel_count"], 16) - 1 ) - def test_pending_channel_count(self): - """ - check pending_channel_count - Returns: - """ + # def test_pending_channel_count(self): + # """ + # check pending_channel_count + # Returns: + # """ @pytest.mark.skip("") def test_network_sync_status(self): diff --git a/test_cases/fiber/devnet/open_channel/test_commitment_delay_epoch.py b/test_cases/fiber/devnet/open_channel/test_commitment_delay_epoch.py new file mode 100644 index 00000000..6693efc1 --- /dev/null +++ b/test_cases/fiber/devnet/open_channel/test_commitment_delay_epoch.py @@ -0,0 +1,40 @@ +from framework.basic_fiber import FiberTest + + +class TestCommitmentDelayEpoch(FiberTest): + + def test_epoch(self): + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + "commitment_delay_epoch": hex(2), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY", 120 + ) + self.fiber1.get_client().shutdown_channel( + { + "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ], + "force": True, + } + ) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + self.node.getClient().generate_epochs(hex(2)) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1200) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + message = self.get_tx_message(tx_hash) + print(message) + assert { + "args": "0x470dcdc5e44064909650113a274b3b36aecb6dc7", + "capacity": 6199999545, + } in message["output_cells"] + assert { + "args": "0xc8328aabcd9b9e8e64fbc566c4385c3bdeb219d7", + "capacity": 99999999545, + } in message["output_cells"] diff --git a/test_cases/fiber/devnet/open_channel/test_commitment_fee_rate.py b/test_cases/fiber/devnet/open_channel/test_commitment_fee_rate.py index db89d31f..f570159c 100644 --- a/test_cases/fiber/devnet/open_channel/test_commitment_fee_rate.py +++ b/test_cases/fiber/devnet/open_channel/test_commitment_fee_rate.py @@ -25,15 +25,13 @@ def test_commitment_fee_rate_very_big(self): # "tlc_fee_proportional_millionths": "0x4B0", } ) - expected_error_message = ( - "Commitment fee 18446744073709551 which caculated by commitment fee rate" - ) + expected_error_message = "is larger than half of reserved fee 100000000" 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]}'" ) - @pytest.mark.skip("todo") + # @pytest.mark.skip("todo") def test_commitment_fee_rate_exist(self): """ commitment_fee_rate != default.value @@ -85,7 +83,7 @@ def test_commitment_fee_rate_is_1(self): f"not found in actual string '{exc_info.value.args[0]}'" ) - @pytest.mark.skip("commitment_fee_rate 不准确") + # @pytest.mark.skip("commitment_fee_rate 不准确") def test_check_commitment_fee_rate_is_none(self): """ @@ -144,18 +142,12 @@ def test_check_commitment_fee_rate_is_none(self): self.fiber1.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) self.wait_and_check_tx_pool_fee(1000) - @pytest.mark.skip("commitment_fee_rate 不准确") + # @pytest.mark.skip("commitment_fee_rate 不准确") def test_check_commitment_fee_rate(self): """ 验证我方的commit fee @@ -213,23 +205,13 @@ def test_check_commitment_fee_rate(self): self.fiber1.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) self.wait_and_check_tx_pool_fee(commitment_fee_rate) - @pytest.mark.skip("目前双方commit fee 一致") def test_other_node_check_commitment_fee_rate(self): """ - 因为无法查询到shutdown_channel(force)的交易 - 因为dev 节点只会有我发的交易,所以通过监控pool池 查交易 - 验证对方的commit fee Returns: """ commitment_fee_rate = 21978021 @@ -284,13 +266,10 @@ def test_other_node_check_commitment_fee_rate(self): self.fiber2.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) - self.wait_and_check_tx_pool_fee(1000) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 100) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + tx_message = self.get_tx_message(tx_hash) + assert tx_message["fee"] == 9999999 diff --git a/test_cases/fiber/devnet/open_channel/test_funding_amount.py b/test_cases/fiber/devnet/open_channel/test_funding_amount.py index a22e5d46..0faed925 100644 --- a/test_cases/fiber/devnet/open_channel/test_funding_amount.py +++ b/test_cases/fiber/devnet/open_channel/test_funding_amount.py @@ -7,6 +7,7 @@ class FundingAmount(FiberTest): # FiberTest.debug = True + start_fiber_config = {"fiber_auto_accept_amount": "0"} def test_funding_amount_ckb_is_zero(self): """ @@ -44,12 +45,12 @@ def test_funding_amount_udt_is_zero(self): } ) time.sleep(1) - self.fiber2.get_client().accept_channel( - { - "temporary_channel_id": temporary_channel_id["temporary_channel_id"], - "funding_amount": "0x0", - } - ) + # self.fiber2.get_client().accept_channel( + # { + # "temporary_channel_id": temporary_channel_id["temporary_channel_id"], + # "funding_amount": "0x0", + # } + # ) self.wait_for_channel_state( self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY", 120 ) diff --git a/test_cases/fiber/devnet/open_channel/test_funding_fee_rate.py b/test_cases/fiber/devnet/open_channel/test_funding_fee_rate.py index 4af46685..78211772 100644 --- a/test_cases/fiber/devnet/open_channel/test_funding_fee_rate.py +++ b/test_cases/fiber/devnet/open_channel/test_funding_fee_rate.py @@ -52,6 +52,11 @@ def test_funding_fee_rate_too_big(self): # "tlc_fee_proportional_millionths": "0x4B0", } ) + tx_hash = self.wait_and_check_tx_pool_fee(int("0xffffffffffffffff", 16), False) + tx_message = self.get_tx_message(tx_hash) + print(tx_message) + return + # self.wait_and_check_tx_pool_fee(int("0xffffffffffffffff", 16)) self.wait_for_channel_state( self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY", 120 diff --git a/test_cases/fiber/devnet/open_channel/test_funding_udt_type_script.py b/test_cases/fiber/devnet/open_channel/test_funding_udt_type_script.py index 7e27305d..8b43a4b1 100644 --- a/test_cases/fiber/devnet/open_channel/test_funding_udt_type_script.py +++ b/test_cases/fiber/devnet/open_channel/test_funding_udt_type_script.py @@ -61,7 +61,6 @@ def test_funding_udt_type_script_not_exist(self): def test_funding_udt_type_script_is_white(self): """ 1. funding_udt_type_script 在节点上 - todo: add more check balance Returns: """ # open chanel for fiber @@ -73,7 +72,6 @@ def test_funding_udt_type_script_is_white(self): ) # connect 2 fiber self.fiber1.connect_peer(self.fiber2) - # todo wait peer connet time.sleep(1) # open channel temporary_channel_id = self.fiber1.get_client().open_channel( @@ -145,8 +143,8 @@ def test_funding_udt_type_script_is_white(self): "fee_rate": "0x3FC", } ) - # todo wait close tx commit - time.sleep(20) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 100) + self.Miner.miner_until_tx_committed(self.node, tx_hash) after_account1 = self.udtContract.list_cell( self.node.getClient(), account["lock_arg"], account["lock_arg"] @@ -156,9 +154,27 @@ def test_funding_udt_type_script_is_white(self): ) assert after_account1[-1]["balance"] == 90000000000 - print(after_account2) assert after_account2[-1]["balance"] == 10000000000 - before_balance1 = self.Ckb_cli.wallet_get_live_cells( - account["address"]["testnet"] - ) - print("before_balance1:", before_balance1) + tx_message = self.get_tx_message(tx_hash) + if tx_message["output_cells"][1]["udt_capacity"] == 90000000000: + assert tx_message["output_cells"][1]["udt_capacity"] == 90000000000 + assert ( + tx_message["output_cells"][1]["args"] + == self.fiber1.get_account()["lock_arg"] + ) + assert tx_message["output_cells"][0]["udt_capacity"] == 10000000000 + assert ( + tx_message["output_cells"][0]["args"] + == self.fiber2.get_account()["lock_arg"] + ) + else: + assert tx_message["output_cells"][0]["udt_capacity"] == 90000000000 + assert ( + tx_message["output_cells"][0]["args"] + == self.fiber1.get_account()["lock_arg"] + ) + assert tx_message["output_cells"][1]["udt_capacity"] == 10000000000 + assert ( + tx_message["output_cells"][1]["args"] + == self.fiber2.get_account()["lock_arg"] + ) diff --git a/test_cases/fiber/devnet/open_channel/test_linked.py b/test_cases/fiber/devnet/open_channel/test_linked.py index de0940a4..6e2051d2 100644 --- a/test_cases/fiber/devnet/open_channel/test_linked.py +++ b/test_cases/fiber/devnet/open_channel/test_linked.py @@ -113,7 +113,9 @@ def test_linked_peer(self): } ) # todo wait close tx commit - time.sleep(20) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 100) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + after_balance1 = self.Ckb_cli.wallet_get_capacity( self.account1["address"]["testnet"] ) diff --git a/test_cases/fiber/devnet/open_channel/test_max_tlc_number_in_flight.py b/test_cases/fiber/devnet/open_channel/test_max_tlc_number_in_flight.py index 0b0481d0..12c7e8f7 100644 --- a/test_cases/fiber/devnet/open_channel/test_max_tlc_number_in_flight.py +++ b/test_cases/fiber/devnet/open_channel/test_max_tlc_number_in_flight.py @@ -176,8 +176,9 @@ def test_max_tlc_number_in_flight_zero(self): "fee_rate": "0x3FC", } ) - # todo wait close tx commit - time.sleep(20) + + tx_hash = self.wait_and_check_tx_pool_fee(1000, False) + self.Miner.miner_until_tx_committed(self.node, tx_hash) after_balance1 = self.Ckb_cli.wallet_get_capacity( self.account1["address"]["testnet"] ) @@ -273,8 +274,6 @@ def test_max_tlc_number_in_flight_not_eq_default(self): f"Expected substring '{expected_error_message}' " f"not found in actual string '{exc_info.value.args[0]}'" ) - self.fiber1.get_client().list_channels({}) - self.fiber2.get_client().list_channels({}) def test_max_tlc_number_in_flight_not_eq_default_other_node(self): """ diff --git a/test_cases/fiber/devnet/open_channel/test_max_tlc_value_in_flight.py b/test_cases/fiber/devnet/open_channel/test_max_tlc_value_in_flight.py index e5f9f747..eea2edbb 100644 --- a/test_cases/fiber/devnet/open_channel/test_max_tlc_value_in_flight.py +++ b/test_cases/fiber/devnet/open_channel/test_max_tlc_value_in_flight.py @@ -74,81 +74,7 @@ def test_max_tlc_value_in_flight_is_zero(self): "invoice": invoice["invoice_address"], } ) - self.wait_payment_state(self.fiber1, payment["payment_hash"], "Failed") - # expected_error_message = "TemporaryChannelFailure" - # assert expected_error_message in payment["failed_error"] - - # invoice_balance = hex(160 * 100000000) - # payment_preimage = self.generate_random_preimage() - # invoice = self.fiber1.get_client().new_invoice( - # { - # "amount": invoice_balance, - # "currency": "Fibd", - # "description": "test invoice generated by node2", - # "expiry": "0xe10", - # "final_cltv": "0x28", - # "payment_preimage": payment_preimage, - # "hash_algorithm": "sha256", - # "udt_type_script": { - # "code_hash": self.udtContract.get_code_hash(True, self.node.rpcUrl), - # "hash_type": "type", - # "args": self.udtContract.get_owner_arg_by_lock_arg( - # self.account1["lock_arg"] - # ), - # }, - # } - # ) - # before_channel = self.fiber2.get_client().list_channels({}) - # print("node2 send 1 ckb failed ") - # with pytest.raises(Exception) as exc_info: - # self.fiber2.get_client().send_payment( - # { - # "invoice": invoice["invoice_address"], - # } - # ) - # expected_error_message = "no path found" - # 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]}'" - # ) - - channels = self.fiber1.get_client().list_channels( - {"peer_id": self.fiber2.get_peer_id()} - ) - N1N2_CHANNEL_ID = channels["channels"][0]["channel_id"] - self.fiber1.get_client().graph_channels() - - before_balance1 = self.Ckb_cli.wallet_get_capacity( - self.account1["address"]["testnet"] - ) - before_balance2 = self.Ckb_cli.wallet_get_capacity( - self.account2["address"]["testnet"] - ) - # shut down - self.fiber1.get_client().shutdown_channel( - { - "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", - } - ) - # todo wait close tx commit - time.sleep(20) - after_balance1 = self.Ckb_cli.wallet_get_capacity( - self.account1["address"]["testnet"] - ) - after_balance2 = self.Ckb_cli.wallet_get_capacity( - self.account2["address"]["testnet"] - ) - print("before_balance1:", before_balance1) - print("before_balance2:", before_balance2) - print("after_balance1:", after_balance1) - print("after_balance2:", after_balance2) def test_max_tlc_value_in_flight_overflow(self): with pytest.raises(Exception) as exc_info: @@ -277,44 +203,6 @@ def test_ckb_max_tlc_value_in_flight_too_min(self): after_channel_2["channels"][0]["local_balance"], 16 ) == int(invoice_balance, 16) - channels = self.fiber1.get_client().list_channels( - {"peer_id": self.fiber2.get_peer_id()} - ) - N1N2_CHANNEL_ID = channels["channels"][0]["channel_id"] - self.fiber1.get_client().graph_channels() - - before_balance1 = self.Ckb_cli.wallet_get_capacity( - self.account1["address"]["testnet"] - ) - before_balance2 = self.Ckb_cli.wallet_get_capacity( - self.account2["address"]["testnet"] - ) - # shut down - self.fiber1.get_client().shutdown_channel( - { - "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", - } - ) - # todo wait close tx commit - time.sleep(20) - after_balance1 = self.Ckb_cli.wallet_get_capacity( - self.account1["address"]["testnet"] - ) - after_balance2 = self.Ckb_cli.wallet_get_capacity( - self.account2["address"]["testnet"] - ) - print("before_balance1:", before_balance1) - print("before_balance2:", before_balance2) - print("after_balance1:", after_balance1) - print("after_balance2:", after_balance2) - assert after_balance2 - before_balance2 == 62 - def test_udt_max_tlc_value_in_flight_too_min(self): """ max_tlc_value_in_flight == 1 @@ -393,12 +281,12 @@ def test_udt_max_tlc_value_in_flight_too_min(self): ) before_channel = self.fiber1.get_client().list_channels({}) - self.fiber1.get_client().send_payment( + payment = self.fiber1.get_client().send_payment( { "invoice": invoice["invoice_address"], } ) - time.sleep(10) + self.wait_payment_state(self.fiber1, payment["payment_hash"], "Success") after_channel = self.fiber1.get_client().list_channels({}) assert int(before_channel["channels"][0]["local_balance"], 16) - int( after_channel["channels"][0]["local_balance"], 16 @@ -423,51 +311,17 @@ def test_udt_max_tlc_value_in_flight_too_min(self): time.sleep(1) print("node2 send 1 ckb failed ") before_channel_2 = self.fiber2.get_client().list_channels({}) - self.fiber2.get_client().send_payment( + payment = self.fiber2.get_client().send_payment( { "invoice": invoice["invoice_address"], } ) - time.sleep(10) + self.wait_payment_state(self.fiber2, payment["payment_hash"], "Success") after_channel_2 = self.fiber2.get_client().list_channels({}) assert int(before_channel_2["channels"][0]["local_balance"], 16) - int( after_channel_2["channels"][0]["local_balance"], 16 ) == int(invoice_balance, 16) - channels = self.fiber1.get_client().list_channels( - {"peer_id": self.fiber2.get_peer_id()} - ) - N1N2_CHANNEL_ID = channels["channels"][0]["channel_id"] - self.fiber1.get_client().graph_channels() - - before_balance1 = self.Ckb_cli.wallet_get_capacity( - self.account1["address"]["testnet"] - ) - before_balance2 = self.Ckb_cli.wallet_get_capacity( - self.account2["address"]["testnet"] - ) - # shut down - self.fiber1.get_client().shutdown_channel( - { - "channel_id": N1N2_CHANNEL_ID, - "close_script": self.get_account_script(self.fiber1.account_private), - "fee_rate": "0x3FC", - } - ) - # todo wait close tx commit - time.sleep(20) - after_balance1 = self.Ckb_cli.wallet_get_capacity( - self.account1["address"]["testnet"] - ) - after_balance2 = self.Ckb_cli.wallet_get_capacity( - self.account2["address"]["testnet"] - ) - print("before_balance1:", before_balance1) - print("before_balance2:", before_balance2) - print("after_balance1:", after_balance1) - print("after_balance2:", after_balance2) - assert after_balance2 - before_balance2 == 143 - # @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/450") def test_debug_ckb_max_tlc_value_in_flight_not_eq_default(self): self.fiber1.get_client().open_channel( @@ -510,7 +364,6 @@ def test_debug_ckb_max_tlc_value_in_flight_not_eq_default(self): "invoice": invoice["invoice_address"], } ) - self.wait_payment_state(self.fiber1, payment["payment_hash"], "Failed") # @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/450") @@ -649,40 +502,6 @@ def test_ckb_max_tlc_value_in_flight_not_eq_default(self): after_channel_2["channels"][0]["local_balance"], 16 ) == int(invoice_balance, 16) - channels = self.fiber1.get_client().list_channels( - {"peer_id": self.fiber2.get_peer_id()} - ) - N1N2_CHANNEL_ID = channels["channels"][0]["channel_id"] - self.fiber1.get_client().graph_channels() - - before_balance1 = self.Ckb_cli.wallet_get_capacity( - self.account1["address"]["testnet"] - ) - before_balance2 = self.Ckb_cli.wallet_get_capacity( - self.account2["address"]["testnet"] - ) - # shut down - self.fiber1.get_client().shutdown_channel( - { - "channel_id": N1N2_CHANNEL_ID, - "close_script": self.get_account_script(self.fiber1.account_private), - "fee_rate": "0x3FC", - } - ) - # todo wait close tx commit - time.sleep(20) - after_balance1 = self.Ckb_cli.wallet_get_capacity( - self.account1["address"]["testnet"] - ) - after_balance2 = self.Ckb_cli.wallet_get_capacity( - self.account2["address"]["testnet"] - ) - print("before_balance1:", before_balance1) - print("before_balance2:", before_balance2) - print("after_balance1:", after_balance1) - print("after_balance2:", after_balance2) - assert after_balance2 - before_balance2 == 62.90000057220459 - # @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/450") def test_udt_max_tlc_value_in_flight_not_eq_default(self): """ @@ -834,51 +653,3 @@ def test_udt_max_tlc_value_in_flight_not_eq_default(self): assert int(before_channel["channels"][0]["local_balance"], 16) - int( after_channel_2["channels"][0]["local_balance"], 16 ) == int(invoice_balance, 16) - - channels = self.fiber1.get_client().list_channels( - {"peer_id": self.fiber2.get_peer_id()} - ) - N1N2_CHANNEL_ID = channels["channels"][0]["channel_id"] - self.fiber1.get_client().graph_channels() - - before_balance1 = self.Ckb_cli.wallet_get_capacity( - self.account1["address"]["testnet"] - ) - before_balance2 = self.Ckb_cli.wallet_get_capacity( - self.account2["address"]["testnet"] - ) - # shut down - self.fiber1.get_client().shutdown_channel( - { - "channel_id": N1N2_CHANNEL_ID, - "close_script": self.get_account_script(self.fiber1.account_private), - "fee_rate": "0x3FC", - } - ) - # todo wait close tx commit - time.sleep(20) - after_balance1 = self.Ckb_cli.wallet_get_capacity( - self.account1["address"]["testnet"] - ) - after_balance2 = self.Ckb_cli.wallet_get_capacity( - self.account2["address"]["testnet"] - ) - print("before_balance1:", before_balance1) - print("before_balance2:", before_balance2) - print("after_balance1:", after_balance1) - print("after_balance2:", after_balance2) - assert after_balance2 - before_balance2 == 143 - account2_balance = self.udtContract.list_cell( - self.node.getClient(), - own_arg=self.account1["lock_arg"], - query_arg=self.account2["lock_arg"], - ) - account1_balance = self.udtContract.list_cell( - self.node.getClient(), - own_arg=self.account1["lock_arg"], - query_arg=self.account1["lock_arg"], - ) - print("account1:", account1_balance) - print("account2:", account2_balance) - assert account1_balance[-1]["balance"] == 99900000001 - assert account2_balance[-1]["balance"] == 99999999 diff --git a/test_cases/fiber/devnet/open_channel/test_n_user.py b/test_cases/fiber/devnet/open_channel/test_n_user.py new file mode 100644 index 00000000..4d513293 --- /dev/null +++ b/test_cases/fiber/devnet/open_channel/test_n_user.py @@ -0,0 +1,54 @@ +import time + +import pytest + +from framework.basic_fiber import FiberTest + + +class TestNUser(FiberTest): + + @pytest.mark.skip("skip") + def test_n_user(self): + n_user = 5 + for i in range(n_user): + self.start_new_fiber(self.generate_account(10000)) + for i in range(0, len(self.fibers) - 1): + self.fibers[i].connect_peer(self.fibers[-1]) + time.sleep(1) + for i in range(0, len(self.fibers) - 1): + self.fibers[i].get_client().open_channel( + { + "peer_id": self.fibers[-1].get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + } + ) + for i in range(0, len(self.fibers) - 1): + self.wait_for_channel_state( + self.fibers[i].get_client(), + self.fibers[-1].get_peer_id(), + "CHANNEL_READY", + 120, + ) + + for i in range(0, len(self.fibers) - 1): + self.send_payment(self.fibers[i], self.fibers[-1]) + + for i in range(0, len(self.fibers) - 1): + self.fibers[i].get_client().shutdown_channel( + { + "channel_id": self.fibers[i] + .get_client() + .list_channels({"peer_id": self.fibers[-1].get_peer_id()})[ + "channels" + ][0]["channel_id"], + "close_script": self.get_account_script( + self.fibers[i].account_private + ), + "fee_rate": "0x3FC", + } + ) + for i in range(0, len(self.fibers) - 1): + self.wait_for_channel_state( + self.fibers[i], self.fibers[-1].get_peer_id(), "CLOSED" + ) diff --git a/test_cases/fiber/devnet/open_channel/test_public.py b/test_cases/fiber/devnet/open_channel/test_public.py index 12bf36b8..7230d5c3 100644 --- a/test_cases/fiber/devnet/open_channel/test_public.py +++ b/test_cases/fiber/devnet/open_channel/test_public.py @@ -22,14 +22,11 @@ def test_public_none(self): # "tlc_fee_proportional_millionths": "0x4B0", } ) - time.sleep(1) self.wait_for_channel_state( self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY", 120 ) - time.sleep(5) + time.sleep(2) # transfer - self.fiber1.get_client().graph_channels() - self.fiber1.get_client().graph_nodes() payment_preimage = self.generate_random_preimage() invoice_balance = 100 * 100000000 invoice = self.fiber2.get_client().new_invoice( @@ -83,7 +80,8 @@ def test_public_none(self): } ) # todo wait close tx commit - time.sleep(20) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 100) + self.Miner.miner_until_tx_committed(self.node, tx_hash) after_balance1 = self.Ckb_cli.wallet_get_capacity( self.account1["address"]["testnet"] ) @@ -95,19 +93,15 @@ def test_public_none(self): print("after_balance1:", after_balance1) print("after_balance2:", after_balance2) - @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/170") def test_public_false(self): """ https://github.com/nervosnetwork/fiber/issues/268 https://github.com/nervosnetwork/fiber/issues/170 public : false - - todo: add check 多路支付会失败 - Returns: """ self.fiber1.connect_peer(self.fiber2) - time.sleep(5) + time.sleep(1) temporary_channel_id = self.fiber1.get_client().open_channel( { "peer_id": self.fiber2.get_peer_id(), @@ -116,14 +110,16 @@ def test_public_false(self): # "tlc_fee_proportional_millionths": "0x4B0", } ) - time.sleep(1) self.wait_for_channel_state( self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY", 120 ) - time.sleep(5) + time.sleep(2) + + # graph_channels is none + channels = self.fiber1.get_client().graph_channels({}) + assert channels["channels"] == [] + # transfer - self.fiber1.get_client().graph_channels() - self.fiber1.get_client().graph_nodes() payment_preimage = self.generate_random_preimage() invoice_balance = 100 * 100000000 invoice = self.fiber2.get_client().new_invoice( @@ -139,12 +135,13 @@ def test_public_false(self): ) before_channel = self.fiber1.get_client().list_channels({}) - self.fiber1.get_client().send_payment( + payment = self.fiber1.get_client().send_payment( { "invoice": invoice["invoice_address"], } ) - time.sleep(10) + self.wait_payment_state(self.fiber1, payment["payment_hash"], "Success") + after_channel = self.fiber1.get_client().list_channels({}) assert ( int(before_channel["channels"][0]["local_balance"], 16) @@ -177,7 +174,9 @@ def test_public_false(self): } ) # todo wait close tx commit - time.sleep(20) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 100) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + after_balance1 = self.Ckb_cli.wallet_get_capacity( self.account1["address"]["testnet"] ) @@ -197,7 +196,7 @@ def test_public_true(self): """ self.fiber1.connect_peer(self.fiber2) - time.sleep(5) + time.sleep(1) temporary_channel_id = self.fiber1.get_client().open_channel( { "peer_id": self.fiber2.get_peer_id(), @@ -229,12 +228,13 @@ def test_public_true(self): ) before_channel = self.fiber1.get_client().list_channels({}) - self.fiber1.get_client().send_payment( + payment = self.fiber1.get_client().send_payment( { "invoice": invoice["invoice_address"], } ) - time.sleep(10) + self.wait_payment_state(self.fiber1, payment["payment_hash"], "Success") + after_channel = self.fiber1.get_client().list_channels({}) assert ( int(before_channel["channels"][0]["local_balance"], 16) @@ -267,7 +267,8 @@ def test_public_true(self): } ) # todo wait close tx commit - time.sleep(20) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 100) + self.Miner.miner_until_tx_committed(self.node, tx_hash) after_balance1 = self.Ckb_cli.wallet_get_capacity( self.account1["address"]["testnet"] ) diff --git a/test_cases/fiber/devnet/open_channel/test_shutdown_script.py b/test_cases/fiber/devnet/open_channel/test_shutdown_script.py index 0dd2ae40..5f0ae615 100644 --- a/test_cases/fiber/devnet/open_channel/test_shutdown_script.py +++ b/test_cases/fiber/devnet/open_channel/test_shutdown_script.py @@ -97,8 +97,9 @@ def test_script_udt_none(self): "fee_rate": "0x3FC", } ) - # todo wait close tx commit - time.sleep(40) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 100) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + after_balance1 = self.node.getClient().get_cells_capacity( { "script": { @@ -168,8 +169,9 @@ def test_shutdown_script(self): "fee_rate": "0x3FC", } ) - # todo wait close tx commit - time.sleep(40) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 100) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + after_balance1 = self.node.getClient().get_cells_capacity( { "script": { @@ -204,6 +206,8 @@ def test_shutdown_script_udt(self): ), } ) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 100) + open_channel_message = self.get_tx_message(tx_hash) self.wait_for_channel_state( self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY", 120 ) @@ -221,41 +225,41 @@ def test_shutdown_script_udt(self): "script": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "hash_type": "type", - "args": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9f9bd7e06f3ecf4be0f2fcd2188b23f1b9f9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "args": self.account1["lock_arg"], }, "script_type": "lock", "script_search_mode": "prefix", } ) # shut down - self.fiber2.get_client().shutdown_channel( + self.fiber1.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, "close_script": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "hash_type": "type", - "args": self.account2["lock_arg"], + "args": self.account1["lock_arg"], }, "fee_rate": "0x3FC", } ) - # todo wait close tx commit - time.sleep(40) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 100) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + message = self.get_tx_message(tx_hash) + print("message:", message) + assert message["fee"] < 10000 after_balance1 = self.node.getClient().get_cells_capacity( { "script": { "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", "hash_type": "type", - "args": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9f9bd7e06f3ecf4be0f2fcd2188b23f1b9f9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce89bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "args": self.account1["lock_arg"], }, "script_type": "lock", "script_search_mode": "prefix", } ) - print("before_balance1:", before_balance1) - print("after_balance1:", after_balance1) assert ( int(after_balance1["capacity"], 16) - int(before_balance1["capacity"], 16) - == 732 * 100000000 + >= 700 * 100000000 ) - # todo check udt balance diff --git a/test_cases/fiber/devnet/open_channel/test_tlc_expiry_delta.py b/test_cases/fiber/devnet/open_channel/test_tlc_expiry_delta.py new file mode 100644 index 00000000..3f64c35c --- /dev/null +++ b/test_cases/fiber/devnet/open_channel/test_tlc_expiry_delta.py @@ -0,0 +1,73 @@ +import time + +import pytest + +from framework.basic_fiber import FiberTest + + +class TestTlcLocktimeExpiryDelta(FiberTest): + start_fiber_config = {"fiber_watchtower_check_interval_seconds": 5} + + @pytest.mark.skip("todo") + def test_tlc_expiry_delta_none(self): + """ + tlc_expiry_delta = none + Returns: + """ + # self.test_linked_peer() + + def test_tlc_expiry_delta_is_zero_or_bigger(self): + """ + tlc_expiry_delta = 0 + Returns: + """ + with pytest.raises(Exception) as exc_info: + temporary_channel_id = self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(200 * 100000000), + "public": True, + "tlc_expiry_delta": "0x0", + # "tlc_fee_proportional_millionths": "0x4B0", + } + ) + expected_error_message = ( + "TLC expiry delta is too small, expect larger than 900000" + ) + 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]}'" + ) + temporary_channel_id = self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(200 * 100000000), + "public": True, + "tlc_expiry_delta": "0xffffffff", + # "tlc_fee_proportional_millionths": "0x4B0", + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY", 120 + ) + + @pytest.mark.skip("todo") + def test_tlc_expiry_delta_is_1(self): + """ + tlc_expiry_delta = 1 + Returns: + todo: + qa: open_channel 的 tlc_expiry_delta 作用是什么呢? 有点没理解 @by 我要怎么才能测到这个参数 + A 给 B 发送一个 tlc,如果 B 知道原相,那 B 可以取走 tlc 里面的资金,否则过了时间 tlc_expiry_delta 之后,A 可以取回 tlc 里面的资金。 + 那a 可以怎么取回tlc的资金 + 要在 watchtower 里面做,我们现在似乎没有这个功能 + """ + + @pytest.mark.skip("todo") + def test_tlc_expiry_delta_not_eq_default(self): + """ + tlc_expiry_delta != default + + Returns: + + """ diff --git a/test_cases/fiber/devnet/open_channel/test_tlc_fee_proportional_millionths.py b/test_cases/fiber/devnet/open_channel/test_tlc_fee_proportional_millionths.py index dcb121be..0b18987a 100644 --- a/test_cases/fiber/devnet/open_channel/test_tlc_fee_proportional_millionths.py +++ b/test_cases/fiber/devnet/open_channel/test_tlc_fee_proportional_millionths.py @@ -106,6 +106,49 @@ def test_tlc_fee_proportional_millionths_overflow(self): f"not found in actual string '{exc_info.value.args[0]}'" ) + def test_tlc_fee_proportional_millionths_100_100000000_1000_1000(self): + """ + tlc_fee_proportional_millionths :100 * 100000000 * 1000 * 1000 + 发送 1,收取100ckb的手续费 + Returns: + """ + temporary_channel_id = self.fiber2.get_client().open_channel( + { + "peer_id": self.fiber1.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + # "tlc_min_value": hex(2 * 100000000) + # "funding_fee_rate": "0xffff", + "tlc_fee_proportional_millionths": hex(100 * 100000000 * 1000 * 1000), + } + ) + self.wait_for_channel_state( + self.fiber2.get_client(), self.fiber1.get_peer_id(), "CHANNEL_READY", 120 + ) + channel = self.fiber1.get_client().list_channels({}) + assert channel["channels"][0]["tlc_fee_proportional_millionths"] == "0x3e8" + channel = self.fiber2.get_client().list_channels({}) + assert channel["channels"][0]["tlc_fee_proportional_millionths"] == hex( + 100 * 100000000 * 1000000 + ) + fiber3 = self.start_new_fiber(self.generate_account(10000)) + fiber3.connect_peer(self.fiber2) + time.sleep(1) + fiber3.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + # "tlc_min_value": hex(2 * 100000000) + # "funding_fee_rate": "0xffff", + "tlc_fee_proportional_millionths": "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + } + ) + self.wait_for_channel_state( + fiber3.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY", 120 + ) + self.send_payment(fiber3, self.fiber1, 1) + def test_ckb_tlc_fee_proportional_millionths_not_eq_default(self): """ tlc_fee_proportional_millionths != default @@ -577,4 +620,45 @@ def test_udt_tlc_fee_proportional_millionths_not_eq_default(self): after_channel_12["channels"][0]["local_balance"], 16 ) == int(invoice_balance, 16) - # todo tlc_fee_proportional_millionths add more test case + def test_ckb_tlc_fee_proportional_millionths_is_zero(self): + """ + tlc_fee_proportional_millionths == 0 + + Returns: + """ + account3_private_key = self.generate_account(1000) + new_fiber = self.start_new_fiber(account3_private_key) + self.fiber2.connect_peer(new_fiber) + time.sleep(1) + temporary_channel_id = self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(500 * 100000000), + "public": True, + # "funding_fee_rate": "0xffff", + # "tlc_fee_proportional_millionths": hex(1000000), + } + ) + time.sleep(1) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY", 120 + ) + fiber2_tlc_fee = 0 + temporary_channel_id = self.fiber2.get_client().open_channel( + { + "peer_id": new_fiber.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + "tlc_fee_proportional_millionths": hex(fiber2_tlc_fee), + # "tlc_min_value": hex(2 * 100000000) + # "funding_fee_rate": "0xffff", + # "tlc_fee_proportional_millionths": "0x4B0", + } + ) + time.sleep(1) + self.wait_for_channel_state( + self.fiber2.get_client(), new_fiber.get_peer_id(), "CHANNEL_READY", 120 + ) + payment_hash = self.send_payment(self.fiber1, new_fiber, 100 * 100000000) + payment = self.fiber1.get_client().get_payment({"payment_hash": payment_hash}) + assert payment["fee"] == "0x0" diff --git a/test_cases/fiber/devnet/open_channel/test_tlc_locktime_expiry_delta.py b/test_cases/fiber/devnet/open_channel/test_tlc_locktime_expiry_delta.py deleted file mode 100644 index 0a177cf4..00000000 --- a/test_cases/fiber/devnet/open_channel/test_tlc_locktime_expiry_delta.py +++ /dev/null @@ -1,125 +0,0 @@ -import time - -import pytest - -from framework.basic_fiber import FiberTest - - -class TestTlcLocktimeExpiryDelta(FiberTest): - - @pytest.mark.skip("todo") - def test_tlc_locktime_expiry_delta_none(self): - """ - tlc_locktime_expiry_delta = none - Returns: - """ - # self.test_linked_peer() - - def test_tlc_locktime_expiry_delta_is_zero(self): - """ - tlc_locktime_expiry_delta = 0 - Returns: - """ - - temporary_channel_id = self.fiber1.get_client().open_channel( - { - "peer_id": self.fiber2.get_peer_id(), - "funding_amount": hex(200 * 100000000), - "public": True, - "tlc_locktime_expiry_delta": "0x0", - # "tlc_fee_proportional_millionths": "0x4B0", - } - ) - self.wait_for_channel_state( - self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY", 120 - ) - time.sleep(1) - # transfer - self.fiber1.get_client().graph_channels() - self.fiber1.get_client().graph_nodes() - payment_preimage = self.generate_random_preimage() - invoice_balance = 100 * 100000000 - invoice = self.fiber2.get_client().new_invoice( - { - "amount": hex(invoice_balance), - "currency": "Fibd", - "description": "test invoice generated by node2", - "expiry": "0xe10", - "final_cltv": "0x28", - "payment_preimage": payment_preimage, - "hash_algorithm": "sha256", - } - ) - before_channel = self.fiber1.get_client().list_channels({}) - - self.fiber1.get_client().send_payment( - { - "invoice": invoice["invoice_address"], - } - ) - time.sleep(10) - after_channel = self.fiber1.get_client().list_channels({}) - assert ( - int(before_channel["channels"][0]["local_balance"], 16) - - int(after_channel["channels"][0]["local_balance"], 16) - == invoice_balance - ) - - channels = self.fiber1.get_client().list_channels( - {"peer_id": self.fiber2.get_peer_id()} - ) - N1N2_CHANNEL_ID = channels["channels"][0]["channel_id"] - self.fiber1.get_client().graph_channels() - - before_balance1 = self.Ckb_cli.wallet_get_capacity( - self.account1["address"]["testnet"] - ) - before_balance2 = self.Ckb_cli.wallet_get_capacity( - self.account2["address"]["testnet"] - ) - # shut down - self.fiber1.get_client().shutdown_channel( - { - "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", - } - ) - # todo wait close tx commit - time.sleep(20) - after_balance1 = self.Ckb_cli.wallet_get_capacity( - self.account1["address"]["testnet"] - ) - after_balance2 = self.Ckb_cli.wallet_get_capacity( - self.account2["address"]["testnet"] - ) - print("before_balance1:", before_balance1) - print("before_balance2:", before_balance2) - print("after_balance1:", after_balance1) - print("after_balance2:", after_balance2) - assert after_balance2 - before_balance2 == 162 - - @pytest.mark.skip("todo") - def test_tlc_locktime_expiry_delta_is_1(self): - """ - tlc_locktime_expiry_delta = 1 - Returns: - todo: - qa: open_channel 的 tlc_locktime_expiry_delta 作用是什么呢? 有点没理解 @by 我要怎么才能测到这个参数 - A 给 B 发送一个 tlc,如果 B 知道原相,那 B 可以取走 tlc 里面的资金,否则过了时间 tlc_locktime_expiry_delta 之后,A 可以取回 tlc 里面的资金。 - 那a 可以怎么取回tlc的资金 - 要在 watchtower 里面做,我们现在似乎没有这个功能 - """ - - @pytest.mark.skip("todo") - def test_tlc_locktime_expiry_delta_not_eq_default(self): - """ - tlc_locktime_expiry_delta != default - - Returns: - - """ diff --git a/test_cases/fiber/devnet/open_channel/test_tlc_min_value.py b/test_cases/fiber/devnet/open_channel/test_tlc_min_value.py index 4d270bca..5d722e6c 100644 --- a/test_cases/fiber/devnet/open_channel/test_tlc_min_value.py +++ b/test_cases/fiber/devnet/open_channel/test_tlc_min_value.py @@ -81,8 +81,10 @@ def test_tlc_min_value_none(self): "fee_rate": "0x3FC", } ) - # todo wait close tx commit - time.sleep(20) + + tx_hash = self.wait_and_check_tx_pool_fee(1000, False) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + after_balance1 = self.Ckb_cli.wallet_get_capacity( self.account1["address"]["testnet"] ) @@ -183,7 +185,6 @@ def test_tlc_min_value_is_not_zero(self): "fee_rate": "0x3FC", } ) - # todo wait close tx commit tx_hash = self.wait_and_check_tx_pool_fee(1000, False) tx_response = self.get_tx_message(tx_hash) print("tx response:", tx_response) @@ -434,143 +435,3 @@ def test_udt_tlc_min_value_not_eq_default(self): ), "udt_capacity": 18016000000, } in tx_response["output_cells"] - - # fiber remove tlc_max_value option - # - # def test_udt_tlc_min_value_gt_tlc_max_value(self): - # """ - # tlc_min_value > tlc_max_value - # Returns: - # """ - # - # self.fiber1.get_client().open_channel( - # { - # "peer_id": self.fiber2.get_peer_id(), - # "funding_amount": hex(1000 * 100000000), - # "public": True, - # "tlc_min_value": hex(160 * 100000000), - # "tlc_max_value": hex(160 * 100000000 - 1), - # "funding_udt_type_script": { - # "code_hash": self.udtContract.get_code_hash(True, self.node.rpcUrl), - # "hash_type": "type", - # "args": self.udtContract.get_owner_arg_by_lock_arg( - # self.account1["lock_arg"] - # ), - # }, - # # "tlc_fee_proportional_millionths": "0x4B0", - # } - # ) - # - # time.sleep(1) - # self.wait_for_channel_state( - # self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY", 120 - # ) - # time.sleep(5) - # # transfer - # self.fiber1.get_client().graph_channels() - # self.fiber1.get_client().graph_nodes() - # payment_preimage = self.generate_random_preimage() - # channels = self.fiber1.get_client().list_channels({}) - # invoice_balance = hex(500 * 100000000) - # - # invoice = self.fiber2.get_client().new_invoice( - # { - # "amount": invoice_balance, - # "currency": "Fibd", - # "description": "test invoice generated by node2", - # "expiry": "0xe10", - # "final_cltv": "0x28", - # "payment_preimage": payment_preimage, - # "hash_algorithm": "sha256", - # "udt_type_script": { - # "code_hash": self.udtContract.get_code_hash(True, self.node.rpcUrl), - # "hash_type": "type", - # "args": self.udtContract.get_owner_arg_by_lock_arg( - # self.account1["lock_arg"] - # ), - # }, - # } - # ) - # before_channel = self.fiber1.get_client().list_channels({}) - # - # self.fiber1.get_client().send_payment( - # { - # "invoice": invoice["invoice_address"], - # } - # ) - # time.sleep(10) - # after_channel = self.fiber1.get_client().list_channels({}) - # assert int(before_channel["channels"][0]["local_balance"], 16) - int( - # after_channel["channels"][0]["local_balance"], 16 - # ) == int(invoice_balance, 16) - # - # invoice_balance = hex(160 * 100000000) - # payment_preimage = self.generate_random_preimage() - # invoice = self.fiber1.get_client().new_invoice( - # { - # "amount": invoice_balance, - # "currency": "Fibd", - # "description": "test invoice generated by node2", - # "expiry": "0xe10", - # "final_cltv": "0x28", - # "payment_preimage": payment_preimage, - # "hash_algorithm": "sha256", - # "udt_type_script": { - # "code_hash": self.udtContract.get_code_hash(True, self.node.rpcUrl), - # "hash_type": "type", - # "args": self.udtContract.get_owner_arg_by_lock_arg( - # self.account1["lock_arg"] - # ), - # }, - # } - # ) - # before_channel = self.fiber2.get_client().list_channels({}) - # print("node2 send 1 ckb failed ") - # with pytest.raises(Exception) as exc_info: - # self.fiber2.get_client().send_payment( - # { - # "invoice": invoice["invoice_address"], - # } - # ) - # expected_error_message = "Failed to build route" - # 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]}'" - # ) - # - # channels = self.fiber1.get_client().list_channels( - # {"peer_id": self.fiber2.get_peer_id()} - # ) - # N1N2_CHANNEL_ID = channels["channels"][0]["channel_id"] - # self.fiber1.get_client().graph_channels() - # - # before_balance1 = self.Ckb_cli.wallet_get_capacity( - # self.account1["address"]["testnet"] - # ) - # before_balance2 = self.Ckb_cli.wallet_get_capacity( - # self.account2["address"]["testnet"] - # ) - # # shut down - # self.fiber1.get_client().shutdown_channel( - # { - # "channel_id": N1N2_CHANNEL_ID, - # "close_script": { - # "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - # "hash_type": "type", - # "args": self.account1["lock_arg"], - # }, - # "fee_rate": "0x3FC", - # } - # ) - # # todo wait close tx commit - # time.sleep(20) - # after_balance1 = self.Ckb_cli.wallet_get_capacity( - # self.account1["address"]["testnet"] - # ) - # after_balance2 = self.Ckb_cli.wallet_get_capacity( - # self.account2["address"]["testnet"] - # ) - # print("before_balance1:", before_balance1) - # print("before_balance2:", before_balance2) - # print("after_balance1:", after_balance1) - # print("after_balance2:", after_balance2) diff --git a/test_cases/fiber/devnet/remove_tlc/test_remove_tlc.py b/test_cases/fiber/devnet/remove_tlc/test_remove_tlc.py new file mode 100644 index 00000000..e69de29b diff --git a/test_cases/fiber/devnet/send_payment/test_send_payment.py b/test_cases/fiber/devnet/send_payment/module/test_send_payment.py similarity index 99% rename from test_cases/fiber/devnet/send_payment/test_send_payment.py rename to test_cases/fiber/devnet/send_payment/module/test_send_payment.py index 26040a4a..e65df5ff 100644 --- a/test_cases/fiber/devnet/send_payment/test_send_payment.py +++ b/test_cases/fiber/devnet/send_payment/module/test_send_payment.py @@ -138,7 +138,7 @@ def test_Musig2VerifyError(self): payment1 = self.fiber1.get_client().send_payment( { "target_pubkey": parse_invoice["invoice"]["data"]["attrs"][3][ - "PayeePublicKey" + "payee_public_key" ], "currency": parse_invoice["invoice"]["currency"], "amount": parse_invoice["invoice"]["amount"], diff --git a/test_cases/fiber/devnet/send_payment/test_send_payment_with_shutdown.py b/test_cases/fiber/devnet/send_payment/module/test_send_payment_with_shutdown.py similarity index 100% rename from test_cases/fiber/devnet/send_payment/test_send_payment_with_shutdown.py rename to test_cases/fiber/devnet/send_payment/module/test_send_payment_with_shutdown.py diff --git a/test_cases/fiber/devnet/send_payment/test_send_payment_with_update_channel.py b/test_cases/fiber/devnet/send_payment/module/test_send_payment_with_update_channel.py similarity index 100% rename from test_cases/fiber/devnet/send_payment/test_send_payment_with_update_channel.py rename to test_cases/fiber/devnet/send_payment/module/test_send_payment_with_update_channel.py diff --git a/test_cases/fiber/devnet/send_payment/test_force_restart.py b/test_cases/fiber/devnet/send_payment/offline/test_force_restart.py similarity index 97% rename from test_cases/fiber/devnet/send_payment/test_force_restart.py rename to test_cases/fiber/devnet/send_payment/offline/test_force_restart.py index 57b208e3..5ac7973a 100644 --- a/test_cases/fiber/devnet/send_payment/test_force_restart.py +++ b/test_cases/fiber/devnet/send_payment/offline/test_force_restart.py @@ -228,7 +228,7 @@ def test_restart_node_send_payment_invoice(self): channels = self.fiber3.get_client().list_channels({}) assert channels["channels"][0]["local_balance"] == hex(30 * 100000000) - @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/363") + # @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/363") def test_restart_when_node_send_payment(self): account3_private = self.generate_account(1000) self.fiber3 = self.start_new_fiber(account3_private) @@ -332,7 +332,7 @@ def test_restart_when_node_send_payment(self): print("fiber2 list channels:", channelsN23) self.fiber2.start() - self.wait_payment_state(self.fiber1, payment["payment_hash"], "Inflight", 120) + self.wait_payment_state(self.fiber1, payment["payment_hash"], "Success", 120) channels = self.fiber3.get_client().list_channels({}) assert channels["channels"][0]["local_balance"] == hex(20 * 100000000) @@ -363,6 +363,4 @@ def test_restart_when_node_send_payment(self): ) print("self.fiber3.force_stop() payment:", payment) self.fiber3.start() - self.wait_payment_state(self.fiber1, payment["payment_hash"], "Success", 120) - channels = self.fiber3.get_client().list_channels({}) - assert channels["channels"][0]["local_balance"] == hex(30 * 100000000) + self.wait_payment_finished(self.fiber1, payment["payment_hash"], 120) diff --git a/test_cases/fiber/devnet/send_payment/test_restart.py b/test_cases/fiber/devnet/send_payment/offline/test_restart.py similarity index 97% rename from test_cases/fiber/devnet/send_payment/test_restart.py rename to test_cases/fiber/devnet/send_payment/offline/test_restart.py index e9c0d923..123e3070 100644 --- a/test_cases/fiber/devnet/send_payment/test_restart.py +++ b/test_cases/fiber/devnet/send_payment/offline/test_restart.py @@ -230,7 +230,7 @@ def test_restart_node_send_payment_invoice(self): # FiberTest.debug = True - @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/363") + # @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/363") def test_restart_when_node_send_payment(self): account3_private = self.generate_account(1000) self.fiber3 = self.start_new_fiber(account3_private) @@ -365,6 +365,5 @@ def test_restart_when_node_send_payment(self): ) print("self.fiber3.stop() payment:", payment) self.fiber3.start() - self.wait_payment_state(self.fiber1, payment["payment_hash"], "Success", 120) - channels = self.fiber3.get_client().list_channels({}) - assert channels["channels"][0]["local_balance"] == hex(30 * 100000000) + self.wait_payment_finished(self.fiber1, payment["payment_hash"], 120) + self.send_payment(self.fiber1, self.fiber2, 1) diff --git a/test_cases/fiber/devnet/send_payment/offline/test_send_payment_with_stop.py b/test_cases/fiber/devnet/send_payment/offline/test_send_payment_with_stop.py new file mode 100644 index 00000000..c690c4e3 --- /dev/null +++ b/test_cases/fiber/devnet/send_payment/offline/test_send_payment_with_stop.py @@ -0,0 +1,27 @@ +from framework.basic_fiber import FiberTest + + +class TestSendPaymentWithStop(FiberTest): + pass + # debug = True + # def test_0000(self): + # self.start_new_fiber(self.generate_account(10000)) + # self.start_new_fiber(self.generate_account(10000)) + # for i in range(len(self.fibers) - 1): + # self.open_channel(self.fibers[i], self.fibers[i + 1], 1000 * 100000000, 1) + # + # for i in range(100): + # self.send_payment(self.fibers[0], self.fibers[-1], 1, False) + # self.fibers[0].stop() + # self.fibers[-1].stop() + + # def test_cccc(self): + # self.start_new_mock_fiber("") + # self.start_new_mock_fiber("") + # # for i in range(1000): + # # self.send_payment(self.fibers[0], self.fibers[-1], 1, False) + # # self.send_payment(self.fibers[-1], self.fibers[0], 1, False) + # # self.fiber1.stop() + # self.fibers[1].get_client().list_channels({ + # "peer_id":self.fibers[2].get_peer_id() + # }) diff --git a/test_cases/fiber/devnet/send_payment/test_stop_mid_node.py b/test_cases/fiber/devnet/send_payment/offline/test_stop_mid_node.py similarity index 100% rename from test_cases/fiber/devnet/send_payment/test_stop_mid_node.py rename to test_cases/fiber/devnet/send_payment/offline/test_stop_mid_node.py diff --git a/test_cases/fiber/devnet/send_payment/test_allow_self_payment.py b/test_cases/fiber/devnet/send_payment/params/test_allow_self_payment.py similarity index 99% rename from test_cases/fiber/devnet/send_payment/test_allow_self_payment.py rename to test_cases/fiber/devnet/send_payment/params/test_allow_self_payment.py index 2172b980..0708be5c 100644 --- a/test_cases/fiber/devnet/send_payment/test_allow_self_payment.py +++ b/test_cases/fiber/devnet/send_payment/params/test_allow_self_payment.py @@ -382,4 +382,3 @@ def test_a1_to_b1_to_c1_a2_2(self): } ) self.wait_payment_state(self.fiber1, payment1["payment_hash"], "Success") - # after fix todo add check diff --git a/test_cases/fiber/devnet/send_payment/test_amount.py b/test_cases/fiber/devnet/send_payment/params/test_amount.py similarity index 100% rename from test_cases/fiber/devnet/send_payment/test_amount.py rename to test_cases/fiber/devnet/send_payment/params/test_amount.py diff --git a/test_cases/fiber/devnet/send_payment/params/test_custom_records.py b/test_cases/fiber/devnet/send_payment/params/test_custom_records.py new file mode 100644 index 00000000..983fa794 --- /dev/null +++ b/test_cases/fiber/devnet/send_payment/params/test_custom_records.py @@ -0,0 +1,163 @@ +import time + +import pytest + +from framework.basic_fiber import FiberTest + + +class TestCustomRecords(FiberTest): + + def test_custom(self): + """ + {} + none + 单独的key + 重复的key + 会过滤掉重复的key + key 最大值 + 0xffffffff + key 最小值 + 0x0 + 特别大 + OnionPacket(Sphinx(HopDataLenTooLarge)) + 查询 + 我方可以通过get_payment 查询 + 接受方可以通过get_payment 查询: 目前不可以 + Returns: + + """ + self.open_channel(self.fiber1, self.fiber2, 1000 * 100000000, 1000 * 100000000) + payment = self.fiber1.get_client().send_payment( + { + "target_pubkey": self.fiber2.get_client().node_info()["node_id"], + "amount": hex(100), + "keysend": True, + "allow_self_payment": True, + "custom_records": { + "0x1": "0x1234", + "0x2": "0x5678", + }, + } + ) + print("payment:", payment) + time.sleep(1) + payment = self.fiber1.get_client().get_payment( + { + "payment_hash": payment["payment_hash"], + } + ) + assert {"0x1": "0x1234", "0x2": "0x5678"} == payment["custom_records"] + # todo + # self.fiber2.get_client().get_payment({ + # "payment_hash": payment["payment_hash"], + # }) + + # custom_records empty string + payment = self.fiber1.get_client().send_payment( + { + "target_pubkey": self.fiber2.get_client().node_info()["node_id"], + "amount": hex(100), + "keysend": True, + "allow_self_payment": True, + "custom_records": {}, + } + ) + print("payment:", payment) + time.sleep(1) + payment = self.fiber1.get_client().get_payment( + { + "payment_hash": payment["payment_hash"], + } + ) + assert {} == payment["custom_records"] + + payment = self.fiber1.get_client().get_payment( + { + "payment_hash": payment["payment_hash"], + } + ) + + # 单独的key + custom_records = {} + for i in range(0, 100): + custom_records.update({hex(i): self.generate_random_preimage()}) + payment = self.fiber1.get_client().send_payment( + { + "target_pubkey": self.fiber2.get_client().node_info()["node_id"], + "amount": hex(100), + "keysend": True, + "allow_self_payment": True, + "custom_records": custom_records, + } + ) + print("payment:", payment) + time.sleep(1) + payment = self.fiber1.get_client().get_payment( + { + "payment_hash": payment["payment_hash"], + } + ) + assert custom_records == payment["custom_records"] + + # 最大值 和最小值 + payment = self.fiber1.get_client().send_payment( + { + "target_pubkey": self.fiber2.get_client().node_info()["node_id"], + "amount": hex(100), + "keysend": True, + "allow_self_payment": True, + "custom_records": { + "0xffffffff": "0x1234", + "0x0": "0x5678", + }, + } + ) + print("payment:", payment) + time.sleep(1) + payment = self.fiber1.get_client().get_payment( + { + "payment_hash": payment["payment_hash"], + } + ) + assert { + "0xffffffff": "0x1234", + "0x0": "0x5678", + } == payment["custom_records"] + + # 特别大 报错: OnionPacket(Sphinx(HopDataLenTooLarge)) + with pytest.raises(Exception) as exc_info: + payment = self.fiber1.get_client().send_payment( + { + "target_pubkey": self.fiber2.get_client().node_info()["node_id"], + "amount": hex(100), + "keysend": True, + "allow_self_payment": True, + "custom_records": { + "0xffffffff": self.generate_random_str(13000), + # "0x0": "0x5678", + }, + } + ) + expected_error_message = "HopDataLenTooLarge" + 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]}'" + ) + + # none + payment = self.fiber1.get_client().send_payment( + { + "target_pubkey": self.fiber2.get_client().node_info()["node_id"], + "amount": hex(100), + "keysend": True, + "allow_self_payment": True, + } + ) + print("payment:", payment) + time.sleep(1) + payment = self.fiber1.get_client().get_payment( + { + "payment_hash": payment["payment_hash"], + } + ) + assert None == payment["custom_records"] diff --git a/test_cases/fiber/devnet/send_payment/test_dry_run.py b/test_cases/fiber/devnet/send_payment/params/test_dry_run.py similarity index 100% rename from test_cases/fiber/devnet/send_payment/test_dry_run.py rename to test_cases/fiber/devnet/send_payment/params/test_dry_run.py diff --git a/test_cases/fiber/devnet/send_payment/test_final_tlc_expiry_delta.py b/test_cases/fiber/devnet/send_payment/params/test_final_tlc_expiry_delta.py similarity index 100% rename from test_cases/fiber/devnet/send_payment/test_final_tlc_expiry_delta.py rename to test_cases/fiber/devnet/send_payment/params/test_final_tlc_expiry_delta.py diff --git a/test_cases/fiber/devnet/send_payment/params/test_hophint.py b/test_cases/fiber/devnet/send_payment/params/test_hophint.py new file mode 100644 index 00000000..e353bf6a --- /dev/null +++ b/test_cases/fiber/devnet/send_payment/params/test_hophint.py @@ -0,0 +1,381 @@ +import time + +import pytest + +from framework.basic_fiber import FiberTest + + +class TestHopHint(FiberTest): # a-b + # FiberTest.debug = True + + def test_not_hophit_simple(self): + """ + b-c-d-私-a + 1.b-a(不通过hophit应该发送失败) + Returns: + + """ + self.start_new_fiber(self.generate_account(10000)) # c + self.start_new_fiber(self.generate_account(10000)) # d + + fiber1_balance = 1000 * 100000000 + fiber1_fee = 1000 + self.open_channel(self.fibers[1], self.fibers[2], 1000 * 100000000, 1) # b-c + self.open_channel( + self.fibers[2], self.fibers[3], 1000 * 100000000, 1 + ) # c-d == b-c-d + + self.fibers[3].connect_peer(self.fibers[0]) # d-a + time.sleep(1) + self.fibers[3].get_client().open_channel( # d -a private channel + { + "peer_id": self.fibers[0].get_peer_id(), + "funding_amount": hex(fiber1_balance + 62 * 100000000), + "tlc_fee_proportional_millionths": hex(fiber1_fee), + "public": False, + } + ) + time.sleep(1) + self.wait_for_channel_state( + self.fibers[3].get_client(), self.fibers[0].get_peer_id(), "CHANNEL_READY" + ) + + # b-a(不通过hophit应该发送失败) + + try: + self.send_payment(self.fibers[1], self.fibers[0], 1 * 100000000) + except Exception as e: + error_message = str(e) + assert ( + error_message + == "Error: Send payment error: Failed to build route, PathFind error: no path found" + ), f"Unexpected error message: {error_message}" + + def test_not_hophit(self): + """ + a-私-b-c-d-私-a + 路径选择 + 1. b-a,预期是能成功 + 2. 如果走的是b-c-d-a,则需要走hint才可以成功,预期是失败(大概率走这个路径) + Returns: + + """ + self.start_new_fiber(self.generate_account(10000)) # c + self.start_new_fiber(self.generate_account(10000)) # d + + fiber1_balance = 1000 * 100000000 + fiber1_fee = 1000 + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(fiber1_balance + 62 * 100000000), + "tlc_fee_proportional_millionths": hex(fiber1_fee), + "public": False, + } + ) # a-b private channel + time.sleep(1) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + self.open_channel(self.fibers[1], self.fibers[2], 1000 * 100000000, 1) # b-c + self.open_channel( + self.fibers[2], self.fibers[3], 1000 * 100000000, 1 + ) # c-d == b-c-d + + self.fibers[3].connect_peer(self.fibers[0]) # d-a + time.sleep(1) + self.fibers[3].get_client().open_channel( # d -a private channel + { + "peer_id": self.fibers[0].get_peer_id(), + "funding_amount": hex(fiber1_balance + 62 * 100000000), + "tlc_fee_proportional_millionths": hex(fiber1_fee), + "public": False, + } + ) + time.sleep(1) + self.wait_for_channel_state( + self.fibers[3].get_client(), self.fibers[0].get_peer_id(), "CHANNEL_READY" + ) + + try: + # 走b-a会成功 + payment = ( + self.fibers[1] + .get_client() + .send_payment( # b + { + "target_pubkey": self.fibers[0] + .get_client() + .node_info()["node_id"], + "amount": hex(10 * 100000000), + "keysend": True, + } + ) + ) + print(f"debug payment content:{payment}") + + except Exception as e: + # 如果走的是b-c-d-a,不通过hophit应该发送失败 + error_message = str(e) + assert ( + error_message + == "Error: Send payment error: Failed to build route, PathFind error: no path found" + ), f"Unexpected error message: {error_message}" + + # @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/620") + def test_not_hophit_issue620(self): + """ + a-私-b-c-d-私-a + 1. a->b + 2. a->c + 3. a->d + 4. a->a(不支持,不能自己转给自己) + 5. 路径选择 + 5.1. b-a,预期是能成功(大概率走这个) + 5.2. 如果走的是b-c-d-a,则需要走hint才可以成功,预期是失败 + Returns: + + """ + self.start_new_fiber(self.generate_account(10000)) # c + self.start_new_fiber(self.generate_account(10000)) # d + + fiber1_balance = 1000 * 100000000 + fiber1_fee = 1000 + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(fiber1_balance + 62 * 100000000), + "tlc_fee_proportional_millionths": hex(fiber1_fee), + "public": False, + } + ) # a-b private channel + time.sleep(1) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + self.open_channel(self.fibers[1], self.fibers[2], 1000 * 100000000, 1) # b-c + self.open_channel( + self.fibers[2], self.fibers[3], 1000 * 100000000, 1 + ) # c-d == b-c-d + + self.fibers[3].connect_peer(self.fibers[0]) # d-a + time.sleep(1) + self.fibers[3].get_client().open_channel( # d -a private channel + { + "peer_id": self.fibers[0].get_peer_id(), + "funding_amount": hex(fiber1_balance + 62 * 100000000), + "tlc_fee_proportional_millionths": hex(fiber1_fee), + "public": False, + } + ) + time.sleep(1) + self.wait_for_channel_state( + self.fibers[3].get_client(), self.fibers[0].get_peer_id(), "CHANNEL_READY" + ) + + for i in range(1, len(self.fibers)): # b,c,d + self.send_payment( + self.fibers[0], self.fibers[i], 1 * 100000000 + ) # a->b,a->c,a>d + print(f"debug:a-a,route") + # a->a是不支持的,除非a-私-b-c-d-私-a这么走一圈,异常捕捉在方法里面 + self.send_payment(self.fibers[0], self.fibers[0], 1 * 100000000) + + # b-a(不通过hophit应该发送失败) + try: + payment = ( + self.fibers[1] + .get_client() + .send_payment( # b + { + "target_pubkey": self.fibers[0] + .get_client() + .node_info()["node_id"], + "amount": hex(1 * 100000000), + "keysend": True, + } + ) + ) + print(f"debug payment content:{payment}") + + channels = ( + self.fibers[1] + .get_client() + .list_channels({"peer_id": self.fibers[0].get_peer_id()}) + ) + print(f"b-a,channel:{channels}") + ba_channel_outpoint = channels["channels"][0]["channel_outpoint"] + print(f"b-a, channel_outpoint:{ba_channel_outpoint}") + assert payment["router"][0]["channel_outpoint"] == ba_channel_outpoint + except Exception as e: + # 如果走的是b-c-d-a,不通过hophit应该发送失败 + error_message = str(e) + assert ( + error_message + == "Error: Send payment error: Failed to build route, PathFind error: no path found" + ), f"Unexpected error message: {error_message}" + + def test_use_hophit(self): + """ + a-私-b-c-d-私-a + 1. b-a(通过hophit应该发送成功) + Returns: + """ + self.start_new_fiber(self.generate_account(10000)) # c + self.start_new_fiber(self.generate_account(10000)) # d + + fiber1_balance = 1000 * 100000000 + fiber1_fee = 1000 + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(fiber1_balance + 62 * 100000000), + "tlc_fee_proportional_millionths": hex(fiber1_fee), + "public": False, + } + ) # a-b private channel + time.sleep(1) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + self.open_channel(self.fibers[1], self.fibers[2], 1000 * 100000000, 1) # b-c + self.open_channel( + self.fibers[2], self.fibers[3], 1000 * 100000000, 1 + ) # c-d == b-c-d + + self.fibers[3].connect_peer(self.fibers[0]) # d-a + time.sleep(1) + self.fibers[3].get_client().open_channel( # d -a private channel + { + "peer_id": self.fibers[0].get_peer_id(), + "funding_amount": hex(fiber1_balance + 62 * 100000000), + "tlc_fee_proportional_millionths": hex(fiber1_fee), + "public": False, + } + ) + time.sleep(1) + self.wait_for_channel_state( + self.fibers[3].get_client(), self.fibers[0].get_peer_id(), "CHANNEL_READY" + ) + # 查看d-a的channeloutpoint + print(f"a peer_id:{self.fibers[0].get_peer_id()}") + print(f"d peer_id:{self.fibers[3].get_peer_id()}") + channels = ( + self.fibers[3] + .get_client() + .list_channels({"peer_id": self.fibers[0].get_peer_id()}) + ) + print( + f"d-a,channel:{channels}" + ) # {'channels': [{'channel_id': '0xe59fc475a5e32bfd4130f5d7b73e2c77e94e40a1c4de0f4c4f7cb65a23cfa808', 'is_public': False, 'channel_outpoint': '0x7f2fc106cbc01d25e9682826ec131e67be8e9868fbb37edd6591bb7423feb21000000000', 'peer_id': 'QmT5SaY3CSSY9XvgoqJ521TXSUQ5DBZ58DTdafPKFBEcWf', 'funding_udt_type_script': None, 'state': {'state_name': 'CHANNEL_READY'}, 'local_balance': '0x174876e800', 'offered_tlc_balance': '0x0', 'remote_balance': '0x0', 'received_tlc_balance': '0x0', 'latest_commitment_transaction_hash': '0x93e75ade9b0016dbca0a56698fbf04f4a4ca5d8bc3c40fa781769e37ebb9fba2', 'created_at': '0x195d58690aa', 'enabled': True, 'tlc_expiry_delta': '0x5265c00', 'tlc_fee_proportional_millionths': '0x3e8'}, {'channel_id': '0xab117469b812d64410e1f4a6429475908f8672eda1a492772387880fd9046f07', 'is_public': False, 'channel_outpoint': '0xfe4f6fbfd2fb31ec9ca6dc7a4e43efa4e864002fae281c7c5e38fc51cd89465f00000000', 'peer_id': 'QmT5SaY3CSSY9XvgoqJ521TXSUQ5DBZ58DTdafPKFBEcWf', 'funding_udt_type_script': None, 'state': {'state_name': 'CHANNEL_READY'}, 'local_balance': '0x174876e800', 'offered_tlc_balance': '0x0', 'remote_balance': '0x0', 'received_tlc_balance': '0x0', 'latest_commitment_transaction_hash': '0xc6f38fe84030eba95376c63e76ccfa9605c07f5ca407e395ca53db609b305787', 'created_at': '0x195d2e09a4d', 'enabled': True, 'tlc_expiry_delta': '0x5265c00', 'tlc_fee_proportional_millionths': '0x3e8'}]} + da_channel_outpoint = channels["channels"][0]["channel_outpoint"] + print(f"d-a, channel_outpoint:{da_channel_outpoint}") + # b-a,怎么填d-私-a的信息 + + payment_hash = ( + self.fibers[1] + .get_client() + .send_payment( # b + { + "target_pubkey": self.fibers[0].get_client().node_info()["node_id"], + "amount": hex(10 * 100000000), + "keysend": True, + "hop_hints": [ + { + "pubkey": self.fibers[3] + .get_client() + .node_info()["node_id"], + # 填的是 d 的 pubkey,表示在 d 节点使用 channel_outpoint 到 a + "channel_outpoint": da_channel_outpoint, + "fee_rate": hex(1000), + "tlc_expiry_delta": hex(1000), + } + ], + } + ) + ) + + payment = ( + self.fibers[1] + .get_client() + .get_payment({"payment_hash": payment_hash["payment_hash"]}) + ) + print("payment", payment) + assert payment["status"] == "Created" + + def test_use_hophit_simple(self): + """ + b-c-d-私-a + 1. b-a(通过hophit应该发送成功) + Returns: + """ + self.start_new_fiber(self.generate_account(10000)) # c + self.start_new_fiber(self.generate_account(10000)) # d + + fiber1_balance = 1000 * 100000000 + fiber1_fee = 1000 + + self.open_channel(self.fibers[1], self.fibers[2], 1000 * 100000000, 1) # b-c + self.open_channel( + self.fibers[2], self.fibers[3], 1000 * 100000000, 1 + ) # c-d == b-c-d + + self.fibers[3].connect_peer(self.fibers[0]) # d-a + time.sleep(1) + self.fibers[3].get_client().open_channel( # d -a private channel + { + "peer_id": self.fibers[0].get_peer_id(), + "funding_amount": hex(fiber1_balance + 62 * 100000000), + "tlc_fee_proportional_millionths": hex(fiber1_fee), + "public": False, + } + ) + time.sleep(1) + self.wait_for_channel_state( + self.fibers[3].get_client(), self.fibers[0].get_peer_id(), "CHANNEL_READY" + ) + # 查看d-a的channeloutpoint + print(f"a peer_id:{self.fibers[0].get_peer_id()}") + print(f"d peer_id:{self.fibers[3].get_peer_id()}") + channels = ( + self.fibers[3] + .get_client() + .list_channels({"peer_id": self.fibers[0].get_peer_id()}) + ) + print( + f"d-a,channel:{channels}" + ) # {'channels': [{'channel_id': '0xe59fc475a5e32bfd4130f5d7b73e2c77e94e40a1c4de0f4c4f7cb65a23cfa808', 'is_public': False, 'channel_outpoint': '0x7f2fc106cbc01d25e9682826ec131e67be8e9868fbb37edd6591bb7423feb21000000000', 'peer_id': 'QmT5SaY3CSSY9XvgoqJ521TXSUQ5DBZ58DTdafPKFBEcWf', 'funding_udt_type_script': None, 'state': {'state_name': 'CHANNEL_READY'}, 'local_balance': '0x174876e800', 'offered_tlc_balance': '0x0', 'remote_balance': '0x0', 'received_tlc_balance': '0x0', 'latest_commitment_transaction_hash': '0x93e75ade9b0016dbca0a56698fbf04f4a4ca5d8bc3c40fa781769e37ebb9fba2', 'created_at': '0x195d58690aa', 'enabled': True, 'tlc_expiry_delta': '0x5265c00', 'tlc_fee_proportional_millionths': '0x3e8'}, {'channel_id': '0xab117469b812d64410e1f4a6429475908f8672eda1a492772387880fd9046f07', 'is_public': False, 'channel_outpoint': '0xfe4f6fbfd2fb31ec9ca6dc7a4e43efa4e864002fae281c7c5e38fc51cd89465f00000000', 'peer_id': 'QmT5SaY3CSSY9XvgoqJ521TXSUQ5DBZ58DTdafPKFBEcWf', 'funding_udt_type_script': None, 'state': {'state_name': 'CHANNEL_READY'}, 'local_balance': '0x174876e800', 'offered_tlc_balance': '0x0', 'remote_balance': '0x0', 'received_tlc_balance': '0x0', 'latest_commitment_transaction_hash': '0xc6f38fe84030eba95376c63e76ccfa9605c07f5ca407e395ca53db609b305787', 'created_at': '0x195d2e09a4d', 'enabled': True, 'tlc_expiry_delta': '0x5265c00', 'tlc_fee_proportional_millionths': '0x3e8'}]} + da_channel_outpoint = channels["channels"][0]["channel_outpoint"] + print(f"d-a, channel_outpoint:{da_channel_outpoint}") + # b-a,怎么填d-私-a的信息 + + payment_hash = ( + self.fibers[1] + .get_client() + .send_payment( # b + { + "target_pubkey": self.fibers[0].get_client().node_info()["node_id"], + "amount": hex(10 * 100000000), + "keysend": True, + "hop_hints": [ + { + "pubkey": self.fibers[3] + .get_client() + .node_info()[ + "node_id" + ], # 填的是 d 的 pubkey,表示在 d 节点使用 channel_outpoint 到 a + "channel_outpoint": da_channel_outpoint, + "fee_rate": hex(1000), + "tlc_expiry_delta": hex(1000), + } + ], + } + ) + ) + payment = ( + self.fibers[1] + .get_client() + .get_payment({"payment_hash": payment_hash["payment_hash"]}) + ) + print("payment", payment) + assert payment["status"] == "Created" diff --git a/test_cases/fiber/devnet/send_payment/params/test_max_fee_amount.py b/test_cases/fiber/devnet/send_payment/params/test_max_fee_amount.py new file mode 100644 index 00000000..29a10023 --- /dev/null +++ b/test_cases/fiber/devnet/send_payment/params/test_max_fee_amount.py @@ -0,0 +1,85 @@ +import pytest + +from framework.basic_fiber import FiberTest + + +class TestMaxFeeAmount(FiberTest): + + def test_fee(self): + account_private = self.generate_account(1000) + self.fiber3 = self.start_new_fiber(account_private) + self.fiber3.connect_peer(self.fiber2) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(100000000 * 100000000), + "public": True, + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + self.fiber2.get_client().open_channel( + { + "peer_id": self.fiber3.get_peer_id(), + "funding_amount": hex(100000000 * 100000000), + "public": True, + } + ) + self.wait_for_channel_state( + self.fiber3.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + + # send to node1 -> node2 no fee max_fee = 0 + payment1 = self.fiber1.get_client().send_payment( + { + "target_pubkey": self.fiber2.get_client().node_info()["node_id"], + "amount": hex(1000000 * 100000000), + "keysend": True, + "max_fee_amount": hex(0), + "dry_run": True, + } + ) + # send to node1 - > node3 need fee 10000 but max_fee = 0 + with pytest.raises(Exception) as exc_info: + payment1 = self.fiber1.get_client().send_payment( + { + "target_pubkey": self.fiber3.get_client().node_info()["node_id"], + "amount": hex(1000000 * 100000000), + "keysend": True, + "max_fee_amount": hex(0), + "dry_run": True, + } + ) + expected_error_message = "Failed to build route" + 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]}'" + ) + + payment1 = self.fiber1.get_client().send_payment( + { + "target_pubkey": self.fiber3.get_client().node_info()["node_id"], + "amount": hex(1000000 * 100000000), + "keysend": True, + "dry_run": True, + } + ) + payment1 = self.fiber1.get_client().send_payment( + { + "target_pubkey": self.fiber3.get_client().node_info()["node_id"], + "amount": hex(1000000 * 100000000), + "keysend": True, + "max_fee_amount": payment1["fee"], + } + ) + self.wait_payment_state(self.fiber1, payment1["payment_hash"]) + + # + # + # def test_max_fee_amount_is_none(self): + # """ + # max_fee_amount == node 代表什么 + # Returns: + # + # """ diff --git a/test_cases/fiber/devnet/send_payment/test_max_parts.py b/test_cases/fiber/devnet/send_payment/params/test_max_parts.py similarity index 100% rename from test_cases/fiber/devnet/send_payment/test_max_parts.py rename to test_cases/fiber/devnet/send_payment/params/test_max_parts.py diff --git a/test_cases/fiber/devnet/send_payment/test_payment_hash.py b/test_cases/fiber/devnet/send_payment/params/test_payment_hash.py similarity index 96% rename from test_cases/fiber/devnet/send_payment/test_payment_hash.py rename to test_cases/fiber/devnet/send_payment/params/test_payment_hash.py index 000fb3da..8b3a1bc0 100644 --- a/test_cases/fiber/devnet/send_payment/test_payment_hash.py +++ b/test_cases/fiber/devnet/send_payment/params/test_payment_hash.py @@ -53,14 +53,15 @@ def test_payment_hash_not_exist(self): payment1 = self.fiber1.get_client().send_payment( { "target_pubkey": parse_invoice["invoice"]["data"]["attrs"][3][ - "PayeePublicKey" + "payee_public_key" ], "currency": parse_invoice["invoice"]["currency"], "payment_hash": self.generate_random_preimage(), "amount": invoice["invoice"]["amount"], - "dry_run": True, + # "dry_run": True, } ) + self.wait_payment_state(self.fiber1, payment1["payment_hash"], "Failed") def test_rand_hash_Musig2VerifyError(self): account_private = self.generate_account(1000) @@ -105,7 +106,7 @@ def test_rand_hash_Musig2VerifyError(self): payment1 = self.fiber1.get_client().send_payment( { "target_pubkey": parse_invoice["invoice"]["data"]["attrs"][3][ - "PayeePublicKey" + "payee_public_key" ], "currency": parse_invoice["invoice"]["currency"], "payment_hash": self.generate_random_preimage(), @@ -116,7 +117,7 @@ def test_rand_hash_Musig2VerifyError(self): payment1 = self.fiber1.get_client().send_payment( { "target_pubkey": parse_invoice["invoice"]["data"]["attrs"][3][ - "PayeePublicKey" + "payee_public_key" ], "currency": parse_invoice["invoice"]["currency"], "payment_hash": self.generate_random_preimage(), diff --git a/test_cases/fiber/devnet/send_payment/params/test_timeout.py b/test_cases/fiber/devnet/send_payment/params/test_timeout.py new file mode 100644 index 00000000..a5a6a2a7 --- /dev/null +++ b/test_cases/fiber/devnet/send_payment/params/test_timeout.py @@ -0,0 +1,40 @@ +from framework.basic_fiber import FiberTest + + +class TestTimeout(FiberTest): + + def test_01(self): + self.fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.open_channel(self.fiber1, self.fiber2, 1000 * 100000000, 1000 * 100000000) + self.open_channel(self.fiber2, self.fiber3, 1000 * 100000000, 1000 * 100000000) + payment = self.fiber1.get_client().send_payment( + { + "target_pubkey": self.fiber3.get_client().node_info()["node_id"], + "amount": hex(10 * 100000000), + "keysend": True, + "timeout": hex(0), + } + ) + self.wait_payment_state(self.fiber1, payment["payment_hash"], "Success", 100) + + # for i in range(100): + # payment = self.fiber1.get_client().send_payment({ + # "target_pubkey": self.fiber3.get_client().node_info()["node_id"], + # "amount": hex(1 * 10000000), + # "keysend": True, + # "timeout": hex(0) + # }) + # payments.append(payment) + # for i in range(100): + # payment = payments[i] + # print(i, payment) + # self.wait_payment_finished(self.fiber1, payment["payment_hash"], 1000) + # payment_result = [] + # for i in range(100): + # ret = self.fiber1.get_client().get_payment({ + # "payment_hash": payments[i]["payment_hash"] + # }) + # payment_result.append(ret) + # for i in range(100): + # ret = payment_result[i] + # print(i, ret) diff --git a/test_cases/fiber/devnet/send_payment/test_tlc_expiry_limit.py b/test_cases/fiber/devnet/send_payment/params/test_tlc_expiry_limit.py similarity index 100% rename from test_cases/fiber/devnet/send_payment/test_tlc_expiry_limit.py rename to test_cases/fiber/devnet/send_payment/params/test_tlc_expiry_limit.py diff --git a/test_cases/fiber/devnet/send_payment/test_tlc_fee.py b/test_cases/fiber/devnet/send_payment/params/test_tlc_fee.py similarity index 100% rename from test_cases/fiber/devnet/send_payment/test_tlc_fee.py rename to test_cases/fiber/devnet/send_payment/params/test_tlc_fee.py diff --git a/test_cases/fiber/devnet/send_payment/params/test_used_preimage.py b/test_cases/fiber/devnet/send_payment/params/test_used_preimage.py new file mode 100644 index 00000000..976df537 --- /dev/null +++ b/test_cases/fiber/devnet/send_payment/params/test_used_preimage.py @@ -0,0 +1,46 @@ +import pytest + +from framework.basic_fiber import FiberTest + + +class TestUsedPreimage(FiberTest): + + def test_used_preimage(self): + self.open_channel(self.fiber1, self.fiber2, 1000 * 100000000, 1000 * 100000000) + payment_preimage = self.generate_random_preimage() + invoice = self.fiber2.get_client().new_invoice( + { + "amount": hex(1), + "currency": "Fibd", + "description": "test invoice generated by node2", + "expiry": "0xe10", + "final_cltv": "0x28", + "payment_preimage": payment_preimage, + "hash_algorithm": "sha256", + } + ) + payment = self.fiber1.get_client().send_payment( + { + "invoice": invoice["invoice_address"], + } + ) + self.wait_payment_state(self.fiber1, payment["payment_hash"], "Success") + # send payment again + + with pytest.raises(Exception) as exc_info: + invoice = self.fiber2.get_client().new_invoice( + { + "amount": hex(1), + "currency": "Fibd", + "description": "test invoice generated by node2", + "expiry": "0xe10", + "final_cltv": "0x28", + "payment_preimage": payment_preimage, + "hash_algorithm": "sha256", + } + ) + expected_error_message = "Duplicated invoice" + 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/fiber/devnet/send_payment/test_find_path.py b/test_cases/fiber/devnet/send_payment/path/test_find_path.py similarity index 100% rename from test_cases/fiber/devnet/send_payment/test_find_path.py rename to test_cases/fiber/devnet/send_payment/path/test_find_path.py diff --git a/test_cases/fiber/devnet/send_payment/test_long_router.py b/test_cases/fiber/devnet/send_payment/path/test_long_router.py similarity index 100% rename from test_cases/fiber/devnet/send_payment/test_long_router.py rename to test_cases/fiber/devnet/send_payment/path/test_long_router.py diff --git a/test_cases/fiber/devnet/send_payment/path/test_mutil_channel.py b/test_cases/fiber/devnet/send_payment/path/test_mutil_channel.py new file mode 100644 index 00000000..f3bf784a --- /dev/null +++ b/test_cases/fiber/devnet/send_payment/path/test_mutil_channel.py @@ -0,0 +1,40 @@ +from framework.basic_fiber import FiberTest + + +class TestMutilChannel(FiberTest): + + def test_mutil_channel(self): + """ + 1. 节点1 和节点2之间建立多个channel + 2. 节点1 疯狂给节点2发交易 + 可以用到多个channel + Returns: + """ + open_channel_size = 5 + send_payment_size = 20 + for i in range(open_channel_size): + self.open_channel(self.fiber1, self.fiber2, 1000 * 100000000, 1) + + payment_list = [] + before_channels = self.fiber1.get_client().list_channels({}) + + for i in range(send_payment_size): + payment_list.append( + self.send_payment(self.fiber1, self.fiber2, 1 * 100000000, False) + ) + + for payment_hash in payment_list: + self.wait_payment_finished(self.fiber1, payment_hash, 120) + + channels = self.fiber1.get_client().list_channels({}) + for i in range(len(before_channels["channels"])): + print(before_channels["channels"][i]) + used_channel = 0 + for i in range(len(channels["channels"])): + print(channels["channels"][i]) + if ( + channels["channels"][i]["remote_balance"] + > before_channels["channels"][i]["remote_balance"] + ): + used_channel += 1 + assert used_channel > 1 diff --git a/test_cases/fiber/devnet/send_payment/test_private_channel.py b/test_cases/fiber/devnet/send_payment/path/test_private_channel.py similarity index 98% rename from test_cases/fiber/devnet/send_payment/test_private_channel.py rename to test_cases/fiber/devnet/send_payment/path/test_private_channel.py index 70088fe9..f680718d 100644 --- a/test_cases/fiber/devnet/send_payment/test_private_channel.py +++ b/test_cases/fiber/devnet/send_payment/path/test_private_channel.py @@ -52,7 +52,7 @@ def test_private_channel(self): self.wait_for_channel_state( self.fibers[3].get_client(), self.fibers[0].get_peer_id(), "CHANNEL_READY" ) - + time.sleep(1) for i in range(1, len(self.fibers)): self.send_payment(self.fibers[0], self.fibers[i], 1 * 100000000) diff --git a/test_cases/fiber/devnet/send_payment/test_max_fee_amount.py b/test_cases/fiber/devnet/send_payment/test_max_fee_amount.py deleted file mode 100644 index 7c6f456e..00000000 --- a/test_cases/fiber/devnet/send_payment/test_max_fee_amount.py +++ /dev/null @@ -1,52 +0,0 @@ -import pytest - -from framework.basic_fiber import FiberTest - - -class TestMaxFeeAmount(FiberTest): - # FiberTest.debug = True - - # @pytest.mark.skip("send to node1 -> node2 no fee 设置 max_fee = 0 会报错") - def test_fee(self): - account_private = self.generate_account(1000) - self.fiber3 = self.start_new_fiber(account_private) - self.fiber3.connect_peer(self.fiber2) - self.fiber1.get_client().open_channel( - { - "peer_id": self.fiber2.get_peer_id(), - "funding_amount": hex(100000000 * 100000000), - "public": True, - } - ) - self.wait_for_channel_state( - self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" - ) - self.fiber2.get_client().open_channel( - { - "peer_id": self.fiber3.get_peer_id(), - "funding_amount": hex(100000000 * 100000000), - "public": True, - } - ) - self.wait_for_channel_state( - self.fiber3.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" - ) - - # send to node1 -> node2 no fee max_fee = 0 - payment1 = self.fiber1.get_client().send_payment( - { - "target_pubkey": self.fiber2.get_client().node_info()["node_id"], - "amount": hex(1000000 * 100000000), - "keysend": True, - "max_fee_amount": hex(0), - "dry_run": True, - } - ) - # send to node1 - > node3 need fee 10000 but max_fee = 0 - - def test_max_fee_amount_is_none(self): - """ - max_fee_amount == node 代表什么 - Returns: - - """ diff --git a/test_cases/fiber/devnet/send_payment_with_router/test_send_payment_with_router.py b/test_cases/fiber/devnet/send_payment_with_router/test_send_payment_with_router.py new file mode 100644 index 00000000..aa374d27 --- /dev/null +++ b/test_cases/fiber/devnet/send_payment_with_router/test_send_payment_with_router.py @@ -0,0 +1,399 @@ +import time +from framework.basic_fiber import FiberTest +import pytest + + +class TestSendPaymentWithRouter(FiberTest): + """ + 测试 send_payment_with_router RPC 的功能: + 1. 基本支付功能 + - 使用指定路由发送支付 + - 验证支付状态和路由信息 + + 2. 路由指定测试 + - 使用 build_router 构建的路由进行支付 + - 手动指定完整路由进行支付 + - 测试无效路由的情况 + + 3. 支付选项测试 + - 测试指定 payment_hash 的情况 + - 测试使用 invoice 的情况 + - 测试 keysend 支付 + - 测试带自定义记录的支付 + + 4. 特殊情况测试 + - 使用 dry_run 模式测试支付可行性 + - 测试 UDT 支付 + - 测试支付失败的错误处理 + + 5. 路由追踪 + - 验证支付历史中的路由信息 + - 验证每个节点的金额和通道信息 + """ + + FiberTest.debug = True + + def test_base_send_payment_with_router(self): + """ + b-c-d-私-a网络 + 1. d-a建立了路由关系,查看构建的路由返回信息 + 2. d call a ,route info: d-a channel outpoint + """ + self.start_new_fiber(self.generate_account(10000)) + self.start_new_fiber(self.generate_account(10000)) + + fiber1_balance = 1000 * 100000000 + fiber1_fee = 1000 + + self.open_channel(self.fibers[1], self.fibers[2], 1000 * 100000000, 1) # b-c + self.open_channel( + self.fibers[2], self.fibers[3], 1000 * 100000000, 1 + ) # c-d == b-c-d + + self.fibers[3].connect_peer(self.fibers[0]) # d-a + time.sleep(1) + self.fibers[3].get_client().open_channel( # d -a private channel + { + "peer_id": self.fibers[0].get_peer_id(), + "funding_amount": hex(fiber1_balance + 62 * 100000000), + "tlc_fee_proportional_millionths": hex(fiber1_fee), + "public": False, + } + ) + time.sleep(1) + self.wait_for_channel_state( + self.fibers[3].get_client(), self.fibers[0].get_peer_id(), "CHANNEL_READY" + ) + # 查看d-a的channeloutpoint,预期能调用成功 + print(f"a peer_id:{self.fibers[0].get_peer_id()}") + print(f"d peer_id:{self.fibers[3].get_peer_id()}") + channels = ( + self.fibers[3] + .get_client() + .list_channels({"peer_id": self.fibers[0].get_peer_id()}) + ) + print(f"d-a,channel:{channels}") + da_channel_outpoint = channels["channels"][0]["channel_outpoint"] + print(f"d-a, channel_outpoint:{da_channel_outpoint}") + + router_hops = ( + self.fibers[3] + .get_client() + .build_router( + { + "amount": hex(1 + 62 * 100000000), + "udt_type_script": None, + "hops_info": [ + { + "pubkey": self.fibers[0] + .get_client() + .node_info()["node_id"], + "channel_outpoint": da_channel_outpoint, + }, + ], + "final_tlc_expiry_delta": None, + } + ) + ) + print(f"router_hops:{router_hops}") + hop = router_hops["router_hops"][0] + print(f"hop:{hop}") + assert hop["channel_outpoint"] == da_channel_outpoint + assert hop["target"] == self.fibers[0].get_client().node_info()["node_id"] + assert hop["amount_received"] == hex(1 + 62 * 100000000) + + # d call a ,route info: d-a channel outpoint + payment = ( + self.fibers[3] + .get_client() + .send_payment_with_router( + { + "payment_hash": None, + "invoice": None, + "keysend": True, + "custom_records": None, + "dry_run": False, + "udt_type_script": None, + "router": router_hops["router_hops"], + } + ) + ) + print(f"payment:{payment}") + assert payment["status"] == "Created" + self.wait_payment_state(self.fibers[3], payment["payment_hash"], "Success") + + # @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/641") + def test_auto_send_payment_with_router(self): + """ + b-c-d-私-a网络 + 1. d-a建立了路由关系,查看构建的路由返回信息 + 2. b call a ,走route info: b-c-d-私-a网络(检查应该不支持自动拼接完整的路由) + """ + self.start_new_fiber(self.generate_account(10000)) + self.start_new_fiber(self.generate_account(10000)) + + fiber1_balance = 1000 * 100000000 + fiber1_fee = 1000 + + self.open_channel(self.fibers[1], self.fibers[2], 1000 * 100000000, 1) # b-c + self.open_channel( + self.fibers[2], self.fibers[3], 1000 * 100000000, 1 + ) # c-d == b-c-d + + self.fibers[3].connect_peer(self.fibers[0]) # d-a + time.sleep(1) + self.fibers[3].get_client().open_channel( # d -a private channel + { + "peer_id": self.fibers[0].get_peer_id(), + "funding_amount": hex(fiber1_balance + 62 * 100000000), + "tlc_fee_proportional_millionths": hex(fiber1_fee), + "public": False, + } + ) + time.sleep(1) + self.wait_for_channel_state( + self.fibers[3].get_client(), self.fibers[0].get_peer_id(), "CHANNEL_READY" + ) + # 查看d-a的channeloutpoint,预期能调用成功 + print(f"a peer_id:{self.fibers[0].get_peer_id()}") + print(f"d peer_id:{self.fibers[3].get_peer_id()}") + channels = ( + self.fibers[3] + .get_client() + .list_channels({"peer_id": self.fibers[0].get_peer_id()}) + ) + print(f"d-a,channel:{channels}") + da_channel_outpoint = channels["channels"][0]["channel_outpoint"] + print(f"d-a, channel_outpoint:{da_channel_outpoint}") + + router_hops = ( + self.fibers[3] + .get_client() + .build_router( + { + "amount": hex(1 + 62 * 100000000), + "udt_type_script": None, + "hops_info": [ + { + "pubkey": self.fibers[0] + .get_client() + .node_info()["node_id"], + "channel_outpoint": da_channel_outpoint, + }, + ], + "final_tlc_expiry_delta": None, + } + ) + ) + print(f"router_hops:{router_hops}") + hop = router_hops["router_hops"][0] + print(f"hop:{hop}") + assert hop["channel_outpoint"] == da_channel_outpoint + assert hop["target"] == self.fibers[0].get_client().node_info()["node_id"] + assert hop["amount_received"] == hex(1 + 62 * 100000000) + + # b call a ,走route info: b-c-d-私-a网络(检查应该不支持自动拼接完整的路由) + try: + payment = ( + self.fibers[1] + .get_client() + .send_payment_with_router( + { + "payment_hash": None, + "invoice": None, + "keysend": True, + "custom_records": None, + "dry_run": False, + "udt_type_script": None, + "router": router_hops["router_hops"], + } + ) + ) + except Exception as e: + error_message = str(e) + assert ( + "Error: Send payment first hop error: Failed to send onion packet with error UnknownNextPeer" + in error_message + ), f"预期错误信息不匹配,实际错误: {error_message}" + + def test_loop_send_payment_with_router(self): + """ + b-c-d-私-a网络-b网络(网络成环状) + 1. b call b成环,走route info:b-c-d-a-b + """ + self.start_new_fiber(self.generate_account(10000)) + self.start_new_fiber(self.generate_account(10000)) + + fiber1_balance = 1000 * 100000000 + fiber1_fee = 1000 + self.open_channel(self.fibers[0], self.fibers[1], 1000 * 100000000, 1) # a-b + self.open_channel(self.fibers[1], self.fibers[2], 1000 * 100000000, 1) # b-c + self.open_channel( + self.fibers[2], self.fibers[3], 1000 * 100000000, 1 + ) # c-d == b-c-d + + self.fibers[3].connect_peer(self.fibers[0]) # d-a + time.sleep(1) + self.fibers[3].get_client().open_channel( # d -a private channel + { + "peer_id": self.fibers[0].get_peer_id(), + "funding_amount": hex(fiber1_balance + 62 * 100000000), + "tlc_fee_proportional_millionths": hex(fiber1_fee), + "public": False, + } + ) + time.sleep(1) + self.wait_for_channel_state( + self.fibers[3].get_client(), self.fibers[0].get_peer_id(), "CHANNEL_READY" + ) + + bc_channel_outpoint = self.get_channel_outpoint(self.fibers[1], self.fibers[2]) + print(f"b-c, channel_outpoint:{bc_channel_outpoint}") + cd_channel_outpoint = self.get_channel_outpoint(self.fibers[2], self.fibers[3]) + print(f"c-d, channel_outpoint:{cd_channel_outpoint}") + da_channel_outpoint = self.get_channel_outpoint(self.fibers[3], self.fibers[0]) + print(f"d-a, channel_outpoint:{da_channel_outpoint}") + ab_channel_outpoint = self.get_channel_outpoint(self.fibers[0], self.fibers[1]) + print(f"a-b, channel_outpoint:{ab_channel_outpoint}") + + bc_router_hops = ( + self.fibers[1] + .get_client() + .build_router( + { + "amount": hex(4 * (1 + 62 * 100000000)), + "udt_type_script": None, + "hops_info": [ + { + "pubkey": self.fibers[2] + .get_client() + .node_info()["node_id"], + "channel_outpoint": bc_channel_outpoint, + }, + ], + "final_tlc_expiry_delta": None, + } + ) + ) + + cd_router_hops = ( + self.fibers[2] + .get_client() + .build_router( + { + "amount": hex(3 * (1 + 62 * 100000000)), + "udt_type_script": None, + "hops_info": [ + { + "pubkey": self.fibers[3] + .get_client() + .node_info()["node_id"], + "channel_outpoint": cd_channel_outpoint, + }, + ], + "final_tlc_expiry_delta": None, + } + ) + ) + + da_router_hops = ( + self.fibers[3] + .get_client() + .build_router( + { + "amount": hex(2 * (1 + 62 * 100000000)), + "udt_type_script": None, + "hops_info": [ + { + "pubkey": self.fibers[0] + .get_client() + .node_info()["node_id"], + "channel_outpoint": da_channel_outpoint, + }, + ], + "final_tlc_expiry_delta": None, + } + ) + ) + + ab_router_hops = ( + self.fibers[0] + .get_client() + .build_router( + { + "amount": hex(1 * (1 + 62 * 100000000)), + "udt_type_script": None, + "hops_info": [ + { + "pubkey": self.fibers[1] + .get_client() + .node_info()["node_id"], + "channel_outpoint": ab_channel_outpoint, + }, + ], + "final_tlc_expiry_delta": None, + } + ) + ) + + # 获取各个路由跳的基本信息 + bc_hop = bc_router_hops["router_hops"][0] + cd_hop = cd_router_hops["router_hops"][0] + da_hop = da_router_hops["router_hops"][0] + ab_hop = ab_router_hops["router_hops"][0] + + # 修改每一跳的 incoming_tlc_expiry 值,依次增加 172800000 + base_expiry = 86400000 # 基础过期时间 + delta = 172800000 # 每一跳增加的差值 + + # 从最后一跳开始,依次增加过期时间 + ab_hop["incoming_tlc_expiry"] = hex(base_expiry) # 0x5265c00 + da_hop["incoming_tlc_expiry"] = hex(base_expiry + delta) # 0xa4cb800 + cd_hop["incoming_tlc_expiry"] = hex(base_expiry + 2 * delta) # 0xf731400 + bc_hop["incoming_tlc_expiry"] = hex(base_expiry + 3 * delta) # 0x14997000 + + # b call b ,route info:b-c,c-d,d-a,a-b的route + payment = ( + self.fibers[1] + .get_client() + .send_payment_with_router( + { + "payment_hash": None, + "invoice": None, + "keysend": True, + "custom_records": None, + "dry_run": False, + "udt_type_script": None, + "router": [ + bc_hop, + cd_hop, + da_hop, + ab_hop, + ], + } + ) + ) + + print(f"payment:{payment}") + assert payment["status"] == "Created" + self.wait_payment_state(self.fibers[1], payment["payment_hash"], "Success") + + def get_channel_outpoint(self, from_fiber, to_fiber): + """ + 获取两个节点之间的通道outpoint + Args: + from_fiber: 起始节点 + to_fiber: 目标节点 + + Returns: + channel_outpoint: 通道outpoint + """ + channels = from_fiber.get_client().list_channels( + {"peer_id": to_fiber.get_peer_id()} + ) + print(f"{from_fiber.get_peer_id()}-{to_fiber.get_peer_id()},channel:{channels}") + channel_outpoint = channels["channels"][0]["channel_outpoint"] + print( + f"{from_fiber.get_peer_id()}-{to_fiber.get_peer_id()}, channel_outpoint:{channel_outpoint}" + ) + return channel_outpoint diff --git a/test_cases/fiber/devnet/shutdown_channel/test_channel_id.py b/test_cases/fiber/devnet/shutdown_channel/test_channel_id.py index 730625af..e5bc6b82 100644 --- a/test_cases/fiber/devnet/shutdown_channel/test_channel_id.py +++ b/test_cases/fiber/devnet/shutdown_channel/test_channel_id.py @@ -63,8 +63,12 @@ def test_channel_id_exist(self): "fee_rate": "0x3FC", } ) - # todo wait close tx commit - time.sleep(20) + + tx_hash = self.wait_and_check_tx_pool_fee(1000, False) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CLOSED", 120, True + ) node_info = self.fiber1.get_client().node_info() print("node info :", node_info) assert node_info["channel_count"] == "0x0" diff --git a/test_cases/fiber/devnet/shutdown_channel/test_close_script.py b/test_cases/fiber/devnet/shutdown_channel/test_close_script.py index eec7b504..968fa55f 100644 --- a/test_cases/fiber/devnet/shutdown_channel/test_close_script.py +++ b/test_cases/fiber/devnet/shutdown_channel/test_close_script.py @@ -57,11 +57,14 @@ def test_secp256k1_blake160_sighash_all(self): "fee_rate": "0x3FC", } ) - # todo wait close tx commit - time.sleep(20) - node_info = self.fiber1.get_client().node_info() - print("node info :", node_info) - assert node_info["channel_count"] == "0x0" + tx_hash = self.wait_and_check_tx_pool_fee(1000, False) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + # for i in range(4): + # self.Miner.miner_with_version(self.node, "0x0") + # time.sleep(5) + # node_info = self.fiber1.get_client().node_info() + # print("node info :", node_info) + # assert node_info["channel_count"] == "0x0" after_balance1 = self.Ckb_cli.wallet_get_capacity( self.account1["address"]["testnet"] ) @@ -74,7 +77,7 @@ def test_secp256k1_blake160_sighash_all(self): print("after_balance2:", after_balance2) assert after_balance2 - before_balance2 == 62.0 - @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/431") + # @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/431") def test_not_secp256k1_blake160_sighash_all(self): temporary_channel_id = self.fiber1.get_client().open_channel( { @@ -113,8 +116,12 @@ def test_not_secp256k1_blake160_sighash_all(self): "fee_rate": "0x3FC", } ) - # todo wait close tx commit - time.sleep(20) + + tx_hash = self.wait_and_check_tx_pool_fee(1000, False) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CLOSED", 120, True + ) node_info = self.fiber1.get_client().node_info() print("node info :", node_info) assert node_info["channel_count"] == "0x0" @@ -229,8 +236,9 @@ def test_ckb_arg_change_long_enough(self): "fee_rate": "0x3FC", } ) - # todo wait close tx commit - time.sleep(40) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + time.sleep(5) after_account_balance1 = self.node.getClient().get_cells_capacity( { "script": { @@ -242,9 +250,9 @@ def test_ckb_arg_change_long_enough(self): "script_search_mode": "prefix", } ) - node_info = self.fiber1.get_client().node_info() - print("node info :", node_info) - assert node_info["channel_count"] == "0x0" + # node_info = self.fiber1.get_client().node_info() + # print("node info :", node_info) + # assert node_info["channel_count"] == "0x0" after_balance1 = self.Ckb_cli.wallet_get_capacity( self.account1["address"]["testnet"], self.node.getClient().url ) @@ -313,7 +321,9 @@ def test_ckb_arg_change_short(self): } ) # todo wait close tx commit - time.sleep(40) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + after_balance1 = self.node.getClient().get_cells_capacity( { "script": { @@ -385,8 +395,8 @@ def test_arg_udt_change_short(self): "fee_rate": "0x3FC", } ) - # todo wait close tx commit - time.sleep(40) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False) + self.Miner.miner_until_tx_committed(self.node, tx_hash) after_balance1 = self.node.getClient().get_cells_capacity( { "script": { @@ -524,8 +534,9 @@ def test_arg_udt_change_short(self): "fee_rate": "0x3FC", } ) - # todo wait close tx commit - time.sleep(40) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False) + self.Miner.miner_until_tx_committed(self.node, tx_hash) + after_balance1 = self.node.getClient().get_cells_capacity( { "script": { diff --git a/test_cases/fiber/devnet/shutdown_channel/test_force.py b/test_cases/fiber/devnet/shutdown_channel/test_force.py index 21003925..b0b72423 100644 --- a/test_cases/fiber/devnet/shutdown_channel/test_force.py +++ b/test_cases/fiber/devnet/shutdown_channel/test_force.py @@ -49,21 +49,34 @@ def test_node_offline(self): latest_commitment_transaction_hash = list_channels["channels"][0][ "latest_commitment_transaction_hash" ] + with pytest.raises(Exception) as exc_info: + self.fiber1.get_client().shutdown_channel( + { + "channel_id": N1N2_CHANNEL_ID, + "close_script": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": self.account1["lock_arg"], + }, + "fee_rate": "0x3FC", + } + ) + expected_error_message = "Messaging failed because channel is closed" + 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]}'" + ) + # shut down self.fiber1.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) tx_hash = self.wait_and_check_tx_pool_fee(1000, False) assert latest_commitment_transaction_hash == tx_hash + self.Miner.miner_until_tx_committed(self.node, tx_hash) def test_node_online(self): temporary_channel_id = self.fiber1.get_client().open_channel( @@ -138,19 +151,23 @@ def test_node_online(self): before_balance2 = self.Ckb_cli.wallet_get_capacity( self.account2["address"]["testnet"] ) + list_channels = self.fiber1.get_client().list_channels({}) + latest_commitment_transaction_hash = list_channels["channels"][0][ + "latest_commitment_transaction_hash" + ] # shut down self.fiber1.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) + tx_hash = self.wait_and_check_tx_pool_fee(1000, False) + assert latest_commitment_transaction_hash == tx_hash + self.Miner.miner_until_tx_committed(self.node, tx_hash) + + self.fiber1.get_client().list_channels({}) + self.fiber2.get_client().list_channels({}) # def test_node_online(self): # temporary_channel_id = self.fiber1.get_client().open_channel( @@ -196,14 +213,14 @@ def test_node_online(self): # # todo check graph_channels # # todo check list channel - def test_NegotiatingFunding(self): - pass - - def test_CollaboratingFundingTx(self): - pass - - def test_SigningCommitment(self): - pass + # def test_NegotiatingFunding(self): + # pass + # + # def test_CollaboratingFundingTx(self): + # pass + # + # def test_SigningCommitment(self): + # pass def test_AwaitingTxSignatures(self): temporary_channel_id = self.fiber1.get_client().open_channel( @@ -230,12 +247,6 @@ def test_AwaitingTxSignatures(self): self.fiber1.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -276,12 +287,6 @@ def test_AwaitingChannelReady(self): self.fiber1.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -295,6 +300,25 @@ def test_AwaitingChannelReady(self): def test_ChannelReady(self): pass + # debug = True + + # def test_bb1(self): + # self.fiber1.get_client().list_channels({ + # "include_closed": True, + # }) + # self.fiber2.get_client().list_channels({}) + # + # def test_get_message(self): + # msg = self.get_tx_message("0x85c2334a63dc0850b425eb2e9346f57af6a47c18c895aabbdaf7d02fa445109b") + # print(msg) + # + # def test_bb(self): + # f1_b = self.get_fiber_balance(self.fiber1) + # f2_b = self.get_fiber_balance(self.fiber2) + # print(f1_b) + # print(f2_b) + # self.node.getClient().generate_epochs("0x2") + # @pytest.mark.skip("have bug") def test_in_tx(self): temporary_channel_id = self.fiber1.get_client().open_channel( @@ -311,14 +335,14 @@ def test_in_tx(self): ) payment = self.fiber1.get_client().send_payment( { - "amount": hex(100), + "amount": hex(1 * 100000000), "target_pubkey": self.fiber2.get_client().node_info()["node_id"], "keysend": True, } ) self.wait_payment_state(self.fiber1, payment["payment_hash"]) - amount = 1 + amount = 10 * 100000000 invoice = self.fiber2.get_client().new_invoice( { "amount": hex(amount), @@ -346,12 +370,6 @@ def test_in_tx(self): self.fiber1.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -362,6 +380,73 @@ def test_in_tx(self): # todo check assert payment["status"] == "Inflight" + def test_in_tx_force_2(self): + self.open_channel(self.fiber1, self.fiber2, 1000 * 100000000, 1) + for i in range(100): + self.send_payment(self.fiber1, self.fiber2, 1 * 100000000, False) + self.fiber1.get_client().shutdown_channel( + { + "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ], + "force": True, + } + ) + + # def test_in_key_send_tx2(self): + # self.open_channel(self.fiber1, self.fiber2, 1000 * 100000000, 1) + # + # for i in range(100): + # self.send_payment(self.fiber1, self.fiber2, 1 * 100000000, False) + # self.fiber1.get_client().shutdown_channel({ + # "channel_id": self.fiber1.get_client().list_channels({})["channels"][0]["channel_id"], + # "close_script": { + # "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + # "hash_type": "type", + # "args": self.account1["lock_arg"], + # }, + # "fee_rate": "0x3FC", + # }) + # self.wait_for_channel_state(self.fiber1.get_client(), self.fiber2.get_peer_id(), "CLOSED", 120, True) + + # def test_in_invoice_send_tx2(self): + # self.open_channel(self.fiber1, self.fiber2, 1000 * 100000000, 1) + # invocies = [] + # for i in range(50): + # invocies.append( + # self.fibers[1].get_client().new_invoice( + # {"amount": hex(1 * 100000000), + # "currency": "Fibd", + # "description": "test invoice generated by node2", + # "expiry": "0xe10", + # "final_cltv": "0x28", + # "payment_preimage": self.generate_random_preimage(), + # "hash_algorithm": "sha256", + # } + # ) + # ) + # # transfer + # for i in range(50): + # self.fiber1.get_client().send_payment({ + # "invoice": invocies[i]["invoice_address"], + # }) + # self.fiber1.get_client().shutdown_channel({ + # "channel_id": self.fiber1.get_client().list_channels({})["channels"][0]["channel_id"], + # "close_script": { + # "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + # "hash_type": "type", + # "args": self.account1["lock_arg"], + # }, + # "fee_rate": "0x3FC", + # }) + # self.wait_for_channel_state(self.fiber1.get_client(), self.fiber2.get_peer_id(), "SHUTTING_DOWN", 120, True) + # self.fiber1.get_client().shutdown_channel({ + # "channel_id": self.fiber1.get_client().list_channels({})["channels"][0]["channel_id"], + # "force": True + # }) + # tx_hash = self.wait_and_check_tx_pool_fee(1000, False) + # self.Miner.miner_until_tx_committed(self.node, tx_hash) + # @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/333") def test_in_tx_offline(self): temporary_channel_id = self.fiber1.get_client().open_channel( @@ -400,12 +485,6 @@ def test_in_tx_offline(self): self.fiber2.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -470,12 +549,6 @@ def test_ShuttingDown(self): self.fiber2.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -533,12 +606,6 @@ def test_force_ckb(self): self.fiber1.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -606,12 +673,6 @@ def test_force_udt(self): self.fiber1.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) diff --git a/test_cases/fiber/devnet/shutdown_channel/test_node_state.py b/test_cases/fiber/devnet/shutdown_channel/test_node_state.py index afef775f..c84d7566 100644 --- a/test_cases/fiber/devnet/shutdown_channel/test_node_state.py +++ b/test_cases/fiber/devnet/shutdown_channel/test_node_state.py @@ -20,7 +20,7 @@ class TestNodeState(FiberTest): # @pytest.mark.skip("交易发送一半,如果交易卡在Inflight,下一笔交易好像也发不出去") def test_shutdown_in_send_payment(self): """ - payment state 卡在 Inflight + payment state 最终会failed Returns: @@ -69,18 +69,17 @@ def test_shutdown_in_send_payment(self): # node1 send payment to node4 node4_info = self.fiber4.get_client().node_info() fiber4_pub = node4_info["node_id"] - payment = self.fiber1.get_client().send_payment( - { - "target_pubkey": fiber4_pub, - "amount": hex(1 * 100000000), - "keysend": True, - # "invoice": "0x123", - } - ) + for i in range(10): + payment = self.fiber1.get_client().send_payment( + { + "target_pubkey": fiber4_pub, + "amount": hex(1 * 100000000), + "keysend": True, + # "invoice": "0x123", + } + ) - self.wait_payment_state(self.fiber1, payment["payment_hash"], "Success", 120) - channels = self.fiber4.get_client().list_channels({}) - assert channels["channels"][0]["local_balance"] == hex(1 * 100000000) + # self.wait_payment_state(self.fiber1, payment["payment_hash"], "Success", 120) N3N4_CHANNEL_ID = self.fiber4.get_client().list_channels({})["channels"][0][ "channel_id" ] @@ -106,10 +105,12 @@ def test_shutdown_in_send_payment(self): ) tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 120) tx_message = self.get_tx_message(tx_hash) + time.sleep(1) payment = self.fiber1.get_client().get_payment( {"payment_hash": payment["payment_hash"]} ) - assert payment["status"] == "Inflight" + print("payment:", payment) + self.wait_payment_state(self.fiber1, payment["payment_hash"], "Failed", 120) assert { "args": self.fiber4.get_account()["lock_arg"], "capacity": 6300000000, diff --git a/test_cases/fiber/devnet/update_channel/test_chain_status.py b/test_cases/fiber/devnet/update_channel/test_chain_status.py index 364fb4b4..13cc1796 100644 --- a/test_cases/fiber/devnet/update_channel/test_chain_status.py +++ b/test_cases/fiber/devnet/update_channel/test_chain_status.py @@ -1,3 +1,5 @@ +import time + import pytest from framework.basic_fiber import FiberTest @@ -20,10 +22,6 @@ def test_chain_status_pending(self): "AWAITING_TX_SIGNATURES", ) - # self.fiber2.get_client().update_channel({ - # "channel_id": self.fiber1.get_client().list_channels({})["channels"][0]["channel_id"], - # "tlc_fee_proportional_millionths": hex(2000), - # }) self.fiber1.get_client().update_channel( { "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ @@ -35,4 +33,41 @@ def test_chain_status_pending(self): self.wait_for_channel_state( self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" ) + channels = self.fiber1.get_client().list_channels({}) + assert channels["channels"][0]["tlc_fee_proportional_millionths"] == hex(2000) # node2 add channel with node3 + self.fiber1.get_client().update_channel( + { + "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ], + "tlc_fee_proportional_millionths": hex(3000), + } + ) + channels = self.fiber1.get_client().list_channels({}) + assert channels["channels"][0]["tlc_fee_proportional_millionths"] == hex(3000) + + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ], + "close_script": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": self.account1["lock_arg"], + }, + "fee_rate": "0x3FC", + } + ) + self.fiber1.get_client().update_channel( + { + "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ], + "tlc_fee_proportional_millionths": hex(4000), + } + ) + channels = self.fiber1.get_client().list_channels({"include_closed": True}) + assert channels["channels"][0]["tlc_fee_proportional_millionths"] == hex(4000) diff --git a/test_cases/fiber/devnet/update_channel/test_enabled.py b/test_cases/fiber/devnet/update_channel/test_enabled.py index 3ca4c8fb..e2dfe25e 100644 --- a/test_cases/fiber/devnet/update_channel/test_enabled.py +++ b/test_cases/fiber/devnet/update_channel/test_enabled.py @@ -14,7 +14,7 @@ class TestEnable(FiberTest): # FiberTest.debug = True - @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/499") + # @pytest.mark.skip("https://github.com/nervosnetwork/fiber/issues/499") def test_true(self): """ A-B-C @@ -44,10 +44,30 @@ def test_true(self): .get_client() .list_channels({"peer_id": self.fibers[2].get_peer_id()}) ) + channels = self.fibers[1].get_client().graph_channels({}) + assert len(channels["channels"]) == 2 self.fibers[1].get_client().update_channel( {"channel_id": channel["channels"][0]["channel_id"], "enabled": False} ) - time.sleep(1) + time.sleep(3) + channels = self.fibers[1].get_client().graph_channels({}) + assert len(channels["channels"]) == 2 + + channel = ( + self.fibers[1] + .get_client() + .list_channels({"peer_id": self.fibers[2].get_peer_id()}) + ) + print("fiber1 channel:", channel) + assert channel["channels"][0]["enabled"] == False + channel = ( + self.fibers[2] + .get_client() + .list_channels({"peer_id": self.fibers[1].get_peer_id()}) + ) + print("fiber2 channel:", channel) + assert channel["channels"][0]["enabled"] == True + # 2. A->C 报错 with pytest.raises(Exception) as exc_info: self.send_payment(self.fibers[0], self.fibers[2], 1) @@ -81,6 +101,23 @@ def test_true(self): {"channel_id": channel["channels"][0]["channel_id"], "enabled": True} ) time.sleep(1) + channels = self.fibers[1].get_client().graph_channels({}) + print("after true graph_channels:", channels) + assert len(channels["channels"]) == 2 + channel = ( + self.fibers[1] + .get_client() + .list_channels({"peer_id": self.fibers[2].get_peer_id()}) + ) + print("fiber1 channel:", channel) + assert channel["channels"][0]["enabled"] == True + channel = ( + self.fibers[2] + .get_client() + .list_channels({"peer_id": self.fibers[1].get_peer_id()}) + ) + print("fiber2 channel:", channel) + assert channel["channels"][0]["enabled"] == True # 7. A->C 不会报错 # 8. B->C 不会报错 self.send_payment(self.fibers[0], self.fibers[2], 1) diff --git a/test_cases/fiber/devnet/update_channel/test_tlc_expiry_delta.py b/test_cases/fiber/devnet/update_channel/test_tlc_expiry_delta.py index a3669231..b8495e44 100644 --- a/test_cases/fiber/devnet/update_channel/test_tlc_expiry_delta.py +++ b/test_cases/fiber/devnet/update_channel/test_tlc_expiry_delta.py @@ -1,13 +1,76 @@ +import pytest + from framework.basic_fiber import FiberTest class TestTlcExpiryDelta(FiberTest): - def test_none(self): - pass + @pytest.mark.skip("tlc_expiry_delta = 0xffffffffffffffff, 预期:成功") + def test_01(self): + """ + + Returns: + + """ + self.open_channel(self.fiber1, self.fiber2, 1000 * 100000000, 1) + channel = ( + self.fibers[0] + .get_client() + .list_channels({"peer_id": self.fibers[1].get_peer_id()}) + ) + + # 0x0 + with pytest.raises(Exception) as exc_info: + self.fibers[1].get_client().update_channel( + { + "channel_id": channel["channels"][0]["channel_id"], + "tlc_expiry_delta": "0x0", + } + ) + expected_error_message = ( + "TLC expiry delta is too small, expect larger than 900000" + ) + 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]}'" + ) + + with pytest.raises(Exception) as exc_info: + self.fibers[1].get_client().update_channel( + { + "channel_id": channel["channels"][0]["channel_id"], + "tlc_expiry_delta": hex(900000 - 1), + } + ) + expected_error_message = ( + "TLC expiry delta is too small, expect larger than 900000" + ) + 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]}'" + ) - def test_overflow(self): - pass + with pytest.raises(Exception) as exc_info: + self.fibers[1].get_client().update_channel( + { + "channel_id": channel["channels"][0]["channel_id"], + "tlc_expiry_delta": "0xffffffffffffffffff", + } + ) + expected_error_message = ( + "TLC expiry delta is too small, expect larger than 900000" + ) + 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]}'" + ) - def test_0x0(self): - pass + self.fibers[1].get_client().update_channel( + { + "channel_id": channel["channels"][0]["channel_id"], + "tlc_expiry_delta": hex(1000000), + } + ) + channel = self.fibers[1].get_client().list_channels({}) + print(channel) + assert channel["tlc_expiry_delta"] == hex(1000000) diff --git a/test_cases/fiber/devnet/update_channel/test_tlc_fee_proportional_millionths.py b/test_cases/fiber/devnet/update_channel/test_tlc_fee_proportional_millionths.py index 676d930c..79f4ffa4 100644 --- a/test_cases/fiber/devnet/update_channel/test_tlc_fee_proportional_millionths.py +++ b/test_cases/fiber/devnet/update_channel/test_tlc_fee_proportional_millionths.py @@ -181,10 +181,10 @@ def test_max(self): ) time.sleep(3) graph_channels = self.fiber1.get_client().graph_channels() - assert graph_channels["channels"][0]["fee_rate_of_node2"] == hex( + assert graph_channels["channels"][0]["update_info_of_node2"]["fee_rate"] == hex( 340282366920938463 ) - assert graph_channels["channels"][0]["fee_rate_of_node1"] == hex( + assert graph_channels["channels"][0]["update_info_of_node1"]["fee_rate"] == hex( 340282366920938463 ) diff --git a/test_cases/fiber/devnet/update_channel/test_tlc_maximum_value.py b/test_cases/fiber/devnet/update_channel/test_tlc_maximum_value.py deleted file mode 100644 index 8aa52ee5..00000000 --- a/test_cases/fiber/devnet/update_channel/test_tlc_maximum_value.py +++ /dev/null @@ -1,13 +0,0 @@ -from framework.basic_fiber import FiberTest - - -class TestTlcMaximumValue(FiberTest): - - def test_0x0(self): - pass - - def test_normal(self): - pass - - def test_none(self): - pass diff --git a/test_cases/fiber/devnet/update_channel/test_tlc_minimum_value.py b/test_cases/fiber/devnet/update_channel/test_tlc_minimum_value.py index 07df0247..8f26cd8f 100644 --- a/test_cases/fiber/devnet/update_channel/test_tlc_minimum_value.py +++ b/test_cases/fiber/devnet/update_channel/test_tlc_minimum_value.py @@ -1,16 +1,74 @@ +import time + +import pytest + from framework.basic_fiber import FiberTest class TestTlcMinimumValue(FiberTest): + def test_01(self): + """ + 0x0 succ + 1ckb succ + int.max succ + int.max+1=> falied + Returns: - def test_0x0(self): - pass - - def test_overflow(self): - pass + """ + self.open_channel(self.fiber1, self.fiber2, 1000 * 100000000, 1000 * 100000000) + self.send_payment(self.fiber1, self.fiber2, 1 * 100000000) + self.send_payment(self.fiber2, self.fiber1, 1 * 100000000) + self.fiber1.get_client().update_channel( + { + "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ], + "tlc_minimum_value": hex(1 * 100000000), + } + ) + time.sleep(1) + self.send_payment(self.fiber2, self.fiber1, 1 * 100000000 - 1) + print("failed ") + with pytest.raises(Exception) as exc_info: + self.send_payment(self.fiber1, self.fiber2, 1 * 100000000 - 1) + expected_error_message = "no path found" + 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]}'" + ) - def test_max(self): - pass + # 0xffffffff + self.fiber1.get_client().update_channel( + { + "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ], + "tlc_minimum_value": "0xffffffffffffffffffffffffffffffff", + } + ) + time.sleep(1) + graph_channels = self.fiber1.get_client().graph_channels({}) + assert ( + graph_channels["channels"][0]["update_info_of_node2"]["tlc_minimum_value"] + == "0xffffffffffffffffffffffffffffffff" + or graph_channels["channels"][0]["update_info_of_node1"][ + "tlc_minimum_value" + ] + == "0xffffffffffffffffffffffffffffffff" + ) - def test_normal(self): - pass + # overflow + with pytest.raises(Exception) as exc_info: + self.fiber1.get_client().update_channel( + { + "channel_id": self.fiber1.get_client().list_channels({})[ + "channels" + ][0]["channel_id"], + "tlc_minimum_value": "0xfffffffffffffffffffffffffffffffff", + } + ) + expected_error_message = "Invalid params" + 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/fiber/devnet/update_channel/test_update_channel.py b/test_cases/fiber/devnet/update_channel/test_update_channel.py index 515d52df..ec68a8c0 100644 --- a/test_cases/fiber/devnet/update_channel/test_update_channel.py +++ b/test_cases/fiber/devnet/update_channel/test_update_channel.py @@ -24,11 +24,6 @@ class TestUpdateChannel(FiberTest): 2. 修改为正常值 3. overflow 4. 0 - - tlc_maximum_value - 1. 不填 - 2. 修改为正常值 - 3. overflow - 4. 0 - tlc_fee_proportional_millionths 1. 不填 2. 修改为正常值 diff --git a/test_cases/fiber/devnet/watch_tower/test_htlc_expired.py b/test_cases/fiber/devnet/watch_tower/test_htlc_expired.py new file mode 100644 index 00000000..d84871e3 --- /dev/null +++ b/test_cases/fiber/devnet/watch_tower/test_htlc_expired.py @@ -0,0 +1,151 @@ +import time + +import pytest + +from framework.basic_fiber import FiberTest + + +class TestHtlcExpired(FiberTest): + start_fiber_config = {"fiber_watchtower_check_interval_seconds": 5} + + def test_ready_status(self): + """ + 处于ready 状态 + 过期tlc 会自动发送强制shutdown + Returns: + + """ + self.start_new_fiber(self.generate_account(1000)) + self.open_channel(self.fiber1, self.fiber2, 1000 * 100000000, 1) + self.open_channel(self.fiber2, self.fibers[2], 1000 * 100000000, 1) + before_balance1 = self.Ckb_cli.wallet_get_capacity( + self.account1["address"]["testnet"] + ) + before_balance2 = self.Ckb_cli.wallet_get_capacity( + self.account2["address"]["testnet"] + ) + + # add tlc node1 + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 15) * 1000), + } + ) + CHANNEL_ID = ( + self.fibers[2].get_client().list_channels({})["channels"][0]["channel_id"] + ) + # add tlc node2 + self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 10) * 1000), + } + ) + time.sleep(30) + msg = self.get_fibers_balance_message() + print(msg) + channels = self.fiber1.get_client().list_channels({}) + assert len(channels["channels"]) == 0 + channels = self.fiber2.get_client().list_channels( + {"peer_id": self.fibers[2].get_peer_id()} + ) + assert len(channels["channels"]) == 0 + for i in range(6): + self.node.getClient().generate_epochs("0x2") + time.sleep(6) + after_balance1 = self.Ckb_cli.wallet_get_capacity( + self.account1["address"]["testnet"] + ) + after_balance2 = self.Ckb_cli.wallet_get_capacity( + self.account2["address"]["testnet"] + ) + print("before_balance1:", int(before_balance1)) + print("after_balance1:", int(after_balance1)) + assert (int(after_balance1) - int(before_balance1)) == (1062) + print("before_balance2:", int(before_balance2)) + print("after_balance2:", int(after_balance2)) + assert (int(after_balance2) - int(before_balance2)) == (1124) + + @pytest.mark.skip("skip") + def test_shutdown_status(self): + """ + 处于shutdown状态 + 过期tlc 会自动发送强制shutdown + Returns: + """ + self.start_new_fiber(self.generate_account(1000)) + self.open_channel(self.fiber1, self.fiber2, 1000 * 100000000, 1) + self.open_channel(self.fiber2, self.fibers[2], 1000 * 100000000, 1) + before_balance1 = self.Ckb_cli.wallet_get_capacity( + self.account1["address"]["testnet"] + ) + before_balance2 = self.Ckb_cli.wallet_get_capacity( + self.account2["address"]["testnet"] + ) + + # add tlc node1 + CHANNEL_ID1 = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID1, + "amount": hex(300 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 15) * 1000), + } + ) + CHANNEL_ID = ( + self.fibers[2].get_client().list_channels({})["channels"][0]["channel_id"] + ) + # add tlc node2 + self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 10) * 1000), + } + ) + + # 因为有待处理的tlc 会导致正常 shutdown_channel 卡主 + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID1, + "close_script": self.get_account_script(self.fiber1.account_private), + "fee_rate": "0x3FC", + } + ) + + time.sleep(30) + msg = self.get_fibers_balance_message() + print(msg) + channels = self.fiber1.get_client().list_channels({}) + assert len(channels["channels"]) == 0 + channels = self.fiber2.get_client().list_channels( + {"peer_id": self.fibers[2].get_peer_id()} + ) + assert len(channels["channels"]) == 0 + for i in range(6): + self.node.getClient().generate_epochs("0x2") + time.sleep(6) + after_balance1 = self.Ckb_cli.wallet_get_capacity( + self.account1["address"]["testnet"] + ) + after_balance2 = self.Ckb_cli.wallet_get_capacity( + self.account2["address"]["testnet"] + ) + print("before_balance1:", int(before_balance1)) + print("after_balance1:", int(after_balance1)) + assert (int(after_balance1) - int(before_balance1)) == (1062) + print("before_balance2:", int(before_balance2)) + print("after_balance2:", int(after_balance2)) + assert (int(after_balance2) - int(before_balance2)) == (1124) diff --git a/test_cases/fiber/devnet/watch_tower/test_htlc_mutil.py b/test_cases/fiber/devnet/watch_tower/test_htlc_mutil.py new file mode 100644 index 00000000..e69de29b diff --git a/test_cases/fiber/devnet/watch_tower/test_mutil_shutdown.py b/test_cases/fiber/devnet/watch_tower/test_mutil_shutdown.py index 032f39c7..63fb0f9c 100644 --- a/test_cases/fiber/devnet/watch_tower/test_mutil_shutdown.py +++ b/test_cases/fiber/devnet/watch_tower/test_mutil_shutdown.py @@ -79,12 +79,6 @@ def test_mutil_shutdown(self): self.fiber1.get_client().shutdown_channel( { "channel_id": channel["channel_id"], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -93,12 +87,6 @@ def test_mutil_shutdown(self): self.fiber2.get_client().shutdown_channel( { "channel_id": channel["channel_id"], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) diff --git a/test_cases/fiber/devnet/watch_tower/test_revert_tx.py b/test_cases/fiber/devnet/watch_tower/test_revert_tx.py index 1961b03e..e671b030 100644 --- a/test_cases/fiber/devnet/watch_tower/test_revert_tx.py +++ b/test_cases/fiber/devnet/watch_tower/test_revert_tx.py @@ -36,12 +36,6 @@ def test_01(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -86,12 +80,6 @@ def test_02(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) diff --git a/test_cases/fiber/devnet/watch_tower/test_watch_tower.py b/test_cases/fiber/devnet/watch_tower/test_watch_tower.py index 1826e3ae..ff939ca3 100644 --- a/test_cases/fiber/devnet/watch_tower/test_watch_tower.py +++ b/test_cases/fiber/devnet/watch_tower/test_watch_tower.py @@ -46,12 +46,6 @@ def test_node1_shutdown_when_open_and_node2_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -80,7 +74,7 @@ def test_node1_shutdown_when_open_and_node2_split_tx(self): self.fiber1.stop() # Step 10: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # 11. Wait for node2 splits the transaction to be committed and check the transaction message. tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -152,12 +146,6 @@ def test_node2_shutdown_when_open_and_node2_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -186,7 +174,7 @@ def test_node2_shutdown_when_open_and_node2_split_tx(self): self.fiber1.stop() # Step 10: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 11: Wait for node2 splits the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -249,12 +237,6 @@ def test_node2_shutdown_when_open_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -283,7 +265,7 @@ def test_node2_shutdown_when_open_and_node1_split_tx(self): self.fiber2.stop() # Step 10: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 11: Wait for node1 splits the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -346,12 +328,6 @@ def test_node1_shutdown_when_open_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -380,7 +356,7 @@ def test_node1_shutdown_when_open_and_node1_split_tx(self): self.fiber2.stop() # Step 10: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 11: Wait for node1 splits the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -450,12 +426,6 @@ def test_node1_shutdown_after_send_tx1_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -484,7 +454,7 @@ def test_node1_shutdown_after_send_tx1_and_node1_split_tx(self): self.fiber2.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -551,12 +521,6 @@ def test_node1_shutdown_after_send_tx1_and_node2_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -585,7 +549,7 @@ def test_node1_shutdown_after_send_tx1_and_node2_split_tx(self): self.fiber1.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -654,12 +618,6 @@ def test_node2_shutdown_after_send_tx1_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -688,7 +646,7 @@ def test_node2_shutdown_after_send_tx1_and_node1_split_tx(self): self.fiber2.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -755,12 +713,6 @@ def test_node2_shutdown_after_send_tx1_and_node2_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -789,7 +741,7 @@ def test_node2_shutdown_after_send_tx1_and_node2_split_tx(self): self.fiber1.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -865,12 +817,6 @@ def test_node1_shutdown_after_send_tx2_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -899,7 +845,7 @@ def test_node1_shutdown_after_send_tx2_and_node1_split_tx(self): self.fiber2.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -969,12 +915,6 @@ def test_node1_shutdown_after_send_tx2_and_node2_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -1001,9 +941,11 @@ def test_node1_shutdown_after_send_tx2_and_node2_split_tx(self): # Step 10: Stop node1 self.fiber1.stop() + self.fiber2.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) + self.fiber2.start() # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -1072,12 +1014,6 @@ def test_node2_shutdown_after_send_tx2_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -1106,7 +1042,7 @@ def test_node2_shutdown_after_send_tx2_and_node1_split_tx(self): self.fiber1.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -1175,12 +1111,6 @@ def test_node2_shutdown_after_send_tx2_and_node2_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -1209,7 +1139,7 @@ def test_node2_shutdown_after_send_tx2_and_node2_split_tx(self): self.fiber1.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -1277,12 +1207,6 @@ def test_node1_shutdown_after_send_txN_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -1311,7 +1235,7 @@ def test_node1_shutdown_after_send_txN_and_node1_split_tx(self): self.fiber2.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -1383,12 +1307,6 @@ def test_node2_shutdown_after_send_txN_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -1415,10 +1333,10 @@ def test_node2_shutdown_after_send_txN_and_node1_split_tx(self): # Step 10: Stop node1 self.fiber1.stop() - + self.fiber2.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") - + self.node.getClient().generate_epochs("0x6", 0) + self.fiber2.start() # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) tx_message = self.get_tx_message(tx_hash) diff --git a/test_cases/fiber/devnet/watch_tower/test_watch_tower_udt.py b/test_cases/fiber/devnet/watch_tower/test_watch_tower_udt.py index 6296297b..9b274977 100644 --- a/test_cases/fiber/devnet/watch_tower/test_watch_tower_udt.py +++ b/test_cases/fiber/devnet/watch_tower/test_watch_tower_udt.py @@ -49,12 +49,6 @@ def test_node1_shutdown_when_open_and_node2_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -83,7 +77,7 @@ def test_node1_shutdown_when_open_and_node2_split_tx(self): self.fiber1.stop() # Step 10: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 11: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -159,12 +153,6 @@ def test_node2_shutdown_when_open_and_node2_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -193,7 +181,7 @@ def test_node2_shutdown_when_open_and_node2_split_tx(self): self.fiber1.stop() # Step 10: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 11: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -262,12 +250,6 @@ def test_node2_shutdown_when_open_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -296,7 +278,7 @@ def test_node2_shutdown_when_open_and_node1_split_tx(self): self.fiber2.stop() # Step 10: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 11: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -349,12 +331,6 @@ def test_node1_shutdown_when_open_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -375,7 +351,7 @@ def test_node1_shutdown_when_open_and_node1_split_tx(self): node1_graph_channels = self.fiber1.get_client().graph_channels() node2_graph_channels = self.fiber2.get_client().graph_channels() self.fiber2.stop() - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) tx_message = self.get_tx_message(tx_hash) # assert tx_message['input_cells'][0]['capacity'] == @@ -451,12 +427,6 @@ def test_node1_shutdown_after_send_tx1_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -485,7 +455,7 @@ def test_node1_shutdown_after_send_tx1_and_node1_split_tx(self): self.fiber2.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -561,12 +531,6 @@ def test_node1_shutdown_after_send_tx1_and_node2_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -595,7 +559,7 @@ def test_node1_shutdown_after_send_tx1_and_node2_split_tx(self): self.fiber1.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -675,12 +639,6 @@ def test_node2_shutdown_after_send_tx1_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -709,7 +667,7 @@ def test_node2_shutdown_after_send_tx1_and_node1_split_tx(self): self.fiber2.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -786,12 +744,6 @@ def test_node2_shutdown_after_send_tx1_and_node2_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -820,7 +772,7 @@ def test_node2_shutdown_after_send_tx1_and_node2_split_tx(self): self.fiber1.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -899,12 +851,6 @@ def test_node1_shutdown_after_send_tx2_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -933,7 +879,7 @@ def test_node1_shutdown_after_send_tx2_and_node1_split_tx(self): self.fiber2.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -1013,12 +959,6 @@ def test_node1_shutdown_after_send_tx2_and_node2_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -1047,7 +987,7 @@ def test_node1_shutdown_after_send_tx2_and_node2_split_tx(self): self.fiber1.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -1128,12 +1068,6 @@ def test_node2_shutdown_after_send_tx2_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -1162,7 +1096,7 @@ def test_node2_shutdown_after_send_tx2_and_node1_split_tx(self): self.fiber1.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -1241,12 +1175,6 @@ def test_node2_shutdown_after_send_tx2_and_node2_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -1275,7 +1203,7 @@ def test_node2_shutdown_after_send_tx2_and_node2_split_tx(self): self.fiber1.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -1354,12 +1282,6 @@ def test_node1_shutdown_after_send_txN_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -1388,7 +1310,7 @@ def test_node1_shutdown_after_send_txN_and_node1_split_tx(self): self.fiber2.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) @@ -1470,12 +1392,6 @@ def test_node2_shutdown_after_send_txN_and_node1_split_tx(self): "channel_id": self.fiber1.get_client().list_channels({})["channels"][0][ "channel_id" ], - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -1504,7 +1420,7 @@ def test_node2_shutdown_after_send_txN_and_node1_split_tx(self): self.fiber1.stop() # Step 11: Generate epochs - self.node.getClient().generate_epochs("0xa") + self.node.getClient().generate_epochs("0x6", 0) # Step 12: Wait for the transaction to be committed and check the transaction message tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 1000) diff --git a/test_cases/fiber/devnet/watch_tower/test_with_tx.py b/test_cases/fiber/devnet/watch_tower/test_with_tx.py index df452148..d79ce178 100644 --- a/test_cases/fiber/devnet/watch_tower/test_with_tx.py +++ b/test_cases/fiber/devnet/watch_tower/test_with_tx.py @@ -58,12 +58,6 @@ def test_send_force_shutdown_with_tx(self): self.fiber1.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account1["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) @@ -143,12 +137,6 @@ def test_receive_force_shutdown_with_tx(self): self.fiber2.get_client().shutdown_channel( { "channel_id": N1N2_CHANNEL_ID, - "close_script": { - "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", - "hash_type": "type", - "args": self.account2["lock_arg"], - }, - "fee_rate": "0x3FC", "force": True, } ) diff --git a/test_cases/fiber/devnet/watch_tower_wit_tlc/test_pending_tlc.py b/test_cases/fiber/devnet/watch_tower_wit_tlc/test_pending_tlc.py new file mode 100644 index 00000000..fca18793 --- /dev/null +++ b/test_cases/fiber/devnet/watch_tower_wit_tlc/test_pending_tlc.py @@ -0,0 +1,3015 @@ +import time + +import pytest + +from framework.basic_fiber import FiberTest + + +class TestPendingTlc(FiberTest): + """ + pending tlc + watch tower,node1 force shutdown + node1 和node2 都没有tlc + node1 有N个tlc + 在tlc过期前 + 时间过去 0~ 1/3 个 delay_epoch + node2 可以通过pre_image 解锁部分tlc + node2 无法解锁 + node1 无法解锁 + 时间过去 delay_epoch 1/3 -2/3 + node2 可以通过pre_image 解锁部分tlc + node1 无法解锁 + 2/3~1 + node1无法取回 + node2 可以通过pre_image 解锁部分tlc + 时间过去 delay_epoch + node2 可以通过pre_image 解锁部分tlc + node2 可以舍弃tlc + node1 无法解锁 + 在tlc 过期后 + 时间过去 0~ 1/3 个 delay_epoch + node2 可以通过pre_image 解锁部分tlc + node1 无法解锁 + 时间过去 delay_epoch 1/3 -2/3 + node2 可以通过pre_image 解锁部分tlc + node1 可以解锁 + 2/3~1 + node1无法取回 + node2 可以通过pre_image 解锁部分tlc + 时间过去 delay_epoch + node2 可以通过pre_image 解锁部分tlc + node2 可以舍弃 tlc + node1 可以解锁 + node2有N个tlc + 在tlc 过期前 + delay_epoch 过去0-1/3 + node1 可以通过pre_image解锁部分tlc + remove_tlc 会失败 可能测不了 + node2 无法解锁 + delay_epoch 1/3 -2/3 + node1 可以通过pre_image 解锁部分tlc + remove_tlc 会失败 可能测不了 + node2 无法解锁 + 2/3~1 + node2无法取回 + node1 可以通过pre_image 解锁部分tlc + >delay_epoch + node1 可以通过pre_image 解锁部分tlc + remove_tlc 会失败 可能测不了 + node2 无法解锁 + 在tlc 过期后 + delay_epoch 过去0-1/3 + node1 可以通过pre_image 解锁部分tlc + remove_tlc 会失败 可能测不了 + node2 无法解锁 + delay_epoch 1/3 -2/3 + node1 可以通过pre_image 解锁部分tlc + remove_tlc 会失败 可能测不了 + node2 可以解锁 + 2/3~1 + node2无法取回 + node1 可以通过pre_image 解锁部分tlc + >delay_epoch + node1 可以通过pre_image 解锁部分tlc + remove_tlc 会失败 可能测不了 + node1 可以舍弃tlc + node2 可以解锁 + node1和node2 都有n个tlc + 复杂的场景5,5个tlc,node2有一个能解锁的tlc + 测试N的上限 + """ + + start_fiber_config = {"fiber_watchtower_check_interval_seconds": 5} + + # debug = True + + # node1 有tlc 过期前 + + def test_node1_has_n_tlc_with_node2_opt(self): + """ + node1 有N个tlc + 在tlc过期前 + 时间过去 0~ 1/3 个 delay_epoch + node2 无法解锁 + 时间过去 delay_epoch 1/3 -2/3 + node2 可以通过pre_image 解锁部分tlc + + 时间过去 delay_epoch + node2 可以舍弃tlc + + 1. node1 4个 add_tlc + 2. node2 remove_tlc + 1个tlc + 3. node1 强制shutdown + 4. node1 关闭watch tower + 5. 时间过去 0~ 1/3 个 delay_epoch + node2 不会操作 + 6. 时间过去 1/3 个delay_epoch + node2 会发送commit+ tlc + 7. 时间过去 delay epoch + node2 会遗弃 tlc + Returns: + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(10000 * 100000000), + "public": True, + # ), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + tlcs = [] + payment_preimages = [] + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 8000) * 1000), + } + ) + time.sleep(2) + for i in range(3): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(300 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 200) * 1000), + } + ) + payment_preimages.append(payment_preimage) + tlcs.append(tlc) + time.sleep(4) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + # remove tlc + for i in range(1): + try: + self.fiber2.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": tlcs[i]["tlc_id"], + "reason": {"payment_preimage": payment_preimages[i]}, + } + ) + time.sleep(1) + except Exception: + pass + self.fiber1.get_client().remove_watch_channel( + { + "channel_id": CHANNEL_ID, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 5. 时间过去 0~ 1/3 个 delay_epoch + # node2 不会操作 + time.sleep(15) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + + # 6. 时间过去 delay_epoch 1/3 -2/3 + # node2 会 发送commit+ tlc + self.node.getClient().generate_epochs("0x2") + node2_remove_tlc_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + self.Miner.miner_until_tx_committed(self.node, node2_remove_tlc_tx) + node2_remove_tlc_message = self.get_tx_message(node2_remove_tlc_tx) + assert ( + node2_remove_tlc_message["input_cells"][0]["capacity"] + - node2_remove_tlc_message["output_cells"][0]["capacity"] + == 300 * 100000000 + ) + assert ( + node2_remove_tlc_message["output_cells"][1]["args"] + == self.account2["lock_arg"] + ) + + # 7. 时间过去 0~ 1/3 个 delay_epoch + # node2 不会操作 + time.sleep(15) + status = self.node.getClient().get_live_cell(hex(0), node2_remove_tlc_tx) + assert status["status"] == "live" + # 9. 时间过去 delay epoch + # node2 会遗弃 tlc + self.node.getClient().generate_epochs("0x6") + final_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + # self.Miner.miner_until_tx_committed(self.node, final_tx) + final_tx_message = self.get_tx_message(final_tx) + assert { + "args": self.account2["lock_arg"], + "capacity": 6199999545, + } in final_tx_message["output_cells"] + assert { + "args": self.account1["lock_arg"], + "capacity": 879999999545, + } in final_tx_message["output_cells"] + assert final_tx_message["fee"] > 90000000000 + + def test_node1_has_n_tlc_with_node2_2_3_epoch_opt(self): + """ + node1 有N个tlc + 在tlc过期前 + 时间过去 2/3 delay epoch + node2 可以通过pre_image 解锁部分tlc + Returns: + + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(10000 * 100000000), + "public": True, + # ), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + tlcs = [] + payment_preimages = [] + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 8000) * 1000), + } + ) + time.sleep(2) + for i in range(3): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(300 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 200) * 1000), + } + ) + payment_preimages.append(payment_preimage) + tlcs.append(tlc) + time.sleep(4) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + # remove tlc + for i in range(1): + try: + self.fiber2.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": tlcs[i]["tlc_id"], + "reason": {"payment_preimage": payment_preimages[i]}, + } + ) + time.sleep(1) + except Exception: + pass + self.fiber1.get_client().remove_watch_channel( + { + "channel_id": CHANNEL_ID, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 5. 时间过去 0~ 1/3 个 delay_epoch + # node2 不会操作 + time.sleep(15) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + self.fiber2.stop() + + # 6. 时间过去 delay_epoch 2/3 + # node2 会 发送commit+ tlc + self.node.getClient().generate_epochs("0x4") + self.fiber2.start() + node2_remove_tlc_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + self.Miner.miner_until_tx_committed(self.node, node2_remove_tlc_tx) + node2_remove_tlc_message = self.get_tx_message(node2_remove_tlc_tx) + assert ( + node2_remove_tlc_message["input_cells"][0]["capacity"] + - node2_remove_tlc_message["output_cells"][0]["capacity"] + == 300 * 100000000 + ) + assert ( + node2_remove_tlc_message["output_cells"][1]["args"] + == self.account2["lock_arg"] + ) + + # 7. 时间过去 0~ 1/3 个 delay_epoch + # node2 不会操作 + time.sleep(15) + status = self.node.getClient().get_live_cell(hex(0), node2_remove_tlc_tx) + assert status["status"] == "live" + # 9. 时间过去 delay epoch + # node2 会遗弃 tlc + self.node.getClient().generate_epochs("0x6") + final_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + # self.Miner.miner_until_tx_committed(self.node, final_tx) + final_tx_message = self.get_tx_message(final_tx) + assert { + "args": self.account2["lock_arg"], + "capacity": 6199999545, + } in final_tx_message["output_cells"] + assert { + "args": self.account1["lock_arg"], + "capacity": 879999999545, + } in final_tx_message["output_cells"] + assert final_tx_message["fee"] > 90000000000 + + def test_node1_has_n_tlc_with_node2_epoch_opt_2(self): + """ + 在tlc过期前 + 时间过去 delay_epoch + 有能解锁的tlc ,也有不能解锁的tlc + node2 可以通过pre_image 解锁部分tlc + node2 不能 解锁的tlc 直接抛弃 + Returns: + + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(10000 * 100000000), + "public": True, + # ), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + tlcs = [] + payment_preimages = [] + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 8000) * 1000), + } + ) + time.sleep(2) + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(300 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 200) * 1000), + } + ) + payment_preimages.append(payment_preimage) + tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + # remove tlc + for i in range(1): + self.fiber2.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": tlcs[i]["tlc_id"], + "reason": {"payment_preimage": payment_preimages[i]}, + } + ) + time.sleep(1) + self.fiber1.get_client().remove_watch_channel( + { + "channel_id": CHANNEL_ID, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 5. 时间过去 0~ 1/3 个 delay_epoch + # node2 不会操作 + time.sleep(15) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + + self.fiber2.stop() + # 6. 时间过去 delay_epoch 0x6 + # node2 会 发送commit+ tlc + self.node.getClient().generate_epochs("0x6") + self.fiber2.start() + node2_remove_tlc_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + message = self.get_tx_message(node2_remove_tlc_tx) + print(message) + assert ( + message["input_cells"][0]["capacity"] + - message["output_cells"][0]["capacity"] + == 300 * 100000000 + ) + self.node.getClient().generate_epochs("0x6") + node2_remove_tlc_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + message = self.get_tx_message(node2_remove_tlc_tx) + print(message) + assert message["fee"] - 600 * 100000000 < 1000000 + + def test_node1_has_n_tlc_un_expired(self): + """ + node1 有N个tlc + 过期前 + 时间过去 0~ 1/3 个 delay_epoch + node1 无法解锁 + 时间过去 delay_epoch 1/3 -2/3 + node1 无法解锁 + 时间过去 delay_epoch 2/3 -1 + node1 无法解锁 + 时间过去 delay_epoch + node1 遗弃tlc + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + # "commitment_delay_epoch": hex(6), + # "funding_udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + tlcs = [] + payment_preimages = [] + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 300) * 1000), + } + ) + time.sleep(2) + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(300 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 300) * 1000), + } + ) + payment_preimages.append(payment_preimage) + tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + # remove tlc + + self.fiber2.get_client().remove_watch_channel( + { + "channel_id": CHANNEL_ID, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 1/3 epoch + self.node.getClient().generate_epochs("0x2") + time.sleep(10) + self.node.getClient().generate_epochs("0x2") + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + self.node.getClient().generate_epochs("0x2") + tx_hash = self.wait_and_check_tx_pool_fee(1000, False, 120) + message = self.get_tx_message(tx_hash) + assert message["fee"] - 90000000000 > 0 + assert message["fee"] - 90000000000 < 100000 + + # node1 有tlc 过期后 + @pytest.mark.skip("tlc 过期后, node2 不可以通过pre_image 解锁部分tlc") + def test_node1_has_n_tlc_expired_with_node2_1_3_opt(self): + """ + node1 有N个tlc + 在tlc过期后 + 时间过去 0~ 1/3 个 delay_epoch + node2 无法解锁 + 时间过去 delay_epoch 1/3 -2/3 + node2 可以通过pre_image 解锁部分tlc + 时间过去 delay_epoch + node2 可以舍弃tlc + + 1. node1 4个 add_tlc + 2. node2 remove_tlc + 1个tlc + 3. node1 强制shutdown + 4. node1 关闭watch tower + 5. 时间过去 0~ 1/3 个 delay_epoch + node2 不会操作 + 6. 时间过去 1/3 个delay_epoch + node2 会发送commit+ tlc + 7. 时间过去 delay epoch + node2 会遗弃 tlc + Returns: + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(10000 * 100000000), + "public": True, + # ), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + tlcs = [] + payment_preimages = [] + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 5) * 1000), + } + ) + time.sleep(2) + for i in range(3): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(300 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 5) * 1000), + } + ) + payment_preimages.append(payment_preimage) + tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + # remove tlc + for i in range(1): + try: + self.fiber2.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": tlcs[i]["tlc_id"], + "reason": {"payment_preimage": payment_preimages[i]}, + } + ) + time.sleep(1) + except Exception: + pass + self.fiber1.get_client().remove_watch_channel( + { + "channel_id": CHANNEL_ID, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 5. 时间过去 0~ 1/3 个 delay_epoch + # node2 不会操作 + time.sleep(15) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + + # 6. 时间过去 delay_epoch 1/3 -2/3 + # node2 会 发送commit+ tlc + self.node.getClient().generate_epochs("0x2") + node2_remove_tlc_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + self.Miner.miner_until_tx_committed(self.node, node2_remove_tlc_tx) + node2_remove_tlc_message = self.get_tx_message(node2_remove_tlc_tx) + assert ( + node2_remove_tlc_message["input_cells"][0]["capacity"] + - node2_remove_tlc_message["output_cells"][0]["capacity"] + == 300 * 100000000 + ) + assert ( + node2_remove_tlc_message["output_cells"][1]["args"] + == self.account2["lock_arg"] + ) + + # 7. 时间过去 0~ 1/3 个 delay_epoch + # node2 不会操作 + time.sleep(15) + status = self.node.getClient().get_live_cell(hex(0), node2_remove_tlc_tx) + assert status["status"] == "live" + # 9. 时间过去 delay epoch + # node2 会遗弃 tlc + self.node.getClient().generate_epochs("0x6") + final_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + # self.Miner.miner_until_tx_committed(self.node, final_tx) + final_tx_message = self.get_tx_message(final_tx) + assert { + "args": self.account2["lock_arg"], + "capacity": 6199999545, + } in final_tx_message["output_cells"] + assert { + "args": self.account1["lock_arg"], + "capacity": 879999999545, + } in final_tx_message["output_cells"] + assert final_tx_message["fee"] > 90000000000 + + @pytest.mark.skip("tlc 过期后, node2 不可以通过pre_image 解锁部分tlc") + def test_node1_has_n_tlc_expired_with_node2_2_3_opt(self): + """ + node1 有N个tlc + 在tlc过期后 + 时间过去 delay_epoch 2/3~1 + node2 可以通过pre_image 解锁部分tlc + 时间过去 delay_epoch + node2 可以舍弃tlc + Returns: + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(10000 * 100000000), + "public": True, + # ), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + tlcs = [] + payment_preimages = [] + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 5) * 1000), + } + ) + time.sleep(2) + for i in range(3): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(300 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 5) * 1000), + } + ) + payment_preimages.append(payment_preimage) + tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + # remove tlc + for i in range(1): + try: + self.fiber2.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": tlcs[i]["tlc_id"], + "reason": {"payment_preimage": payment_preimages[i]}, + } + ) + time.sleep(1) + except Exception: + pass + self.fiber1.get_client().remove_watch_channel( + { + "channel_id": CHANNEL_ID, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 5. 时间过去 0~ 1/3 个 delay_epoch + # node2 不会操作 + time.sleep(15) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + self.fiber2.stop() + # 6. 时间过去 delay_epoch 1/3 -2/3 + # node2 会 发送commit+ tlc + self.node.getClient().generate_epochs("0x4") + self.fiber2.start() + time.sleep(15) + node2_remove_tlc_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + self.Miner.miner_until_tx_committed(self.node, node2_remove_tlc_tx) + node2_remove_tlc_message = self.get_tx_message(node2_remove_tlc_tx) + assert ( + node2_remove_tlc_message["input_cells"][0]["capacity"] + - node2_remove_tlc_message["output_cells"][0]["capacity"] + == 300 * 100000000 + ) + assert ( + node2_remove_tlc_message["output_cells"][1]["args"] + == self.account2["lock_arg"] + ) + + def test_node1_tlc_discard_by_node2_after_delay(self): + """ + node1 有N个tlc + 在tlc过期后 + 时间过去 delay_epoch + node2 可以舍弃tlc + Returns: + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(10000 * 100000000), + "public": True, + # ), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + tlcs = [] + payment_preimages = [] + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 15) * 1000), + } + ) + time.sleep(2) + for i in range(3): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(300 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 15) * 1000), + } + ) + payment_preimages.append(payment_preimage) + tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + # remove tlc + for i in range(1): + try: + self.fiber2.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": tlcs[i]["tlc_id"], + "reason": {"payment_preimage": payment_preimages[i]}, + } + ) + time.sleep(1) + except Exception: + pass + self.fiber1.get_client().remove_watch_channel( + { + "channel_id": CHANNEL_ID, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + time.sleep(15) + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 5. 时间过去 delay_epoch + # node2 舍弃 tlc + self.fiber2.stop() + self.node.getClient().generate_epochs("0x6") + self.fiber2.start() + final_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + self.Miner.miner_until_tx_committed(self.node, final_tx) + final_tx_tlc_message = self.get_tx_message(final_tx) + print("final_tx_tlc_message:", final_tx_tlc_message) + assert final_tx_tlc_message["fee"] - 120000000000 > 0 + assert final_tx_tlc_message["fee"] - 120000000000 < 100000 + + def test_node1_tlc_expired_node1_opt(self): + """ + node1 有N个tlc + 在tlc过期后 + 时间过去 0~ 1/3 个 delay_epoch + node1 无法解锁 + 时间过去 delay_epoch 1/3 -2/3 + node1 无法解锁 + 时间过去 delay_epoch 2/3~1 + node1 可以解锁 + 时间过去 delay_epoch + node1 可以解锁 + Returns: + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + # "commitment_delay_epoch": hex(6), + # "funding_udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + tlcs = [] + payment_preimages = [] + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 5) * 1000), + } + ) + time.sleep(2) + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(300 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 5) * 1000), + } + ) + payment_preimages.append(payment_preimage) + tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + # remove tlc + for i in range(1): + self.fiber2.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": tlcs[i]["tlc_id"], + "reason": {"payment_preimage": payment_preimages[i]}, + } + ) + self.fiber2.get_client().remove_watch_channel( + { + "channel_id": CHANNEL_ID, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 时间过去 0~ 1/3 个 delay_epoch + # node1 无法解锁 + time.sleep(10) + # 时间过去 delay_epoch 1/3 -2/3 + # node1 无法解锁 + self.node.getClient().generate_epochs("0x2") + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + # 时间过去 delay_epoch 2/3~1 + # node1 可以解锁 + self.node.getClient().generate_epochs("0x2") + first_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, first_tx) + first_tx_message = self.get_tx_message(first_tx) + print("first_tx_message:", first_tx_message) + assert ( + first_tx_message["input_cells"][0]["capacity"] + - first_tx_message["output_cells"][0]["capacity"] + == 300 * 100000000 + ) + # 时间过去 delay_epoch + # node1 可以解锁 + self.fiber1.stop() + self.node.getClient().generate_epochs("0x6") + self.fiber1.start() + next_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + next_message = self.get_tx_message(next_tx) + print("next_message :", next_message) + assert ( + next_message["input_cells"][0]["capacity"] + - next_message["output_cells"][0]["capacity"] + == 300 * 100000000 + ) + self.Miner.miner_until_tx_committed(self.node, next_tx) + + # @pytest.mark.skip("如果有一个过期,一个没过期,node1 无法解锁") + def test_node1_tlc_expired_with_un_expired_node1_opt(self): + """ + 包含过期和没过期的tlc + 时间过去2/3 epoch + node1 解锁 过期tlc + 时间过去delay epoch + node1 能够解锁过期的tlc + Returns: + + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(10000 * 100000000), + "public": True, + # "commitment_delay_epoch": hex(6), + # "funding_udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + tlcs = [] + payment_preimages = [] + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 50000) * 1000), + } + ) + time.sleep(2) + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(300 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 5) * 1000), + } + ) + payment_preimages.append(payment_preimage) + tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + # remove tlc + for i in range(1): + self.fiber2.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": tlcs[i]["tlc_id"], + "reason": {"payment_preimage": payment_preimages[i]}, + } + ) + self.fiber2.get_client().remove_watch_channel( + { + "channel_id": CHANNEL_ID, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 时间过去 0~ 1/3 个 delay_epoch + # node1 无法解锁 + time.sleep(10) + # 时间过去 delay_epoch 1/3 -2/3 + # node1 无法解锁 + self.node.getClient().generate_epochs("0x2") + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + # 时间过去 delay_epoch 2/3~1 + # node1 可以解锁 + self.node.getClient().generate_epochs("0x2") + first_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, first_tx) + first_tx_message = self.get_tx_message(first_tx) + print("first_tx_message:", first_tx_message) + assert ( + first_tx_message["input_cells"][0]["capacity"] + - first_tx_message["output_cells"][0]["capacity"] + == 300 * 100000000 + ) + # 时间过去 delay_epoch + # node1 可以解锁 + self.fiber1.stop() + self.node.getClient().generate_epochs("0x6") + self.fiber1.start() + next_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + next_message = self.get_tx_message(next_tx) + print("next_message :", next_message) + assert ( + next_message["input_cells"][0]["capacity"] + - next_message["output_cells"][0]["capacity"] + == 300 * 100000000 + ) + self.Miner.miner_until_tx_committed(self.node, next_tx) + + def test_node1_tlc_expired_with_un_expired_node2_opt(self): + """ + 包含过期和没过期的tlc + 时间过去1/3 epoch + + 时间过去2/3 epoch + node2 解锁 过期tlc + 时间过去delay epoch + node1 能够解锁过期的tlc + Returns: + + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(10000 * 100000000), + "public": True, + # "commitment_delay_epoch": hex(6), + # "funding_udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + tlcs = [] + payment_preimages = [] + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 50000) * 1000), + } + ) + time.sleep(2) + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(300 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(300 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 5) * 1000), + } + ) + payment_preimages.append(payment_preimage) + tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + # remove tlc + for i in range(1): + self.fiber2.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": tlcs[i]["tlc_id"], + "reason": {"payment_preimage": payment_preimages[i]}, + } + ) + self.fiber1.get_client().remove_watch_channel( + { + "channel_id": CHANNEL_ID, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 时间过去 0~ 1/3 个 delay_epoch + # node1 无法解锁 + time.sleep(10) + # 时间过去 delay_epoch 1/3 -2/3 + # node1 无法解锁 + self.node.getClient().generate_epochs("0x2") + time.sleep(10) + + # 过期前 + def test_node2_has_n_tlc_un_expired_node2_opt(self): + """ + node2 有N个tlc + 过期前 + 0~1/3 delay epoch + node2 无法处理 + 1/3~ 2/3 delay epoch + node2 不可以处理 + 2/3~1 delay epoch + node2 不可以处理 + 1 delay epoch + node2 遗弃tlc + Returns: + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + # "funding_udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + self.send_payment(self.fiber1, self.fiber2, 100 * 100000000) + tlcs = [] + payment_preimages = [] + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(30 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 10000) * 1000), + } + ) + time.sleep(1) + for i in range(1): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(30 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(30 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 10000) * 1000), + } + ) + payment_preimages.append(payment_preimage) + tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + + # remove tlc + for i in range(1): + try: + self.fiber1.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": tlcs[i]["tlc_id"], + "reason": {"payment_preimage": payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + self.fiber1.get_client().remove_watch_channel( + { + "channel_id": CHANNEL_ID, + } + ) + # 过期前 处理不了 + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 0~1/3 delay epoch + # node2 无法处理 + time.sleep(10) + # 1/3~ 2/3 delay epoch + # node2 不可以处理 + self.node.getClient().generate_epochs("0x2") + time.sleep(10) + # 2/3~1 delay epoch + # node2 不可以处理 + self.node.getClient().generate_epochs("0x2") + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + # 1 delay epoch + # node2 遗弃tlc + self.node.getClient().generate_epochs("0x2") + final_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + message = self.get_tx_message(final_tx) + assert message["fee"] - 6000000000 > 0 + assert message["fee"] - 6000000000 < 100000 + + def test_node2_has_n_tlc_un_expired_node1_opt(self): + """ + node2 有N个tlc + 过期前 + 0~1/3 delay epoch + node1 无法处理 + 1/3~ 2/3 delay epoch + node1 可以通过pre_image 解锁部分tlc + 2/3~1 delay epoch + node1 可以通过pre_image 解锁部分tlc + node1 不可以抛弃tlc + 1 delay epoch + node1 可以通过pre_image 解锁部分tlc + node1 不可以抛弃tlc + Returns: + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(10000 * 100000000), + "public": True, + # "funding_udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + self.send_payment(self.fiber1, self.fiber2, 100 * 100000000) + tlcs = [] + payment_preimages = [] + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(3 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 10000) * 1000), + } + ) + time.sleep(1) + for i in range(4): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(3 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(3 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 10000) * 1000), + } + ) + payment_preimages.append(payment_preimage) + tlcs.append(tlc) + time.sleep(5) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + # remove tlc + for i in range(3): + try: + self.fiber1.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": tlcs[i]["tlc_id"], + "reason": {"payment_preimage": payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + time.sleep(1) + self.fiber2.get_client().remove_watch_channel( + { + "channel_id": CHANNEL_ID, + } + ) + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 0~1/3 delay epoch + # node1 无法处理 + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + # 1/3~ 2/3 delay epoch + # node1 可以通过pre_image 解锁部分tlc + self.node.getClient().generate_epochs("0x2") + settle_tx1 = self.wait_and_check_tx_pool_fee(1000, False, 120) + settle_tx1_message = self.get_tx_message(settle_tx1) + print("settle_tx1_message:", settle_tx1_message) + # todo add assert + self.Miner.miner_until_tx_committed(self.node, settle_tx1) + + # 2/3~1 delay epoch + # node1 可以通过pre_image 解锁部分tlc + self.fiber1.stop() + self.node.getClient().generate_epochs("0x4") + self.fiber1.start() + settle_tx2 = self.wait_and_check_tx_pool_fee(1000, False, 120) + settle_tx2_message = self.get_tx_message(settle_tx2) + print("settle_tx2_message:", settle_tx2_message) + + # 1 delay epoch + # node1 可以通过pre_image 解锁部分tlc + + self.fiber1.stop() + self.Miner.miner_until_tx_committed(self.node, settle_tx2) + self.node.getClient().generate_epochs("0x6") + self.fiber1.start() + settle_tx3 = self.wait_and_check_tx_pool_fee(1000, False, 120) + settle_tx3_message = self.get_tx_message(settle_tx3) + print("settle_tx3_message:", settle_tx3_message) + + # 2/3~1 delay epoch + # node1 不可以抛弃tlc + self.node.getClient().generate_epochs("0x4") + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), settle_tx3) + assert status["status"] == "live" + # 1 delay epoch + # node1 可以抛弃tlc + self.node.getClient().generate_epochs("0x2") + final_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + message = self.get_tx_message(final_tx) + print("message:", message) + assert message["fee"] - 6 * 100000000 > 0 + assert message["fee"] - 6 * 100000000 < 100000 + + def test_node2_has_n_tlc_expired_node2_opt(self): + """ + node2有N个tlc + 在tlc 过期后 + 0~1/3 delay epoch + node2 无法解锁 + 1/3~2/3 delay epoch + node2 无法解锁 + 2/3~1 delay epoch + node2 可以解锁 + 1 delay epoch + node2 可以解锁 + Returns: + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + # "funding_udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + self.send_payment(self.fiber1, self.fiber2, 100 * 100000000) + tlcs = [] + payment_preimages = [] + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(30 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 10) * 1000), + } + ) + time.sleep(1) + for i in range(1): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(30 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(30 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 10) * 1000), + } + ) + payment_preimages.append(payment_preimage) + tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + self.fiber1.stop() + # 过期后 + # 0~1/3 delay epoch + # node2 无法解锁 + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + # 1/3~2/3 delay epoch + # node2 无法解锁 + self.node.getClient().generate_epochs("0x2") + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + # 2/3~1 delay epoch + # node2 可以解锁 + self.node.getClient().generate_epochs("0x2") + first_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + self.Miner.miner_until_tx_committed(self.node, first_tx) + first_tx_message = self.get_tx_message(first_tx) + print("first_tx_message:", first_tx_message) + assert ( + first_tx_message["input_cells"][0]["capacity"] + - first_tx_message["output_cells"][0]["capacity"] + == 30 * 100000000 + ) + # 1 delay epoch + # node2 可以解锁 + self.fiber2.stop() + self.node.getClient().generate_epochs("0x6") + self.fiber2.start() + sed_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + self.Miner.miner_until_tx_committed(self.node, sed_tx) + sed_tx_message = self.get_tx_message(sed_tx) + print("sed_tx_message:", sed_tx_message) + assert ( + sed_tx_message["input_cells"][0]["capacity"] + - sed_tx_message["output_cells"][0]["capacity"] + == 30 * 100000000 + ) + + @pytest.mark.skip("如果过期,node1 解锁不了") + def test_node2_has_n_tlc_expired_node1_opt(self): + """ + node2有N个tlc + 在tlc 过期后 + 0~1/3 delay epoch + node1 无法解锁 + 1/3~2/3 delay epoch + node1 可以通过pre_image 解锁部分tlc + node1 无法解锁 没有pre_image 的tlc + 2/3~1 delay epoch + node1 可以通过pre_image 解锁部分tlc + node1 无法解锁 没有pre_image 的tlc + 1 delay epoch + node1 可以通过pre_image 解锁部分tlc + node1 可以遗弃 + Returns: + + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + # "funding_udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + self.send_payment(self.fiber1, self.fiber2, 100 * 100000000) + tlcs = [] + payment_preimages = [] + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(3 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 10) * 1000), + } + ) + time.sleep(1) + for i in range(4): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(3 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(3 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 10) * 1000), + } + ) + payment_preimages.append(payment_preimage) + tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + for i in range(3): + try: + self.fiber1.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": tlcs[i]["tlc_id"], + "reason": {"payment_preimage": payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + time.sleep(1) + continue + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + self.fiber2.stop() + + # 0~1/3 delay epoch + # node1 无法解锁 + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + # 1/3~2/3 delay epoch + # node1 可以通过pre_image 解锁部分tlc + self.node.getClient().generate_epochs("0x2") + first_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, first_tx) + first_tx_message = self.get_tx_message(first_tx) + print("first_tx_message:", first_tx_message) + assert ( + first_tx_message["input_cells"][0]["capacity"] + - first_tx_message["output_cells"][0]["capacity"] + == 3 * 100000000 + ) + # 2/3~1 delay epoch + # node1 可以通过pre_image 解锁部分tlc + self.fiber1.stop() + self.Miner.miner_until_tx_committed(self.node, first_tx) + self.node.getClient().generate_epochs("0x4") + self.fiber1.start() + sed_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + sed_tx_message = self.get_tx_message(sed_tx) + assert ( + sed_tx_message["input_cells"][0]["capacity"] + - sed_tx_message["output_cells"][0]["capacity"] + == 3 * 100000000 + ) + # 1 delay epoch + # node1 可以通过pre_image 解锁部分tlc + self.fiber1.stop() + self.Miner.miner_until_tx_committed(self.node, sed_tx) + self.node.getClient().generate_epochs("0x6") + self.fiber1.start() + thr_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + thr_tx_message = self.get_tx_message(thr_tx) + assert ( + thr_tx_message["input_cells"][0]["capacity"] + - thr_tx_message["output_cells"][0]["capacity"] + == 3 * 100000000 + ) + # 1/3~2/3 delay epoch + # node1 无法解锁 没有pre_image 的tlc + self.node.getClient().generate_epochs("0x2") + time.sleep(10) + + # 2/3~1 delay epoch + # node1 无法解锁 没有pre_image 的tlc + self.node.getClient().generate_epochs("0x2") + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), thr_tx) + assert status["status"] == "live" + # 1 delay epoch + # node1 可以遗弃 + self.node.getClient().generate_epochs("0x2") + final_tx = self.wait_and_check_tx_pool_fee(1000, False, 300) + message = self.get_tx_message(final_tx) + print("message:", message) + assert message["fee"] - 6 * 10000000 > 0 + assert message["fee"] - 6 * 10000000 < 100000 + + # 都有tlc + # 都没过期 + def test_node1_and_node2_has_n_tlc_node1_node2(self): + """ + node1和node2 都有n个tlc + 都没过期 + 过去1/3 delay epoch + node1 解锁 + node2 解锁 + Returns: + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + self.send_payment(self.fiber1, self.fiber2, 100 * 100000000) + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + time.sleep(1) + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + time.sleep(1) + node1_tlcs = [] + node1_payment_preimages = [] + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(30 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + node1_payment_preimages.append(payment_preimage) + node1_tlcs.append(tlc) + time.sleep(2) + + node2_tlcs = [] + node2_payment_preimages = [] + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(30 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + node2_payment_preimages.append(payment_preimage) + node2_tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + + # # remove tlc + for i in range(1): + try: + self.fiber2.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": node1_tlcs[i]["tlc_id"], + "reason": {"payment_preimage": node1_payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + time.sleep(1) + for i in range(1): + try: + self.fiber1.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": node2_tlcs[i]["tlc_id"], + "reason": {"payment_preimage": node2_payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + time.sleep(1) + + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 1/3 + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + self.node.getClient().generate_epochs("0x2") + tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + message = self.get_tx_message(tx) + assert ( + message["input_cells"][0]["capacity"] + - message["output_cells"][0]["capacity"] + == 1 * 100000000 + ) + self.Miner.miner_until_tx_committed(self.node, tx) + self.node.getClient().generate_epochs("0x2") + tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + message = self.get_tx_message(tx) + assert ( + message["input_cells"][0]["capacity"] + - message["output_cells"][0]["capacity"] + == 1 * 100000000 + ) + + def test_node1_and_node2_has_n_tlc_2_3_node1_node2(self): + """ + node1和node2 都有n个tlc + 都没过期 + 过去2/3 delay epoch + node1 解锁 + node2 解锁 + Returns: + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + self.send_payment(self.fiber1, self.fiber2, 100 * 100000000) + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + time.sleep(1) + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + time.sleep(1) + node1_tlcs = [] + node1_payment_preimages = [] + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(30 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + node1_payment_preimages.append(payment_preimage) + node1_tlcs.append(tlc) + time.sleep(2) + + node2_tlcs = [] + node2_payment_preimages = [] + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(30 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + node2_payment_preimages.append(payment_preimage) + node2_tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + # # remove tlc + for i in range(1): + try: + self.fiber2.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": node1_tlcs[i]["tlc_id"], + "reason": {"payment_preimage": node1_payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + time.sleep(1) + + for i in range(1): + try: + self.fiber1.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": node2_tlcs[i]["tlc_id"], + "reason": {"payment_preimage": node2_payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + time.sleep(1) + + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 2/3 + self.fiber1.stop() + self.fiber2.stop() + self.node.getClient().generate_epochs("0x4") + self.fiber1.start() + self.fiber2.start() + tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + message = self.get_tx_message(tx) + assert ( + message["input_cells"][0]["capacity"] + - message["output_cells"][0]["capacity"] + == 1 * 100000000 + ) + time.sleep(5) + self.Miner.miner_until_tx_committed(self.node, tx) + self.fiber1.stop() + self.fiber2.stop() + self.node.getClient().generate_epochs("0x4") + self.fiber1.start() + self.fiber2.start() + tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + message = self.get_tx_message(tx) + assert ( + message["input_cells"][0]["capacity"] + - message["output_cells"][0]["capacity"] + == 1 * 100000000 + ) + + def test_node1_and_node2_has_n_tlc_3_3_node1_node2(self): + """ + node1和node2 都有n个tlc + 都没过期 + 过去 delay epoch + node1 解锁 + node2 解锁 + Returns: + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + self.send_payment(self.fiber1, self.fiber2, 100 * 100000000) + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + time.sleep(1) + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + time.sleep(1) + node1_tlcs = [] + node1_payment_preimages = [] + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(1 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + node1_payment_preimages.append(payment_preimage) + node1_tlcs.append(tlc) + time.sleep(2) + + node2_tlcs = [] + node2_payment_preimages = [] + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(1 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + node2_payment_preimages.append(payment_preimage) + node2_tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + # # remove tlc + for i in range(1): + try: + self.fiber2.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": node1_tlcs[i]["tlc_id"], + "reason": {"payment_preimage": node1_payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + time.sleep(1) + + for i in range(1): + try: + self.fiber1.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": node2_tlcs[i]["tlc_id"], + "reason": {"payment_preimage": node2_payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + time.sleep(1) + + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 2/3 + self.fiber1.stop() + self.fiber2.stop() + self.node.getClient().generate_epochs("0x6") + self.fiber1.start() + tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.fiber2.start() + message = self.get_tx_message(tx) + assert ( + message["input_cells"][0]["capacity"] + - message["output_cells"][0]["capacity"] + == 1 * 100000000 + ) + time.sleep(5) + self.Miner.miner_until_tx_committed(self.node, tx) + self.fiber1.stop() + self.fiber2.stop() + self.node.getClient().generate_epochs("0x6") + self.fiber2.start() + tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.fiber1.start() + message = self.get_tx_message(tx) + print("message:", message) + assert ( + message["input_cells"][0]["capacity"] + - message["output_cells"][0]["capacity"] + == 1 * 100000000 + ) + + @pytest.mark.skip("如果2边tlc都没过期,node1和node2 都解锁不了") + def test_node1_and_node2_has_n_tlc_expired_n12(self): + """ + node1和node2 都有n个tlc + 都没过期 + 过去 delay epoch + 2个节点都解锁不了 + Returns: + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + self.send_payment(self.fiber1, self.fiber2, 100 * 100000000) + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + time.sleep(1) + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + time.sleep(1) + node1_tlcs = [] + node1_payment_preimages = [] + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(1 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + node1_payment_preimages.append(payment_preimage) + node1_tlcs.append(tlc) + time.sleep(2) + + node2_tlcs = [] + node2_payment_preimages = [] + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(1 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 700000) * 1000), + } + ) + node2_payment_preimages.append(payment_preimage) + node2_tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + + # remove tlc + for i in range(1): + try: + self.fiber2.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": node1_tlcs[i]["tlc_id"], + "reason": {"payment_preimage": node1_payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + time.sleep(1) + + for i in range(1): + try: + self.fiber1.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": node2_tlcs[i]["tlc_id"], + "reason": {"payment_preimage": node2_payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + time.sleep(1) + + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 1/3 + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + self.node.getClient().generate_epochs("0x6") + tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + message = self.get_tx_message(tx) + + @pytest.mark.skip("node1 重启会导致 2/3的时候无法解锁过期tlc") + def test_node1_and_node2_has_n_tlc_expired_node1_stop_restart_opt(self): + """ + node1和node2 都有n个tlc + 都过期了 + 过去2/3 delay epoch + node1 能解锁过期的tlc + Returns: + + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + self.send_payment(self.fiber1, self.fiber2, 100 * 100000000) + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 5) * 1000), + } + ) + time.sleep(1) + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "expiry": hex((int(time.time()) + 5) * 1000), + } + ) + time.sleep(1) + node1_tlcs = [] + node1_payment_preimages = [] + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(1 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 5) * 1000), + } + ) + node1_payment_preimages.append(payment_preimage) + node1_tlcs.append(tlc) + time.sleep(2) + + node2_tlcs = [] + node2_payment_preimages = [] + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(1 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 5) * 1000), + } + ) + node2_payment_preimages.append(payment_preimage) + node2_tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 220) + + # # remove tlc + # for i in range(1): + # try: + # self.fiber2.get_client().remove_tlc({ + # "channel_id": CHANNEL_ID, + # "tlc_id": node1_tlcs[i]["tlc_id"], + # "reason": { + # "payment_preimage": node1_payment_preimages[i] + # } + # }) + # except Exception as e: + # print(e) + # time.sleep(1) + + for i in range(1): + try: + self.fiber1.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": node2_tlcs[i]["tlc_id"], + "reason": {"payment_preimage": node2_payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + time.sleep(1) + + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 1/3 + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + # self.node.getClient().generate_epochs("0x2") + # 过去2/3 delay epoch + # node1 能解锁过期的tlc + # node2 能解锁过期的tlc + self.fiber1.stop() + self.fiber2.stop() + self.node.getClient().generate_epochs("0x4") + self.fiber1.start() + tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + message = self.get_tx_message(tx) + print("message:", message) + + def test_node1_and_node2_has_n_tlc_expired_node1_stop_opt(self): + """ + node1和node2 都有n个tlc + 都过期了 + 过去2/3 delay epoch + node1 能解锁过期的tlc + Returns: + + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + self.send_payment(self.fiber1, self.fiber2, 100 * 100000000) + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 15) * 1000), + } + ) + time.sleep(1) + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "expiry": hex((int(time.time()) + 15) * 1000), + } + ) + time.sleep(1) + node1_tlcs = [] + node1_payment_preimages = [] + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(1 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 15) * 1000), + } + ) + node1_payment_preimages.append(payment_preimage) + node1_tlcs.append(tlc) + time.sleep(2) + + node2_tlcs = [] + node2_payment_preimages = [] + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(1 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 100000000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 15) * 1000), + } + ) + node2_payment_preimages.append(payment_preimage) + node2_tlcs.append(tlc) + time.sleep(2) + # shutdown + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 220) + + # # remove tlc + # for i in range(1): + # try: + # self.fiber2.get_client().remove_tlc({ + # "channel_id": CHANNEL_ID, + # "tlc_id": node1_tlcs[i]["tlc_id"], + # "reason": { + # "payment_preimage": node1_payment_preimages[i] + # } + # }) + # except Exception as e: + # print(e) + # time.sleep(1) + + for i in range(1): + try: + self.fiber1.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": node2_tlcs[i]["tlc_id"], + "reason": {"payment_preimage": node2_payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + time.sleep(1) + + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 1/3 + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + # self.node.getClient().generate_epochs("0x2") + # 过去2/3 delay epoch + # node1 能解锁过期的tlc + # node2 能解锁过期的tlc + self.fiber2.stop() + self.node.getClient().generate_epochs("0x4") + tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + message = self.get_tx_message(tx) + print("message:", message) + time.sleep(3) + self.Miner.miner_until_tx_committed(self.node, tx) + + def test_node1_and_node2_has_n_tlc_expired(self): + """ + node1和node2 都有n个tlc + 都过期了 + 过去2/3 delay epoch + node1 能解锁过期的tlc + node2 能解锁过期的tlc + 过去 delay epoch + 2个节点都能解锁 + 当自己tlc 清理完 node 会遗弃交易 + Returns: + """ + fiber3 = self.start_new_fiber(self.generate_account(1000)) + self.fiber1.get_client().open_channel( + { + "peer_id": self.fiber2.get_peer_id(), + "funding_amount": hex(1000 * 100000000), + "public": True, + } + ) + self.wait_for_channel_state( + self.fiber1.get_client(), self.fiber2.get_peer_id(), "CHANNEL_READY" + ) + # 创建N个tlc + self.send_payment(self.fiber1, self.fiber2, 100 * 100000000) + CHANNEL_ID = self.fiber1.get_client().list_channels({})["channels"][0][ + "channel_id" + ] + self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(92 * 100000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "expiry": hex((int(time.time()) + 15) * 1000), + } + ) + time.sleep(1) + self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 110000000), + "payment_hash": "0x0000000000000000000000000000000000000000000000000000000000000001", + "expiry": hex((int(time.time()) + 15) * 1000), + } + ) + time.sleep(1) + self.get_fibers_balance_message() + node1_tlcs = [] + node1_payment_preimages = [] + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(1 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber1.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 101000000 + i * 100000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 15) * 1000), + } + ) + node1_payment_preimages.append(payment_preimage) + node1_tlcs.append(tlc) + time.sleep(2) + + node2_tlcs = [] + node2_payment_preimages = [] + for i in range(2): + payment_preimage = self.generate_random_preimage() + invoice = fiber3.get_client().new_invoice( + { + "amount": hex(1 * 100000000), + "currency": "Fibd", + "description": "test invoice generated by node3", + "expiry": "0xe10", + "final_expiry_delta": "0xDFFA0", + "payment_preimage": payment_preimage, + # "udt_type_script": self.get_account_udt_script( + # self.fiber1.account_private + # ), + } + ) + tlc = self.fiber2.get_client().add_tlc( + { + "channel_id": CHANNEL_ID, + "amount": hex(1 * 102000000 + i * 100000), + "payment_hash": invoice["invoice"]["data"]["payment_hash"], + "expiry": hex((int(time.time()) + 15) * 1000), + } + ) + node2_payment_preimages.append(payment_preimage) + node2_tlcs.append(tlc) + time.sleep(2) + # shutdown + self.get_fibers_balance_message() + self.fiber1.get_client().shutdown_channel( + { + "channel_id": CHANNEL_ID, + "force": True, + } + ) + shutdown_tx = self.wait_and_check_tx_pool_fee(1000, False, 220) + + # # remove tlc + for i in range(1): + try: + self.fiber2.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": node1_tlcs[i]["tlc_id"], + "reason": {"payment_preimage": node1_payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + time.sleep(1) + + for i in range(1): + try: + self.fiber1.get_client().remove_tlc( + { + "channel_id": CHANNEL_ID, + "tlc_id": node2_tlcs[i]["tlc_id"], + "reason": {"payment_preimage": node2_payment_preimages[i]}, + } + ) + except Exception as e: + print(e) + time.sleep(1) + + self.Miner.miner_until_tx_committed(self.node, shutdown_tx) + # 1/3 + time.sleep(10) + status = self.node.getClient().get_live_cell(hex(0), shutdown_tx) + assert status["status"] == "live" + # self.node.getClient().generate_epochs("0x2") + # 过去2/3 delay epoch + # node1 能解锁过期的tlc + # node2 能解锁过期的tlc + self.fiber1.stop() + self.fiber2.stop() + self.node.getClient().generate_epochs("0x4") + self.fiber1.start() + self.fiber2.start() + tx = self.wait_and_check_tx_pool_fee(1000, False, 220) + message = self.get_tx_message(tx) + assert ( + message["input_cells"][0]["capacity"] + - message["output_cells"][0]["capacity"] + == 110000000 + ) + print("first message:", message) + self.fiber1.stop() + self.fiber2.stop() + self.Miner.miner_until_tx_committed(self.node, tx) + self.node.getClient().generate_epochs("0x4") + self.fiber2.start() + tx = self.wait_and_check_tx_pool_fee(1000, False, 220) + self.fiber1.start() + message = self.get_tx_message(tx) + assert ( + message["input_cells"][0]["capacity"] + - message["output_cells"][0]["capacity"] + == 101000000 + ) + print("2 message:", message) + + # 过去 delay epoch + # 2个节点都能解锁 + self.fiber1.stop() + self.fiber2.stop() + self.Miner.miner_until_tx_committed(self.node, tx) + self.node.getClient().generate_epochs("0x6") + self.fiber1.start() + tx = self.wait_and_check_tx_pool_fee(1000, False, 220) + self.fiber2.start() + message = self.get_tx_message(tx) + print("3:", message) + assert ( + message["input_cells"][0]["capacity"] + - message["output_cells"][0]["capacity"] + == 101100000 + ) + self.fiber1.stop() + self.fiber2.stop() + self.Miner.miner_until_tx_committed(self.node, tx) + self.node.getClient().generate_epochs("0x6") + self.fiber2.start() + tx = self.wait_and_check_tx_pool_fee(1000, False, 120) + self.fiber1.start() + message = self.get_tx_message(tx) + assert ( + message["input_cells"][0]["capacity"] + - message["output_cells"][0]["capacity"] + == 9200000000 + ) + self.fiber1.stop() + self.fiber2.stop() + self.Miner.miner_until_tx_committed(self.node, tx) + time.sleep(5) + self.node.getClient().generate_epochs("0x6") + self.fiber1.start() + tx = self.wait_and_check_tx_pool_fee(1000, False, 220) + message = self.get_tx_message(tx) + assert ( + message["input_cells"][0]["capacity"] + - message["output_cells"][0]["capacity"] + == 102000000 + ) + time.sleep(5) + # 当自己tlc 清理完 node 会遗弃交易 + self.Miner.miner_until_tx_committed(self.node, tx) + time.sleep(5) + self.node.getClient().generate_epochs("0x6") + tx = self.wait_and_check_tx_pool_fee(1000, False, 220) + message = self.get_tx_message(tx) + assert message["fee"] > 1000000 diff --git a/test_cases/fiber/testnet/test_fiber.py b/test_cases/fiber/testnet/test_fiber.py index 88d202d5..1809af4f 100644 --- a/test_cases/fiber/testnet/test_fiber.py +++ b/test_cases/fiber/testnet/test_fiber.py @@ -255,8 +255,8 @@ def test_udt_02(self): "args": "0x878fcc6f1f08d48e87bb1c3b3d5083f23f8a39c5d5c764f253b55b998526439b", } self.fiber1.stop() - self.fiber1.start() self.fiber2.stop() + self.fiber1.start() self.fiber2.start() begin = time.time() # wait dry_run success diff --git a/test_cases/fiber/testnet/test_fiber_local_node.py b/test_cases/fiber/testnet/test_fiber_local_node.py new file mode 100644 index 00000000..1809af4f --- /dev/null +++ b/test_cases/fiber/testnet/test_fiber_local_node.py @@ -0,0 +1,351 @@ +import time + +from framework.basic import CkbTest +from framework.fiber_rpc import FiberRPCClient +from framework.test_fiber import Fiber, FiberConfigPath +from framework.util import generate_random_preimage +import logging + +LOGGER = logging.getLogger(__name__) + + +# ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsqt2yg5ctyv59wsrqk2d634rj6k7c8kdjycft39my +# ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq0n4lwpc3k24hnt75pmgpmg2hgack50wdgnlsp6m + + +class TestFiber(CkbTest): + cryptapeFiber1 = FiberRPCClient("http://18.163.221.211:8227") + cryptapeFiber2 = FiberRPCClient("http://18.162.235.225:8227") + + ACCOUNT_PRIVATE_1 = ( + "0xaae4515b745efcd6f00c1b40aaeef3dd66c82d75f8f43d0f18e1a1eecb90ada4" + ) + ACCOUNT_PRIVATE_2 = ( + "0x518d76bbfe5ffe3a8ef3ad486e784ec333749575fb3c697126cdaa8084d42532" + ) + fiber1: Fiber + fiber2: Fiber + + @classmethod + def setup_class(cls): + print("\nSetup TestClass2") + cls.fiber1 = Fiber.init_by_port( + FiberConfigPath.CURRENT_TESTNET, + cls.ACCOUNT_PRIVATE_1, + "fiber/node1", + "8228", + "8227", + ) + + cls.fiber2 = Fiber.init_by_port( + FiberConfigPath.CURRENT_TESTNET, + cls.ACCOUNT_PRIVATE_2, + "fiber/node2", + "8229", + "8230", + ) + + cls.fiber1.prepare() + cls.fiber1.start() + + cls.fiber2.prepare() + cls.fiber2.start() + + cls.fiber1.get_client().connect_peer( + {"address": cls.cryptapeFiber1.node_info()["addresses"][0]} + ) + + cls.fiber2.get_client().connect_peer( + {"address": cls.cryptapeFiber2.node_info()["addresses"][0]} + ) + time.sleep(10) + + @classmethod + def teardown_class(cls): + channels = cls.fiber1.get_client().list_channels({}) + for i in range(len(channels["channels"])): + channel = channels["channels"][i] + if channel["state"]["state_name"] != "CHANNEL_READY": + continue + cls.fiber1.get_client().shutdown_channel( + { + "channel_id": channel["channel_id"], + "close_script": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": cls.fiber1.get_account()["lock_arg"], + }, + "fee_rate": "0x3FC", + } + ) + wait_for_channel_state( + cls.fiber1.get_client(), cls.cryptapeFiber1.get_peer_id(), "CLOSED", 120 + ) + + channels = cls.fiber2.get_client().list_channels({}) + for i in range(len(channels["channels"])): + channel = channels["channels"][i] + if channel["state"]["state_name"] != "CHANNEL_READY": + continue + cls.fiber2.get_client().shutdown_channel( + { + "channel_id": channel["channel_id"], + "close_script": { + "code_hash": "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8", + "hash_type": "type", + "args": cls.fiber2.get_account()["lock_arg"], + }, + "fee_rate": "0x3FC", + } + ) + wait_for_channel_state( + cls.fiber2.get_client(), cls.cryptapeFiber2.get_peer_id(), "CLOSED", 120 + ) + + cls.fiber1.stop() + cls.fiber1.clean() + cls.fiber2.stop() + cls.fiber2.clean() + + def test_ckb_01(self): + # open_channel + temporary_channel_id = self.fiber1.get_client().open_channel( + { + "peer_id": self.cryptapeFiber1.get_peer_id(), + "funding_amount": hex(500 * 100000000), + "public": True, + # "tlc_fee_proportional_millionths": "0x4B0", + } + ) + + temporary_channel_id = self.fiber2.get_client().open_channel( + { + "peer_id": self.cryptapeFiber2.get_peer_id(), + "funding_amount": hex(500 * 100000000), + "public": True, + # "tlc_fee_proportional_millionths": "0x4B0", + } + ) + wait_for_channel_state( + self.fiber1.get_client(), + self.cryptapeFiber1.get_peer_id(), + "CHANNEL_READY", + 120, + ) + + wait_for_channel_state( + self.fiber2.get_client(), + self.cryptapeFiber2.get_peer_id(), + "CHANNEL_READY", + 120, + ) + begin = time.time() + # wait dry_run success + send_payment( + self.fiber1.get_client(), self.fiber2.get_client(), 1000, None, 20 * 60 + ) + fiber1_to_fiber2_time = time.time() + send_payment( + self.fiber2.get_client(), self.fiber1.get_client(), 1000, None, 20 * 60 + ) + fiber2_to_fiber1_time = time.time() + LOGGER.info(f"fiber1_to_fiber2 cost time: {fiber1_to_fiber2_time - begin}") + LOGGER.info( + f"fiber2_to_fiber1 cost time: {fiber2_to_fiber1_time - fiber1_to_fiber2_time}" + ) + + def test_ckb_02(self): + self.fiber1.stop() + self.fiber2.stop() + self.fiber1.start() + self.fiber2.start() + begin = time.time() + send_payment( + self.fiber1.get_client(), self.fiber2.get_client(), 1000, None, 20 * 60 + ) + fiber1_to_fiber2_time = time.time() + send_payment( + self.fiber2.get_client(), self.fiber1.get_client(), 1000, None, 20 * 60 + ) + fiber2_to_fiber1_time = time.time() + LOGGER.info(f"fiber1_to_fiber2 cost time: {fiber1_to_fiber2_time - begin}") + LOGGER.info( + f"fiber2_to_fiber1 cost time: {fiber2_to_fiber1_time - fiber1_to_fiber2_time}" + ) + + def test_udt(self): + funding_udt_type_script = { + "code_hash": "0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a", + "hash_type": "type", + "args": "0x878fcc6f1f08d48e87bb1c3b3d5083f23f8a39c5d5c764f253b55b998526439b", + } + temporary_channel_id = self.fiber1.get_client().open_channel( + { + "peer_id": self.cryptapeFiber1.get_peer_id(), + "funding_amount": hex(20 * 100000000), + "public": True, + "funding_udt_type_script": funding_udt_type_script, + } + ) + + temporary_channel_id = self.fiber2.get_client().open_channel( + { + "peer_id": self.cryptapeFiber2.get_peer_id(), + "funding_amount": hex(20 * 100000000), + "public": True, + "funding_udt_type_script": funding_udt_type_script, + } + ) + wait_for_channel_state( + self.fiber1.get_client(), + self.cryptapeFiber1.get_peer_id(), + "CHANNEL_READY", + 120, + ) + + wait_for_channel_state( + self.fiber2.get_client(), + self.cryptapeFiber2.get_peer_id(), + "CHANNEL_READY", + 120, + ) + begin = time.time() + # wait dry_run success + send_payment( + self.fiber1.get_client(), + self.cryptapeFiber2, + 100000, + funding_udt_type_script, + 20 * 60, + ) + send_payment( + self.fiber2.get_client(), + self.cryptapeFiber1, + 100000, + funding_udt_type_script, + 20 * 60, + ) + + send_payment( + self.fiber1.get_client(), + self.fiber2.get_client(), + 1000, + funding_udt_type_script, + 20 * 60, + ) + + fiber1_to_fiber2_time = time.time() + send_payment( + self.fiber2.get_client(), + self.fiber1.get_client(), + 1000, + funding_udt_type_script, + 20 * 60, + ) + fiber2_to_fiber1_time = time.time() + LOGGER.info(f"fiber1_to_fiber2 cost time: {fiber1_to_fiber2_time - begin}") + LOGGER.info( + f"fiber2_to_fiber1 cost time: {fiber2_to_fiber1_time - fiber1_to_fiber2_time}" + ) + + def test_udt_02(self): + funding_udt_type_script = { + "code_hash": "0x1142755a044bf2ee358cba9f2da187ce928c91cd4dc8692ded0337efa677d21a", + "hash_type": "type", + "args": "0x878fcc6f1f08d48e87bb1c3b3d5083f23f8a39c5d5c764f253b55b998526439b", + } + self.fiber1.stop() + self.fiber2.stop() + self.fiber1.start() + self.fiber2.start() + begin = time.time() + # wait dry_run success + + send_payment( + self.fiber1.get_client(), + self.cryptapeFiber2, + 100000, + funding_udt_type_script, + 20 * 60, + ) + send_payment( + self.fiber2.get_client(), + self.cryptapeFiber1, + 100000, + funding_udt_type_script, + 20 * 60, + ) + + send_payment( + self.fiber1.get_client(), + self.fiber2.get_client(), + 1000, + funding_udt_type_script, + 20 * 60, + ) + fiber1_to_fiber2_time = time.time() + send_payment( + self.fiber2.get_client(), + self.fiber1.get_client(), + 1000, + funding_udt_type_script, + 20 * 60, + ) + fiber2_to_fiber1_time = time.time() + LOGGER.info(f"fiber1_to_fiber2 cost time: {fiber1_to_fiber2_time - begin}") + LOGGER.info( + f"fiber2_to_fiber1 cost time: {fiber2_to_fiber1_time - fiber1_to_fiber2_time}" + ) + + +def send_payment( + fiber1: FiberRPCClient, fiber2: FiberRPCClient, amount, udt=None, wait_times=300 +): + try_times = 0 + payment = None + for i in range(wait_times): + try: + payment = fiber1.send_payment( + { + "amount": hex(amount), + "target_pubkey": fiber2.node_info()["node_id"], + "keysend": True, + "udt_type_script": udt, + } + ) + break + except Exception as e: + print(e) + print(f"send try count: {i}") + time.sleep(1) + continue + for i in range(wait_times): + time.sleep(1) + try: + payment = fiber1.get_payment({"payment_hash": payment["payment_hash"]}) + if payment["status"] == "Failed": + return send_payment(fiber1, fiber2, amount, udt, wait_times - i) + if payment["status"] == "Success": + print("payment success") + return payment + except Exception as e: + print(e) + print(f"wait try count: {i}") + continue + raise TimeoutError("payment timeout") + + +def wait_for_channel_state(client, peer_id, expected_state, timeout=120): + """Wait for a channel to reach a specific state.""" + for _ in range(timeout): + channels = client.list_channels({"peer_id": peer_id, "include_closed": True}) + if channels["channels"][0]["state"]["state_name"] == expected_state: + print(f"Channel reached expected state: {expected_state}") + return channels["channels"][0]["channel_id"] + print( + f"Waiting for channel state: {expected_state}, current state: {channels['channels'][0]['state']['state_name']}" + ) + time.sleep(1) + raise TimeoutError( + f"Channel did not reach state {expected_state} within timeout period." + )