Skip to content

Commit

Permalink
Add unit tests for ICS04 (#5286)
Browse files Browse the repository at this point in the history
* fix test

* 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 cli errors

* fix dependency

* fix dependency

* reflect method name change

* revise querier interface to work both on cli & store

* 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

* reflect downstream changes

* fix from address in tx cli

* fix cli in progress(squash later)

* fix cli

* remove timeout, add channel cli

* fix golangci

* fix cli

* Clean up

* fix mock cli in progress

* finalize cleanup, mock cli wip

* add cli for mocksend

* fix handler

* rm commented lines

* address review in progress

* address review, rm cleanup/closing

* rename mock packages

* fix interface for gaia

* 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)

* update test

* 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

* refactor: remove store accessors, update keeper and types to match spec (WIP)

* update handshake and packet

* implement packet timeouts

* implement send and receive packet

* implement packet ACK

* update handler

* add channel errors

* channel querier

* update expected client keeper and export verification funcs

* ICS 05 Implementation

* release port and godocs

* 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

* update ICS04 with downstream changes

* Implement tx cli actions

* add MsgSendPacket handler; msg validation, errors and events

* update errors and add port Keeper to ibc Keeper

* minor UX improvements

* rename pkg

* fixes

* refactor ICS23

* cleanup types

* ICS 5 updates (#5222)

* Validate port identifiers

* Refactor to static bind

* Add comments

* Add 'GetPorts' query function

* 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

* rm legacy tests; add query proofs support

* remove capability key generation and authentication logic

* 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

* use host validation for port ids

* downstream changes; custom marshal JSON; msg validation, and update errors

* update errors and aliases

* update msg validation and CLI UX

* minor changes on commitment types

* fix channel and packet check (#5243)

* R4R - Store consensus state correctly (#5242)

* store consensus state correctly

* fix client example

* update alias

* update alias

* update alias and keeper.GetPort()

* authenticate port ID; remove send packet msg from CLI

* comment out handlers

* add ibc module to simapp

* ICS20 implementation (#5204)

* add ibc bank mock

* modify handler

* import channel

* add receiving logic

* add cli proof handling

* modify cli

* modify receiver type

* modify errcode

* optimize codes

* add denom prefix when source is true

* refactor code

* error return

* switch ibc antehandler to decorator pattern

* fix name/comment

* ICS 20 implementation (#5250)

* move ics20 code to 20-transfer

* clean code

* fix compiling error

* add transfer module

* address ICS20 comments from review

* add routing callbacks

* clean code

* add missing err return

* modify err type

* modify err type

* add supply handling

* modify proof type

* add comments for msg and packet data

* add timeout supply handling

* modify module account name

* use supply keeper for burn and mint coins

* restructure keeper

* update alias and module.go

* golangci linter

* add ics20 handler to IBC handler

* update callbacks

* update ICS20 escrow address

* fix querier routes

* fix create client cli

* minor updates

* ibc querier test

* Refactor ibc/mock/bank into ICS 20 (#5264)

* Most of code port from mock module to ICS 20

* A few minor fixes

* Apply suggestions from code review

Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com>

* Fix suggestions from autolinter

* Apply suggestions from code review

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

* Fix order of messages

* Add invalid height error code, check non-nil proof

* Fix linter error

* Return the underlying error

* Tendermint starts at height 1

* Apply suggestions from code review

* setup ics20 test suite

* add event to MsgRecvPacket

* update ibc keeper test to use test suite

* Add handshake commands

* WIP connection handshake

* WIP Connection Handshake

* Add cliCtx.WaitForNBlocks

* fix connection handshake in progress

* fix connection handshake in progress

* add channel unit test

* add more channel tests

* fix channel test

* refactor channel test

* add capability test for channel

* make channel testing work

* optimize channel test

* delete types/errors.go

* modify capability test

* uncomment

* add msg tests for channel

* fix port capability store

* fix channel test

* use simapp

* modify channel test

* refactor channel msg test

* go fmt
  • Loading branch information
chengwenxi authored and fedekunze committed Nov 7, 2019
1 parent 7a97b78 commit 0c268c2
Show file tree
Hide file tree
Showing 5 changed files with 780 additions and 5 deletions.
329 changes: 329 additions & 0 deletions x/ibc/04-channel/keeper/handshake_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,329 @@
package keeper_test

import (
"fmt"

"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
clienttypestm "github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint"
connection "github.com/cosmos/cosmos-sdk/x/ibc/03-connection"
"github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types"
commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment"
ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types"
abci "github.com/tendermint/tendermint/abci/types"
)

func (suite *KeeperTestSuite) createClient() {
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 := clienttypestm.ConsensusState{
ChainID: testChainID,
Height: uint64(commitID.Version),
Root: commitment.NewRoot(commitID.Hash),
}

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

func (suite *KeeperTestSuite) updateClient() {
// always commit and begin a new block on updateClient
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 := clienttypestm.ConsensusState{
ChainID: testChainID,
Height: uint64(commitID.Version),
Root: commitment.NewRoot(commitID.Hash),
}

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

func (suite *KeeperTestSuite) createConnection(state connection.State) {
connection := connection.ConnectionEnd{
State: state,
ClientID: testClient,
Counterparty: connection.Counterparty{
ClientID: testClient,
ConnectionID: testConnection,
Prefix: suite.app.IBCKeeper.ConnectionKeeper.GetCommitmentPrefix(),
},
Versions: connection.GetCompatibleVersions(),
}

suite.app.IBCKeeper.ConnectionKeeper.SetConnection(suite.ctx, testConnection, connection)
}

func (suite *KeeperTestSuite) createChannel(portID string, chanID string, connID string, counterpartyPort string, counterpartyChan string, state types.State) {
channel := types.Channel{
State: state,
Ordering: testChannelOrder,
Counterparty: types.Counterparty{
PortID: counterpartyPort,
ChannelID: counterpartyChan,
},
ConnectionHops: []string{connID},
Version: testChannelVersion,
}

suite.app.IBCKeeper.ChannelKeeper.SetChannel(suite.ctx, portID, chanID, channel)
}

func (suite *KeeperTestSuite) deleteChannel(portID string, chanID string) {
store := prefix.NewStore(suite.ctx.KVStore(suite.app.GetKey(ibctypes.StoreKey)), []byte{})
store.Delete(types.KeyChannel(portID, chanID))
}

func (suite *KeeperTestSuite) bindPort(portID string) sdk.CapabilityKey {
return suite.app.IBCKeeper.PortKeeper.BindPort(portID)
}

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

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

return
}

func (suite *KeeperTestSuite) TestChanOpenInit() {
counterparty := types.NewCounterparty(testPort2, testChannel2)

suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT)
err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion)
suite.NotNil(err) // channel has already exist

suite.deleteChannel(testPort1, testChannel1)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion)
suite.NotNil(err) // connection does not exist

suite.createConnection(connection.NONE)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion)
suite.NotNil(err) // invalid connection state

suite.createConnection(connection.OPEN)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenInit(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel1, counterparty, testChannelVersion)
suite.Nil(err) // successfully executed

channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1)
suite.True(found)
suite.Equal(types.INIT, channel.State)
}

func (suite *KeeperTestSuite) TestChanOpenTry() {
counterparty := types.NewCounterparty(testPort1, testChannel1)
suite.bindPort(testPort2)
channelKey := types.ChannelPath(testPort1, testChannel1)

suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT)
suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.INIT)
suite.updateClient()
proofInit, proofHeight := suite.queryProof(channelKey)
err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight))
suite.NotNil(err) // channel has already exist

suite.deleteChannel(testPort2, testChannel2)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort1, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight))
suite.NotNil(err) // unauthenticated port

err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight))
suite.NotNil(err) // connection does not exist

suite.createConnection(connection.NONE)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight))
suite.NotNil(err) // invalid connection state

suite.createConnection(connection.OPEN)
suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPENTRY)
suite.updateClient()
proofInit, proofHeight = suite.queryProof(channelKey)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight))
suite.NotNil(err) // channel membership verification failed due to invalid counterparty

suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT)
suite.updateClient()
proofInit, proofHeight = suite.queryProof(channelKey)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenTry(suite.ctx, testChannelOrder, []string{testConnection}, testPort2, testChannel2, counterparty, testChannelVersion, testChannelVersion, proofInit, uint64(proofHeight))
suite.Nil(err) // successfully executed

channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2)
suite.True(found)
suite.Equal(types.OPENTRY, channel.State)
}

func (suite *KeeperTestSuite) TestChanOpenAck() {
suite.bindPort(testPort1)
channelKey := types.ChannelPath(testPort2, testChannel2)

suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY)
suite.updateClient()
proofTry, proofHeight := suite.queryProof(channelKey)
err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight))
suite.NotNil(err) // channel does not exist

suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight))
suite.NotNil(err) // invalid channel state

suite.createChannel(testPort2, testChannel1, testConnection, testPort1, testChannel2, types.INIT)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort2, testChannel1, testChannelVersion, proofTry, uint64(proofHeight))
suite.NotNil(err) // unauthenticated port

suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.INIT)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight))
suite.NotNil(err) // connection does not exist

suite.createConnection(connection.NONE)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight))
suite.NotNil(err) // invalid connection state

suite.createConnection(connection.OPEN)
suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN)
suite.updateClient()
proofTry, proofHeight = suite.queryProof(channelKey)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight))
suite.NotNil(err) // channel membership verification failed due to invalid counterparty

suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY)
suite.updateClient()
proofTry, proofHeight = suite.queryProof(channelKey)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenAck(suite.ctx, testPort1, testChannel1, testChannelVersion, proofTry, uint64(proofHeight))
suite.Nil(err) // successfully executed

channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1)
suite.True(found)
suite.Equal(types.OPEN, channel.State)
}

func (suite *KeeperTestSuite) TestChanOpenConfirm() {
suite.bindPort(testPort2)
channelKey := types.ChannelPath(testPort1, testChannel1)

suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN)
suite.updateClient()
proofAck, proofHeight := suite.queryProof(channelKey)
err := suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight))
suite.NotNil(err) // channel does not exist

suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight))
suite.NotNil(err) // invalid channel state

suite.createChannel(testPort1, testChannel2, testConnection, testPort2, testChannel1, types.OPENTRY)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort1, testChannel2, proofAck, uint64(proofHeight))
suite.NotNil(err) // unauthenticated port

suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPENTRY)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight))
suite.NotNil(err) // connection does not exist

suite.createConnection(connection.NONE)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight))
suite.NotNil(err) // invalid connection state

suite.createConnection(connection.OPEN)
suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPENTRY)
suite.updateClient()
proofAck, proofHeight = suite.queryProof(channelKey)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight))
suite.NotNil(err) // channel membership verification failed due to invalid counterparty

suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN)
suite.updateClient()
proofAck, proofHeight = suite.queryProof(channelKey)
err = suite.app.IBCKeeper.ChannelKeeper.ChanOpenConfirm(suite.ctx, testPort2, testChannel2, proofAck, uint64(proofHeight))
suite.Nil(err) // successfully executed

channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2)
suite.True(found)
suite.Equal(types.OPEN, channel.State)
}

func (suite *KeeperTestSuite) TestChanCloseInit() {
suite.bindPort(testPort1)

err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort2, testChannel1)
suite.NotNil(err) // authenticated port

err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1)
suite.NotNil(err) // channel does not exist

suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED)
err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1)
suite.NotNil(err) // channel is already closed

suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN)
err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1)
suite.NotNil(err) // connection does not exist

suite.createConnection(connection.TRYOPEN)
err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1)
suite.NotNil(err) // invalid connection state

suite.createConnection(connection.OPEN)
err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseInit(suite.ctx, testPort1, testChannel1)
suite.Nil(err) // successfully executed

channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort1, testChannel1)
suite.True(found)
suite.Equal(types.CLOSED, channel.State)
}

func (suite *KeeperTestSuite) TestChanCloseConfirm() {
suite.bindPort(testPort2)
channelKey := types.ChannelPath(testPort1, testChannel1)

suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED)
suite.updateClient()
proofInit, proofHeight := suite.queryProof(channelKey)
err := suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort1, testChannel2, proofInit, uint64(proofHeight))
suite.NotNil(err) // unauthenticated port

err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight))
suite.NotNil(err) // channel does not exist

suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.CLOSED)
err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight))
suite.NotNil(err) // channel is already closed

suite.createChannel(testPort2, testChannel2, testConnection, testPort1, testChannel1, types.OPEN)
err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight))
suite.NotNil(err) // connection does not exist

suite.createConnection(connection.TRYOPEN)
err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight))
suite.NotNil(err) // invalid connection state

suite.createConnection(connection.OPEN)
suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.OPEN)
suite.updateClient()
proofInit, proofHeight = suite.queryProof(channelKey)
err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight))
suite.NotNil(err) // channel membership verification failed due to invalid counterparty

suite.createChannel(testPort1, testChannel1, testConnection, testPort2, testChannel2, types.CLOSED)
suite.updateClient()
proofInit, proofHeight = suite.queryProof(channelKey)
err = suite.app.IBCKeeper.ChannelKeeper.ChanCloseConfirm(suite.ctx, testPort2, testChannel2, proofInit, uint64(proofHeight))
suite.Nil(err) // successfully executed

channel, found := suite.app.IBCKeeper.ChannelKeeper.GetChannel(suite.ctx, testPort2, testChannel2)
suite.True(found)
suite.Equal(types.CLOSED, channel.State)
}
10 changes: 10 additions & 0 deletions x/ibc/04-channel/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,13 @@ func (k Keeper) SetPacketAcknowledgement(ctx sdk.Context, portID, channelID stri
store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix)
store.Set(types.KeyPacketAcknowledgement(portID, channelID, sequence), ackHash)
}

// GetPacketAcknowledgement gets the packet ack hash from the store
func (k Keeper) GetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) ([]byte, bool) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), k.prefix)
bz := store.Get(types.KeyPacketAcknowledgement(portID, channelID, sequence))
if bz == nil {
return nil, false
}
return bz, true
}
Loading

0 comments on commit 0c268c2

Please sign in to comment.