Skip to content
Prev Previous commit
Next Next commit
Merge branch 'main' into aditya/multi-payload
  • Loading branch information
gjermundgaraba committed Jun 22, 2025
commit 003a38c33762d9b96946efce0b31a535996c1055
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Features

* [\#8285](https://github.com/cosmos/ibc-go/pull/8285) Packet forward middleware.
* [\#8545](https://github.com/cosmos/ibc-go/pull/8545) Support sending multiple payloads in the same packet for atomic payload execution.
* [\#8473](https://github.com/cosmos/ibc-go/pull/8473) Support sending v2 packets on v1 channel identifiers using aliasing.

### Dependencies

Expand All @@ -64,8 +66,6 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Features

* [\#8545](https://github.com/cosmos/ibc-go/pull/8545) Support sending multiple payloads in the same packet for atomic payload execution.

### Dependencies

* [\#8369](https://github.com/cosmos/ibc-go/pull/8369) Bump **github.com/CosmWasm/wasmvm** to **2.2.4**
Expand Down
12 changes: 0 additions & 12 deletions modules/core/04-channel/v2/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,6 @@ func (k *Keeper) RecvPacket(goCtx context.Context, msg *types.MsgRecvPacket) (*t

var isAsync bool
isSuccess := true
// Cache context before doing any application callbacks
// so that we may write or discard state changes from callbacks atomically.
cacheCtx, writeFn = ctx.CacheContext()
for _, pd := range msg.Packet.Payloads {
cb := k.Router.Route(pd.DestinationPort)
res := cb.OnRecvPacket(cacheCtx, msg.Packet.SourceClient, msg.Packet.DestinationClient, msg.Packet.Sequence, pd, signer)
Expand All @@ -110,15 +107,6 @@ func (k *Keeper) RecvPacket(goCtx context.Context, msg *types.MsgRecvPacket) (*t
break
}

// successful app acknowledgement cannot equal sentinel error acknowledgement
if bytes.Equal(res.GetAcknowledgement(), types.ErrorAcknowledgement[:]) {
return nil, errorsmod.Wrapf(types.ErrInvalidAcknowledgement, "application acknowledgement cannot be sentinel error acknowledgement")
}
// write application state changes for asynchronous and successful acknowledgements
writeFn()
// append app acknowledgement to the overall acknowledgement
ack.AppAcknowledgements = append(ack.AppAcknowledgements, res.Acknowledgement)

if res.Status == types.PacketStatus_Async {
// Set packet acknowledgement to async if any of the acknowledgements are async.
isAsync = true
Expand Down
20 changes: 10 additions & 10 deletions modules/core/04-channel/v2/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (s *KeeperTestSuite) TestMsgSendPacket() {
name: "success: valid timeout timestamp",
malleate: func() {
// ensure a message timeout.
timeoutTimestamp = uint64(suite.chainA.GetContext().BlockTime().Add(types.MaxTimeoutDelta - 10*time.Second).Unix())
timeoutTimestamp = uint64(s.chainA.GetContext().BlockTime().Add(types.MaxTimeoutDelta - 10*time.Second).Unix())
expectedPacket = types.NewPacket(1, path.EndpointA.ClientID, path.EndpointB.ClientID, timeoutTimestamp, payloads...)
},
expError: nil,
Expand Down Expand Up @@ -128,7 +128,7 @@ func (s *KeeperTestSuite) TestMsgSendPacket() {
path = ibctesting.NewPath(s.chainA, s.chainB)
path.SetupV2()

timeoutTimestamp = suite.chainA.GetTimeoutTimestampSecs()
timeoutTimestamp = s.chainA.GetTimeoutTimestampSecs()
payloads = []types.Payload{mockv2.NewMockPayload(mockv2.ModuleNameA, mockv2.ModuleNameB)}

tc.malleate()
Expand Down Expand Up @@ -321,7 +321,7 @@ func (s *KeeperTestSuite) TestMsgRecvPacket() {

var err error
packet, err = path.EndpointA.MsgSendPacket(timeoutTimestamp, tc.payloads...)
suite.Require().NoError(err)
s.Require().NoError(err)

// default expected acknowledgement is a single successful acknowledgement for moduleB.
expAck = types.Acknowledgement{
Expand Down Expand Up @@ -349,7 +349,7 @@ func (s *KeeperTestSuite) TestMsgRecvPacket() {
s.Require().False(ackWritten)
} else { // successful or failed acknowledgement
// ack should be written for synchronous app (default mock application behaviour).
suite.Require().True(ackWritten)
s.Require().True(ackWritten)
expectedBz := types.CommitAcknowledgement(expAck)

actualAckBz := ck.GetPacketAcknowledgement(path.EndpointB.Chain.GetContext(), packet.DestinationClient, packet.Sequence)
Expand Down Expand Up @@ -526,7 +526,7 @@ func (s *KeeperTestSuite) TestMsgAcknowledgement() {
var err error
// Send packet from A to B
packet, err = path.EndpointA.MsgSendPacket(timeoutTimestamp, tc.payloads...)
suite.Require().NoError(err)
s.Require().NoError(err)

err = path.EndpointB.MsgRecvPacket(packet)
s.Require().NoError(err)
Expand Down Expand Up @@ -585,7 +585,7 @@ func (s *KeeperTestSuite) TestMsgTimeout() {
{
name: "success: multiple payloads",
malleate: func() {
suite.Require().NoError(path.EndpointA.UpdateClient())
s.Require().NoError(path.EndpointA.UpdateClient())
},
payloads: []types.Payload{
mockv2.NewMockPayload(mockv2.ModuleNameA, mockv2.ModuleNameB),
Expand Down Expand Up @@ -638,7 +638,7 @@ func (s *KeeperTestSuite) TestMsgTimeout() {
}
return nil
}
suite.Require().NoError(path.EndpointA.UpdateClient())
s.Require().NoError(path.EndpointA.UpdateClient())
},
payloads: []types.Payload{
mockv2.NewMockPayload(mockv2.ModuleNameA, mockv2.ModuleNameB),
Expand Down Expand Up @@ -688,12 +688,12 @@ func (s *KeeperTestSuite) TestMsgTimeout() {
// Send packet from A to B
// make timeoutTimestamp 1 second more than sending chain time to ensure it passes SendPacket
// and times out successfully after update
timeoutTimestamp := uint64(suite.chainA.GetContext().BlockTime().Add(time.Second).Unix())
timeoutTimestamp := uint64(s.chainA.GetContext().BlockTime().Add(time.Second).Unix())

var err error
packet, err = path.EndpointA.MsgSendPacket(timeoutTimestamp, tc.payloads...)
suite.Require().NoError(err)
suite.Require().NotEmpty(packet)
s.Require().NoError(err)
s.Require().NotEmpty(packet)

tc.malleate()

Expand Down
16 changes: 8 additions & 8 deletions modules/core/04-channel/v2/keeper/packet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ func (s *KeeperTestSuite) TestRecvPacket() {

// send packet with multiple payloads
packet, err = path.EndpointA.MsgSendPacket(timeoutTimestamp, payload, payload)
suite.Require().NoError(err)
s.Require().NoError(err)

tc.malleate()

Expand Down Expand Up @@ -369,7 +369,7 @@ func (s *KeeperTestSuite) TestWriteAcknowledgement() {
"failure: async packet not found",
func() {
packet.Sequence = 2
suite.chainB.App.GetIBCKeeper().ChannelKeeperV2.SetPacketReceipt(suite.chainB.GetContext(), packet.DestinationClient, packet.Sequence)
s.chainB.App.GetIBCKeeper().ChannelKeeperV2.SetPacketReceipt(s.chainB.GetContext(), packet.DestinationClient, packet.Sequence)
},
types.ErrInvalidAcknowledgement,
},
Expand Down Expand Up @@ -400,10 +400,10 @@ func (s *KeeperTestSuite) TestWriteAcknowledgement() {
// mock receive with async acknowledgement
// we mock the receive of a sequence 1 manually so that the malleate can change the packet sequence
// in order to not have the keys do not match the packet sequence
suite.chainB.App.GetIBCKeeper().ChannelKeeperV2.SetPacketReceipt(suite.chainB.GetContext(), packet.DestinationClient, 1)
suite.chainB.App.GetIBCKeeper().ChannelKeeperV2.SetAsyncPacket(suite.chainB.GetContext(), packet.DestinationClient, 1, packet)
s.chainB.App.GetIBCKeeper().ChannelKeeperV2.SetPacketReceipt(s.chainB.GetContext(), packet.DestinationClient, 1)
s.chainB.App.GetIBCKeeper().ChannelKeeperV2.SetAsyncPacket(s.chainB.GetContext(), packet.DestinationClient, 1, packet)

err := suite.chainB.App.GetIBCKeeper().ChannelKeeperV2.WriteAcknowledgement(suite.chainB.GetContext(), packet.DestinationClient, packet.Sequence, ack)
err := s.chainB.App.GetIBCKeeper().ChannelKeeperV2.WriteAcknowledgement(s.chainB.GetContext(), packet.DestinationClient, packet.Sequence, ack)

expPass := tc.expError == nil
if expPass {
Expand Down Expand Up @@ -503,7 +503,7 @@ func (s *KeeperTestSuite) TestAcknowledgePacket() {

// send packet with multiple payloads
packet, err = path.EndpointA.MsgSendPacket(timeoutTimestamp, payload, payload, payload)
suite.Require().NoError(err)
s.Require().NoError(err)

err = path.EndpointB.MsgRecvPacket(packet)
s.Require().NoError(err)
Expand Down Expand Up @@ -561,9 +561,9 @@ func (s *KeeperTestSuite) TestTimeoutPacket() {
func() {
// send packet with multiple payloads
packet.Payloads = append(packet.Payloads, payload)
_, _, err := suite.chainA.App.GetIBCKeeper().ChannelKeeperV2.SendPacketTest(suite.chainA.GetContext(), packet.SourceClient,
_, _, err := s.chainA.App.GetIBCKeeper().ChannelKeeperV2.SendPacketTest(s.chainA.GetContext(), packet.SourceClient,
packet.TimeoutTimestamp, packet.Payloads)
suite.Require().NoError(err, "send packet failed")
s.Require().NoError(err, "send packet failed")
},
nil,
},
Expand Down
12 changes: 6 additions & 6 deletions testing/endpoint_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ func (ep *Endpoint) RegisterCounterparty() error {
}

// MsgSendPacket sends a packet on the associated endpoint using a predefined sender. The constructed packet is returned.
func (endpoint *Endpoint) MsgSendPacket(timeoutTimestamp uint64, payloads ...channeltypesv2.Payload) (channeltypesv2.Packet, error) {
func (ep *Endpoint) MsgSendPacket(timeoutTimestamp uint64, payloads ...channeltypesv2.Payload) (channeltypesv2.Packet, error) {
senderAccount := SenderAccount{
SenderPrivKey: ep.Chain.SenderPrivKey,
SenderAccount: ep.Chain.SenderAccount,
}

return endpoint.MsgSendPacketWithSender(timeoutTimestamp, payloads, senderAccount)
return ep.MsgSendPacketWithSender(timeoutTimestamp, payloads, senderAccount)
}

// MsgSendPacketWithSender sends a packet on the associated endpoint using the provided sender. The constructed packet is returned.
func (endpoint *Endpoint) MsgSendPacketWithSender(timeoutTimestamp uint64, payloads []channeltypesv2.Payload, sender SenderAccount) (channeltypesv2.Packet, error) {
msgSendPacket := channeltypesv2.NewMsgSendPacket(endpoint.ClientID, timeoutTimestamp, sender.SenderAccount.GetAddress().String(), payloads...)
func (ep *Endpoint) MsgSendPacketWithSender(timeoutTimestamp uint64, payloads []channeltypesv2.Payload, sender SenderAccount) (channeltypesv2.Packet, error) {
msgSendPacket := channeltypesv2.NewMsgSendPacket(ep.ClientID, timeoutTimestamp, sender.SenderAccount.GetAddress().String(), payloads...)

res, err := ep.Chain.SendMsgsWithSender(sender, msgSendPacket)
if err != nil {
Expand All @@ -56,9 +56,9 @@ func (endpoint *Endpoint) MsgSendPacketWithSender(timeoutTimestamp uint64, paylo
if err != nil {
return channeltypesv2.Packet{}, err
}
packet := channeltypesv2.NewPacket(sendResponse.Sequence, endpoint.ClientID, endpoint.Counterparty.ClientID, timeoutTimestamp, payloads...)
packet := channeltypesv2.NewPacket(sendResponse.Sequence, ep.ClientID, ep.Counterparty.ClientID, timeoutTimestamp, payloads...)

err = endpoint.Counterparty.UpdateClient()
err = ep.Counterparty.UpdateClient()
if err != nil {
return channeltypesv2.Packet{}, err
}
Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.