From d72c9e144d87c0d5ef1c8f474369db48fe511d5d Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Thu, 21 Apr 2022 17:36:30 +0200 Subject: [PATCH 1/6] adding new consensus heights return value from UpdateState interface, updating 02-client events emission --- modules/core/02-client/keeper/client.go | 51 ++++++++++--------- modules/core/02-client/keeper/events.go | 16 ++++-- .../core/02-client/legacy/v100/solomachine.go | 2 +- modules/core/02-client/types/events.go | 11 ++-- modules/core/exported/client.go | 4 +- .../06-solomachine/types/update.go | 6 +-- .../06-solomachine/types/update_test.go | 2 +- .../07-tendermint/types/update.go | 9 ++-- .../07-tendermint/types/update_test.go | 2 +- 9 files changed, 58 insertions(+), 45 deletions(-) diff --git a/modules/core/02-client/keeper/client.go b/modules/core/02-client/keeper/client.go index e702c31fe5c..6f31e9e9cd4 100644 --- a/modules/core/02-client/keeper/client.go +++ b/modules/core/02-client/keeper/client.go @@ -70,14 +70,6 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, clientMsg exporte return err } - // Marshal the ClientMessage as an Any and encode the resulting bytes to hex. - // This prevents the event value from containing invalid UTF-8 characters - // which may cause data to be lost when JSON encoding/decoding. - clientMsgStr := hex.EncodeToString(types.MustMarshalClientMessage(k.cdc, clientMsg)) - - // set default consensus height with header height - consensusHeight := clientMsg.GetHeight() - foundMisbehaviour := clientState.CheckForMisbehaviour(ctx, k.cdc, clientStore, clientMsg) if foundMisbehaviour { clientState.UpdateStateOnMisbehaviour(ctx, k.cdc, clientStore, clientMsg) @@ -96,29 +88,40 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, clientMsg exporte ) }() - EmitSubmitMisbehaviourEventOnUpdate(ctx, clientID, clientState.ClientType(), consensusHeight, clientMsgStr) + EmitSubmitMisbehaviourEvent(ctx, clientID, clientState) return nil } - clientState.UpdateState(ctx, k.cdc, clientStore, clientMsg) + consensusHeights, err := clientState.UpdateState(ctx, k.cdc, clientStore, clientMsg) + if err != nil { + return err + } - k.Logger(ctx).Info("client state updated", "client-id", clientID, "height", consensusHeight.String()) + if len(consensusHeights) != 0 { + k.Logger(ctx).Info("client state updated", "client-id", clientID, "heights", consensusHeights) - defer func() { - telemetry.IncrCounterWithLabels( - []string{"ibc", "client", "update"}, - 1, - []metrics.Label{ - telemetry.NewLabel(types.LabelClientType, clientState.ClientType()), - telemetry.NewLabel(types.LabelClientID, clientID), - telemetry.NewLabel(types.LabelUpdateType, "msg"), - }, - ) - }() + defer func() { + telemetry.IncrCounterWithLabels( + []string{"ibc", "client", "update"}, + 1, + []metrics.Label{ + telemetry.NewLabel(types.LabelClientType, clientState.ClientType()), + telemetry.NewLabel(types.LabelClientID, clientID), + telemetry.NewLabel(types.LabelUpdateType, "msg"), + }, + ) + }() - // emitting events in the keeper emits for both begin block and handler client updates - EmitUpdateClientEvent(ctx, clientID, clientState.ClientType(), consensusHeight, clientMsgStr) + // Marshal the ClientMessage as an Any and encode the resulting bytes to hex. + // This prevents the event value from containing invalid UTF-8 characters + // which may cause data to be lost when JSON encoding/decoding. + clientMsgStr := hex.EncodeToString(types.MustMarshalClientMessage(k.cdc, clientMsg)) + + // emitting events in the keeper emits for both begin block and handler client updates + EmitUpdateClientEvent(ctx, clientID, clientState.ClientType(), consensusHeights, clientMsgStr) + + } return nil } diff --git a/modules/core/02-client/keeper/events.go b/modules/core/02-client/keeper/events.go index 4e2f38941a0..2777906aa9e 100644 --- a/modules/core/02-client/keeper/events.go +++ b/modules/core/02-client/keeper/events.go @@ -1,6 +1,8 @@ package keeper import ( + "strings" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/ibc-go/v3/modules/core/02-client/types" @@ -24,13 +26,19 @@ func EmitCreateClientEvent(ctx sdk.Context, clientID string, clientState exporte } // EmitUpdateClientEvent emits an update client event -func EmitUpdateClientEvent(ctx sdk.Context, clientID string, clientType string, consensusHeight exported.Height, clientMsgStr string) { +func EmitUpdateClientEvent(ctx sdk.Context, clientID string, clientType string, consensusHeights []exported.Height, clientMsgStr string) { + var consensusHeightStr []string + for _, height := range consensusHeights { + consensusHeightStr = append(consensusHeightStr, height.String()) + } + ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( types.EventTypeUpdateClient, sdk.NewAttribute(types.AttributeKeyClientID, clientID), sdk.NewAttribute(types.AttributeKeyClientType, clientType), - sdk.NewAttribute(types.AttributeKeyConsensusHeight, consensusHeight.String()), + sdk.NewAttribute(types.AttributeKeyConsensusHeight, consensusHeights[0].String()), + sdk.NewAttribute(types.AttributeKeyConsensusHeight, strings.Join(consensusHeightStr, ",")), sdk.NewAttribute(types.AttributeKeyHeader, clientMsgStr), ), sdk.NewEvent( @@ -80,14 +88,14 @@ func EmitSubmitMisbehaviourEvent(ctx sdk.Context, clientID string, clientState e } // EmitSubmitMisbehaviourEventOnUpdate emits a client misbehaviour event on a client update event -func EmitSubmitMisbehaviourEventOnUpdate(ctx sdk.Context, clientID string, clientType string, consensusHeight exported.Height, headerStr string) { +func EmitSubmitMisbehaviourEventOnUpdate(ctx sdk.Context, clientID string, clientType string, consensusHeight exported.Height, clientMsgStr string) { ctx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeSubmitMisbehaviour, sdk.NewAttribute(types.AttributeKeyClientID, clientID), sdk.NewAttribute(types.AttributeKeyClientType, clientType), sdk.NewAttribute(types.AttributeKeyConsensusHeight, consensusHeight.String()), - sdk.NewAttribute(types.AttributeKeyHeader, headerStr), + sdk.NewAttribute(types.AttributeKeyHeader, clientMsgStr), ), ) } diff --git a/modules/core/02-client/legacy/v100/solomachine.go b/modules/core/02-client/legacy/v100/solomachine.go index 19e5459206c..e59106aebda 100644 --- a/modules/core/02-client/legacy/v100/solomachine.go +++ b/modules/core/02-client/legacy/v100/solomachine.go @@ -108,7 +108,7 @@ func (cs *ClientState) VerifyClientMessage( } // UpdateState panis! -func (cs *ClientState) UpdateState(_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage) error { +func (cs *ClientState) UpdateState(_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage) ([]exported.Height, error) { panic("legacy solo machine is deprecated!") } diff --git a/modules/core/02-client/types/events.go b/modules/core/02-client/types/events.go index 391e1e37080..05708a84859 100644 --- a/modules/core/02-client/types/events.go +++ b/modules/core/02-client/types/events.go @@ -8,11 +8,12 @@ import ( // IBC client events const ( - AttributeKeyClientID = "client_id" - AttributeKeySubjectClientID = "subject_client_id" - AttributeKeyClientType = "client_type" - AttributeKeyConsensusHeight = "consensus_height" - AttributeKeyHeader = "header" + AttributeKeyClientID = "client_id" + AttributeKeySubjectClientID = "subject_client_id" + AttributeKeyClientType = "client_type" + AttributeKeyConsensusHeight = "consensus_height" + AttributeKeyConsensusHeights = "consensus_heights" + AttributeKeyHeader = "header" ) // IBC client events vars diff --git a/modules/core/exported/client.go b/modules/core/exported/client.go index 44fc75a6169..95efca3e86d 100644 --- a/modules/core/exported/client.go +++ b/modules/core/exported/client.go @@ -63,7 +63,7 @@ type ClientState interface { // UpdateState updates and stores as necessary any associated information for an IBC client, such as the ClientState and corresponding ConsensusState. // An error is returned if ClientMessage is of type Misbehaviour - UpdateState(sdk.Context, codec.BinaryCodec, sdk.KVStore, ClientMessage) error + UpdateState(sdk.Context, codec.BinaryCodec, sdk.KVStore, ClientMessage) ([]Height, error) // Update and Misbehaviour functions CheckSubstituteAndUpdateState(ctx sdk.Context, cdc codec.BinaryCodec, subjectClientStore, substituteClientStore sdk.KVStore, substituteClient ClientState) (ClientState, error) @@ -203,7 +203,7 @@ type ConsensusState interface { type ClientMessage interface { proto.Message - GetHeight() Height + GetHeight() Height // Remove ClientType() string ValidateBasic() error } diff --git a/modules/light-clients/06-solomachine/types/update.go b/modules/light-clients/06-solomachine/types/update.go index 0fc5c76544f..59f11124b92 100644 --- a/modules/light-clients/06-solomachine/types/update.go +++ b/modules/light-clients/06-solomachine/types/update.go @@ -81,10 +81,10 @@ func (cs ClientState) verifyMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, } // UpdateState updates the consensus state to the new public key and an incremented sequence. -func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) error { +func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) ([]exported.Height, error) { smHeader, ok := clientMsg.(*Header) if !ok { - return sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected %T got %T", Header{}, clientMsg) + return nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected %T got %T", Header{}, clientMsg) } // create new solomachine ConsensusState @@ -99,7 +99,7 @@ func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, client clientStore.Set(host.ClientStateKey(), clienttypes.MustMarshalClientState(cdc, &cs)) - return nil + return []exported.Height{smHeader.GetHeight()}, nil } // CheckForMisbehaviour returns true for type Misbehaviour (passed VerifyClientMessage check), otherwise returns false diff --git a/modules/light-clients/06-solomachine/types/update_test.go b/modules/light-clients/06-solomachine/types/update_test.go index 7e3acaf0637..4f17e7e6adb 100644 --- a/modules/light-clients/06-solomachine/types/update_test.go +++ b/modules/light-clients/06-solomachine/types/update_test.go @@ -441,7 +441,7 @@ func (suite *SoloMachineTestSuite) TestUpdateState() { suite.Run(tc.name, func() { tc.setup() // setup test - err := clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, clientMsg) + _, err := clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, clientMsg) // TODO: Update tests to account for new consensus heights return value if tc.expPass { suite.Require().NoError(err) diff --git a/modules/light-clients/07-tendermint/types/update.go b/modules/light-clients/07-tendermint/types/update.go index 18849096bba..1a3144f2b7e 100644 --- a/modules/light-clients/07-tendermint/types/update.go +++ b/modules/light-clients/07-tendermint/types/update.go @@ -157,16 +157,16 @@ 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. -func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) error { +func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) ([]exported.Height, error) { header, ok := clientMsg.(*Header) if !ok { - return sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected type %T, got %T", &Header{}, header) + return nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected type %T, got %T", &Header{}, header) } // check for duplicate update if consensusState, _ := GetConsensusState(clientStore, cdc, header.GetHeight()); consensusState != nil { // perform no-op - return nil + return []exported.Height{}, nil } cs.pruneOldestConsensusState(ctx, cdc, clientStore) @@ -175,6 +175,7 @@ func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, client if height.GT(cs.LatestHeight) { cs.LatestHeight = height } + consensusState := &ConsensusState{ Timestamp: header.GetTime(), Root: commitmenttypes.NewMerkleRoot(header.Header.GetAppHash()), @@ -186,7 +187,7 @@ func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, client setConsensusState(clientStore, cdc, consensusState, header.GetHeight()) setConsensusMetadata(ctx, clientStore, header.GetHeight()) - return nil + return []exported.Height{height}, nil } // pruneOldestConsensusState will retrieve the earliest consensus state for this clientID and check if it is expired. If it is, diff --git a/modules/light-clients/07-tendermint/types/update_test.go b/modules/light-clients/07-tendermint/types/update_test.go index 022e6d1ba36..7386fd257c1 100644 --- a/modules/light-clients/07-tendermint/types/update_test.go +++ b/modules/light-clients/07-tendermint/types/update_test.go @@ -419,7 +419,7 @@ func (suite *TendermintTestSuite) TestUpdateState() { clientState := path.EndpointA.GetClientState() clientStore = suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) - err = clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, clientMessage) + _, err = clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, clientMessage) // TODO: Update tests to account for new consensus heights return value if tc.expPass { suite.Require().NoError(err) From 9737a7e8344a054ca95531f095e3efc3ff9ed526 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Thu, 21 Apr 2022 18:01:23 +0200 Subject: [PATCH 2/6] removing GetHeight() from ClientMessage interface, updating tests --- modules/core/exported/client.go | 1 - .../06-solomachine/types/update_test.go | 6 ++- .../07-tendermint/types/update_test.go | 43 ++++++++++++++----- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/modules/core/exported/client.go b/modules/core/exported/client.go index 95efca3e86d..e315edd2799 100644 --- a/modules/core/exported/client.go +++ b/modules/core/exported/client.go @@ -203,7 +203,6 @@ type ConsensusState interface { type ClientMessage interface { proto.Message - GetHeight() Height // Remove ClientType() string ValidateBasic() error } diff --git a/modules/light-clients/06-solomachine/types/update_test.go b/modules/light-clients/06-solomachine/types/update_test.go index 4f17e7e6adb..9c80fdfc76c 100644 --- a/modules/light-clients/06-solomachine/types/update_test.go +++ b/modules/light-clients/06-solomachine/types/update_test.go @@ -441,11 +441,14 @@ func (suite *SoloMachineTestSuite) TestUpdateState() { suite.Run(tc.name, func() { tc.setup() // setup test - _, err := clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, clientMsg) // TODO: Update tests to account for new consensus heights return value + consensusHeights, err := clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, clientMsg) if tc.expPass { suite.Require().NoError(err) + suite.Require().Len(consensusHeights, 1) + suite.Require().Equal(clienttypes.NewHeight(0, clientMsg.(*types.Header).Sequence), consensusHeights[0]) + clientStateBz := suite.store.Get(host.ClientStateKey()) suite.Require().NotEmpty(clientStateBz) @@ -457,6 +460,7 @@ func (suite *SoloMachineTestSuite) TestUpdateState() { suite.Require().Equal(clientMsg.(*types.Header).NewDiversifier, newClientState.(*types.ClientState).ConsensusState.Diversifier) suite.Require().Equal(clientMsg.(*types.Header).Timestamp, newClientState.(*types.ClientState).ConsensusState.Timestamp) } else { + suite.Require().Empty(consensusHeights) suite.Require().Error(err) } diff --git a/modules/light-clients/07-tendermint/types/update_test.go b/modules/light-clients/07-tendermint/types/update_test.go index 7386fd257c1..c51b74c0df2 100644 --- a/modules/light-clients/07-tendermint/types/update_test.go +++ b/modules/light-clients/07-tendermint/types/update_test.go @@ -305,6 +305,7 @@ func (suite *TendermintTestSuite) TestUpdateState() { path *ibctesting.Path clientMessage exported.ClientMessage clientStore sdk.KVStore + consensusHeights []exported.Height pruneHeight clienttypes.Height prevClientState exported.ClientState prevConsensusState exported.ConsensusState @@ -318,10 +319,14 @@ func (suite *TendermintTestSuite) TestUpdateState() { }{ { "success with height later than latest height", func() { - suite.Require().True(path.EndpointA.GetClientState().GetLatestHeight().LT(clientMessage.GetHeight())) + tmHeader, ok := clientMessage.(*types.Header) + suite.Require().True(ok) + suite.Require().True(path.EndpointA.GetClientState().GetLatestHeight().LT(tmHeader.GetHeight())) }, func() { - suite.Require().True(path.EndpointA.GetClientState().GetLatestHeight().EQ(clientMessage.GetHeight())) // new update, updated client state should have changed + tmHeader, ok := clientMessage.(*types.Header) + suite.Require().True(ok) + suite.Require().True(path.EndpointA.GetClientState().GetLatestHeight().EQ(tmHeader.GetHeight())) // new update, updated client state should have changed }, true, }, { @@ -332,7 +337,9 @@ func (suite *TendermintTestSuite) TestUpdateState() { err := path.EndpointA.UpdateClient() suite.Require().NoError(err) - suite.Require().True(path.EndpointA.GetClientState().GetLatestHeight().GT(clientMessage.GetHeight())) + tmHeader, ok := clientMessage.(*types.Header) + suite.Require().True(ok) + suite.Require().True(path.EndpointA.GetClientState().GetLatestHeight().GT(tmHeader.GetHeight())) prevClientState = path.EndpointA.GetClientState() }, @@ -349,14 +356,20 @@ func (suite *TendermintTestSuite) TestUpdateState() { // use the same header which just updated the client clientMessage, err = path.EndpointA.Chain.ConstructUpdateTMClientHeader(path.EndpointA.Counterparty.Chain, path.EndpointA.ClientID) suite.Require().NoError(err) - suite.Require().Equal(path.EndpointA.GetClientState().GetLatestHeight(), clientMessage.GetHeight()) + + tmHeader, ok := clientMessage.(*types.Header) + suite.Require().True(ok) + suite.Require().Equal(path.EndpointA.GetClientState().GetLatestHeight(), tmHeader.GetHeight()) prevClientState = path.EndpointA.GetClientState() - prevConsensusState = path.EndpointA.GetConsensusState(clientMessage.GetHeight()) + prevConsensusState = path.EndpointA.GetConsensusState(tmHeader.GetHeight()) }, func() { suite.Require().Equal(path.EndpointA.GetClientState(), prevClientState) - suite.Require().Equal(path.EndpointA.GetConsensusState(clientMessage.GetHeight()), prevConsensusState) + + tmHeader, ok := clientMessage.(*types.Header) + suite.Require().True(ok) + suite.Require().Equal(path.EndpointA.GetConsensusState(tmHeader.GetHeight()), prevConsensusState) }, true, }, { @@ -385,7 +398,9 @@ func (suite *TendermintTestSuite) TestUpdateState() { suite.Require().NoError(err) }, func() { - suite.Require().True(path.EndpointA.GetClientState().GetLatestHeight().EQ(clientMessage.GetHeight())) // new update, updated client state should have changed + tmHeader, ok := clientMessage.(*types.Header) + suite.Require().True(ok) + suite.Require().True(path.EndpointA.GetClientState().GetLatestHeight().EQ(tmHeader.GetHeight())) // new update, updated client state should have changed // ensure consensus state was pruned _, found := path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, pruneHeight) @@ -396,7 +411,9 @@ func (suite *TendermintTestSuite) TestUpdateState() { "invalid ClientMessage type", func() { clientMessage = &types.Misbehaviour{} }, - func() {}, false, + func() { + suite.Require().Empty(consensusHeights) + }, false, }, } for _, tc := range testCases { @@ -419,7 +436,7 @@ func (suite *TendermintTestSuite) TestUpdateState() { clientState := path.EndpointA.GetClientState() clientStore = suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) - _, err = clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, clientMessage) // TODO: Update tests to account for new consensus heights return value + consensusHeights, err = clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, clientMessage) if tc.expPass { suite.Require().NoError(err) @@ -556,7 +573,9 @@ func (suite *TendermintTestSuite) TestCheckForMisbehaviour() { NextValidatorsHash: header.Header.NextValidatorsHash, } - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), path.EndpointA.ClientID, clientMessage.GetHeight(), consensusState) + tmHeader, ok := clientMessage.(*types.Header) + suite.Require().True(ok) + suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), path.EndpointA.ClientID, tmHeader.GetHeight(), consensusState) }, false, }, @@ -572,7 +591,9 @@ func (suite *TendermintTestSuite) TestCheckForMisbehaviour() { NextValidatorsHash: header.Header.NextValidatorsHash, } - suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), path.EndpointA.ClientID, clientMessage.GetHeight(), consensusState) + tmHeader, ok := clientMessage.(*types.Header) + suite.Require().True(ok) + suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), path.EndpointA.ClientID, tmHeader.GetHeight(), consensusState) }, true, }, From b30380f3bc352447e6678b2204eb6e8b90cc1471 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Fri, 22 Apr 2022 17:25:12 +0200 Subject: [PATCH 3/6] updating godocs to include returned consensus height data --- modules/core/exported/client.go | 3 ++- modules/light-clients/06-solomachine/types/update.go | 1 + modules/light-clients/07-tendermint/types/update.go | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/core/exported/client.go b/modules/core/exported/client.go index e315edd2799..00759dbfa01 100644 --- a/modules/core/exported/client.go +++ b/modules/core/exported/client.go @@ -62,7 +62,8 @@ type ClientState interface { VerifyClientMessage(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) error // UpdateState updates and stores as necessary any associated information for an IBC client, such as the ClientState and corresponding ConsensusState. - // An error is returned if ClientMessage is of type Misbehaviour + // Upon successful update, a list of consensus heights is returned. + // An error is returned if ClientMessage is of type Misbehaviour. It assumes the ClientMessage has already been verified. UpdateState(sdk.Context, codec.BinaryCodec, sdk.KVStore, ClientMessage) ([]Height, error) // Update and Misbehaviour functions diff --git a/modules/light-clients/06-solomachine/types/update.go b/modules/light-clients/06-solomachine/types/update.go index 59f11124b92..d3c520f3d7d 100644 --- a/modules/light-clients/06-solomachine/types/update.go +++ b/modules/light-clients/06-solomachine/types/update.go @@ -81,6 +81,7 @@ func (cs ClientState) verifyMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, } // UpdateState updates the consensus state to the new public key and an incremented sequence. +// A list containing the updated consensus height is returned. func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) ([]exported.Height, error) { smHeader, ok := clientMsg.(*Header) if !ok { diff --git a/modules/light-clients/07-tendermint/types/update.go b/modules/light-clients/07-tendermint/types/update.go index 1a3144f2b7e..f377feba2d6 100644 --- a/modules/light-clients/07-tendermint/types/update.go +++ b/modules/light-clients/07-tendermint/types/update.go @@ -154,6 +154,7 @@ func (cs *ClientState) verifyHeader( // If we are updating to a past height, a consensus state is created for that height to be persisted in client store // If we are updating to a future height, the consensus state is created and the client state is updated to reflect // the new latest height +// A list containing the updated consensus height is returned. // 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. From 832ca2e70163f5288ef7c9addda386bb63f94675 Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Mon, 25 Apr 2022 14:23:38 +0200 Subject: [PATCH 4/6] removing unused event emission func, adding deprecation notice, removing GetHeight from solomachine Header, updating tests --- modules/core/02-client/keeper/events.go | 13 ------------- modules/core/02-client/types/events.go | 9 ++++++--- .../light-clients/06-solomachine/types/header.go | 7 ------- .../light-clients/06-solomachine/types/update.go | 2 +- .../06-solomachine/types/update_test.go | 7 ++++--- 5 files changed, 11 insertions(+), 27 deletions(-) diff --git a/modules/core/02-client/keeper/events.go b/modules/core/02-client/keeper/events.go index 2777906aa9e..08d5e9a2057 100644 --- a/modules/core/02-client/keeper/events.go +++ b/modules/core/02-client/keeper/events.go @@ -86,16 +86,3 @@ func EmitSubmitMisbehaviourEvent(ctx sdk.Context, clientID string, clientState e ), ) } - -// EmitSubmitMisbehaviourEventOnUpdate emits a client misbehaviour event on a client update event -func EmitSubmitMisbehaviourEventOnUpdate(ctx sdk.Context, clientID string, clientType string, consensusHeight exported.Height, clientMsgStr string) { - ctx.EventManager().EmitEvent( - sdk.NewEvent( - types.EventTypeSubmitMisbehaviour, - sdk.NewAttribute(types.AttributeKeyClientID, clientID), - sdk.NewAttribute(types.AttributeKeyClientType, clientType), - sdk.NewAttribute(types.AttributeKeyConsensusHeight, consensusHeight.String()), - sdk.NewAttribute(types.AttributeKeyHeader, clientMsgStr), - ), - ) -} diff --git a/modules/core/02-client/types/events.go b/modules/core/02-client/types/events.go index 05708a84859..83206f9ba7b 100644 --- a/modules/core/02-client/types/events.go +++ b/modules/core/02-client/types/events.go @@ -8,9 +8,12 @@ import ( // IBC client events const ( - AttributeKeyClientID = "client_id" - AttributeKeySubjectClientID = "subject_client_id" - AttributeKeyClientType = "client_type" + AttributeKeyClientID = "client_id" + AttributeKeySubjectClientID = "subject_client_id" + AttributeKeyClientType = "client_type" + + // Deprecated: AttributeKeyConsensusHeight is deprecated and will be removed in a future release. + // Please use AttributeKeyConsensusHeights instead. AttributeKeyConsensusHeight = "consensus_height" AttributeKeyConsensusHeights = "consensus_heights" AttributeKeyHeader = "header" diff --git a/modules/light-clients/06-solomachine/types/header.go b/modules/light-clients/06-solomachine/types/header.go index eb2cbe5f8b3..a6639a0f0c9 100644 --- a/modules/light-clients/06-solomachine/types/header.go +++ b/modules/light-clients/06-solomachine/types/header.go @@ -17,13 +17,6 @@ func (Header) ClientType() string { return exported.Solomachine } -// GetHeight returns the current sequence number as the height. -// Return clientexported.Height to satisfy interface -// Revision number is always 0 for a solo-machine -func (h Header) GetHeight() exported.Height { - return clienttypes.NewHeight(0, h.Sequence) -} - // GetPubKey unmarshals the new public key into a cryptotypes.PubKey type. // An error is returned if the new public key is nil or the cached value // is not a PubKey. diff --git a/modules/light-clients/06-solomachine/types/update.go b/modules/light-clients/06-solomachine/types/update.go index d3c520f3d7d..ec9e541415a 100644 --- a/modules/light-clients/06-solomachine/types/update.go +++ b/modules/light-clients/06-solomachine/types/update.go @@ -100,7 +100,7 @@ func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, client clientStore.Set(host.ClientStateKey(), clienttypes.MustMarshalClientState(cdc, &cs)) - return []exported.Height{smHeader.GetHeight()}, nil + return []exported.Height{clienttypes.NewHeight(0, cs.Sequence)}, nil } // CheckForMisbehaviour returns true for type Misbehaviour (passed VerifyClientMessage check), otherwise returns false diff --git a/modules/light-clients/06-solomachine/types/update_test.go b/modules/light-clients/06-solomachine/types/update_test.go index 9c80fdfc76c..0a4169f4a12 100644 --- a/modules/light-clients/06-solomachine/types/update_test.go +++ b/modules/light-clients/06-solomachine/types/update_test.go @@ -446,14 +446,15 @@ func (suite *SoloMachineTestSuite) TestUpdateState() { if tc.expPass { suite.Require().NoError(err) - suite.Require().Len(consensusHeights, 1) - suite.Require().Equal(clienttypes.NewHeight(0, clientMsg.(*types.Header).Sequence), consensusHeights[0]) - clientStateBz := suite.store.Get(host.ClientStateKey()) suite.Require().NotEmpty(clientStateBz) newClientState := clienttypes.MustUnmarshalClientState(suite.chainA.Codec, clientStateBz) + suite.Require().Len(consensusHeights, 1) + suite.Require().Equal(uint64(0), consensusHeights[0].GetRevisionNumber()) + suite.Require().Equal(newClientState.(*types.ClientState).Sequence, consensusHeights[0].GetRevisionHeight()) + suite.Require().False(newClientState.(*types.ClientState).IsFrozen) suite.Require().Equal(clientMsg.(*types.Header).Sequence+1, newClientState.(*types.ClientState).Sequence) suite.Require().Equal(clientMsg.(*types.Header).NewPublicKey, newClientState.(*types.ClientState).ConsensusState.PublicKey) From 9116fd127152e6fee2cc3a19c9807a6788e6db0e Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Tue, 26 Apr 2022 10:55:08 +0200 Subject: [PATCH 5/6] removing error return from UpdateState, returning height on duplicate header update --- modules/core/02-client/keeper/client.go | 6 +--- .../core/02-client/legacy/v100/solomachine.go | 2 +- modules/core/exported/client.go | 5 ++- .../06-solomachine/types/update.go | 8 +++-- .../06-solomachine/types/update_test.go | 9 +++--- .../07-tendermint/types/update.go | 9 +++--- .../07-tendermint/types/update_test.go | 31 ++++++++++++------- 7 files changed, 38 insertions(+), 32 deletions(-) diff --git a/modules/core/02-client/keeper/client.go b/modules/core/02-client/keeper/client.go index 6f31e9e9cd4..be35a21a50e 100644 --- a/modules/core/02-client/keeper/client.go +++ b/modules/core/02-client/keeper/client.go @@ -93,11 +93,7 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, clientMsg exporte return nil } - consensusHeights, err := clientState.UpdateState(ctx, k.cdc, clientStore, clientMsg) - if err != nil { - return err - } - + consensusHeights := clientState.UpdateState(ctx, k.cdc, clientStore, clientMsg) if len(consensusHeights) != 0 { k.Logger(ctx).Info("client state updated", "client-id", clientID, "heights", consensusHeights) diff --git a/modules/core/02-client/legacy/v100/solomachine.go b/modules/core/02-client/legacy/v100/solomachine.go index e59106aebda..3080c5c8ce4 100644 --- a/modules/core/02-client/legacy/v100/solomachine.go +++ b/modules/core/02-client/legacy/v100/solomachine.go @@ -108,7 +108,7 @@ func (cs *ClientState) VerifyClientMessage( } // UpdateState panis! -func (cs *ClientState) UpdateState(_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage) ([]exported.Height, error) { +func (cs *ClientState) UpdateState(_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, _ exported.ClientMessage) []exported.Height { panic("legacy solo machine is deprecated!") } diff --git a/modules/core/exported/client.go b/modules/core/exported/client.go index 00759dbfa01..b1ed5ca85b2 100644 --- a/modules/core/exported/client.go +++ b/modules/core/exported/client.go @@ -62,9 +62,8 @@ type ClientState interface { VerifyClientMessage(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg ClientMessage) error // UpdateState updates and stores as necessary any associated information for an IBC client, such as the ClientState and corresponding ConsensusState. - // Upon successful update, a list of consensus heights is returned. - // An error is returned if ClientMessage is of type Misbehaviour. It assumes the ClientMessage has already been verified. - UpdateState(sdk.Context, codec.BinaryCodec, sdk.KVStore, ClientMessage) ([]Height, error) + // Upon successful update, a list of consensus heights is returned. It assumes the ClientMessage has already been verified. + UpdateState(sdk.Context, codec.BinaryCodec, sdk.KVStore, ClientMessage) []Height // Update and Misbehaviour functions CheckSubstituteAndUpdateState(ctx sdk.Context, cdc codec.BinaryCodec, subjectClientStore, substituteClientStore sdk.KVStore, substituteClient ClientState) (ClientState, error) diff --git a/modules/light-clients/06-solomachine/types/update.go b/modules/light-clients/06-solomachine/types/update.go index ec9e541415a..e8c464772f7 100644 --- a/modules/light-clients/06-solomachine/types/update.go +++ b/modules/light-clients/06-solomachine/types/update.go @@ -1,6 +1,8 @@ package types import ( + "fmt" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -82,10 +84,10 @@ func (cs ClientState) verifyMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, // UpdateState updates the consensus state to the new public key and an incremented sequence. // A list containing the updated consensus height is returned. -func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) ([]exported.Height, error) { +func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) []exported.Height { smHeader, ok := clientMsg.(*Header) if !ok { - return nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected %T got %T", Header{}, clientMsg) + panic(fmt.Errorf("unsupported ClientMessage: %T", clientMsg)) } // create new solomachine ConsensusState @@ -100,7 +102,7 @@ func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, client clientStore.Set(host.ClientStateKey(), clienttypes.MustMarshalClientState(cdc, &cs)) - return []exported.Height{clienttypes.NewHeight(0, cs.Sequence)}, nil + return []exported.Height{clienttypes.NewHeight(0, cs.Sequence)} } // CheckForMisbehaviour returns true for type Misbehaviour (passed VerifyClientMessage check), otherwise returns false diff --git a/modules/light-clients/06-solomachine/types/update_test.go b/modules/light-clients/06-solomachine/types/update_test.go index 0a4169f4a12..223e468e87f 100644 --- a/modules/light-clients/06-solomachine/types/update_test.go +++ b/modules/light-clients/06-solomachine/types/update_test.go @@ -441,10 +441,8 @@ func (suite *SoloMachineTestSuite) TestUpdateState() { suite.Run(tc.name, func() { tc.setup() // setup test - consensusHeights, err := clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, clientMsg) - if tc.expPass { - suite.Require().NoError(err) + consensusHeights := clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, clientMsg) clientStateBz := suite.store.Get(host.ClientStateKey()) suite.Require().NotEmpty(clientStateBz) @@ -461,8 +459,9 @@ func (suite *SoloMachineTestSuite) TestUpdateState() { suite.Require().Equal(clientMsg.(*types.Header).NewDiversifier, newClientState.(*types.ClientState).ConsensusState.Diversifier) suite.Require().Equal(clientMsg.(*types.Header).Timestamp, newClientState.(*types.ClientState).ConsensusState.Timestamp) } else { - suite.Require().Empty(consensusHeights) - suite.Require().Error(err) + suite.Require().Panics(func() { + clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.Codec, suite.store, clientMsg) + }) } }) diff --git a/modules/light-clients/07-tendermint/types/update.go b/modules/light-clients/07-tendermint/types/update.go index f377feba2d6..b862e80fd30 100644 --- a/modules/light-clients/07-tendermint/types/update.go +++ b/modules/light-clients/07-tendermint/types/update.go @@ -2,6 +2,7 @@ package types import ( "bytes" + "fmt" "reflect" "github.com/cosmos/cosmos-sdk/codec" @@ -158,16 +159,16 @@ 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. -func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) ([]exported.Height, error) { +func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, clientMsg exported.ClientMessage) []exported.Height { header, ok := clientMsg.(*Header) if !ok { - return nil, sdkerrors.Wrapf(clienttypes.ErrInvalidClientType, "expected type %T, got %T", &Header{}, header) + panic(fmt.Errorf("expected type %T, got %T", &Header{}, clientMsg)) } // check for duplicate update if consensusState, _ := GetConsensusState(clientStore, cdc, header.GetHeight()); consensusState != nil { // perform no-op - return []exported.Height{}, nil + return []exported.Height{header.GetHeight()} } cs.pruneOldestConsensusState(ctx, cdc, clientStore) @@ -188,7 +189,7 @@ func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, client setConsensusState(clientStore, cdc, consensusState, header.GetHeight()) setConsensusMetadata(ctx, clientStore, header.GetHeight()) - return []exported.Height{height}, nil + return []exported.Height{height} } // pruneOldestConsensusState will retrieve the earliest consensus state for this clientID and check if it is expired. If it is, diff --git a/modules/light-clients/07-tendermint/types/update_test.go b/modules/light-clients/07-tendermint/types/update_test.go index c51b74c0df2..59326645248 100644 --- a/modules/light-clients/07-tendermint/types/update_test.go +++ b/modules/light-clients/07-tendermint/types/update_test.go @@ -326,7 +326,10 @@ func (suite *TendermintTestSuite) TestUpdateState() { func() { tmHeader, ok := clientMessage.(*types.Header) suite.Require().True(ok) - suite.Require().True(path.EndpointA.GetClientState().GetLatestHeight().EQ(tmHeader.GetHeight())) // new update, updated client state should have changed + + clientState := path.EndpointA.GetClientState() + suite.Require().True(clientState.GetLatestHeight().EQ(tmHeader.GetHeight())) // new update, updated client state should have changed + suite.Require().True(clientState.GetLatestHeight().EQ(consensusHeights[0])) }, true, }, { @@ -344,7 +347,9 @@ func (suite *TendermintTestSuite) TestUpdateState() { prevClientState = path.EndpointA.GetClientState() }, func() { - suite.Require().Equal(path.EndpointA.GetClientState(), prevClientState) // fill in height, no change to client state + clientState := path.EndpointA.GetClientState() + suite.Require().Equal(clientState, prevClientState) // fill in height, no change to client state + suite.Require().True(clientState.GetLatestHeight().GT(consensusHeights[0])) }, true, }, { @@ -365,7 +370,9 @@ func (suite *TendermintTestSuite) TestUpdateState() { prevConsensusState = path.EndpointA.GetConsensusState(tmHeader.GetHeight()) }, func() { - suite.Require().Equal(path.EndpointA.GetClientState(), prevClientState) + clientState := path.EndpointA.GetClientState() + suite.Require().Equal(clientState, prevClientState) + suite.Require().True(clientState.GetLatestHeight().EQ(consensusHeights[0])) tmHeader, ok := clientMessage.(*types.Header) suite.Require().True(ok) @@ -400,7 +407,10 @@ func (suite *TendermintTestSuite) TestUpdateState() { func() { tmHeader, ok := clientMessage.(*types.Header) suite.Require().True(ok) - suite.Require().True(path.EndpointA.GetClientState().GetLatestHeight().EQ(tmHeader.GetHeight())) // new update, updated client state should have changed + + clientState := path.EndpointA.GetClientState() + suite.Require().True(clientState.GetLatestHeight().EQ(tmHeader.GetHeight())) // new update, updated client state should have changed + suite.Require().True(clientState.GetLatestHeight().EQ(consensusHeights[0])) // ensure consensus state was pruned _, found := path.EndpointA.Chain.GetConsensusState(path.EndpointA.ClientID, pruneHeight) @@ -411,9 +421,8 @@ func (suite *TendermintTestSuite) TestUpdateState() { "invalid ClientMessage type", func() { clientMessage = &types.Misbehaviour{} }, - func() { - suite.Require().Empty(consensusHeights) - }, false, + func() {}, + false, }, } for _, tc := range testCases { @@ -434,12 +443,10 @@ func (suite *TendermintTestSuite) TestUpdateState() { tc.malleate() clientState := path.EndpointA.GetClientState() - clientStore = suite.chainA.App.GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), path.EndpointA.ClientID) - consensusHeights, err = clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, clientMessage) if tc.expPass { - suite.Require().NoError(err) + consensusHeights = clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, clientMessage) header := clientMessage.(*types.Header) expConsensusState := &types.ConsensusState{ @@ -454,7 +461,9 @@ func (suite *TendermintTestSuite) TestUpdateState() { suite.Require().Equal(expConsensusState, updatedConsensusState) } else { - suite.Require().Error(err) + suite.Require().Panics(func() { + clientState.UpdateState(suite.chainA.GetContext(), suite.chainA.App.AppCodec(), clientStore, clientMessage) + }) } // perform custom checks From aca9870f73714f534b173ad65e08903f1a11f6af Mon Sep 17 00:00:00 2001 From: Damian Nolan Date: Tue, 26 Apr 2022 15:22:04 +0200 Subject: [PATCH 6/6] updating event emissions as per suggestions --- modules/core/02-client/keeper/client.go | 38 ++++++++++++------------- modules/core/02-client/keeper/events.go | 15 +++++++--- modules/core/02-client/types/events.go | 9 ++---- 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/modules/core/02-client/keeper/client.go b/modules/core/02-client/keeper/client.go index be35a21a50e..a0ab6348dcf 100644 --- a/modules/core/02-client/keeper/client.go +++ b/modules/core/02-client/keeper/client.go @@ -94,30 +94,28 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, clientMsg exporte } consensusHeights := clientState.UpdateState(ctx, k.cdc, clientStore, clientMsg) - if len(consensusHeights) != 0 { - k.Logger(ctx).Info("client state updated", "client-id", clientID, "heights", consensusHeights) - defer func() { - telemetry.IncrCounterWithLabels( - []string{"ibc", "client", "update"}, - 1, - []metrics.Label{ - telemetry.NewLabel(types.LabelClientType, clientState.ClientType()), - telemetry.NewLabel(types.LabelClientID, clientID), - telemetry.NewLabel(types.LabelUpdateType, "msg"), - }, - ) - }() + k.Logger(ctx).Info("client state updated", "client-id", clientID, "heights", consensusHeights) - // Marshal the ClientMessage as an Any and encode the resulting bytes to hex. - // This prevents the event value from containing invalid UTF-8 characters - // which may cause data to be lost when JSON encoding/decoding. - clientMsgStr := hex.EncodeToString(types.MustMarshalClientMessage(k.cdc, clientMsg)) + defer func() { + telemetry.IncrCounterWithLabels( + []string{"ibc", "client", "update"}, + 1, + []metrics.Label{ + telemetry.NewLabel(types.LabelClientType, clientState.ClientType()), + telemetry.NewLabel(types.LabelClientID, clientID), + telemetry.NewLabel(types.LabelUpdateType, "msg"), + }, + ) + }() - // emitting events in the keeper emits for both begin block and handler client updates - EmitUpdateClientEvent(ctx, clientID, clientState.ClientType(), consensusHeights, clientMsgStr) + // Marshal the ClientMessage as an Any and encode the resulting bytes to hex. + // This prevents the event value from containing invalid UTF-8 characters + // which may cause data to be lost when JSON encoding/decoding. + clientMsgStr := hex.EncodeToString(types.MustMarshalClientMessage(k.cdc, clientMsg)) - } + // emitting events in the keeper emits for both begin block and handler client updates + EmitUpdateClientEvent(ctx, clientID, clientState.ClientType(), consensusHeights, clientMsgStr) return nil } diff --git a/modules/core/02-client/keeper/events.go b/modules/core/02-client/keeper/events.go index 08d5e9a2057..d49d41cb1cb 100644 --- a/modules/core/02-client/keeper/events.go +++ b/modules/core/02-client/keeper/events.go @@ -27,9 +27,14 @@ func EmitCreateClientEvent(ctx sdk.Context, clientID string, clientState exporte // EmitUpdateClientEvent emits an update client event func EmitUpdateClientEvent(ctx sdk.Context, clientID string, clientType string, consensusHeights []exported.Height, clientMsgStr string) { - var consensusHeightStr []string + var consensusHeightAttr string + if len(consensusHeights) != 0 { + consensusHeightAttr = consensusHeights[0].String() + } + + var consensusHeightsAttr []string for _, height := range consensusHeights { - consensusHeightStr = append(consensusHeightStr, height.String()) + consensusHeightsAttr = append(consensusHeightsAttr, height.String()) } ctx.EventManager().EmitEvents(sdk.Events{ @@ -37,8 +42,10 @@ func EmitUpdateClientEvent(ctx sdk.Context, clientID string, clientType string, types.EventTypeUpdateClient, sdk.NewAttribute(types.AttributeKeyClientID, clientID), sdk.NewAttribute(types.AttributeKeyClientType, clientType), - sdk.NewAttribute(types.AttributeKeyConsensusHeight, consensusHeights[0].String()), - sdk.NewAttribute(types.AttributeKeyConsensusHeight, strings.Join(consensusHeightStr, ",")), + // Deprecated: AttributeKeyConsensusHeight is deprecated and will be removed in a future release. + // Please use AttributeKeyConsensusHeights instead. + sdk.NewAttribute(types.AttributeKeyConsensusHeight, consensusHeightAttr), + sdk.NewAttribute(types.AttributeKeyConsensusHeights, strings.Join(consensusHeightsAttr, ",")), sdk.NewAttribute(types.AttributeKeyHeader, clientMsgStr), ), sdk.NewEvent( diff --git a/modules/core/02-client/types/events.go b/modules/core/02-client/types/events.go index 83206f9ba7b..05708a84859 100644 --- a/modules/core/02-client/types/events.go +++ b/modules/core/02-client/types/events.go @@ -8,12 +8,9 @@ import ( // IBC client events const ( - AttributeKeyClientID = "client_id" - AttributeKeySubjectClientID = "subject_client_id" - AttributeKeyClientType = "client_type" - - // Deprecated: AttributeKeyConsensusHeight is deprecated and will be removed in a future release. - // Please use AttributeKeyConsensusHeights instead. + AttributeKeyClientID = "client_id" + AttributeKeySubjectClientID = "subject_client_id" + AttributeKeyClientType = "client_type" AttributeKeyConsensusHeight = "consensus_height" AttributeKeyConsensusHeights = "consensus_heights" AttributeKeyHeader = "header"