diff --git a/modules/apps/29-fee/ibc_middleware.go b/modules/apps/29-fee/ibc_middleware.go index 8f5b0dca759..218efb08882 100644 --- a/modules/apps/29-fee/ibc_middleware.go +++ b/modules/apps/29-fee/ibc_middleware.go @@ -345,7 +345,7 @@ func (im IBCMiddleware) OnChanUpgradeInit( versionMetadata, err := types.MetadataFromVersion(proposedVersion) if err != nil { // since it is valid for fee version to not be specified, the upgrade version may be for a middleware - // or application further down in the stack. Thus, passthrough to next middleware or application in callstack. + // or application further down in the stack. Thus, pass through to next middleware or application in callstack. return cbs.OnChanUpgradeInit(ctx, portID, channelID, proposedOrder, proposedConnectionHops, proposedVersion) } @@ -367,7 +367,7 @@ func (im IBCMiddleware) OnChanUpgradeInit( return string(versionBz), nil } -// OnChanUpgradeTry implement s the IBCModule interface +// OnChanUpgradeTry implements the IBCModule interface func (im IBCMiddleware) OnChanUpgradeTry(ctx sdk.Context, portID, channelID string, proposedOrder channeltypes.Order, proposedConnectionHops []string, counterpartyVersion string) (string, error) { cbs, ok := im.app.(porttypes.UpgradableModule) if !ok { @@ -377,7 +377,7 @@ func (im IBCMiddleware) OnChanUpgradeTry(ctx sdk.Context, portID, channelID stri versionMetadata, err := types.MetadataFromVersion(counterpartyVersion) if err != nil { // since it is valid for fee version to not be specified, the counterparty upgrade version may be for a middleware - // or application further down in the stack. Thus, passthrough to next middleware or application in callstack. + // or application further down in the stack. Thus, pass through to next middleware or application in callstack. return cbs.OnChanUpgradeTry(ctx, portID, channelID, proposedOrder, proposedConnectionHops, counterpartyVersion) } @@ -409,7 +409,7 @@ func (im IBCMiddleware) OnChanUpgradeAck(ctx sdk.Context, portID, channelID, cou versionMetadata, err := types.MetadataFromVersion(counterpartyVersion) if err != nil { // since it is valid for fee version to not be specified, the counterparty upgrade version may be for a middleware - // or application further down in the stack. Thus, passthrough to next middleware or application in callstack. + // or application further down in the stack. Thus, pass through to next middleware or application in callstack. return cbs.OnChanUpgradeAck(ctx, portID, channelID, counterpartyVersion) } @@ -430,13 +430,13 @@ func (im IBCMiddleware) OnChanUpgradeOpen(ctx sdk.Context, portID, channelID str versionMetadata, err := types.MetadataFromVersion(proposedVersion) if err != nil { - // set fee disabled and passthrough to the next middleware or application in callstack. + // set fee disabled and pass through to the next middleware or application in callstack. im.keeper.DeleteFeeEnabled(ctx, portID, channelID) cbs.OnChanUpgradeOpen(ctx, portID, channelID, proposedOrder, proposedConnectionHops, proposedVersion) return } - // set fee enabled and passthrough to the next middleware of application in callstack. + // set fee enabled and pass through to the next middleware of application in callstack. im.keeper.SetFeeEnabled(ctx, portID, channelID) cbs.OnChanUpgradeOpen(ctx, portID, channelID, proposedOrder, proposedConnectionHops, versionMetadata.AppVersion) } diff --git a/modules/core/ante/ante.go b/modules/core/ante/ante.go index 6ab7e63d26e..ac4950964a0 100644 --- a/modules/core/ante/ante.go +++ b/modules/core/ante/ante.go @@ -1,10 +1,13 @@ package ante import ( + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" + "github.com/cosmos/ibc-go/v8/modules/core/exported" "github.com/cosmos/ibc-go/v8/modules/core/keeper" ) @@ -70,8 +73,7 @@ func (rrd RedundantRelayDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula packetMsgs++ case *clienttypes.MsgUpdateClient: - _, err := rrd.k.UpdateClient(ctx, msg) - if err != nil { + if err := rrd.updateClientCheckTx(ctx, msg); err != nil { return ctx, err } @@ -90,3 +92,34 @@ func (rrd RedundantRelayDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula } return next(ctx, tx, simulate) } + +// updateClientCheckTx runs a subset of ibc client update logic to be used specifically within the RedundantRelayDecorator AnteHandler. +// The following function performs ibc client message verification for CheckTx only and state updates in both CheckTx and ReCheckTx. +// Note that misbehaviour checks are omitted. +func (rrd RedundantRelayDecorator) updateClientCheckTx(ctx sdk.Context, msg *clienttypes.MsgUpdateClient) error { + clientMsg, err := clienttypes.UnpackClientMessage(msg.ClientMessage) + if err != nil { + return err + } + + if status := rrd.k.ClientKeeper.GetClientStatus(ctx, msg.ClientId); status != exported.Active { + return errorsmod.Wrapf(clienttypes.ErrClientNotActive, "cannot update client (%s) with status %s", msg.ClientId, status) + } + + clientModule, found := rrd.k.ClientKeeper.Route(msg.ClientId) + if !found { + return errorsmod.Wrap(clienttypes.ErrRouteNotFound, msg.ClientId) + } + + if !ctx.IsReCheckTx() { + if err := clientModule.VerifyClientMessage(ctx, msg.ClientId, clientMsg); err != nil { + return err + } + } + + heights := clientModule.UpdateState(ctx, msg.ClientId, clientMsg) + + ctx.Logger().With("module", "x/"+exported.ModuleName).Debug("ante ibc client update", "consensusHeights", heights) + + return nil +} diff --git a/modules/core/ante/ante_test.go b/modules/core/ante/ante_test.go index 8f5071e13fe..2033f1f4e18 100644 --- a/modules/core/ante/ante_test.go +++ b/modules/core/ante/ante_test.go @@ -6,6 +6,7 @@ import ( "github.com/stretchr/testify/require" testifysuite "github.com/stretchr/testify/suite" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" @@ -13,6 +14,7 @@ import ( host "github.com/cosmos/ibc-go/v8/modules/core/24-host" "github.com/cosmos/ibc-go/v8/modules/core/ante" "github.com/cosmos/ibc-go/v8/modules/core/exported" + ibctm "github.com/cosmos/ibc-go/v8/modules/light-clients/07-tendermint" ibctesting "github.com/cosmos/ibc-go/v8/testing" ) @@ -387,6 +389,39 @@ func (suite *AnteTestSuite) TestAnteDecorator() { }, false, }, + { + "no success on one new UpdateClient message: invalid client identifier", + func(suite *AnteTestSuite) []sdk.Msg { + clientMsg, err := codectypes.NewAnyWithValue(&ibctm.Header{}) + suite.Require().NoError(err) + + msgs := []sdk.Msg{&clienttypes.MsgUpdateClient{ClientId: ibctesting.InvalidID, ClientMessage: clientMsg}} + return msgs + }, + false, + }, + { + "no success on one new UpdateClient message: client module not found", + func(suite *AnteTestSuite) []sdk.Msg { + clientMsg, err := codectypes.NewAnyWithValue(&ibctm.Header{}) + suite.Require().NoError(err) + + msgs := []sdk.Msg{&clienttypes.MsgUpdateClient{ClientId: clienttypes.FormatClientIdentifier("08-wasm", 1), ClientMessage: clientMsg}} + return msgs + }, + false, + }, + { + "no success on one new UpdateClient message: no consensus state for trusted height", + func(suite *AnteTestSuite) []sdk.Msg { + clientMsg, err := codectypes.NewAnyWithValue(&ibctm.Header{TrustedHeight: clienttypes.NewHeight(1, 10000)}) + suite.Require().NoError(err) + + msgs := []sdk.Msg{&clienttypes.MsgUpdateClient{ClientId: suite.path.EndpointA.ClientID, ClientMessage: clientMsg}} + return msgs + }, + false, + }, { "no success on three new UpdateClient messages and three redundant messages of each type", func(suite *AnteTestSuite) []sdk.Msg {