Skip to content

Commit

Permalink
Problem: ica in ibc v7.2.0 is not adjust correctly (#1165)
Browse files Browse the repository at this point in the history
* Problem: icaauth route is not registered correctly

test icaauth

* rm dup claim capability

handle in https://github.com/cosmos/ibc-go/blob/v7.2.0/modules/apps/27-interchain-accounts/controller/ibc_middleware.go#L60

* fix submit tx

https://github.com/cosmos/ibc-go/blob/v7.2.0/modules/apps/27-interchain-accounts/controller/keeper/relay.go#L28

* Apply suggestions from code review

* cleanup test
  • Loading branch information
mmsqe authored Sep 15, 2023
1 parent 98c3d06 commit 6935b19
Show file tree
Hide file tree
Showing 11 changed files with 288 additions and 280 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
- [cronos#997](https://github.com/crypto-org-chain/cronos/pull/997) Fix logic to support proxy contract for cronos originated crc20.
- [cronos#1005](https://github.com/crypto-org-chain/cronos/pull/1005) Support specify channel id for send-to-ibc event in case of source token.
- [cronos#1069](https://github.com/crypto-org-chain/cronos/pull/1069) Update ethermint to develop, go-ethereum to `v1.10.26` and ibc-go to `v6.2.0`.
- [cronos#1147](https://github.com/crypto-org-chain/cronos/pull/1147) integrate ica module.
- [cronos#1147](https://github.com/crypto-org-chain/cronos/pull/1147) Integrate ica module.
- (deps) [#1121](https://github.com/crypto-org-chain/cronos/pull/1121) Bump Cosmos-SDK to v0.47.5 and ibc-go to v7.2.0.
- [cronos#1014](https://github.com/crypto-org-chain/cronos/pull/1014) Support stateful precompiled contract for relayer.
- [cronos#1165](https://github.com/crypto-org-chain/cronos/pull/1165) Icaauth module is not adjusted correctly in ibc-go v7.2.0.

### Bug Fixes

Expand Down
14 changes: 6 additions & 8 deletions integration_tests/cosmoscli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1253,7 +1253,7 @@ def transfer_tokens(self, from_, to, amount, **kwargs):
)
)

def ica_register_account(self, connid, **kwargs):
def icaauth_register_account(self, connid, **kwargs):
"execute on host chain to attach an account to the connection"
default_kwargs = {
"home": self.data_dir,
Expand All @@ -1264,9 +1264,8 @@ def ica_register_account(self, connid, **kwargs):
rsp = json.loads(
self.raw(
"tx",
"ica",
"controller",
"register",
"icaauth",
"register-account",
connid,
"-y",
**(default_kwargs | kwargs),
Expand All @@ -1276,7 +1275,7 @@ def ica_register_account(self, connid, **kwargs):
rsp = self.event_query_tx_for(rsp["txhash"])
return rsp

def ica_submit_tx(self, connid, tx, **kwargs):
def icaauth_submit_tx(self, connid, tx, **kwargs):
default_kwargs = {
"home": self.data_dir,
"node": self.node_rpc,
Expand All @@ -1286,9 +1285,8 @@ def ica_submit_tx(self, connid, tx, **kwargs):
rsp = json.loads(
self.raw(
"tx",
"ica",
"controller",
"send-tx",
"icaauth",
"submit-tx",
connid,
tx,
"-y",
Expand Down
245 changes: 189 additions & 56 deletions integration_tests/ibc_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
deploy_contract,
eth_to_bech32,
parse_events,
parse_events_rpc,
send_transaction,
setup_token_mapping,
wait_for_fn,
Expand All @@ -32,13 +33,99 @@ class IBCNetwork(NamedTuple):
proc: subprocess.Popen[bytes] | None


def call_hermes_cmd(
hermes,
connection_only,
incentivized,
version,
):
if connection_only:
subprocess.check_call(
[
"hermes",
"--config",
hermes.configpath,
"create",
"connection",
"--a-chain",
"cronos_777-1",
"--b-chain",
"chainmain-1",
]
)
else:
subprocess.check_call(
[
"hermes",
"--config",
hermes.configpath,
"create",
"channel",
"--a-port",
"transfer",
"--b-port",
"transfer",
"--a-chain",
"cronos_777-1",
"--b-chain",
"chainmain-1",
"--new-client-connection",
"--yes",
]
+ (
[
"--channel-version",
json.dumps(version),
]
if incentivized
else []
)
)


def call_rly_cmd(path, version):
cmd = [
"rly",
"pth",
"new",
"chainmain-1",
"cronos_777-1",
"chainmain-cronos",
"--home",
str(path),
]
subprocess.check_call(cmd)
cmd = [
"rly",
"tx",
"connect",
"chainmain-cronos",
"--src-port",
"transfer",
"--dst-port",
"transfer",
"--order",
"unordered",
"--version",
json.dumps(version),
"--home",
str(path),
]
subprocess.check_call(cmd)


def prepare_network(
tmp_path,
file,
incentivized=True,
is_relay=True,
connection_only=False,
relayer=cluster.Relayer.HERMES.value,
):
print("incentivized", incentivized)
print("is_relay", is_relay)
print("connection_only", connection_only)
print("relayer", relayer)
is_hermes = relayer == cluster.Relayer.HERMES.value
hermes = None
file = f"configs/{file}.jsonnet"
Expand All @@ -55,66 +142,18 @@ def prepare_network(
wait_for_port(ports.grpc_port(cronos.base_port(0))) # cronos grpc

version = {"fee_version": "ics29-1", "app_version": "ics20-1"}
incentivized_args = (
[
"--channel-version",
json.dumps(version),
]
if incentivized
else []
)
path = cronos.base_dir.parent / "relayer"
if is_hermes:
hermes = Hermes(cronos.base_dir.parent / "relayer.toml")
subprocess.check_call(
[
"hermes",
"--config",
hermes.configpath,
"create",
"channel",
"--a-port",
"transfer",
"--b-port",
"transfer",
"--a-chain",
"cronos_777-1",
"--b-chain",
"chainmain-1",
"--new-client-connection",
"--yes",
]
+ incentivized_args
hermes = Hermes(path.with_suffix(".toml"))
call_hermes_cmd(
hermes,
connection_only,
incentivized,
version,
)
else:
cmd = [
"rly",
"pth",
"new",
"chainmain-1",
"cronos_777-1",
"chainmain-cronos",
"--home",
str(path),
]
subprocess.check_call(cmd)
cmd = [
"rly",
"tx",
"connect",
"chainmain-cronos",
"--src-port",
"transfer",
"--dst-port",
"transfer",
"--order",
"unordered",
"--version",
json.dumps(version),
"--home",
str(path),
]
subprocess.check_call(cmd)
call_rly_cmd(path, version)

proc = None
if incentivized:
# register fee payee
Expand Down Expand Up @@ -181,6 +220,58 @@ def hermes_transfer(ibc):
return src_amount


def find_duplicate(attributes):
res = set()
key = attributes[0]["key"]
for attribute in attributes:
if attribute["key"] == key:
value0 = attribute["value"]
elif attribute["key"] == "amount":
amount = attribute["value"]
value_pair = f"{value0}:{amount}"
if value_pair in res:
return value_pair
res.add(value_pair)
return None


def ibc_transfer_with_hermes(ibc):
src_amount = hermes_transfer(ibc)
dst_amount = src_amount * RATIO # the decimal places difference
dst_denom = "basetcro"
dst_addr = eth_to_bech32(ADDRS["signer2"])
old_dst_balance = get_balance(ibc.cronos, dst_addr, dst_denom)

new_dst_balance = 0

def check_balance_change():
nonlocal new_dst_balance
new_dst_balance = get_balance(ibc.cronos, dst_addr, dst_denom)
return new_dst_balance != old_dst_balance

wait_for_fn("balance change", check_balance_change)
assert old_dst_balance + dst_amount == new_dst_balance

# assert that the relayer transactions do enables the dynamic fee extension option.
cli = ibc.cronos.cosmos_cli()
criteria = "message.action=/ibc.core.channel.v1.MsgChannelOpenInit"
tx = cli.tx_search(criteria)["txs"][0]
events = parse_events_rpc(tx["events"])
fee = int(events["tx"]["fee"].removesuffix(dst_denom))
gas = int(tx["gas_wanted"])
# the effective fee is decided by the max_priority_fee (base fee is zero)
# rather than the normal gas price
assert fee == gas * 1000000

# check duplicate OnRecvPacket events
criteria = "message.action=/ibc.core.channel.v1.MsgRecvPacket"
tx = cli.tx_search(criteria)["txs"][0]
events = tx["logs"][1]["events"]
for event in events:
dup = find_duplicate(event["attributes"])
assert not dup, f"duplicate {dup} in {event['type']}"


def get_balance(chain, addr, denom):
balance = chain.cosmos_cli().balance(addr, denom)
print("balance", balance, addr, denom)
Expand Down Expand Up @@ -467,3 +558,45 @@ def check_contract_balance_change():
wait_for_fn("check contract balance change", check_contract_balance_change)
assert cronos_balance_after_send == amount
return amount, contract.address


def wait_for_check_channel_ready(cli, connid, channel_id):
print("wait for channel ready")

def check_channel_ready():
channels = cli.ibc_query_channels(connid)["channels"]
try:
state = next(
channel["state"]
for channel in channels
if channel["channel_id"] == channel_id
)
except StopIteration:
return False
return state == "STATE_OPEN"

wait_for_fn("channel ready", check_channel_ready)


def wait_for_check_tx(cli, adr, num_txs):
print("wait for tx arrive")

def check_tx():
current = len(cli.query_all_txs(adr)["txs"])
print("current", current)
return current > num_txs

wait_for_fn("transfer tx", check_tx)


def funds_ica(cli, adr):
# initial balance of interchain account should be zero
assert cli.balance(adr) == 0

# send some funds to interchain account
rsp = cli.transfer("signer2", adr, "1cro", gas_prices="1000000basecro")
assert rsp["code"] == 0, rsp["raw_log"]
wait_for_new_blocks(cli, 1)

# check if the funds are received in interchain account
assert cli.balance(adr, denom="basecro") == 100000000
Loading

0 comments on commit 6935b19

Please sign in to comment.