Skip to content

Commit

Permalink
initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
PolkachuIntern committed Aug 19, 2023
1 parent 943d36d commit 46e043e
Show file tree
Hide file tree
Showing 12 changed files with 222 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
inventory.ini
group_vars/mainnet.yml
group_vars/testnet.yml
53 changes: 51 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,52 @@
# gm-ibc
# GM IBC

Every day we wake up, you say "GM IBC".
Every day we wake up, we say "GM IBC". -Polkachu, probably

**THIS PRODUCT IS NOT READY FOR PUBLIC**

## Problem Statement

IBC is good but complex. Every relayer ends up maintaining their own infrastructure. Config file templates are shared everywhere such as GitHub Gist and Discord. There is no single point of reliable truth about canonical channels, gas prices, and various other config params. When a chain makes a change, every relayer scrabbles to update config files. Sometimes a channel can be broken for days before people realize it.

Chain Registry solves some problems, but it is not enough for IBC relayers. It is so decentralized that it is difficult to make opinionated and radical changes when situations emerge. It is maintained as many json files and updated via PRs. It is fully transparency, but can be at times brittle.

## What's GM-IBC?

GM IBC is to maintain a source of truth for IBC with an opinionated and centralized design. We will be inferior to Chain Registry when if you value openness and community participation, but we will make it up by offering better tools to make relayer's life easier. We dog-food these tools ourselves so it is a worthwhile effort even if we are the only users.

- A public API endpoint to fetch all IBC config data
- An open-sourced Ansible playbook to use the API data to compose and deploy a Hermes relayer in a few seconds.
- A frontend tool to help a relayer to generate Hermes config snippets on the fly.

## Design Philosophy

1. Support Hermes relayer only for now
1. Decouple data and config template
1. Data is stored in a structured database
1. Keep config template extremely simple but compose the Hermes config file with remote API data
1. API data can be called by any relayers regardless whether they choose to use Polkachu playbook
1. Offer a frontend tool for relayer to generate one-off config snippets manually

## How it works

First, copy inventory file and customize to suit your need.

```bash
cp inventory.ini.sample inventory.ini
```

Second copy mainnet group_vars file and customize to suit your need

```bash
cp group_vars/sample.yml group_vars/mainnet.yml
```

Finally run the playbook. If you make some minimum changes to the config files, you should have a relayer between CosmosHub and Osmosis running now.

```bash
ansible-playbook main.yml -e "target=mainnet"
```

# Conclusion

GM, IBC!
2 changes: 2 additions & 0 deletions ansible.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[defaults]
inventory=inventory.ini
Empty file added group_vars/all.yml
Empty file.
12 changes: 12 additions & 0 deletions group_vars/sample.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
hermes_directory: '.hermes'
rest_port: 3001
telemetry_port: 4001
chains_api: https://polkachu.com/api/v1/chains_test
routes:
- chain: cosmos
ip: 'YOUR IP'
connections: ['osmosis']
- chain: osmosis
ip: 'YOUR IP'
connections: ['cosmos']
11 changes: 11 additions & 0 deletions inventory.ini.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[relayer]
10.0.0.1

[all:vars]
ansible_user=ubuntu
ansible_port=22
ansible_ssh_private_key_file="~/.ssh/id_rsa"
user_dir="/home/{{ansible_user}}"

key_name="relayer"
memo='Relayed by Polkachu'
8 changes: 8 additions & 0 deletions main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: Main
hosts: 'relayer'
gather_facts: false
vars_files:
- 'group_vars/{{ target }}.yml'
roles:
- hermes
51 changes: 51 additions & 0 deletions roles/hermes/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
- name: make hermes dir
file:
path: '/home/{{ ansible_user }}/{{ hermes_directory }}/'
owner: '{{ ansible_user }}'
group: '{{ ansible_user }}'
state: directory

- name: Get the chain data
uri:
url: '{{ chains_api }}'
status_code: 200
body_format: json
register: chains_data

- name: Parse the chain data and set fact
set_fact:
chains: '{{ chains_data.json }}'

- name: Copy hermes config script with customization
template:
src: '{{ target }}.toml.j2'
dest: '/home/{{ ansible_user }}/{{ hermes_directory }}/{{ target }}.toml'
owner: '{{ ansible_user }}'
group: '{{ ansible_user }}'
mode: '0644'

- name: create hermes systemd unit
become: true
template:
src: 'hermes.service.j2'
dest: '/etc/systemd/system/hermes_{{ target }}.service'
owner: root
group: root
mode: '644'

- name: Open hermes telemetry port
become: true
ufw:
rule: allow
proto: tcp
port: '{{ telemetry_port }}'

- name: start hermes service
become: true
systemd:
name: 'hermes_{{ target }}'
state: restarted
daemon_reload: yes
enabled: yes
changed_when: false
33 changes: 33 additions & 0 deletions roles/hermes/templates/chain.toml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

[[chains]]
id = "{{ chain['chain_id'] }}"
rpc_addr = "http://{{ route['ip'] }}:{{ chain['port_prefix'] }}57"
grpc_addr = "http://{{ route['ip'] }}:{{ chain['port_prefix'] }}90"
event_source = { mode = 'push', url = "ws://{{ route['ip'] }}:{{ chain['port_prefix'] }}57/websocket", batch_delay = '500ms' }

rpc_timeout = "20s"
account_prefix = "{{ chain['account_prefix'] }}"
key_name = "{{ key_name }}"
address_type = { derivation = "cosmos" }
store_prefix = "ibc"
default_gas = {{ chain['default_gas'] }}
max_gas = {{ chain['max_gas'] }}
gas_multiplier = {{ chain['gas_multiplier'] }}
gas_price = { price = {{ chain['gas_price'] }}, denom = "{{ chain['denom'] }}" }
max_msg_num = 30
max_tx_size = 1800000
clock_drift = "15s"
max_block_time = "10s"
trusting_period = "{{ chain['trusting_period'] }}"
memo_prefix = "{{ memo }}"
trust_threshold = { numerator = '1', denominator = '3' }

[chains.packet_filter]
policy = 'allow'
list = [
{% for channel in chain['channels'] %}
{% if channel['dest'] in route['connections'] %}
['{{ channel['port'] }}', '{{ channel['channel'] }}'], {{ "#" }} {{ channel['dest'] }}
{% endif %}
{% endfor %}
]
30 changes: 30 additions & 0 deletions roles/hermes/templates/header.toml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[global]
log_level = 'info'

[mode]
[mode.clients]
enabled = true
refresh = true
misbehaviour = false

[mode.connections]
enabled = true

[mode.channels]
enabled = true

[mode.packets]
enabled = true
clear_interval = 200
clear_on_start = true
tx_confirmation = true

[rest]
enabled = true
host = '0.0.0.0'
port = {{ rest_port }}

[telemetry]
enabled = true
host = '0.0.0.0'
port = {{ telemetry_port }}
12 changes: 12 additions & 0 deletions roles/hermes/templates/hermes.service.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Description=Hermes IBC relayer for {{ target }}
After=network.target

[Service]
Type=simple
User={{ ansible_user }}
ExecStart=/usr/local/bin/hermes --config /home/{{ ansible_user }}/{{ hermes_directory }}/{{ target }}.toml start
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
9 changes: 9 additions & 0 deletions roles/hermes/templates/mainnet.toml.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% include 'header.toml.j2' %}

{%- for route in routes %}
{%- for chain in chains %}
{%- if chain['network'] == route['chain'] %}
{%- include 'chain.toml.j2' %}
{%- endif %}
{%- endfor %}
{%- endfor %}

0 comments on commit 46e043e

Please sign in to comment.