Skip to content

Commit

Permalink
Add unit tests for ICS03 (#5275)
Browse files Browse the repository at this point in the history
* add Is() to counterobject

* add readme, reflect ICS02 revision

* reflect downstream ics

* test in progress

* add test

* in progres

* fin rebase

* in progress

* fin rebase

* add CLIObject in progress

* cli in progress

* add CLIObject

* separate testing from tendermint

* add key to node

* add root and storekey to tests/node, add codec

* rm cli/query.go

* fix test

* fix lint

* fix lint

* add handler/msgs/client

* rm relay

* finalize rebase on 23 root/path sep

* fix lint, fix syntax

* fix querying

* extract out context withstore

* fix 02-client test

* fix 23-commitment test

* add query in progress

* rm freebase, reformat query

* add cli/handler/msg in progress

* add cli/msg/handler

* add CLIQuery, fix tests

* fix golangci

* add docs in progre

* add comments

* add comments

* Apply suggestions from code review

Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com>

* add comments in progress

* add comments

* fix comment

* add comments in progress

* recover IntEncoding scheme for integer

* add uint tests, don't use codec in custom types

* finalize merge

* add godoc

* add godoc in progress

* reformat test

* rm XXX

* add godoc

* modify store

* add query

* update query.go

* update query.go

* cli refactor in progress

* cli refactor in progress

* add Query to boolean.go

* fix key

* fix cli / merkle test

* godoc cleanup

* godoc cleanup

* godoc cleanup

* godoc cleanup

* godoc cleanup

* fix test

* fix client

* merge from ics04 branch

* merge from ics04 branch

* merge from ics04 branch

* merge from ics04 branch

* fix lint

* Apply suggestions from code review

Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com>

* applying review in progress

* apply review - make querier interface

* fix dependency

* fix dependency

* revise querier interface to work both on cli & store

* revise querier interface to work both on cli & store

* reflect downstream change

* fix cli

* reflect downstream changes

* rm commented lines

* address review in progress

* address review, rm cleanup/closing

* rename Path -> Prefix

* Store accessor upstream changes (#5119)

* Store accessor upstream changes (#5119)

* add comments, reformat merkle querier

* rm merkle/utils

* ICS 23 upstream changes (#5120)

* ICS 23 upstream changes (#5120)

* update Value

* update test

* fix

* ICS 02 upstream changes (#5122)

* ICS 02 upstream changes (#5122)

* ICS 03 upstream changes (#5123)

* ICS 03 upstream changes (#5123)

* cleanup types and submodule

* more cleanup and godocs

* remove counterPartyManager/State and cleanup

* implement SubmitMisbehaviour and refactor

* errors

* events

* fix test

* refactors

* WIP refactor ICS03

* remove Mapping

* remove store accessors

* proposed refactor

* remove store accessors from ICS02

* refactor queriers, handler and clean keeper

* logger and tx long description

* ineffassign

* Apply suggestions from code review

Co-Authored-By: Jack Zampolin <jack.zampolin@gmail.com>

* Apply suggestions from code review

Co-Authored-By: Jack Zampolin <jack.zampolin@gmail.com>

* remove store accessors

* refactor handshake to update it to the latest ICS03 spec

* update handler and msgs

* add verification functions

* update verification

* ICS02 module.go

* top level x/ibc structure

* update connection queries

* update connection tx

* remove extra files

* update expected client keeper and export verification funcs

* Update x/ibc/02-client/client/cli/query.go

Co-Authored-By: Jack Zampolin <jack.zampolin@gmail.com>

* Update x/ibc/02-client/types/tendermint/consensus_state.go

Co-Authored-By: Jack Zampolin <jack.zampolin@gmail.com>

* address some of the review comments

* resolve some TODOs and address comments from review

* update connection versioning

* minor error updates

* minor UX improvements

* rename pkg

* fixes

* refactor ICS23

* cleanup types

* rename pkg and fix import

* implement batch verification

* gosimple suggestion

* various fixes; remove legacy tests; remove commitment path query

* alias

* minor updates from ICS23

* renaming

* update verification and rename root funcs

* move querier to x/ibc

* update query.go to use 'custom/...' query path

* add tests

* ICS 24 Implementation (#5229)

* add validation functions

* validate path in ics-23

* address @fede comments

* move errors into host package

* flatten ICS23 structure

* fix ApplyPrefix

* updates from ICS23 and ICS24

* msg.ValidateBasic and ADR09 evidence interface

* complete types testing

* delete empty test file

* remove ibc errors from core error package

* custom JSON marshaling; msg.ValidateBasic; renaming of variables

* minor update

* custom JSON marshaling

* minor changes on commitment types

* R4R - Store consensus state correctly (#5242)

* store consensus state correctly

* fix client example

* update alias

* update alias

* implement ics25

* update comment

* refactor method name

* fix file name

* add test case

* refactor code

* refactor code

* blocked the consensusState check

* refactor code

* fix golangci comments

* refactor testcase

* replace rootMultiStore with simApp

* remove unless code

* remove unless code & refactor test case

* refactor testcase

* goimports code

* clean up
  • Loading branch information
chengwenxi authored and jackzampolin committed Jan 15, 2020
1 parent c378fb6 commit d8cf351
Show file tree
Hide file tree
Showing 4 changed files with 545 additions and 3 deletions.
311 changes: 311 additions & 0 deletions x/ibc/03-connection/keeper/handshake_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,311 @@
package keeper_test

import (
"fmt"

client "github.com/cosmos/cosmos-sdk/x/ibc/02-client"
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint"
connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection"
commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment"
abci "github.com/tendermint/tendermint/abci/types"
)

func (suite *KeeperTestSuite) TestConnOpenInit() {
suite.createClient(testClientID1)
counterparty := connection.NewCounterparty(testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix())

success := func() error {
err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.ctx, testConnectionID1, testClientID1, counterparty)

conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1)
suite.True(existed)

expectConn := connection.ConnectionEnd{
State: connection.INIT,
ClientID: testClientID1,
Counterparty: counterparty,
Versions: connection.GetCompatibleVersions(),
}
suite.EqualValues(expectConn, conn)

return err
}

connectionExists := func() error {
err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenInit(suite.ctx, testConnectionID1, testClientID1, counterparty)
return err
}

var testCases = []TestCase{
{success, true, ""},
{connectionExists, false, "connection already exists"},
}

for _, tc := range testCases {
suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg)
}
}

func (suite *KeeperTestSuite) TestConnOpenTry() {
suite.createClient(testClientID2)
suite.createClient(testClientID1)
suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT)

connectionKey := connection.ConnectionPath(testConnectionID2)
consensusKey := string(client.KeyConsensusState(testClientID2))

invalidProof := func() error {
proofInit, proofHeight := suite.queryProof(connectionKey)
proofConsensus, consensusHeight := suite.queryProof(consensusKey)

counterparty := connection.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix())
err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry(suite.ctx,
testConnectionID1, counterparty, testClientID1,
connection.GetCompatibleVersions(),
proofInit, proofConsensus,
uint64(proofHeight), uint64(consensusHeight))
return err
}

success := func() error {
suite.updateClient(testClientID1)
proofInit, proofHeight := suite.queryProof(connectionKey)
proofConsensus, consensusHeight := suite.queryProof(consensusKey)

counterparty := connection.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix())
err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry(suite.ctx,
testConnectionID1, counterparty, testClientID1,
connection.GetCompatibleVersions(),
proofInit, proofConsensus,
uint64(proofHeight), uint64(consensusHeight))
suite.Nil(err)

//check connection state
conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1)
suite.True(existed)
suite.Equal(connection.TRYOPEN, conn.State)
return err
}

connectionExists := func() error {
suite.updateClient(testClientID1)
proofInit, proofHeight := suite.queryProof(connectionKey)
proofConsensus, consensusHeight := suite.queryProof(consensusKey)

counterparty := connection.NewCounterparty(testClientID2, testConnectionID2, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix())
err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenTry(suite.ctx,
testConnectionID1, counterparty, testClientID1,
connection.GetCompatibleVersions(),
proofInit, proofConsensus,
uint64(proofHeight), uint64(consensusHeight))
return err
}

var testCases = []TestCase{
{invalidProof, false, "invalid proof"},
{success, true, ""},
{connectionExists, false, "connection already exists"},
}

for _, tc := range testCases {
suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg)
}

}

func (suite *KeeperTestSuite) TestConnOpenAck() {
suite.createClient(testClientID2)
suite.createClient(testClientID1)

suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.TRYOPEN)
connectionKey := connection.ConnectionPath(testConnectionID1)
consensusKey := string(client.KeyConsensusState(testClientID1))

connectionNotFound := func() error {
//suite.updateClient(testClientID2)

proofTry, proofHeight := suite.queryProof(connectionKey)
proofConsensus, consensusHeight := suite.queryProof(consensusKey)
err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight))
return err
}

invalidConnectionState := func() error {
suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.NONE)
//suite.updateClient(testClientID2)

proofTry, proofHeight := suite.queryProof(connectionKey)
proofConsensus, consensusHeight := suite.queryProof(consensusKey)
err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight))
return err
}

invalidVersion := func() error {
suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT)
//suite.updateClient(testClientID2)

proofTry, proofHeight := suite.queryProof(connectionKey)
proofConsensus, consensusHeight := suite.queryProof(consensusKey)
err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, "1.0.1", proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight))
return err
}

invalidProof := func() error {
suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT)
//suite.updateClient(testClientID2)

proofTry, proofHeight := suite.queryProof(connectionKey)
proofConsensus, consensusHeight := suite.queryProof(consensusKey)
err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight))
return err
}

success := func() error {
suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.INIT)
suite.updateClient(testClientID2)

proofTry, proofHeight := suite.queryProof(connectionKey)
proofConsensus, consensusHeight := suite.queryProof(consensusKey)
err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenAck(suite.ctx, testConnectionID2, connection.GetCompatibleVersions()[0], proofTry, proofConsensus, uint64(proofHeight), uint64(consensusHeight))

//check connection state
conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID2)
suite.True(existed)
suite.Equal(connection.OPEN, conn.State)
return err

}

var testCases = []TestCase{
{connectionNotFound, false, "connection not exists"},
{invalidConnectionState, false, "invalid connection state"},
{invalidVersion, false, "invalid version"},
{invalidProof, false, "invalid proof"},
{success, true, ""},
}

for _, tc := range testCases {
suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg)
}

}

func (suite *KeeperTestSuite) TestConnOpenConfirm() {
suite.createClient(testClientID2)
suite.createClient(testClientID1)
suite.createConnection(testConnectionID2, testConnectionID1, testClientID2, testClientID1, connection.OPEN)

connKey := connection.ConnectionPath(testConnectionID2)
proof, h := suite.queryProof(connKey)

connectionNotFound := func() error {
//ErrConnectionNotFound
err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h))
return err
}

invalidConnectionState := func() error {
suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.INIT)
err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h))
return err
}

invalidProof := func() error {
//Error proof
suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.TRYOPEN)
err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h))
return err
}

success := func() error {
//Success
suite.createConnection(testConnectionID1, testConnectionID2, testClientID1, testClientID2, connection.TRYOPEN)
suite.updateClient(testClientID1)
proof, h = suite.queryProof(connKey)
err := suite.app.IBCKeeper.ConnectionKeeper.ConnOpenConfirm(suite.ctx, testConnectionID1, proof, uint64(h))

//check connection state
conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1)
suite.True(existed)
suite.Equal(connection.OPEN, conn.State)
return err
}

var testCases = []TestCase{
{connectionNotFound, false, "connection not exists"},
{invalidConnectionState, false, "invalid connection state"},
{invalidProof, false, "invalid proof"},
{success, true, ""},
}

for _, tc := range testCases {
suite.Equal(tc.expected, tc.fun() == nil, "error: %s", tc.errMsg)
}
}

func (suite *KeeperTestSuite) queryProof(key string) (proof commitment.Proof, height int64) {
res := suite.app.Query(abci.RequestQuery{
Path: fmt.Sprintf("store/%s/key", storeKey),
Data: []byte(key),
Prove: true,
})

height = res.Height
proof = commitment.Proof{
Proof: res.Proof,
}

return
}

func (suite *KeeperTestSuite) createClient(clientID string) {
suite.app.Commit()
commitID := suite.app.LastCommitID()

suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}})
suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{})

consensusState := tendermint.ConsensusState{
ChainID: chainID,
Height: uint64(commitID.Version),
Root: commitment.NewRoot(commitID.Hash),
}

_, err := suite.app.IBCKeeper.ClientKeeper.CreateClient(suite.ctx, clientID, clientType, consensusState)
suite.NoError(err)
}

func (suite *KeeperTestSuite) updateClient(clientID string) {
// always commit when updateClient and begin a new block
suite.app.Commit()
commitID := suite.app.LastCommitID()

suite.app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: suite.app.LastBlockHeight() + 1}})
suite.ctx = suite.app.BaseApp.NewContext(false, abci.Header{})

state := tendermint.ConsensusState{
ChainID: chainID,
Height: uint64(commitID.Version),
Root: commitment.NewRoot(commitID.Hash),
}

suite.app.IBCKeeper.ClientKeeper.SetConsensusState(suite.ctx, clientID, state)
suite.app.IBCKeeper.ClientKeeper.SetVerifiedRoot(suite.ctx, clientID, state.GetHeight(), state.GetRoot())
}

func (suite *KeeperTestSuite) createConnection(connID, counterpartyConnID string, clientID, counterpartyClientID string, state connection.State) {
counterparty := connection.NewCounterparty(counterpartyClientID, counterpartyConnID, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix())
connection := connection.ConnectionEnd{
State: state,
ClientID: clientID,
Counterparty: counterparty,
Versions: connection.GetCompatibleVersions(),
}
suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, connID, connection)
}

type TestCase = struct {
fun func() error
expected bool
errMsg string
}
75 changes: 75 additions & 0 deletions x/ibc/03-connection/keeper/keeper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package keeper_test

import (
"testing"

"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported"
"github.com/cosmos/cosmos-sdk/x/ibc/03-connection/types"
ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types"
"github.com/stretchr/testify/suite"
abci "github.com/tendermint/tendermint/abci/types"
)

const (
clientType = clientexported.Tendermint
storeKey = ibctypes.StoreKey
chainID = "test"

testClientID1 = "testclientid1"
testConnectionID1 = "connectionid1"

testClientID2 = "testclientid2"
testConnectionID2 = "connectionid2"
)

type KeeperTestSuite struct {
suite.Suite

cdc *codec.Codec
ctx sdk.Context
app *simapp.SimApp
}

func (suite *KeeperTestSuite) SetupTest() {
isCheckTx := false
app := simapp.Setup(isCheckTx)

suite.cdc = app.Codec()
suite.ctx = app.BaseApp.NewContext(isCheckTx, abci.Header{})
suite.app = app
}

func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}

func (suite *KeeperTestSuite) TestSetAndGetConnection() {
_, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1)
suite.False(existed)

counterparty := types.NewCounterparty(testClientID1, testConnectionID1, suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix())
expConn := types.ConnectionEnd{
State: types.INIT,
ClientID: testClientID1,
Counterparty: counterparty,
Versions: types.GetCompatibleVersions(),
}
suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnectionID1, expConn)
conn, existed := suite.app.IBCKeeper.ConnectionKeeper.GetConnection(suite.ctx, testConnectionID1)
suite.True(existed)
suite.EqualValues(expConn, conn)
}

func (suite *KeeperTestSuite) TestSetAndGetClientConnectionPaths() {

_, existed := suite.app.IBCKeeper.ConnectionKeeper.GetClientConnectionPaths(suite.ctx, testClientID1)
suite.False(existed)

suite.app.IBCKeeper.ConnectionKeeper.SetClientConnectionPaths(suite.ctx, testClientID1, types.GetCompatibleVersions())
paths, existed := suite.app.IBCKeeper.ConnectionKeeper.GetClientConnectionPaths(suite.ctx, testClientID1)
suite.True(existed)
suite.EqualValues(types.GetCompatibleVersions(), paths)
}
Loading

0 comments on commit d8cf351

Please sign in to comment.