From 62412b2609c4bc0e04f542bec3a762cca2e35d46 Mon Sep 17 00:00:00 2001 From: yihuang Date: Fri, 27 Nov 2020 17:30:02 +0800 Subject: [PATCH] Problem (fix #283): ibc-transfer not directly tested with chain-maind Solution: - start `relayer start` together with chain binaries - send ibc-transfer transaction with chain binary --- integration_tests/test_ibc.py | 83 ++++++++++++++++++++------------ integration_tests/utils.py | 3 +- nix/sources.json | 8 +-- pystarport/pystarport/cli.py | 5 +- pystarport/pystarport/cluster.py | 60 ++++++++++++++++++++--- 5 files changed, 114 insertions(+), 45 deletions(-) diff --git a/integration_tests/test_ibc.py b/integration_tests/test_ibc.py index a0ac933f5..f15f632dd 100644 --- a/integration_tests/test_ibc.py +++ b/integration_tests/test_ibc.py @@ -1,6 +1,7 @@ import hashlib import json import subprocess +import time from pathlib import Path import pytest @@ -42,20 +43,6 @@ def test_ibc(cluster): check=True, ) - # setup path - subprocess.run( - relayer - + [ - "tx", - "link", - "demo", - "-d", - "-o", - "3s", - ], - check=True, - ) - # check status rsp = json.loads(subprocess.check_output(relayer + ["chains", "list", "--json"])) assert rsp == [ @@ -78,6 +65,7 @@ def test_ibc(cluster): "trusting-period": "336h", }, ] + rsp = json.loads(subprocess.check_output(relayer + ["paths", "list", "--json"])) assert rsp == { "demo": { @@ -104,6 +92,44 @@ def test_ibc(cluster): }, } } + + # wait for channel to be setup + for i in range(60): + channels = json.loads( + raw( + "query", + "ibc", + "channel", + "channels", + node=cluster["ibc-0"].node_rpc(0), + output="json", + ) + )["channels"] + print("channels", channels) + if channels and channels[0]["state"] == "STATE_OPEN": + break + time.sleep(1) + else: + raise TimeoutError("src channel still not setup") + + for i in range(60): + channels = json.loads( + raw( + "query", + "ibc", + "channel", + "channels", + node=cluster["ibc-1"].node_rpc(0), + output="json", + ) + )["channels"] + print("channels", channels) + if channels and channels[0]["state"] == "STATE_OPEN": + break + time.sleep(1) + else: + raise TimeoutError("dst channel still not setup") + # query balance of relayer account for chain_id in cluster: assert ( @@ -114,14 +140,16 @@ def test_ibc(cluster): # do a transfer from ibc-0 to ibc-1 recipient = cluster["ibc-1"].address("relayer") - subprocess.run( - relayer + ["tx", "transfer", "ibc-0", "ibc-1", "10000basecro", recipient], - check=True, + rsp = cluster["ibc-0"].ibc_transfer( + "relayer", recipient, "10000basecro", "demo0channel", 1 ) + assert rsp["code"] == 0, rsp["raw_log"] # sender balance decreased assert cluster["ibc-0"].balance(cluster["ibc-0"].address("relayer")) == 9999990000 + print("ibc transfer") - subprocess.run(relayer + ["tx", "relay", "demo", "-d"], check=True) + # FIXME more stable way to wait for relaying + time.sleep(10) denom_hash = hashlib.sha256(b"transfer/demo1channel/basecro").hexdigest().upper() assert ( @@ -157,19 +185,14 @@ def test_ibc(cluster): # transfer back recipient = cluster["ibc-0"].address("relayer") - subprocess.run( - relayer - + [ - "tx", - "transfer", - "ibc-1", - "ibc-0", - "10000transfer/demo1channel/basecro", - recipient, - ], - check=True, + rsp = cluster["ibc-1"].ibc_transfer( + "relayer", recipient, f"10000ibc/{denom_hash}", "demo1channel", 0 ) - subprocess.run(relayer + ["tx", "relay", "demo", "-d"], check=True) + print("ibc transfer back") + assert rsp["code"] == 0, rsp["raw_log"] + + # FIXME more stable way to wait for relaying + time.sleep(10) # both accounts return to normal for i, cli in enumerate(cluster.values()): diff --git a/integration_tests/utils.py b/integration_tests/utils.py index bec855e6a..b6513c4d8 100644 --- a/integration_tests/utils.py +++ b/integration_tests/utils.py @@ -107,8 +107,7 @@ def cluster_fixture( supervisord = cluster.start_cluster(data) if not quiet: - tailer = cluster.TailLogsThread(data, ["*/node*.log"]) - tailer.start() + tailer = cluster.start_tail_logs_thread(data) begin = time.time() for cli in clis.values(): diff --git a/nix/sources.json b/nix/sources.json index 2b88c7c13..ab2679b5a 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -36,15 +36,15 @@ "url_template": "https://github.com///archive/.tar.gz" }, "relayer": { - "branch": "custom-coin-type", + "branch": "cryptocom", "description": "An example of a server side IBC relayer to be used for Game of Zones and beyond", "homepage": null, "owner": "yihuang", "repo": "relayer", - "rev": "5e9fd91198e206fe85be6214da68f4250b557063", - "sha256": "14067sm24d6y479c835vbg527lxmrjznc0zgd2ywnslyz052kdis", + "rev": "bdb89886db510626bbd1a9d836fd530dea7d1409", + "sha256": "03d8y8skhj3vi645cs407x37vn2wykqhkvqk2k56v7sm8g6dyq7j", "type": "tarball", - "url": "https://github.com/yihuang/relayer/archive/5e9fd91198e206fe85be6214da68f4250b557063.tar.gz", + "url": "https://github.com/yihuang/relayer/archive/bdb89886db510626bbd1a9d836fd530dea7d1409.tar.gz", "url_template": "https://github.com///archive/.tar.gz" } } diff --git a/pystarport/pystarport/cli.py b/pystarport/pystarport/cli.py index be061c139..538eb6065 100644 --- a/pystarport/pystarport/cli.py +++ b/pystarport/pystarport/cli.py @@ -10,9 +10,9 @@ IMAGE, SUPERVISOR_CONFIG_FILE, ClusterCLI, - TailLogsThread, init_cluster, start_cluster, + start_tail_logs_thread, ) from .utils import build_cli_args, interact @@ -33,8 +33,7 @@ def start(data, quiet): signal.signal(getattr(signal, signame), lambda *args: supervisord.terminate()) if not quiet: - tailer = TailLogsThread(data, ["*/node*.log"]) - tailer.start() + tailer = start_tail_logs_thread(data) supervisord.wait() diff --git a/pystarport/pystarport/cluster.py b/pystarport/pystarport/cluster.py index 64d03f33f..95636722e 100644 --- a/pystarport/pystarport/cluster.py +++ b/pystarport/pystarport/cluster.py @@ -973,6 +973,36 @@ def query_tally(self, proposal_id): ) ) + def ibc_transfer( + self, + from_, + to, + amount, + channel, # src channel + target_version, # chain version number of target chain + i=0, + ): + return json.loads( + self.raw( + "tx", + "ibc-transfer", + "transfer", + "transfer", # src port + channel, + to, + amount, + "-y", + "--absolute-timeouts", # FIXME avoid an ClientState decoding error + from_=from_, + home=self.home(i), + node=self.node_rpc(i), + keyring_backend="test", + chain_id=self.chain_id, + packet_timeout_height=f"{target_version}-10000000000", + packet_timeout_timestamp=0, + ) + ) + def start_cluster(data_dir): cmd = [ @@ -1007,6 +1037,12 @@ def stopped(self): return self._stop_event.is_set() +def start_tail_logs_thread(data_dir): + t = TailLogsThread(data_dir, ["*/node*.log", "relayer-*.log"]) + t.start() + return t + + def process_config(config, base_port): """ fill default values in config @@ -1189,6 +1225,7 @@ def relayer_chain_config(data_dir, chain_id): "gas-adjustment": 1.5, "gas-prices": "0.0basecro", "trusting-period": "336h", + "debug": True, } @@ -1198,7 +1235,7 @@ def init_cluster( config = yaml.safe_load(open(config_path)) # override relayer config in config.yaml - rly_section = config.pop("relayer", None) + rly_section = config.pop("relayer", {}) for chain_id, cfg in config.items(): cfg["path"] = str(config_path) cfg["chain_id"] = chain_id @@ -1210,7 +1247,12 @@ def init_cluster( data_dir / chain["chain_id"], chain, base_port, image, cmd, gen_compose_file ) with (data_dir / SUPERVISOR_CONFIG_FILE).open("w") as fp: - write_ini(fp, supervisord_ini_group(config.keys())) + write_ini( + fp, + supervisord_ini_group( + config.keys(), list(rly_section.get("paths", {}).keys()) + ), + ) if len(chains) > 1: # write relayer config rly_home = data_dir / "relayer" @@ -1259,8 +1301,8 @@ def supervisord_ini(cmd, validators, chain_id): return ini -def supervisord_ini_group(chain_ids): - return { +def supervisord_ini_group(chain_ids, paths): + cfg = { "include": { "files": " ".join( f"%(here)s/{chain_id}/tasks.ini" for chain_id in chain_ids @@ -1279,6 +1321,13 @@ def supervisord_ini_group(chain_ids): "unix_http_server": {"file": "%(here)s/supervisor.sock"}, "supervisorctl": {"serverurl": "unix://%(here)s/supervisor.sock"}, } + for path in paths: + cfg[f"program:relayer-{path}"] = dict( + COMMON_PROG_OPTIONS, + command=f"relayer --home %(here)s/relayer tx link-then-start {path}", + stdout_logfile=f"%(here)s/relayer-{path}.log", + ) + return cfg def docker_compose_yml(cmd, validators, data_dir, image): @@ -1333,8 +1382,7 @@ def edit_app_cfg(path, base_port): data_dir = Path("data") init_cluster(data_dir, "config.yaml", 26650) supervisord = start_cluster(data_dir) - t = TailLogsThread(data_dir, ["*/node*.log"]) - t.start() + t = start_tail_logs_thread(data_dir) supervisord.wait() t.stop() t.join()