Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emit event upon setting upgrade consensus state #1741

3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (modules/core/02-client) [\#1195](https://github.com/cosmos/ibc-go/pull/1210) Removing `CheckHeaderAndUpdateState` from `ClientState` interface & associated light client implementations.
* (modules/core/02-client) [\#1189](https://github.com/cosmos/ibc-go/pull/1212) Removing `CheckMisbehaviourAndUpdateState` from `ClientState` interface & associated light client implementations.
* (modules/core/exported) [\#1206](https://github.com/cosmos/ibc-go/pull/1206) Adding new method `UpdateState` to `ClientState` interface.
* (testing) [\#1302](https://github.com/cosmos/ibc-go/pull/1302) Change testchain default behaviour to use a chainID in the revision format. Set `ChainIDSuffix` to an empty string to disable this functionality.
* (testing) [\#1302](https://github.com/cosmos/ibc-go/pull/1302) Change testchain default behaviour to use a chainID in the revision format. Set `ChainIDSuffix` to an empty string to disable this functionality.
* (modules/core/02-client) [\#1741](https://github.com/cosmos/ibc-go/pull/1741) Emitting a new `upgrade_chain` event upon setting upgrade consensus state.

### Features

Expand Down
1 change: 1 addition & 0 deletions modules/core/02-client/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) {
bz := k.MustMarshalConsensusState(upgradedConsState)

k.SetUpgradedConsensusState(ctx, plan.Height, bz)
keeper.EmitUpgradeChainEvent(ctx, plan.Height)
}
}
}
55 changes: 55 additions & 0 deletions modules/core/02-client/abci_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package client_test

import (
"strings"
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/suite"
abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"

upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should we group upgradetypes with the above?


client "github.com/cosmos/ibc-go/v3/modules/core/02-client"
"github.com/cosmos/ibc-go/v3/modules/core/02-client/types"
ibctmtypes "github.com/cosmos/ibc-go/v3/modules/light-clients/07-tendermint"
Expand Down Expand Up @@ -74,3 +77,55 @@ func (suite *ClientTestSuite) TestBeginBlockerConsensusState() {
suite.Require().NoError(err)
suite.Require().Equal(bz, consState)
}

func (suite *ClientTestSuite) TestBeginBlockerWithUpgradePlan_EmitsUpgradeChainEvent() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I don't think underscores in test names are convention in Go, right?
Could use TestBeginBlockerUpgradeEvents and TestBeginBlockerUpgradeEventsAbsence?

But I mean its probably fine to be honest, the names are meaningful as is!

Copy link
Contributor Author

@chatton chatton Jul 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah no harm simplifying the name a bit, great suggestion!

plan := &upgradetypes.Plan{
Name: "test",
Height: suite.chainA.GetContext().BlockHeight() + 1,
}
// set upgrade plan in the upgrade store
store := suite.chainA.GetContext().KVStore(suite.chainA.GetSimApp().GetKey(upgradetypes.StoreKey))
bz := suite.chainA.App.AppCodec().MustMarshal(plan)
store.Set(upgradetypes.PlanKey(), bz)

nextValsHash := []byte("nextValsHash")
newCtx := suite.chainA.GetContext().WithBlockHeader(tmproto.Header{
Height: suite.chainA.GetContext().BlockHeight(),
NextValidatorsHash: nextValsHash,
})

err := suite.chainA.GetSimApp().UpgradeKeeper.SetUpgradedClient(newCtx, plan.Height, []byte("client state"))
suite.Require().NoError(err)

cacheCtx, writeCache := suite.chainA.GetContext().CacheContext()

client.BeginBlocker(cacheCtx, suite.chainA.App.GetIBCKeeper().ClientKeeper)
writeCache()

suite.requireContainsEvent(cacheCtx.EventManager().Events(), types.EventTypeUpgradeChain, true)
Comment on lines +99 to +104
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just as a note, the caching of the context should be unnecessary in this situation. You should be able to get the event via suite.chainA.GetContext() after calling begin blocker on that context

}

func (suite *ClientTestSuite) TestBeginBlockerWithoutUpgradePlan_DoesNotEmitUpgradeChainEvent() {
cacheCtx, writeCache := suite.chainA.GetContext().CacheContext()
client.BeginBlocker(suite.chainA.GetContext(), suite.chainA.App.GetIBCKeeper().ClientKeeper)
writeCache()
suite.requireContainsEvent(cacheCtx.EventManager().Events(), types.EventTypeUpgradeChain, false)
}

// requireContainsEvent verifies if an event of a specific type was emitted.
func (suite *ClientTestSuite) requireContainsEvent(events sdk.Events, eventType string, shouldContain bool) {
found := false
var eventTypes []string
for _, e := range events {
eventTypes = append(eventTypes, e.Type)
if e.Type == eventType {
found = true
break
}
}
if shouldContain {
suite.Require().True(found, "event type %s was not found in %s", eventType, strings.Join(eventTypes, ","))
} else {
suite.Require().False(found, "event type %s was found in %s", eventType, strings.Join(eventTypes, ","))
}
}
13 changes: 13 additions & 0 deletions modules/core/02-client/keeper/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package keeper

import (
"encoding/hex"
"strconv"
"strings"

"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

"github.com/cosmos/ibc-go/v3/modules/core/02-client/types"
"github.com/cosmos/ibc-go/v3/modules/core/exported"
Expand Down Expand Up @@ -101,3 +103,14 @@ func EmitSubmitMisbehaviourEvent(ctx sdk.Context, clientID string, clientState e
),
)
}

// EmitUpgradeChainEvent emits an upgrade chain event.
func EmitUpgradeChainEvent(ctx sdk.Context, height int64) {
ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
types.EventTypeUpgradeChain,
sdk.NewAttribute(types.AttributeKeyUpgradePlanHeight, strconv.Itoa(int(height))),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this PR Fede recommended to use strconv.FormatUint for converting uint64 to string. Could we not use strconv.FormatInt instead here? It's not like I have a strong opinion for using one or the other way, but I guess it would be nice to settle in one (if possible) and use that always. :)

Copy link
Contributor Author

@chatton chatton Jul 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type is int64 rather than uint64 but there is also a strconv.FormatInt(height, 10) we can use instead!

sdk.NewAttribute(types.AttributeKeyUpgradeStore, upgradetypes.StoreKey), // which store to query proof of consensus state from
),
})
}
15 changes: 9 additions & 6 deletions modules/core/02-client/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import (

// IBC client events
const (
AttributeKeyClientID = "client_id"
AttributeKeySubjectClientID = "subject_client_id"
AttributeKeyClientType = "client_type"
AttributeKeyConsensusHeight = "consensus_height"
AttributeKeyConsensusHeights = "consensus_heights"
AttributeKeyHeader = "header"
AttributeKeyClientID = "client_id"
AttributeKeySubjectClientID = "subject_client_id"
AttributeKeyClientType = "client_type"
AttributeKeyConsensusHeight = "consensus_height"
AttributeKeyConsensusHeights = "consensus_heights"
AttributeKeyHeader = "header"
AttributeKeyUpgradeStore = "upgrade_store"
AttributeKeyUpgradePlanHeight = "upgrade_plan_height"
)

// IBC client events vars
Expand All @@ -23,6 +25,7 @@ var (
EventTypeUpgradeClient = "upgrade_client"
EventTypeSubmitMisbehaviour = "client_misbehaviour"
EventTypeUpdateClientProposal = "update_client_proposal"
EventTypeUpgradeChain = "upgrade_chain"

AttributeValueCategory = fmt.Sprintf("%s_%s", host.ModuleName, SubModuleName)
)