diff --git a/modules/ibc/commands/query.go b/modules/ibc/commands/query.go index 38514d4c2e..fed670fd17 100644 --- a/modules/ibc/commands/query.go +++ b/modules/ibc/commands/query.go @@ -88,7 +88,7 @@ func ibcQueryCmd(cmd *cobra.Command, args []string) error { func chainsQueryCmd(cmd *cobra.Command, args []string) error { list := [][]byte{} - key := stack.PrefixedKey(ibc.NameIBC, ibc.HandlerKey()) + key := stack.PrefixedKey(ibc.NameIBC, ibc.ChainsKey()) proof, err := proofcmd.GetAndParseAppProof(key, &list) if err != nil { return err diff --git a/modules/ibc/handler.go b/modules/ibc/handler.go index be97ab83fc..57c7d9638e 100644 --- a/modules/ibc/handler.go +++ b/modules/ibc/handler.go @@ -145,7 +145,8 @@ func (h Handler) updateSeed(ctx basecoin.Context, store state.KVStore, t UpdateChainTx) (res basecoin.Result, err error) { chainID := t.ChainID() - if !NewChainSet(store).Exists([]byte(chainID)) { + s := NewChainSet(store) + if !s.Exists([]byte(chainID)) { return res, ErrNotRegistered(chainID) } @@ -159,7 +160,13 @@ func (h Handler) updateSeed(ctx basecoin.Context, store state.KVStore, // this will import the seed if it is valid in the current context err = cert.Update(seed.Checkpoint, seed.Validators) - return res, ErrInvalidCommit(err) + if err != nil { + return res, ErrInvalidCommit(err) + } + + // update the tracked height in chain info + err = s.Update(chainID, t.Seed.Height()) + return res, err } // createPacket makes sure all permissions are good and the destination diff --git a/modules/ibc/store.go b/modules/ibc/store.go index 17506ad65e..af5654424d 100644 --- a/modules/ibc/store.go +++ b/modules/ibc/store.go @@ -62,6 +62,27 @@ func (c ChainSet) Register(chainID string, ourHeight uint64, theirHeight int) er return nil } +// Update sets the new tracked height on this chain +// returns error if not present +func (c ChainSet) Update(chainID string, theirHeight int) error { + d := c.Set.Get([]byte(chainID)) + if len(d) == 0 { + return ErrNotRegistered(chainID) + } + // load the data + var info ChainInfo + err := wire.ReadBinaryBytes(d, &info) + if err != nil { + return err + } + + // change the remote block and save it + info.RemoteBlock = theirHeight + d = wire.BinaryBytes(info) + c.Set.Set([]byte(chainID), d) + return nil +} + // Packet is a wrapped transaction and permission that we want to // send off to another chain. type Packet struct { diff --git a/tests/cli/ibc.sh b/tests/cli/ibc.sh index 5a5c91c0db..252c297ee4 100755 --- a/tests/cli/ibc.sh +++ b/tests/cli/ibc.sh @@ -9,8 +9,8 @@ ACCOUNTS=(jae ethan bucky rigel igor) RICH=${ACCOUNTS[0]} POOR=${ACCOUNTS[4]} -# Uncomment the following line for full stack traces in error output -# CLIENT_EXE="basecli --trace" +# For full stack traces in error output, run +# BC_TRACE=1 ./ibc.sh oneTimeSetUp() { # These are passed in as args @@ -99,6 +99,8 @@ test01RegisterChains() { txSucceeded $? "$TX" "register chain2 on chain 1" # an example to quit early if there is no point in more tests if [ $? != 0 ]; then echo "aborting!"; return 1; fi + # this is used later to check data + REG_HEIGHT=$(echo $TX | jq .height) # register chain1 on chain2 (no money needed... yet) TX=$(echo qwertyuiop | ${CLIENT_EXE} tx ibc-register \ @@ -122,6 +124,9 @@ test02UpdateChains() { ${CLIENT_EXE} seeds export $UPDATE_2 --home=${CLIENT_2} assertTrue "line=${LINENO}, export seed failed" $? assertNewHeight "line=${LINENO}" $ROOT_2 $UPDATE_2 + # this is used later to check query data + REGISTER_2_HEIGHT=$(cat $ROOT_2 | jq .checkpoint.header.height) + UPDATE_2_HEIGHT=$(cat $UPDATE_2 | jq .checkpoint.header.height) # update chain2 on chain1 TX=$(echo qwertyuiop | ${CLIENT_EXE} tx ibc-update \ @@ -138,8 +143,23 @@ test02UpdateChains() { if [ $? != 0 ]; then echo "aborting!"; return 1; fi } +# make sure all query commands about ibc work... test03QueryIBC() { + # just test on one chain, as they are all symetrical + export BC_HOME=${CLIENT_1} + # make sure we can list all chains + CHAINS=$(${CLIENT_EXE} query ibc chains) + assertTrue "line=${LINENO}, cannot query chains" $? + assertEquals "1" $(echo $CHAINS | jq '.data | length') + assertEquals "line=${LINENO}" "\"$CHAIN_ID_2\"" $(echo $CHAINS | jq '.data[0]') + + # error on unknown chain, data on proper chain + assertFalse "line=${LINENO}, unknown chain" "${CLIENT_EXE} query ibc chain random 2>/dev/null" + CHAIN_INFO=$(${CLIENT_EXE} query ibc chain $CHAIN_ID_2) + assertTrue "line=${LINENO}, cannot query chain $CHAIN_ID_2" $? + assertEquals "line=${LINENO}, register height" $REG_HEIGHT $(echo $CHAIN_INFO | jq .data.registered_at) + assertEquals "line=${LINENO}, tracked height" $UPDATE_2_HEIGHT $(echo $CHAIN_INFO | jq .data.remote_block) } # XXX Ex Usage: assertNewHeight $MSG $SEED_1 $SEED_2