Skip to content

Instantly share code, notes, and snippets.

@jackzampolin
Last active November 23, 2019 20:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jackzampolin/2a7f90105fb5e778c3a3081681f10675 to your computer and use it in GitHub Desktop.
Save jackzampolin/2a7f90105fb5e778c3a3081681f10675 to your computer and use it in GitHub Desktop.
ibc-testnet-alpha
#!/bin/bash
# Create clients on two different IBC nodes
# Each chain needs to have an RPC endpoint to run transactions against
NODE0="http://34.82.17.52:26657"
NODE1="http://34.83.208.127:26657"
# Input the two chains you would like to begin connecting CHAINID0 should be "your" chain
CHAINID0="testnetibc0"
CHAINID1="testnetibc1"
# For spec compatability we will only use letter characters for some identifiers
ANCID0="ibczero"
ANCID1="ibcone"
# I've taken the naming convention "{{ .ChainID }}client" for clients. Note that the `testnetibc1client` is created on `testnetibc0`
CLIENT0="${ANCID1}client"
CLIENT1="${ANCID0}client"
# Note, the account key creating these transactions must have tokens on each chain
KEY0="jackibc0"
KEY1="jackibc0"
# Name for connection strings
CONNID0="${ANCID1}conn"
CONNID1="${ANCID0}conn"
# Name for channel strings
CHANID0="${ANCID1}chan"
CHANID1="${ANCID0}chan"
CHANTYPE="bank"
# Create testnetibc1client on testnetibc0
gaiacli tx ibc client create $CLIENT0 --chain-id $CHAINID0 --node $NODE0 $(gaiacli q ibc client node-state --node $NODE1 --chain-id $CHAINID1 -o json) --from $KEY0 -o text
# Create testnetibc0client on testnetibc1
gaiacli tx ibc client create $CLIENT1 --chain-id $CHAINID1 --node $NODE1 $(gaiacli q ibc client node-state --node $NODE0 --chain-id $CHAINID0 -o json) --from $KEY1 -o text
sleep 5
# Query clients on both nodes:
gaiacli --node $NODE0 --chain-id $CHAINID0 q ibc client consensus-state $CLIENT0 --indent
gaiacli --node $NODE1 --chain-id $CHAINID1 q ibc client consensus-state $CLIENT1 --indent
# Create the connection:
# NOTE: This command is currently broken
gaiacli \
tx ibc connection handshake \
--node $NODE0 --chain-id $CHAINID0 \
$CONNID0 $CLIENT0 $(gaiacli q ibc client path --node $NODE1 --chain-id $CHAINID1) \
$CONNID1 $CLIENT1 $(gaiacli q ibc client path --node $NODE0 --chain-id $CHAINID0) \
--chain-id2 $CHAINID1 \
--from1 $KEY0 --from2 $KEY1 \
--node1 $NODE0 \
--node2 $NODE1
# Query the connetion from both nodes:
gaiacli --node $NODE0 q ibc connection end $CONNID0 --indent --trust-node
gaiacli --node $NODE1 q ibc connection end $CONNID1 --indent --trust-node
sleep 3
# Create the channel:
gaiacli \
tx ibc channel handshake \
--node $NODE0 --chain-id $CHAINID0 \
$CLIENT0 $CHANTYPE $CHANID0 $CONNID0 \
$CLIENT1 $CHANTYPE $CHANID1 $CONNID1 \
--node1 $NODE0 \
--node2 $NODE1 \
--chain-id2 $CHAINID1 \
--from1 $KEY0 --from2 $KEY1
# Query the channel from both nodes:
gaiacli --node $NODE0 --chain-id $CHAINID0 q ibc channel end $CHANTYPE $CHANID0 --indent --trust-node
gaiacli --node $NODE1 --chain-id $CHAINID1 q ibc channel end $CHANTYPE $CHANID1 --indent --trust-node

ibc-testnet-alpha

This is an attempt at the first IBC testnet. The goal here is to have multiple independent actors each spin up their own chain. Once this is done all the participants in the testnet should be able to connect to each other's chains. Ideally this testnet runs for around a week in initial preperation for Game of Zones. To spin up a single node chain the bootstrapping proceedure looks like the following:

NOTE: Your RPC port needs to be routable by other testnet participants. You will need to manage configuration on your cloud provider, but also be sure to change the default RPC listen in your ~/.gaiad/config/config.toml:

##### rpc server configuration options #####
[rpc]

# TCP or UNIX socket address for the RPC server to listen on
laddr = "tcp://0.0.0.0:26657"
# install golang https://golang.org/doc/install and setup gopath
# install gaia from the fedekunze/ibc branch
git clone https://github.com/cosmos/gaia
cd gaia && git checkout fedekunze/ibc
make install

# Once gaia is installed create a new chain-id
gaiad init {{ .Moniker }} --chain-id {{ .Unique.Chain-ID }}

# Create a couple of accounts on your chain
# NOTE: If you can add other testnet participant wallets to the genesis this will allow 
# them to more easily create transactions (required for connections on IBC) on your chain
gaiacli keys add validator-key
gaiacli keys add faucet
gaiad add-genesis-account validator-key 100000000stake,100000000validatortoken
gaiad add-genesis-account faucet 100000000stake,100000000faucettoken
# for other participants, see addresses in the telegram channel: 
# gaiad add-genesis-account {{ .TestnetAccount }} 1000000stake

# Create your gentx, collect the gentxs and start the chain:
gaiad gentx --name validator-key 
gaiad collect-gentxs

# Change the RPC listener to `tcp://0.0.0.0:26657`
sed -i '' 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:26657"#g' ~/.gaiad/config/config.toml

# Note its pretty easy to setup systemd to manage this: https://cosmos.network/docs/cosmos-hub/validators/validator-setup.html#problem-2-my-gaiad-crashes-because-of-too-many-open-files
gaiad start

Once you have the chain started you will need to share the following information for other users to connect to your chain via IBC. There is a spreadsheet to do so:

  1. RPC endpoint for your chain (http://{{ .IP }}:26657)
  2. --chain-id for your chain
  3. Users may need some tokens on your chain depending on --min-fees, use the faucet account to fund those user's accounts or include them in your genesis file.

Once your chain is setup you should be able to connect to the TBD chain. The following is the necessary information:

  1. RPC Endpoint: http://TBD:26657
  2. --chain-id: TBD
  3. Ping jackzampolin on telegram if you need funds on the TBD chain.

This gist also includes a couple of scripts to help setup the necessary connections and then send funds. First configure connect.sh with the details for the two chains you would like to use

Telegram coordination channel link: https://t.me/joinchat/IYdbxRRFYIkj9FR99X3-BA

# Create clients on two different IBC nodes
set -x
# Each chain needs to have an RPC endpoint to run transactions against
NODE0="http://34.82.17.52:26657"
NODE1="http://34.83.208.127:26657"
# Input the two chains you would like to begin connecting CHAINID0 should be "your" chain
CHAINID0="testnetibc0"
CHAINID1="testnetibc1"
# For spec compatability we will only use letter characters for some identifiers
ANCID0="ibczero"
ANCID1="ibcone"
# I've taken the naming convention "{{ .ChainID }}client" for clients. Note that the `testnetibc1client` is created on `testnetibc0`
CLIENT0="${ANCID1}client"
CLIENT1="${ANCID0}client"
# Note, the account key creating these transactions must have tokens on each chain
KEY0="jackibc0"
KEY1="jackibc0"
# Name for channel strings
CHANID0="${ANCID1}chan"
CHANID1="${ANCID0}chan"
CHANTYPE="bank"
# Amount to send
AMOUNT="10stake"
SEQUENCE="1"
echo "Send packets from $CHAINID0, they will need to be recieved on $CHAINID1 in another transaction"
gaiacli --node $NODE0 --chain-id $CHAINID0 tx ibc transfer transfer $CHANTYPE $CHANID0 $(gaiacli keys show $KEY0 -a) $AMOUNT --from $KEY0 --source
echo "Enter height:"
read -r HEIGHT
TIMEOUT=$(echo "$HEIGHT + 1000" | bc -l)
sleep 3
echo "Balance on $CHAINID1 before transfer:"
gaiacli --node $NODE1 --chain-id $CHAINID1 q account $(gaiacli keys show $KEY1 -a) --indent --trust-node
echo "Create transaction to recieve tokens on $CHAINID1"
gaiacli \
tx ibc transfer recv-packet \
$CHANTYPE $CHANID0 $CLIENT1 \
--node $NODE1 \
--chain-id $CHAINID1 \
--packet-sequence $SEQUENCE \
--timeout $TIMEOUT \
--from $KEY1 \
--node2 $NODE0 \
--chain-id2 $CHAINID0 \
--source
echo "Balance on $CHAINID1 after transfer:"
gaiacli --node $NODE1 --chain-id $CHAINID1 q account $(gaiacli keys show $KEY1 -a) --indent --trust-node
@cyborgshead
Copy link

@jackzampolin Hi

  1. connection handshake gives error
    ERROR: UnmarshalBinaryLengthPrefixed cannot decode empty bytes
    because ANCID is too long string and initialized from also (just put ibczero/ibcone)

  2. channel handshake gives error

  tx ibc channel handshake \ 
  --home $NODE0 --chain-id $CHAINID0 \

--home need to be --node

@jackzampolin
Copy link
Author

I've made those changes @litvintech thanks for the report! Can you try the xfer.sh script I added? Interested to see how you made that one work

@tyrion70
Copy link

ibc@ibc-test1:~$ gaiacli tx ibc channel handshake --help
initialize a connection on chain A with a given counterparty chain B:

Example:
$ gaiacli tx ibc channel handshake [client-id] [port-id] [chan-id] [conn-id] [cp-client-id] [cp-port-id] [cp-chain-id] [cp-conn-id]

In above example, cp-chain-id should actually be cp-chan-id since its the channel ID not the chain ID that is wanted here.

@xiangjianmeng
Copy link

Is the code in connect.sh OK?

CLIENT0="${ANCID1}client"
CLIENT1="${ANCID0}client"

@xiangjianmeng
Copy link

gaiacli --node $NODE0 --chain-id $CHAINID0 tx ibc transfer transfer $CHANTYPE $CHANID0 $(gaiacli keys show $KEY0 -a) $AMOUNT --from $KEY0 --source

Are there no the destination address and destination chain?

@xiangjianmeng
Copy link

gaiacli \
  tx ibc transfer recv-packet \
  $CHANTYPE $CHANID1 $CLIENT1 \
  --node $NODE1 \
  --chain-id $CHAINID1 \
  --packet-sequence $SEQUENCE \
  --timeout $TIMEOUT \
  --from $KEY1 \
  --node2 $NODE0 \
  --chain-id2 $CHAINID0 \
  --source

$CHANTYPE $CHANID1 $CLIENT1 should be $CHANTYPE $CHANID0 $CLIENT1 , $CHANID0 is the sending channel.

@jackzampolin
Copy link
Author

Thank you for the report @xiangjianmeng, I've fixed it in the instructions!!

@kphed
Copy link

kphed commented Nov 22, 2019

Update: Actually, I should take a closer look at the implementation to really contribute... since my setup does differ from the above (e.g. different machines or variable values).

Hey @jackzampolin, for the ... connection handshake command, it looks like the *-chain-1 inputs have to match the node that's initiating the connection - tested the other combinations (e.g. chain B as connection initiator + *-chain-1 inputs) and this seems to hold up (not matching = 1chain).

Use:   "handshake [conn-id-chain-1] [client-id-chain-1] [path-chain-1] [conn-id-chain-2] [client-id-chain-2] [path-chain-2] ",
gaiacli \
  tx ibc connection handshake \
  $CHAIN_A_CONN $CHAIN_A_CLIENT $(gaiacli q ibc client path --node $CHAIN_A_NODE --chain-id $CHAIN_A_CHAIN -o json) \
  $CHAIN_B_CONN $CHAIN_B_CLIENT $(gaiacli q ibc client path --node $CHAIN_B_NODE --chain-id $CHAIN_B_CHAIN -o json) \
  --node $CHAIN_A_NODE --chain-id $CHAIN_A_CHAIN \
  --chain-id2 $CHAIN_B_CHAIN \
  --from1 $CHAIN_B_KEY --from2 $CHAIN_A_KEY \
  --node1 $CHAIN_B_NODE \
  --node2 $CHAIN_A_NODE

*CHAIN_A_CLIENT is the id of a client created from chain B's consensus state (and B's client = A state).

*Edit: Corrected chain state used (e.g. CHAIN_A_CLIENT = chainB's state)

Thanks for the 🚀 guides!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment