Skip to content

Commit

Permalink
Add Channel worker (informalsystems#924)
Browse files Browse the repository at this point in the history
* Added a worker for  channel 

* Added query_connection_channels to the chain handle and runtime

* Redo informalsystems#923 to return `Uninitialized` when empty value bytes are returned

* Changed the CLI to return error if connection/ channel does not exist

* Allow entering the destination channel id in `hermes tx raw chan-open-try...` 

* Change `strategy` in config to be either `packets`(only relay packets) or `all` (relay from all events)

* e2e CI changes

Co-authored-by: Anca Zamfir <zamfiranca@gmail.com>
Co-authored-by: Romain Ruetschi <romain@informal.systems>
Co-authored-by: Adi Seredinschi <adi@informal.systems>
  • Loading branch information
4 people authored May 26, 2021
1 parent f3b38db commit 4ab78b9
Show file tree
Hide file tree
Showing 36 changed files with 1,086 additions and 403 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### FEATURES

- [ibc-relayer]
- Add support for event based channel relaying ([#822])
- Graceful handling of packet events in the presence of multiple relayers ([#983])

### IMPROVEMENTS
Expand All @@ -22,10 +23,11 @@
- [ibc-relayer-cli]
- Promote `start-multi` command to `start` ([#911])

[#983]: https://github.com/informalsystems/ibc-rs/issues/983
[#822]: https://github.com/informalsystems/ibc-rs/issues/822
[#871]: https://github.com/informalsystems/ibc-rs/issues/871
[#911]: https://github.com/informalsystems/ibc-rs/issues/911
[#972]: https://github.com/informalsystems/ibc-rs/issues/972
[#983]: https://github.com/informalsystems/ibc-rs/issues/983

## v0.3.2
*May 21st, 2021*
Expand Down
2 changes: 1 addition & 1 deletion ci/relayer.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LABEL maintainer="hello@informal.systems"
ARG RELEASE

# Add Python 3
RUN apt-get update -y && apt-get install python3 -y
RUN apt-get update -y && apt-get install python3 -y && apt-get install python3-toml -y

# Copy relayer executable
COPY ./hermes /usr/bin/hermes
Expand Down
2 changes: 1 addition & 1 deletion ci/simple_config.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[global]
strategy = 'naive'
strategy = 'packets'
log_level = 'info'

[[chains]]
Expand Down
7 changes: 5 additions & 2 deletions config.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
[global]
strategy = 'naive'
log_level = 'error'
# Valid strategies:
# 'packets': restricts relaying to packets only, or
# 'all': relay from all types of events
strategy = 'packets'
log_level = 'info'

[[chains]]
id = 'ibc-0'
Expand Down
58 changes: 0 additions & 58 deletions config_example.toml

This file was deleted.

30 changes: 3 additions & 27 deletions docs/architecture/adr-002-ibc-relayer.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Below is an example of a configuration file.

```toml
[global]
strategy = "naive"
strategy = "packets"
log_level = "error"

[[chains]]
Expand Down Expand Up @@ -152,31 +152,6 @@ log_level = "error"
gas_price = "0.025stake"
trusting_period = "336h"

[[connections]]

[connections.src]
client_id = "clB1"
connection_id = "connAtoB"

[connections.dest]
client_id = "clA1"
connection_id = "connBtoA"

[[connections.paths]]
src_port = "portA1"
dest_port = "portB1"
direction = "unidirectional"

[[connections.paths]]
src_port = "portA2"
dest_port = "portB2"
direction = "bidirectional"

[[connections.paths]]
src_port = "portA3"
dest_port = "portB3"
src_channel = "chan3-on-A"
dest_channel = "chan3-on-B"
```
The main sections of the configuration file are:
- `global`:
Expand All @@ -200,7 +175,8 @@ pub struct Config {
}

pub enum Strategy {
Naive,
Packets,
HandshakeAndPackets,
}

pub struct GlobalConfig {
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture/adr-006-hermes-v0.2-usecases.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ of the config file will look as follows:

```toml
[global]
strategy = 'naive'
strategy = 'packets'
log_level = 'error'
log_json = 'false'
```
Expand Down
102 changes: 97 additions & 5 deletions e2e/e2e/channel.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from typing import Optional, Tuple
import toml

from .cmd import *
from .common import *

import e2e.relayer as relayer

@dataclass
class TxChanOpenInitRes:
Expand Down Expand Up @@ -418,18 +420,19 @@ def handshake(
c: Config,
side_a: ChainId, side_b: ChainId,
conn_a: ConnectionId, conn_b: ConnectionId,
port_id: PortId
) -> Tuple[ChannelId, ChannelId]:
a_chan_id = chan_open_init(c, dst=side_a, src=side_b, dst_conn=conn_a)

split()

b_chan_id = chan_open_try(
c, dst=side_b, src=side_a, dst_conn=conn_b, dst_port=PortId('transfer'), src_port=PortId('transfer'),
c, dst=side_b, src=side_a, dst_conn=conn_b, dst_port=port_id, src_port=port_id,
src_chan=a_chan_id)

split()

ack_res = chan_open_ack(c, dst=side_a, src=side_b, dst_port=PortId('transfer'), src_port=PortId('transfer'),
ack_res = chan_open_ack(c, dst=side_a, src=side_b, dst_port=port_id, src_port=port_id,
dst_conn=conn_a, dst_chan=a_chan_id, src_chan=b_chan_id)

if ack_res != a_chan_id:
Expand All @@ -438,7 +441,7 @@ def handshake(
exit(1)

confirm_res = chan_open_confirm(
c, dst=side_b, src=side_a, dst_port=PortId('transfer'), src_port=PortId('transfer'),
c, dst=side_b, src=side_a, dst_port=port_id, src_port=port_id,
dst_conn=conn_b, dst_chan=b_chan_id, src_chan=a_chan_id)

if confirm_res != b_chan_id:
Expand All @@ -448,13 +451,13 @@ def handshake(

split()

a_chan_end = query_channel_end(c, side_a, PortId('transfer'), a_chan_id)
a_chan_end = query_channel_end(c, side_a, port_id, a_chan_id)
if a_chan_end.state != 'Open':
l.error(
f'Channel end with id {a_chan_id} on chain {side_a} is not in Open state, got: {a_chan_end.state}')
exit(1)

b_chan_end = query_channel_end(c, side_b, PortId('transfer'), b_chan_id)
b_chan_end = query_channel_end(c, side_b, port_id, b_chan_id)
if b_chan_end.state != 'Open':
l.error(
f'Channel end with id {b_chan_id} on chain {side_b} is not in Open state, got: {b_chan_end.state}')
Expand All @@ -475,3 +478,92 @@ def query_channel_end(c: Config, chain_id: ChainId, port: PortId, chan_id: Chann
l.debug(f'Status of channel end {chan_id}: {res}')

return res


# =============================================================================
# Passive CHANNEL relayer tests
# =============================================================================

def verify_state(c: Config,
ibc1: ChainId, ibc0: ChainId,
ibc1_chan_id: ChannelId, port_id: PortId):

strategy = toml.load(c.config_file)['global']['strategy']
# verify channel state on both chains, should be 'Open' for 'all' strategy, 'Init' otherwise

if strategy == 'all':
sleep(10.0)
for i in range(20):
sleep(2.0)
ibc1_chan_end = query_channel_end(c, ibc1, port_id, ibc1_chan_id)
ibc0_chan_id = ibc1_chan_end.remote.channel_id
ibc0_chan_end = query_channel_end(c, ibc0, port_id, ibc0_chan_id)
if ibc0_chan_end.state == 'Open' and ibc1_chan_end.state == 'Open':
break
else:
assert (ibc0_chan_end.state == 'Open'), (ibc0_chan_end, "state is not Open")
assert (ibc1_chan_end.state == 'Open'), (ibc1_chan_end, "state is not Open")

elif strategy == 'packets':
sleep(5.0)
ibc1_chan_end = query_channel_end(c, ibc1, port_id, ibc1_chan_id)
assert (ibc1_chan_end.state == 'Init'), (ibc1_chan_end, "state is not Init")


def passive_channel_start_then_init(c: Config,
ibc1: ChainId, ibc0: ChainId,
ibc1_conn_id: ConnectionId, port_id: PortId):

# 1. start hermes
proc = relayer.start(c)
sleep(2.0)

# 2. create a channel in Init state
ibc1_chan_id = chan_open_init(c, dst=ibc1, src=ibc0, dst_conn=ibc1_conn_id)

# 3. wait for channel handshake to finish and verify channel state on both chains
verify_state(c, ibc1, ibc0, ibc1_chan_id, port_id)

# 4. All good, stop the relayer
proc.kill()


def passive_channel_init_then_start(c: Config,
ibc1: ChainId, ibc0: ChainId,
ibc1_conn_id: ConnectionId, port_id: PortId):

# 1. create a channel in Init state
ibc1_chan_id = chan_open_init(c, dst=ibc1, src=ibc0, dst_conn=ibc1_conn_id)
sleep(2.0)

# 2. start relaying
proc = relayer.start(c)

# 3. wait for channel handshake to finish and verify channel state on both chains
verify_state(c, ibc1, ibc0, ibc1_chan_id, port_id)

# 4. All good, stop the relayer
proc.kill()


def passive_channel_try_then_start(c: Config,
ibc1: ChainId,
ibc0: ChainId,
ibc1_conn_id: ConnectionId,
ibc0_conn_id: ConnectionId,
port_id: PortId):

# 1. create a channel in Try state
ibc1_chan_id = chan_open_init(c, dst=ibc1, src=ibc0, dst_conn=ibc1_conn_id)
sleep(2.0)
ibc0_chan_id = chan_open_try(c, dst=ibc0, src=ibc1, dst_conn=ibc0_conn_id, src_port=port_id, dst_port=port_id, src_chan=ibc1_chan_id)
sleep(2.0)

# 2. start relaying
proc = relayer.start(c)

# 3. wait for channel handshake to finish and verify channel state on both chains
verify_state(c, ibc1, ibc0, ibc1_chan_id, port_id)

# 4. All good, stop the relayer
proc.kill()
Loading

0 comments on commit 4ab78b9

Please sign in to comment.