From 0647d897f58603846418e032d0931a5dbf6e5b35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Tue, 17 Nov 2020 13:55:33 +0100 Subject: [PATCH] add is frozen client state check to send packet (#7957) Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- x/ibc/core/04-channel/keeper/packet.go | 5 +++++ x/ibc/core/04-channel/keeper/packet_test.go | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/x/ibc/core/04-channel/keeper/packet.go b/x/ibc/core/04-channel/keeper/packet.go index 87ba9ce3371..e86887eee92 100644 --- a/x/ibc/core/04-channel/keeper/packet.go +++ b/x/ibc/core/04-channel/keeper/packet.go @@ -67,6 +67,11 @@ func (k Keeper) SendPacket( return clienttypes.ErrConsensusStateNotFound } + // prevent accidental sends with clients that cannot be updated + if clientState.IsFrozen() { + return sdkerrors.Wrapf(clienttypes.ErrClientFrozen, "cannot send packet on a frozen client with ID %s", connectionEnd.GetClientID()) + } + // check if packet timeouted on the receiving chain latestHeight := clientState.GetLatestHeight() timeoutHeight := packet.GetTimeoutHeight() diff --git a/x/ibc/core/04-channel/keeper/packet_test.go b/x/ibc/core/04-channel/keeper/packet_test.go index f04b6ac1006..f53ed794755 100644 --- a/x/ibc/core/04-channel/keeper/packet_test.go +++ b/x/ibc/core/04-channel/keeper/packet_test.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types" host "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host" "github.com/cosmos/cosmos-sdk/x/ibc/core/exported" + ibctmtypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types" ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing" ibcmock "github.com/cosmos/cosmos-sdk/x/ibc/testing/mock" ) @@ -111,6 +112,22 @@ func (suite *KeeperTestSuite) TestSendPacket() { packet = types.NewPacket(validPacketData, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, disabledTimeoutTimestamp) channelCap = suite.chainA.GetChannelCapability(channelA.PortID, channelA.ID) }, false}, + {"client state is frozen", func() { + _, _, connA, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED) + + connection := suite.chainA.GetConnection(connA) + clientState := suite.chainA.GetClientState(connection.ClientId) + cs, ok := clientState.(*ibctmtypes.ClientState) + suite.Require().True(ok) + + // freeze client + cs.FrozenHeight = clienttypes.NewHeight(0, 1) + suite.chainA.App.IBCKeeper.ClientKeeper.SetClientState(suite.chainA.GetContext(), connection.ClientId, cs) + + packet = types.NewPacket(validPacketData, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, disabledTimeoutTimestamp) + channelCap = suite.chainA.GetChannelCapability(channelA.PortID, channelA.ID) + }, false}, + {"timeout height passed", func() { clientA, _, _, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB, types.UNORDERED) // use client state latest height for timeout