Skip to content

Commit a1ed61c

Browse files
perf: minimize necessary execution on recvpacket checktx (backport #6302) (#6334)
* 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]>
1 parent 48b8858 commit a1ed61c

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
4444

4545
### Improvements
4646

47+
* (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.
48+
4749
### Features
4850

4951
### Bug Fixes

modules/core/ante/ante.go

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package ante
22

33
import (
44
sdk "github.com/cosmos/cosmos-sdk/types"
5+
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
56

67
clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
78
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
@@ -30,10 +31,22 @@ func (rrd RedundantRelayDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
3031
for _, m := range tx.GetMsgs() {
3132
switch msg := m.(type) {
3233
case *channeltypes.MsgRecvPacket:
33-
response, err := rrd.k.RecvPacket(sdk.WrapSDKContext(ctx), msg)
34+
var (
35+
response *channeltypes.MsgRecvPacketResponse
36+
err error
37+
)
38+
// when we are in ReCheckTx mode, ctx.IsCheckTx() will also return true
39+
// there we must start the if statement on ctx.IsReCheckTx() to correctly
40+
// determine which mode we are in
41+
if ctx.IsReCheckTx() {
42+
response, err = rrd.k.RecvPacket(sdk.WrapSDKContext(ctx), msg)
43+
} else {
44+
response, err = rrd.recvPacketCheckTx(ctx, msg)
45+
}
3446
if err != nil {
3547
return ctx, err
3648
}
49+
3750
if response.Result == channeltypes.NOOP {
3851
redundancies++
3952
}
@@ -90,3 +103,29 @@ func (rrd RedundantRelayDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula
90103
}
91104
return next(ctx, tx, simulate)
92105
}
106+
107+
// recvPacketCheckTx runs a subset of ibc recv packet logic to be used specifically within the RedundantRelayDecorator AnteHandler.
108+
// It only performs core IBC receiving logic and skips any application logic.
109+
func (rrd RedundantRelayDecorator) recvPacketCheckTx(ctx sdk.Context, msg *channeltypes.MsgRecvPacket) (*channeltypes.MsgRecvPacketResponse, error) {
110+
// grab channel capability
111+
_, capability, err := rrd.k.ChannelKeeper.LookupModuleByChannel(ctx, msg.Packet.DestinationPort, msg.Packet.DestinationChannel)
112+
if err != nil {
113+
return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id")
114+
}
115+
116+
// If the packet was already received, perform a no-op
117+
// Use a cached context to prevent accidental state changes
118+
cacheCtx, writeFn := ctx.CacheContext()
119+
err = rrd.k.ChannelKeeper.RecvPacket(cacheCtx, capability, msg.Packet, msg.ProofCommitment, msg.ProofHeight)
120+
121+
switch err {
122+
case nil:
123+
writeFn()
124+
case channeltypes.ErrNoOpMsg:
125+
return &channeltypes.MsgRecvPacketResponse{Result: channeltypes.NOOP}, nil
126+
default:
127+
return nil, sdkerrors.Wrap(err, "receive packet verification failed")
128+
}
129+
130+
return &channeltypes.MsgRecvPacketResponse{Result: channeltypes.SUCCESS}, nil
131+
}

modules/core/ante/ante_test.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ package ante_test
33
import (
44
"testing"
55

6-
sdk "github.com/cosmos/cosmos-sdk/types"
76
"github.com/stretchr/testify/require"
87
"github.com/stretchr/testify/suite"
98

9+
sdk "github.com/cosmos/cosmos-sdk/types"
10+
1011
clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
1112
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
1213
host "github.com/cosmos/ibc-go/v7/modules/core/24-host"
@@ -45,7 +46,7 @@ func TestAnteTestSuite(t *testing.T) {
4546
}
4647

4748
// createRecvPacketMessage creates a RecvPacket message for a packet sent from chain A to chain B.
48-
func (suite *AnteTestSuite) createRecvPacketMessage(isRedundant bool) sdk.Msg {
49+
func (suite *AnteTestSuite) createRecvPacketMessage(isRedundant bool) *channeltypes.MsgRecvPacket {
4950
sequence, err := suite.path.EndpointA.SendPacket(clienttypes.NewHeight(2, 0), 0, ibctesting.MockPacketData)
5051
suite.Require().NoError(err)
5152

@@ -450,6 +451,15 @@ func (suite *AnteTestSuite) TestAnteDecorator() {
450451
},
451452
false,
452453
},
454+
{
455+
"no success on recvPacket checkTx, no capability found",
456+
func(suite *AnteTestSuite) []sdk.Msg {
457+
msg := suite.createRecvPacketMessage(false)
458+
msg.Packet.DestinationPort = "invalid-port"
459+
return []sdk.Msg{msg}
460+
},
461+
false,
462+
},
453463
}
454464

455465
for _, tc := range testCases {

0 commit comments

Comments
 (0)