Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: cosmos/ibc-go
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v7.4.0
Choose a base ref
...
head repository: cosmos/ibc-go
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: release/v7.4.x
Choose a head ref
  • 8 commits
  • 8 files changed
  • 4 contributors

Commits on Apr 5, 2024

  1. Update CHANGELOG.md

    crodriguezvega authored Apr 5, 2024
    Copy the full SHA
    885fdce View commit details

Commits on Apr 11, 2024

  1. Copy the full SHA
    762d482 View commit details
  2. Update CHANGELOG.md

    crodriguezvega authored Apr 11, 2024
    Copy the full SHA
    68f9c87 View commit details

Commits on May 20, 2024

  1. perf: minimize necessary execution on recvpacket checktx (backport #6302

    ) (#6333)
    
    * perf: minimize necessary execution on recvpacket checktx (#6302)
    
    * perf: only perform core ibc logic on recvpacket checktx
    
    * try me linter
    
    * fix: reorder if and add comment
    
    * chore: add changelog entry
    
    (cherry picked from commit 0993246)
    
    # Conflicts:
    #	CHANGELOG.md
    #	modules/core/ante/ante.go
    #	modules/core/ante/ante_test.go
    
    * fix: merge conflicts
    
    ---------
    
    Co-authored-by: colin axnér <[email protected]>
    mergify[bot] and colin-axner authored May 20, 2024
    Copy the full SHA
    90dbe6e View commit details

Commits on May 21, 2024

  1. perf: minimize logic on rechecktx for recvpacket (backport #6280) (#6342

    )
    
    * perf: minimize logic on rechecktx for recvpacket (#6280)
    
    * perf: minimize logic on rechecktx for recvpacket
    
    * refactor: rework layout for recvpacket rechecktx
    
    * test: add tests for 04-channel rechecktx func
    
    * test: add tests for core ante handler
    
    * chore: add comment explaining is rechecktx usage
    
    * linter appeasement
    
    * chore: add changelog entry
    
    * Update modules/core/ante/ante.go
    
    Co-authored-by: Carlos Rodriguez <[email protected]>
    
    * imp: use cached ctx for consistency
    
    * refactor: change added test to use expected errors
    
    * lint
    
    ---------
    
    Co-authored-by: Carlos Rodriguez <[email protected]>
    (cherry picked from commit 56ae97d)
    
    # Conflicts:
    #	modules/core/04-channel/keeper/packet.go
    #	modules/core/ante/ante.go
    
    * fix: merge conflicts
    
    * lint
    
    * lint
    
    ---------
    
    Co-authored-by: colin axnér <[email protected]>
    mergify[bot] and colin-axner authored May 21, 2024
    Copy the full SHA
    f60998d View commit details
  2. refactor(v7.4.x): performance improvements for update client in ante (#…

    …6306)
    
    * imp: add updateClientCheckTx to redunant relayer ante decorator (#6279)
    
    * imp: add checkTxUpdateClient to redunant relayer ante decorator
    
    * chore: update godoc and duplicate imports
    
    * test: add coverage for checkTxUpdateClient func
    
    * chore: rename ante func to updateClientCheckTx
    
    * refactor: ignore misbehaviour types for UpdateState in ante handler
    
    * chore: make lint-fix
    
    * test: add misbehaviour testcases to ante handler
    
    * lint
    
    * chore: add changelog entry
    
    ---------
    
    Co-authored-by: Colin Axnér <[email protected]>
    damiannolan and colin-axner authored May 21, 2024
    Copy the full SHA
    ee842be View commit details

Commits on May 22, 2024

  1. update changelog before v7.4.1 release

    crodriguezvega authored May 22, 2024
    Copy the full SHA
    5bf12e6 View commit details

Commits on May 24, 2024

  1. Update CHANGELOG.md

    crodriguezvega authored May 24, 2024
    Copy the full SHA
    864049e View commit details
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -34,6 +34,29 @@ Ref: https://keepachangelog.com/en/1.0.0/

# Changelog

## [[Unreleased]]

### Dependencies

### API Breaking

### State Machine Breaking

### Improvements

### Features

### Bug Fixes

## [v7.4.1](https://github.com/cosmos/ibc-go/releases/tag/v7.4.1) - 2024-05-22

### Improvements

* (apps/27-interchain-accounts) [\#6144](https://github.com/cosmos/ibc-go/pull/6144) Emit an event signalling that the host submodule is disabled.
* (core/ante) [\#6302](https://github.com/cosmos/ibc-go/pull/6302) Performance: Skip app callbacks during RecvPacket execution in checkTx within the redundant relay ante handler.
* (core/ante) [\#6280](https://github.com/cosmos/ibc-go/pull/6280) Performance: Skip redundant proof checking in RecvPacket execution in reCheckTx within the redundant relay ante handler.
* (core/ante) [\#6306](https://github.com/cosmos/ibc-go/pull/6306) Performance: Skip misbehaviour checks in UpdateClient flow and skip signature checks in reCheckTx mode.

## [v7.4.0](https://github.com/cosmos/ibc-go/releases/tag/v7.4.0) - 2024-04-05

## [v7.3.2](https://github.com/cosmos/ibc-go/releases/tag/v7.3.2) - 2024-01-31
1 change: 1 addition & 0 deletions modules/apps/27-interchain-accounts/host/ibc_module.go
Original file line number Diff line number Diff line change
@@ -106,6 +106,7 @@ func (im IBCModule) OnRecvPacket(
_ sdk.AccAddress,
) ibcexported.Acknowledgement {
if !im.keeper.IsHostEnabled(ctx) {
keeper.EmitHostDisabledEvent(ctx, packet)
return channeltypes.NewErrorAcknowledgement(types.ErrHostSubModuleDisabled)
}

15 changes: 15 additions & 0 deletions modules/apps/27-interchain-accounts/host/keeper/events.go
Original file line number Diff line number Diff line change
@@ -5,7 +5,9 @@ import (

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/host/types"
icatypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types"
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
"github.com/cosmos/ibc-go/v7/modules/core/exported"
)

@@ -29,3 +31,16 @@ func EmitAcknowledgementEvent(ctx sdk.Context, packet exported.PacketI, ack expo
),
)
}

// EmitHostDisabledEvent emits an event signalling that the host submodule is disabled.
func EmitHostDisabledEvent(ctx sdk.Context, packet channeltypes.Packet) {
ctx.EventManager().EmitEvent(
sdk.NewEvent(
icatypes.EventTypePacket,
sdk.NewAttribute(sdk.AttributeKeyModule, icatypes.ModuleName),
sdk.NewAttribute(icatypes.AttributeKeyHostChannelID, packet.GetDestChannel()),
sdk.NewAttribute(icatypes.AttributeKeyAckError, types.ErrHostSubModuleDisabled.Error()),
sdk.NewAttribute(icatypes.AttributeKeyAckSuccess, "false"),
),
)
}
24 changes: 24 additions & 0 deletions modules/core/04-channel/keeper/ante.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package keeper

import (
errorsmod "cosmossdk.io/errors"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
)

// RecvPacketReCheckTx applies replay protection ensuring that when relay messages are
// re-executed in ReCheckTx, we can appropriately filter out redundant relay transactions.
func (k *Keeper) RecvPacketReCheckTx(ctx sdk.Context, packet types.Packet) error {
channel, found := k.GetChannel(ctx, packet.GetDestPort(), packet.GetDestChannel())
if !found {
return errorsmod.Wrap(types.ErrChannelNotFound, packet.GetDestChannel())
}

if err := k.applyReplayProtection(ctx, packet, channel); err != nil {
return err
}

return nil
}
64 changes: 64 additions & 0 deletions modules/core/04-channel/keeper/ante_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package keeper_test

import (
"github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
ibctesting "github.com/cosmos/ibc-go/v7/testing"
)

func (suite *KeeperTestSuite) TestRecvPacketReCheckTx() {
var (
path *ibctesting.Path
packet types.Packet
)

testCases := []struct {
name string
malleate func()
expError error
}{
{
"success",
func() {},
nil,
},
{
"channel not found",
func() {
packet.DestinationPort = "invalid-port" //nolint:goconst
},
types.ErrChannelNotFound,
},
{
"redundant relay",
func() {
err := suite.chainB.App.GetIBCKeeper().ChannelKeeper.RecvPacketReCheckTx(suite.chainB.GetContext(), packet)
suite.Require().NoError(err)
},
types.ErrNoOpMsg,
},
}

for _, tc := range testCases {
tc := tc
suite.Run(tc.name, func() {
suite.SetupTest() // reset
path = ibctesting.NewPath(suite.chainA, suite.chainB)
suite.coordinator.Setup(path)

sequence, err := path.EndpointA.SendPacket(defaultTimeoutHeight, disabledTimeoutTimestamp, ibctesting.MockPacketData)
suite.Require().NoError(err)
packet = types.NewPacket(ibctesting.MockPacketData, sequence, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, defaultTimeoutHeight, disabledTimeoutTimestamp)

tc.malleate()

err = suite.chainB.App.GetIBCKeeper().ChannelKeeper.RecvPacketReCheckTx(suite.chainB.GetContext(), packet)

expPass := tc.expError == nil
if expPass {
suite.Require().NoError(err)
} else {
suite.Require().ErrorIs(err, tc.expError)
}
})
}
}
36 changes: 23 additions & 13 deletions modules/core/04-channel/keeper/packet.go
Original file line number Diff line number Diff line change
@@ -204,6 +204,29 @@ func (k Keeper) RecvPacket(
return sdkerrors.Wrap(err, "couldn't verify counterparty packet commitment")
}

if err := k.applyReplayProtection(ctx, packet, channel); err != nil {
return err
}

// log that a packet has been received & executed
k.Logger(ctx).Info(
"packet received",
"sequence", strconv.FormatUint(packet.GetSequence(), 10),
"src_port", packet.GetSourcePort(),
"src_channel", packet.GetSourceChannel(),
"dst_port", packet.GetDestPort(),
"dst_channel", packet.GetDestChannel(),
)

// emit an event that the relayer can query for
EmitRecvPacketEvent(ctx, packet, channel)

return nil
}

// applyReplayProtection ensures a packet has not already been received
// and performs the necessary state changes to ensure it cannot be received again.
func (k *Keeper) applyReplayProtection(ctx sdk.Context, packet exported.PacketI, channel types.Channel) error {
switch channel.Ordering {
case types.UNORDERED:
// check if the packet receipt has been received already for unordered channels
@@ -257,19 +280,6 @@ func (k Keeper) RecvPacket(

}

// log that a packet has been received & executed
k.Logger(ctx).Info(
"packet received",
"sequence", strconv.FormatUint(packet.GetSequence(), 10),
"src_port", packet.GetSourcePort(),
"src_channel", packet.GetSourceChannel(),
"dst_port", packet.GetDestPort(),
"dst_channel", packet.GetDestChannel(),
)

// emit an event that the relayer can query for
EmitRecvPacketEvent(ctx, packet, channel)

return nil
}

110 changes: 107 additions & 3 deletions modules/core/ante/ante.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package ante

import (
errorsmod "cosmossdk.io/errors"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
"github.com/cosmos/ibc-go/v7/modules/core/exported"
"github.com/cosmos/ibc-go/v7/modules/core/keeper"
solomachine "github.com/cosmos/ibc-go/v7/modules/light-clients/06-solomachine"
tendermint "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint"
)

type RedundantRelayDecorator struct {
@@ -30,10 +36,22 @@ func (rrd RedundantRelayDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
for _, m := range tx.GetMsgs() {
switch msg := m.(type) {
case *channeltypes.MsgRecvPacket:
response, err := rrd.k.RecvPacket(sdk.WrapSDKContext(ctx), msg)
var (
response *channeltypes.MsgRecvPacketResponse
err error
)
// when we are in ReCheckTx mode, ctx.IsCheckTx() will also return true
// therefore we must start the if statement on ctx.IsReCheckTx() to correctly
// determine which mode we are in
if ctx.IsReCheckTx() {
response, err = rrd.recvPacketReCheckTx(ctx, msg)
} else {
response, err = rrd.recvPacketCheckTx(ctx, msg)
}
if err != nil {
return ctx, err
}

if response.Result == channeltypes.NOOP {
redundancies++
}
@@ -70,8 +88,7 @@ func (rrd RedundantRelayDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
packetMsgs++

case *clienttypes.MsgUpdateClient:
_, err := rrd.k.UpdateClient(sdk.WrapSDKContext(ctx), msg)
if err != nil {
if err := rrd.updateClientCheckTx(ctx, msg); err != nil {
return ctx, err
}

@@ -90,3 +107,90 @@ func (rrd RedundantRelayDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
}
return next(ctx, tx, simulate)
}

// recvPacketCheckTx runs a subset of ibc recv packet logic to be used specifically within the RedundantRelayDecorator AnteHandler.
// It only performs core IBC receiving logic and skips any application logic.
func (rrd RedundantRelayDecorator) recvPacketCheckTx(ctx sdk.Context, msg *channeltypes.MsgRecvPacket) (*channeltypes.MsgRecvPacketResponse, error) {
// grab channel capability
_, capability, err := rrd.k.ChannelKeeper.LookupModuleByChannel(ctx, msg.Packet.DestinationPort, msg.Packet.DestinationChannel)
if err != nil {
return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id")
}

// If the packet was already received, perform a no-op
// Use a cached context to prevent accidental state changes
cacheCtx, writeFn := ctx.CacheContext()
err = rrd.k.ChannelKeeper.RecvPacket(cacheCtx, capability, msg.Packet, msg.ProofCommitment, msg.ProofHeight)

switch err {
case nil:
writeFn()
case channeltypes.ErrNoOpMsg:
return &channeltypes.MsgRecvPacketResponse{Result: channeltypes.NOOP}, nil
default:
return nil, sdkerrors.Wrap(err, "receive packet verification failed")
}

return &channeltypes.MsgRecvPacketResponse{Result: channeltypes.SUCCESS}, nil
}

// recvPacketReCheckTx runs a subset of ibc recv packet logic to be used specifically within the RedundantRelayDecorator AnteHandler.
// It only performs core IBC receiving logic and skips any application logic.
func (rrd RedundantRelayDecorator) recvPacketReCheckTx(ctx sdk.Context, msg *channeltypes.MsgRecvPacket) (*channeltypes.MsgRecvPacketResponse, error) {
// If the packet was already received, perform a no-op
// Use a cached context to prevent accidental state changes
cacheCtx, writeFn := ctx.CacheContext()
err := rrd.k.ChannelKeeper.RecvPacketReCheckTx(cacheCtx, msg.Packet)

switch err {
case nil:
writeFn()
case channeltypes.ErrNoOpMsg:
return &channeltypes.MsgRecvPacketResponse{Result: channeltypes.NOOP}, nil
default:
return nil, sdkerrors.Wrap(err, "receive packet verification failed")
}

return &channeltypes.MsgRecvPacketResponse{Result: channeltypes.SUCCESS}, nil
}

// 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
}

clientState, found := rrd.k.ClientKeeper.GetClientState(ctx, msg.ClientId)
if !found {
return errorsmod.Wrapf(clienttypes.ErrClientNotFound, msg.ClientId)
}

if status := rrd.k.ClientKeeper.GetClientStatus(ctx, clientState, msg.ClientId); status != exported.Active {
return errorsmod.Wrapf(clienttypes.ErrClientNotActive, "cannot update client (%s) with status %s", msg.ClientId, status)
}

clientStore := rrd.k.ClientKeeper.ClientStore(ctx, msg.ClientId)

if !ctx.IsReCheckTx() {
if err := clientState.VerifyClientMessage(ctx, rrd.k.Codec(), clientStore, clientMsg); err != nil {
return err
}
}

// NOTE: the following avoids panics in ante handler client updates for ibc-go v7.4.x
// without state machine breaking changes within light client modules.
switch clientMsg.(type) {
case *solomachine.Misbehaviour:
// ignore solomachine misbehaviour for update state in ante
case *tendermint.Misbehaviour:
// ignore tendermint misbehaviour for update state in ante
default:
heights := clientState.UpdateState(ctx, rrd.k.Codec(), clientStore, clientMsg)
ctx.Logger().With("module", "x/"+exported.ModuleName).Debug("ante ibc client update", "consensusHeights", heights)
}

return nil
}
Loading