owned this note
owned this note
Published
Linked with GitHub
# Agoric ↔ Pooltoy IBC Testnet [WIP]
## Hardware Requirements
Two new virtual machines are required in order to create a validator node for the Agoric Devnet and a Hermes Relayer to enable interoperability with the existing Pooltoy application.
VMs can be hosted via DigitalOcean Droplets. The following specifications are recommended:
- 2vCPU
- 4GB Memory
- 80GB SSD Storage
- Region AMS3
**NOTE:** Region AMS3 is not a requirement however to make use of an existing VPC network this was chosen.
## Agoric Validator Guide for Devnet
https://github.com/Agoric/agoric-sdk/wiki/Validator-Guide-for-Devnet
Following the documentation above an Agoric Validator node can be created and synced with the network. The link provides extensive steps on configuring a system with all prerequisite dependencies required to get up and running.
**Caveat**: When running the `create-validator` transaction command the `--pubkey` option arg should be replaced with `$(ag-chain-cosmos tendermint show-validator)`
For example:
```
# Set the chainName value
chainName=`curl https://devnet.agoric.net/network-config | jq -r .chainName`
ag-cosmos-helper tx staking create-validator \
--amount=50000000ubld \
--broadcast-mode=block \
--pubkey=$(ag-chain-cosmos tendermint show-validator) \
--moniker=ibc-dev-sandbox \
--commission-rate="0.10" \
--commission-max-rate="0.20" \
--commission-max-change-rate="0.01" \
--min-self-delegation="1" \
--from=ibc-dev-sandbox \
--chain-id=$chainName \
--gas=auto \
--gas-adjustment=1.4
```
#### Exposing RPC endpoints for Relayers
Open and edit the application `config.toml` for `agoricdev-3` and update the RPC listen address from `127.0.0.1:26657` to `0.0.0.0:26657`.
The `config.toml` can be found at the following path:
`~/.ag-chain-cosmos/config/config.toml`
This can also be achieved with the following `sed` command.
```
sed -i -e 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ~/.ag-chain-cosmos/config/config.toml
```
#### Streaming logs
```
journalctl -f -u ag-chain-cosmos.service
```
## Hermes Relayer
### Prerequisites
Here you can find installation instructions to prepare your DigitalOcean Droplet for the Hermes Relayer.
#### Install Rust
Following the [official Rust documentation](https://www.rust-lang.org/tools/install) install Rust using `rustup`.
```
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
#### Install other dependencies
A number of other dependencies are required in order to build and install the Hermes Relayer. For example, a C linker is required for some dependencies of Hermes which can be obtained via `build-essentials` on Ubuntu 20.04.
```
sudo apt install build-essentials libssl-dev pkg-config
```
#### Install Hermes via Cargo
Here you can install the Hermes Relayer using `cargo`, the default Rust package manager.
```
cargo install ibc-relayer-cli --bin hermes --locked
```
#### Install specific version of Hermes from source
**NOTE:** When using the latest version of Hermes: `v0.7.0`, a number of warning logs are displayed, expressing potential compatibility issues with Cosmos SDK versions.
This can be avoided by using an older version of Hermes.
Build from source by cloning the repository and checking out your desired release version.
```
git clone https://github.com/informalsystems/ibc-rs && cd ibc-rs/relayer-cli
git checkout v0.5.0
cargo build
```
It may be desirable to create an alias for alternative binaries, for example: `hermesv0.5.0`
### Configuring Hermes
Some intro words...
[Hermes](https://hermes.informal.systems/) is a Rust implementation of a relayer for the [Inter-Blockchain Communication (IBC)](https://ibcprotocol.org/) protocol.
> The Inter-Blockchain Communication protocol is an end-to-end, connection-oriented, stateful protocol for reliable, ordered, and authenticated communication between modules on separate distributed ledgers.
In order to establish connectivity between two different blockchains or zones we must first restore keys for wallets on both networks. Any wallet can be used as long as it contains sufficient funds.
#### Restoring Keys
In order to restore keys for Agoric wallets a key derivation path option must be specified when using Hermes. This can be done using `-p` or `--hd-path` flag with Hermes in the format: `m/44'/118'/0'/0/0`
##### Key Derivation Paths
As specified in [BIP-44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) an appropriate Key Derivation Path must be used in order to reproduce a deterministic HD wallet address.
The following format is employed:
```
m / purpose' / coin_type' / account' / change / address_index
```
[Click here for a synopsis](https://ethereum.stackexchange.com/a/70029)
The Agoric network uses a CoinType of `564` whereas above, the default being used by Hermes is `118` (atom).
For a detailed list of CoinType: [SLIP-0044 : Registered coin types for BIP-0044
](https://github.com/satoshilabs/slips/blob/master/slip-0044.md)
Restore keys for relayer wallet on `agoricdev-3`:
```
hermes keys restore agoricdev-3 -p "m/44'/564'/0'/0/0" -m $MNEMONIC
```
Restore keys for relayer wallet on `pooltoy-6`:
```
hermes keys restore pooltoy-6 -m $MNEMONIC
```
Hermes Configuration:
*Note the use of private IP addresses for connectivity as all nodes are in the `default-ams3` VPC.*
```
[global]
strategy = 'all'
filter = false
log_level = 'trace'
clear_packets_interval = 100
[telemetry]
enabled = false
host = '127.0.0.1'
port = 3001
[[chains]]
id = 'agoricdev-3'
rpc_addr = 'http://10.110.0.3:26657'
grpc_addr = 'http://10.110.0.3:9090'
websocket_addr = 'ws://10.110.0.3:26657/websocket'
rpc_timeout = '10s'
account_prefix = 'agoric'
key_name = 'testkey'
store_prefix = 'ibc'
max_gas = 3000000
gas_price = { price = 0.001, denom = 'urun' }
gas_adjustment = 0.1
clock_drift = '5s'
trusting_period = '14days'
[chains.trust_threshold]
numerator = '1'
denominator = '3'
[[chains]]
id = 'pooltoy-6'
rpc_addr = 'http://10.110.0.2:26657'
grpc_addr = 'http://10.110.0.2:9090'
websocket_addr = 'ws://10.110.0.2:26657/websocket'
rpc_timeout = '10s'
account_prefix = 'cosmos'
key_name = 'testkey'
store_prefix = 'ibc'
max_gas = 3000000
gas_price = { price = 0.001, denom = 'stake' }
gas_adjustment = 0.1
clock_drift = '5s'
trusting_period = '14days'
[chains.trust_threshold]
numerator = '1'
denominator = '3'
```
### Clients, Connections & Channels - Enabling IBC
In order to enable IBC transfer functionality between two chains we must create the associated IBC entities that enable the protocol semantics of the IBC transport authetication and ordering layer (TAO), and subsequently enable the transfer application via it's associated port identifier.
[Read more about the IBC protocol specification](https://github.com/cosmos/ibc)
- Creation of IBC clients, for example: [Tendermint Lightclient](https://medium.com/tendermint/everything-you-need-to-know-about-the-tendermint-light-client-f80d03856f98)
- Establishing IBC connections between zones
- Configuring channels with the associated port identifiers
**Caveat**: The Agoric platform provides a javascript VM for smart contracts and binds the `transfer` port identifier to a handler that uses the "Pegasus" JS transfer protocol. To enable generic IBC transfer functionality Agoric binds to `cosmos-transfer`.
[Hermes CLI Documentation](https://hermes.informal.systems/index.html)
```
# create new clients
hermesv0.5.0 create client agoricdev-3 pooltoy-6
# creates a new connection using new clients
hermesv0.5.0 create connection agoricdev-3 pooltoy-6
# creates a new connection using existing clients
hermesv0.5.0 create connection ibc-0 --client-a 07-tendermint-0 --client-b
07-tendermint-0
# create a new ics20 transfer channel to agoric using an existing connection
# note: cosmos-transfer as the port identifier
hermesv0.5.0 create channel agoricdev-3 --connection-a connection-4 --port-a cosmos-transfer --port-b transfer -o unordered -v "ics20-1"
# start hermes in the background a redirect to ~/.hermes/hermes.log
# note: would be nice to run with systemctl
hermesv0.5.0 start > ~/.hermes/hermes.log 2>&1 &
```
### IBC Transfers
```
- TODO: Add example CLI commands, transfer emojis, slackbot integration...etc
```
![](https://i.imgur.com/CjLwRVB.png)
---
### Troubleshooting Notes
Networking and dealing with pain and anguish...
When debugging gRPC connectivity grpcurl is recommended as it can be used to query the reflection service and describe available grpc endpoints:
```
grpcurl -plaintext $HOSTNAME:$PORT list
```
Exposing port 9090 for gRPC via iptables
```
iptables -A INPUT -p tcp --dport 9090 -j ACCEPT
```
---
### Current Path Topology
| Chain ID | Client ID | Connection ID | Channel ID |
| -------- | -------- | -------- | -------- |
| pooltoy-6 | 07-tendermint-2 | connection-0 | channel-1
| agoricdev-3 | 07-tendermint-4 | connection-4 | channel-4
```
Success: Channel {
ordering: Unordered,
a_side: ChannelSide {
chain: ProdChainHandle {
chain_id: ChainId {
id: "agoricdev-3",
version: 3,
},
runtime_sender: Sender { .. },
},
client_id: ClientId(
"07-tendermint-4",
),
connection_id: ConnectionId(
"connection-4",
),
port_id: PortId(
"cosmos-transfer",
),
channel_id: Some(
ChannelId(
"channel-4",
),
),
},
b_side: ChannelSide {
chain: ProdChainHandle {
chain_id: ChainId {
id: "pooltoy-6",
version: 6,
},
runtime_sender: Sender { .. },
},
client_id: ClientId(
"07-tendermint-2",
),
connection_id: ConnectionId(
"connection-0",
),
port_id: PortId(
"transfer",
),
channel_id: Some(
ChannelId(
"channel-1",
),
),
},
connection_delay: 0ns,
version: Some(
"ics20-1",
),
}
```