diff --git a/CHANGELOG.md b/CHANGELOG.md index 28b96fd8f61..618e1c21825 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### State Machine Breaking +* (light-clients/07-tendermint) Fix: No-op to avoid panicking on `UpdateState` for invalid misbehaviour submissions. + ### Improvements * (apps/27-interchain-accounts, apps/tranfer, apps/29-fee) [\#6253](https://github.com/cosmos/ibc-go/pull/6253) Allow channel handshake to succeed if fee middleware is wired up on one side, but not the other. diff --git a/modules/light-clients/07-tendermint/update.go b/modules/light-clients/07-tendermint/update.go index c884b4bfba9..59c050cc903 100644 --- a/modules/light-clients/07-tendermint/update.go +++ b/modules/light-clients/07-tendermint/update.go @@ -2,7 +2,6 @@ package tendermint import ( "bytes" - "fmt" errorsmod "cosmossdk.io/errors" storetypes "cosmossdk.io/store/types" @@ -131,10 +130,12 @@ func (cs *ClientState) verifyHeader( // UpdateState must only be used to update within a single revision, thus header revision number and trusted height's revision // number must be the same. To update to a new revision, use a separate upgrade path // UpdateState will prune the oldest consensus state if it is expired. +// If the provided clientMsg is not of type of Header then the handler will noop and empty slice is returned. func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore storetypes.KVStore, clientMsg exported.ClientMessage) []exported.Height { header, ok := clientMsg.(*Header) if !ok { - panic(fmt.Errorf("expected type %T, got %T", &Header{}, clientMsg)) + // clientMsg is invalid Misbehaviour, no update necessary + return []exported.Height{} } cs.pruneOldestConsensusState(ctx, cdc, clientStore) diff --git a/modules/light-clients/07-tendermint/update_test.go b/modules/light-clients/07-tendermint/update_test.go index d6b8de6e091..1fe8c75e541 100644 --- a/modules/light-clients/07-tendermint/update_test.go +++ b/modules/light-clients/07-tendermint/update_test.go @@ -509,9 +509,12 @@ func (suite *TendermintTestSuite) TestUpdateState() { suite.Require().Equal(expConsensusState, updatedConsensusState) } else { - suite.Require().Panics(func() { - clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, clientMessage) - }) + consensusHeights = clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, clientMessage) + suite.Require().Empty(consensusHeights) + + consensusState, found := suite.chainA.GetSimApp().GetIBCKeeper().ClientKeeper.GetClientConsensusState(suite.chainA.GetContext(), path.EndpointA.ClientID, clienttypes.NewHeight(1, uint64(suite.chainB.GetContext().BlockHeight()))) + suite.Require().False(found) + suite.Require().Nil(consensusState) } // perform custom checks