Rewrote ibc guide for basecli and relay
This commit is contained in:
parent
9bb3493f78
commit
0b7b639c58
|
@ -23,6 +23,8 @@ BREAKING CHANGES:
|
||||||
- enhanced relay subcommand
|
- enhanced relay subcommand
|
||||||
- relay start did what relay used to do
|
- relay start did what relay used to do
|
||||||
- relay init registers both chains on one another (to set it up so relay start just works)
|
- relay init registers both chains on one another (to set it up so relay start just works)
|
||||||
|
- docs
|
||||||
|
- removed `example-plugin`, put `counter` inside `docs/guide`
|
||||||
|
|
||||||
ENHANCEMENTS:
|
ENHANCEMENTS:
|
||||||
- intergrates tendermint 0.10.0 (not the rc-2, but the real thing)
|
- intergrates tendermint 0.10.0 (not the rc-2, but the real thing)
|
||||||
|
@ -33,6 +35,7 @@ ENHANCEMENTS:
|
||||||
|
|
||||||
BUG FIXES:
|
BUG FIXES:
|
||||||
- no longer panics on missing app_options in genesis (thanks, anton)
|
- no longer panics on missing app_options in genesis (thanks, anton)
|
||||||
|
- updated all docs... again
|
||||||
|
|
||||||
|
|
||||||
## 0.5.2 (June 2, 2017)
|
## 0.5.2 (June 2, 2017)
|
||||||
|
|
|
@ -158,6 +158,22 @@ the key and value are contained in the Merkle tree.
|
||||||
|
|
||||||
The results of a query can thus be used as proof in an `IBCPacketPostTx`.
|
The results of a query can thus be used as proof in an `IBCPacketPostTx`.
|
||||||
|
|
||||||
|
## Relay
|
||||||
|
|
||||||
|
While we need all these packet types internally to keep track of all the
|
||||||
|
proofs on both chains in a secure manner, for the normal work-flow, where
|
||||||
|
we just use the FIFO queue on each side for pending message to send as soon
|
||||||
|
as possible.
|
||||||
|
|
||||||
|
In this case, there are only two steps. First `basecoin relay init`,
|
||||||
|
which must be run once to register each chain with the other one,
|
||||||
|
and make sure they are ready to send and recieve. And then
|
||||||
|
`basecoin relay start`, which is a long-running process polling the queue
|
||||||
|
on each side, and relaying all new message to the other block.
|
||||||
|
|
||||||
|
This requires that the relay has access to accounts with some funds on both
|
||||||
|
chains to pay for all the ibc packets it will be forwarding.
|
||||||
|
|
||||||
## Try it out
|
## Try it out
|
||||||
|
|
||||||
Now that we have all the background knowledge, let's actually walk through the
|
Now that we have all the background knowledge, let's actually walk through the
|
||||||
|
@ -173,116 +189,197 @@ comes with an `IBC` plugin enabled by default.
|
||||||
You will also want to install the [jq](https://stedolan.github.io/jq/) for
|
You will also want to install the [jq](https://stedolan.github.io/jq/) for
|
||||||
handling JSON at the command line.
|
handling JSON at the command line.
|
||||||
|
|
||||||
Now let's start the two blockchains. In this tutorial, each chain will have
|
If you have any trouble with this, you can also look at the
|
||||||
only a single validator, where the initial configuration files are already
|
[test scripts](/tests/cli/ibc.sh) or just run `make test_cli` in basecoin repo.
|
||||||
generated. Let's change directory so these files are easily accessible:
|
Otherwise, open up 5 (yes 5!) terminal tabs....
|
||||||
|
|
||||||
``` cd $GOPATH/src/github.com/tendermint/basecoin/demo ```
|
### Setup Chain 1
|
||||||
|
|
||||||
The relevant data is now in the `data` directory. Before we begin, let's set
|
All commands will be prefixed by the name of the terminal window in which to
|
||||||
some environment variables for convenience:
|
run it...
|
||||||
|
|
||||||
``` export BCHOME="." BCHOME1="./data/chain1" BCHOME2="./data/chain2"
|
|
||||||
|
|
||||||
export CHAIN_ID1=test_chain_1 export CHAIN_ID2=test_chain_2
|
|
||||||
|
|
||||||
CHAIN_FLAGS1="--chain_id $CHAIN_ID1 --from $BCHOME1/key.json"
|
|
||||||
CHAIN_FLAGS2="--chain_id $CHAIN_ID2 --from $BCHOME2/key.json --node
|
|
||||||
tcp://localhost:36657" ```
|
|
||||||
|
|
||||||
In previous examples, we started basecoin in-process with tendermint. Here, we
|
|
||||||
will run them in different processes, using the `--without-tendermint` flag, as
|
|
||||||
described in the [guide to the basecoin tool](basecoin-tool.md). We can start
|
|
||||||
the two chains as follows:
|
|
||||||
|
|
||||||
``` TMROOT=$BCHOME1 tendermint node --log_level=info &> chain1_tendermint.log &
|
|
||||||
BCHOME=$BCHOME1 basecoin start --without-tendermint &> chain1_basecoin.log &
|
|
||||||
```
|
|
||||||
|
|
||||||
and
|
|
||||||
|
|
||||||
``` TMROOT=$BCHOME2 tendermint node --log_level=info --node_laddr
|
|
||||||
tcp://localhost:36656 --rpc_laddr tcp://localhost:36657 --proxy_app
|
|
||||||
tcp://localhost:36658 &> chain2_tendermint.log & BCHOME=$BCHOME2 basecoin start
|
|
||||||
--address tcp://localhost:36658 --without-tendermint &> chain2_basecoin.log &
|
|
||||||
```
|
|
||||||
|
|
||||||
Note how we refer to the relevant data directories, and how we set the various
|
|
||||||
addresses for the second node so as not to conflict with the first.
|
|
||||||
|
|
||||||
We can now check on the status of the two chains:
|
|
||||||
|
|
||||||
``` curl localhost:46657/status curl localhost:36657/status ```
|
|
||||||
|
|
||||||
If either command fails, the nodes may not have finished starting up. Wait a
|
|
||||||
couple seconds and try again. Once you see the status of both chains, it's
|
|
||||||
time to move on.
|
|
||||||
|
|
||||||
In this tutorial, we're going to send some data from `test_chain_1` to
|
|
||||||
`test_chain_2`. We begin by registering `test_chain_1` on `test_chain_2`:
|
|
||||||
|
|
||||||
``` basecoin tx ibc --amount 10mycoin $CHAIN_FLAGS2 register --ibc_chain_id
|
|
||||||
$CHAIN_ID1 --genesis $BCHOME1/genesis.json ```
|
|
||||||
|
|
||||||
Now we can create the outgoing packet on `test_chain_1`:
|
|
||||||
|
|
||||||
``` basecoin tx ibc --amount 10mycoin $CHAIN_FLAGS1 packet create --ibc_from
|
|
||||||
$CHAIN_ID1 --to $CHAIN_ID2 --type coin --payload 0xDEADBEEF --ibc_sequence 1
|
|
||||||
```
|
|
||||||
|
|
||||||
Note our payload is just `DEADBEEF`. Now that the packet is committed in the
|
|
||||||
chain, let's get some proof by querying:
|
|
||||||
|
|
||||||
``` QUERY=$(basecoin query ibc,egress,$CHAIN_ID1,$CHAIN_ID2,1) echo $QUERY ```
|
|
||||||
|
|
||||||
The result contains the latest height, a value (i.e. the hex-encoded binary
|
|
||||||
serialization of our packet), and a proof (i.e. hex-encoded binary
|
|
||||||
serialization of a list of nodes from the Merkle tree) that the value is in the
|
|
||||||
Merkle tree. We keep the result in the `QUERY` variable so we can easily
|
|
||||||
reference subfields using the `jq` tool.
|
|
||||||
|
|
||||||
If we want to send this data to `test_chain_2`, we first have to update what it
|
|
||||||
knows about `test_chain_1`. We'll need a recent block header and a set of
|
|
||||||
commit signatures. Fortunately, we can get them with the `block` command:
|
|
||||||
|
|
||||||
``` BLOCK=$(basecoin block $(echo $QUERY | jq .height)) echo $BLOCK ```
|
|
||||||
|
|
||||||
Here, we are passing `basecoin block` the `height` from our earlier query.
|
|
||||||
Note the result contains both a hex-encoded and json-encoded version of the
|
|
||||||
header and the commit. The former is used as input for later commands; the
|
|
||||||
latter is human-readable, so you know what's going on!
|
|
||||||
|
|
||||||
Let's send this updated information about `test_chain_1` to `test_chain_2`.
|
|
||||||
First, output the header and commit for reference:
|
|
||||||
|
|
||||||
``` echo $BLOCK | jq .hex.header echo $BLOCK | jq .hex.commit ```
|
|
||||||
|
|
||||||
And now forward those values to `test_chain_2`:
|
|
||||||
|
|
||||||
``` basecoin tx ibc --amount 10mycoin $CHAIN_FLAGS2 update --header 0x<header>
|
|
||||||
--commit 0x<commit> ```
|
|
||||||
|
|
||||||
Now that `test_chain_2` knows about some recent state of `test_chain_1`, we can
|
|
||||||
post the packet to `test_chain_2`, along with proof the packet was committed on
|
|
||||||
`test_chain_1`. Since `test_chain_2` knows about some recent state of
|
|
||||||
`test_chain_1`, it will be able to verify the proof!
|
|
||||||
|
|
||||||
First, output the height, packet, and proof for reference:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
echo $QUERY | jq .height
|
# first, clean up any old garbage for a fresh slate...
|
||||||
echo $QUERY | jq .value
|
rm -rf ~/.ibcdemo/
|
||||||
echo $QUERY | jq .proof
|
|
||||||
```
|
```
|
||||||
|
|
||||||
And forward those values to `test_chain_2`:
|
Set up some accounts so we can init everything nicely:
|
||||||
|
|
||||||
|
**Client1**
|
||||||
```
|
```
|
||||||
basecoin tx ibc --amount=10mycoin $CHAIN_FLAGS2 packet post --ibc_from $CHAIN_ID1 --height <height> --packet 0x<packet> --proof 0x<proof>
|
export BCHOME=~/.ibcdemo/chain1/client
|
||||||
|
CHAIN_ID=test-chain-1
|
||||||
|
PORT=12347
|
||||||
|
basecli keys new money
|
||||||
|
basecli keys new gotnone
|
||||||
```
|
```
|
||||||
|
|
||||||
If the command does not return an error, then we have successfuly transfered
|
Prepare the genesis block and start the server:
|
||||||
data from `test_chain_1` to `test_chain_2`. Tada!
|
|
||||||
|
**Server1**
|
||||||
|
```
|
||||||
|
# set up the directory, chainid and port of this chain...
|
||||||
|
export BCHOME=~/.ibcdemo/chain1/server
|
||||||
|
CHAIN_ID=test-chain-1
|
||||||
|
PREFIX=1234
|
||||||
|
basecoin init
|
||||||
|
|
||||||
|
GENKEY=`basecli keys get money -o json --home=$HOME/.ibcdemo/chain1/client | jq .pubkey.data`
|
||||||
|
GENJSON=`cat $BCHOME/genesis.json`
|
||||||
|
echo $GENJSON | jq '.app_options.accounts[0].pub_key.data='$GENKEY | jq ".chain_id=\"$CHAIN_ID\"" > $BCHOME/genesis.json
|
||||||
|
|
||||||
|
sed -ie "s/4665/$PREFIX/" $BCHOME/config.toml
|
||||||
|
|
||||||
|
basecoin start
|
||||||
|
```
|
||||||
|
|
||||||
|
Attach the client to the chain and confirm state. The first account should
|
||||||
|
have money, the second none:
|
||||||
|
|
||||||
|
**Client1**
|
||||||
|
```
|
||||||
|
basecli init --chain-id=${CHAIN_ID} --node=tcp://localhost:${PORT}
|
||||||
|
ME=`basecli keys get money -o=json | jq .address | tr -d '"'`
|
||||||
|
YOU=`basecli keys get gotnone -o=json | jq .address | tr -d '"'`
|
||||||
|
basecli query account $ME
|
||||||
|
basecli query account $YOU
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setup Chain 2
|
||||||
|
|
||||||
|
This is the same as above, except in two new terminal windows with
|
||||||
|
different chain ids, ports, etc. Note that you need to make new accounts
|
||||||
|
on this chain, as the "cool" key only has money on chain 1.
|
||||||
|
|
||||||
|
|
||||||
|
**Client2**
|
||||||
|
```
|
||||||
|
export BCHOME=~/.ibcdemo/chain2/client
|
||||||
|
CHAIN_ID=test-chain-2
|
||||||
|
PORT=23457
|
||||||
|
basecli keys new moremoney
|
||||||
|
basecli keys new broke
|
||||||
|
```
|
||||||
|
|
||||||
|
Prepare the genesis block and start the server:
|
||||||
|
|
||||||
|
**Server2**
|
||||||
|
```
|
||||||
|
# set up the directory, chainid and port of this chain...
|
||||||
|
export BCHOME=~/.ibcdemo/chain2/server
|
||||||
|
CHAIN_ID=test-chain-2
|
||||||
|
PREFIX=2345
|
||||||
|
basecoin init
|
||||||
|
|
||||||
|
|
||||||
|
GENKEY=`basecli keys get moremoney -o json --home=$HOME/.ibcdemo/chain2/client | jq .pubkey.data`
|
||||||
|
GENJSON=`cat $BCHOME/genesis.json`
|
||||||
|
echo $GENJSON | jq '.app_options.accounts[0].pub_key.data='$GENKEY | jq ".chain_id=\"$CHAIN_ID\"" > $BCHOME/genesis.json
|
||||||
|
|
||||||
|
sed -ie "s/4665/$PREFIX/" $BCHOME/config.toml
|
||||||
|
|
||||||
|
basecoin start
|
||||||
|
```
|
||||||
|
|
||||||
|
Attach the client to the chain and confirm state. The first account should
|
||||||
|
have money, the second none:
|
||||||
|
|
||||||
|
**Client2**
|
||||||
|
```
|
||||||
|
basecli init --chain-id=${CHAIN_ID} --node=tcp://localhost:${PORT}
|
||||||
|
ME=`basecli keys get moremoney -o=json | jq .address | tr -d '"'`
|
||||||
|
YOU=`basecli keys get broke -o=json | jq .address | tr -d '"'`
|
||||||
|
basecli query account $ME
|
||||||
|
basecli query account $YOU
|
||||||
|
```
|
||||||
|
|
||||||
|
### Connect these chains
|
||||||
|
|
||||||
|
Great, so we have two chains running on your local machine, with different
|
||||||
|
keys on each. Now it is time to hook them up together. Let's start
|
||||||
|
a relay to forward the messages.
|
||||||
|
|
||||||
|
The relay account needs some money in it to pay for the ibc messages, so
|
||||||
|
for now, we have to transfer some cash from the rich accounts before we start
|
||||||
|
the actual relay.
|
||||||
|
|
||||||
|
**Client1**
|
||||||
|
```
|
||||||
|
# note that this key.json file is a hardcoded demo for all chains, this will
|
||||||
|
# be updated in a future release
|
||||||
|
RELAY_KEY=${BCHOME}/../server/key.json
|
||||||
|
RELAY_ADDR=$(cat $RELAY_KEY | jq .address | tr -d \")
|
||||||
|
basecli tx send --amount=100000mycoin --sequence=1 --to=$RELAY_ADDR --name=money
|
||||||
|
basecli query account $RELAY_ADDR
|
||||||
|
```
|
||||||
|
|
||||||
|
**Client2**
|
||||||
|
```
|
||||||
|
# note that this key.json file is a hardcoded demo for all chains, this will
|
||||||
|
# be updated in a future release
|
||||||
|
RELAY_KEY=${BCHOME}/../server/key.json
|
||||||
|
RELAY_ADDR=$(cat $RELAY_KEY | jq .address | tr -d \")
|
||||||
|
basecli tx send --amount=100000mycoin --sequence=1 --to=$RELAY_ADDR --name=moremoney
|
||||||
|
basecli query account $RELAY_ADDR
|
||||||
|
```
|
||||||
|
|
||||||
|
**Relay**
|
||||||
|
```
|
||||||
|
# lots of config...
|
||||||
|
SERVER_1=~/.ibcdemo/chain1/server
|
||||||
|
SERVER_2=~/.ibcdemo/chain2/server
|
||||||
|
CHAIN_ID_1=test-chain-1
|
||||||
|
CHAIN_ID_2=test-chain-2
|
||||||
|
PORT_1=12347
|
||||||
|
PORT_2=23457
|
||||||
|
RELAY_KEY=${SERVER_1}/key.json
|
||||||
|
|
||||||
|
basecoin relay init --chain1-id=$CHAIN_ID_1 --chain2-id=$CHAIN_ID_2 \
|
||||||
|
--chain1-addr=tcp://localhost:${PORT_1} --chain2-addr=tcp://localhost:${PORT_2} \
|
||||||
|
--genesis1=${SERVER_1}/genesis.json --genesis2=${SERVER_2}/genesis.json \
|
||||||
|
--from=$RELAY_KEY
|
||||||
|
|
||||||
|
basecoin relay start --chain1-id=$CHAIN_ID_1 --chain2-id=$CHAIN_ID_2 \
|
||||||
|
--chain1-addr=tcp://localhost:${PORT_1} --chain2-addr=tcp://localhost:${PORT_2} \
|
||||||
|
--from=$RELAY_KEY
|
||||||
|
```
|
||||||
|
|
||||||
|
This should start up the relay, and assuming no error messages came out,
|
||||||
|
the two chains are now fully connected over IBC. Let's use this to send
|
||||||
|
our first tx accross the chains...
|
||||||
|
|
||||||
|
### Sending cross-chain payments
|
||||||
|
|
||||||
|
The hard part is over, we set up two blockchains, a few private keys, and
|
||||||
|
a secure relay between them. Now we can enjoy the fruits of our labor...
|
||||||
|
|
||||||
|
**Client2**
|
||||||
|
|
||||||
|
```
|
||||||
|
# this should be empty
|
||||||
|
basecli query account $YOU
|
||||||
|
# now, we get the key to copy to the other terminal
|
||||||
|
echo $YOU
|
||||||
|
```
|
||||||
|
|
||||||
|
**Client1**
|
||||||
|
|
||||||
|
```
|
||||||
|
# set TARGET to be $YOU from the other chain
|
||||||
|
basecli tx send --amount=12345mycoin --sequence=2 --to=test-chain-2/$TARGET --name=money
|
||||||
|
```
|
||||||
|
|
||||||
|
**Client2**
|
||||||
|
|
||||||
|
```
|
||||||
|
# give it time to arrive...
|
||||||
|
sleep 1
|
||||||
|
# now you should see 12345 coins!
|
||||||
|
basecli query account $YOU
|
||||||
|
```
|
||||||
|
|
||||||
|
Cool, huh? Now have fun exploring and sending coins across the chains. And
|
||||||
|
making more accounts as you want to.
|
||||||
|
|
||||||
## Conclusion
|
## Conclusion
|
||||||
|
|
||||||
|
|
|
@ -157,13 +157,13 @@ startRelay() {
|
||||||
${SERVER_EXE} relay init --chain1-id=$CHAIN_ID_1 --chain2-id=$CHAIN_ID_2 \
|
${SERVER_EXE} relay init --chain1-id=$CHAIN_ID_1 --chain2-id=$CHAIN_ID_2 \
|
||||||
--chain1-addr=tcp://localhost:${PORT_1} --chain2-addr=tcp://localhost:${PORT_2} \
|
--chain1-addr=tcp://localhost:${PORT_1} --chain2-addr=tcp://localhost:${PORT_2} \
|
||||||
--genesis1=${BASE_DIR_1}/server/genesis.json --genesis2=${BASE_DIR_2}/server/genesis.json \
|
--genesis1=${BASE_DIR_1}/server/genesis.json --genesis2=${BASE_DIR_2}/server/genesis.json \
|
||||||
--from=$RELAY_KEY > ${BASE_DIR_1}/../relay.log &
|
--from=$RELAY_KEY > ${BASE_DIR_1}/../relay.log
|
||||||
if [ $? != 0 ]; then echo "can't initialize relays"; cat ${BASE_DIR_1}/../relay.log; return 1; fi
|
if [ $? != 0 ]; then echo "can't initialize relays"; cat ${BASE_DIR_1}/../relay.log; return 1; fi
|
||||||
|
|
||||||
# now start the relay (constantly send packets)
|
# now start the relay (constantly send packets)
|
||||||
${SERVER_EXE} relay start --chain1-id=$CHAIN_ID_1 --chain2-id=$CHAIN_ID_2 \
|
${SERVER_EXE} relay start --chain1-id=$CHAIN_ID_1 --chain2-id=$CHAIN_ID_2 \
|
||||||
--chain1-addr=tcp://localhost:${PORT_1} --chain2-addr=tcp://localhost:${PORT_2} \
|
--chain1-addr=tcp://localhost:${PORT_1} --chain2-addr=tcp://localhost:${PORT_2} \
|
||||||
--from=$RELAY_KEY > ${BASE_DIR_1}/../relay.log &
|
--from=$RELAY_KEY >> ${BASE_DIR_1}/../relay.log &
|
||||||
sleep 2
|
sleep 2
|
||||||
PID_RELAY=$!
|
PID_RELAY=$!
|
||||||
disown
|
disown
|
||||||
|
|
Loading…
Reference in New Issue