Skip to content

Commit

Permalink
chore: add ParsePacketFromEvents testing helper function (#904)
Browse files Browse the repository at this point in the history
## Description



ref: #891

---

Before we can merge this PR, please make sure that all the following items have been
checked off. If any of the checklist items are not applicable, please leave them but
write a little note why.

- [ ] Targeted PR against correct branch (see [CONTRIBUTING.md](https://github.com/cosmos/ibc-go/blob/master/CONTRIBUTING.md#pr-targeting))
- [ ] Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
- [ ] Code follows the [module structure standards](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules/structure.md).
- [ ] Wrote unit and integration [tests](https://github.com/cosmos/ibc-go/blob/master/CONTRIBUTING.md#testing)
- [ ] Updated relevant documentation (`docs/`) or specification (`x/<module>/spec/`)
- [ ] Added relevant `godoc` [comments](https://blog.golang.org/godoc-documenting-go-code).
- [ ] Added a relevant changelog entry to the `Unreleased` section in `CHANGELOG.md`
- [ ] Re-reviewed `Files changed` in the Github PR explorer
- [ ] Review `Codecov Report` in the comment section below once CI passes
  • Loading branch information
colin-axner authored Feb 14, 2022
1 parent fb2f041 commit c27d5b5
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Improvements

* (testing) [\#904](https://github.com/cosmos/ibc-go/pull/904) Add `ParsePacketFromEvents` function to the testing package. Useful when sending/relaying packets via the testing package.
* (testing) [\#893](https://github.com/cosmos/ibc-go/pull/893) Support custom private keys for testing.
* (testing) [\#810](https://github.com/cosmos/ibc-go/pull/810) Additional testing function added to `Endpoint` type called `RecvPacketWithResult`. Performs the same functionality as the existing `RecvPacket` function but also returns the message result. `path.RelayPacket` no longer uses the provided acknowledgement argument and instead obtains the acknowledgement via MsgRecvPacket events.
* (connection) [\#721](https://github.com/cosmos/ibc-go/pull/721) Simplify connection handshake error messages when unpacking client state.
Expand Down
8 changes: 4 additions & 4 deletions modules/apps/transfer/keeper/relay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,12 @@ func (suite *KeeperTestSuite) TestOnRecvPacket() {
// send coin from chainB to chainA, receive them, acknowledge them, and send back to chainB
coinFromBToA := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))
transferMsg := types.NewMsgTransfer(path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, coinFromBToA, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String(), clienttypes.NewHeight(0, 110), 0)
_, err := suite.chainB.SendMsgs(transferMsg)
res, err := suite.chainB.SendMsgs(transferMsg)
suite.Require().NoError(err) // message committed

// relay send packet
fungibleTokenPacket := types.NewFungibleTokenPacketData(coinFromBToA.Denom, coinFromBToA.Amount.String(), suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String())
packet := channeltypes.NewPacket(fungibleTokenPacket.GetBytes(), 1, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, clienttypes.NewHeight(0, 110), 0)
packet, err := ibctesting.ParsePacketFromEvents(res.GetEvents())
suite.Require().NoError(err)

err = path.RelayPacket(packet)
suite.Require().NoError(err) // relay committed

Expand Down
33 changes: 15 additions & 18 deletions modules/apps/transfer/transfer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (

"github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types"
channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types"
ibctesting "github.com/cosmos/ibc-go/v3/testing"
)

Expand Down Expand Up @@ -56,13 +55,13 @@ func (suite *TransferTestSuite) TestHandleMsgTransfer() {

// send from chainA to chainB
msg := types.NewMsgTransfer(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, coinToSendToB, suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0)

_, err := suite.chainA.SendMsgs(msg)
res, err := suite.chainA.SendMsgs(msg)
suite.Require().NoError(err) // message committed

packet, err := ibctesting.ParsePacketFromEvents(res.GetEvents())
suite.Require().NoError(err)

// relay send
fungibleTokenPacket := types.NewFungibleTokenPacketData(coinToSendToB.Denom, coinToSendToB.Amount.String(), suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String())
packet := channeltypes.NewPacket(fungibleTokenPacket.GetBytes(), 1, path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, path.EndpointB.ChannelConfig.PortID, path.EndpointB.ChannelID, timeoutHeight, 0)
err = path.RelayPacket(packet)
suite.Require().NoError(err) // relay committed

Expand All @@ -82,18 +81,18 @@ func (suite *TransferTestSuite) TestHandleMsgTransfer() {

// send from chainB to chainC
msg = types.NewMsgTransfer(pathBtoC.EndpointA.ChannelConfig.PortID, pathBtoC.EndpointA.ChannelID, coinSentFromAToB, suite.chainB.SenderAccount.GetAddress().String(), suite.chainC.SenderAccount.GetAddress().String(), timeoutHeight, 0)

_, err = suite.chainB.SendMsgs(msg)
res, err = suite.chainB.SendMsgs(msg)
suite.Require().NoError(err) // message committed

// relay send
// NOTE: fungible token is prefixed with the full trace in order to verify the packet commitment
fullDenomPath := types.GetPrefixedDenom(pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID, voucherDenomTrace.GetFullDenomPath())
fungibleTokenPacket = types.NewFungibleTokenPacketData(voucherDenomTrace.GetFullDenomPath(), coinSentFromAToB.Amount.String(), suite.chainB.SenderAccount.GetAddress().String(), suite.chainC.SenderAccount.GetAddress().String())
packet = channeltypes.NewPacket(fungibleTokenPacket.GetBytes(), 1, pathBtoC.EndpointA.ChannelConfig.PortID, pathBtoC.EndpointA.ChannelID, pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID, timeoutHeight, 0)
packet, err = ibctesting.ParsePacketFromEvents(res.GetEvents())
suite.Require().NoError(err)

err = pathBtoC.RelayPacket(packet)
suite.Require().NoError(err) // relay committed

// NOTE: fungible token is prefixed with the full trace in order to verify the packet commitment
fullDenomPath := types.GetPrefixedDenom(pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID, voucherDenomTrace.GetFullDenomPath())

coinSentFromBToC := sdk.NewCoin(types.ParseDenomTrace(fullDenomPath).IBCDenom(), amount)
balance = suite.chainC.GetSimApp().BankKeeper.GetBalance(suite.chainC.GetContext(), suite.chainC.SenderAccount.GetAddress(), coinSentFromBToC.Denom)

Expand All @@ -106,14 +105,12 @@ func (suite *TransferTestSuite) TestHandleMsgTransfer() {

// send from chainC back to chainB
msg = types.NewMsgTransfer(pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID, coinSentFromBToC, suite.chainC.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0)

_, err = suite.chainC.SendMsgs(msg)
res, err = suite.chainC.SendMsgs(msg)
suite.Require().NoError(err) // message committed

// relay send
// NOTE: fungible token is prefixed with the full trace in order to verify the packet commitment
fungibleTokenPacket = types.NewFungibleTokenPacketData(fullDenomPath, coinSentFromBToC.Amount.String(), suite.chainC.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String())
packet = channeltypes.NewPacket(fungibleTokenPacket.GetBytes(), 1, pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID, pathBtoC.EndpointA.ChannelConfig.PortID, pathBtoC.EndpointA.ChannelID, timeoutHeight, 0)
packet, err = ibctesting.ParsePacketFromEvents(res.GetEvents())
suite.Require().NoError(err)

err = pathBtoC.RelayPacket(packet)
suite.Require().NoError(err) // relay committed

Expand Down
60 changes: 60 additions & 0 deletions testing/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ibctesting

import (
"fmt"
"strconv"

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

Expand Down Expand Up @@ -56,6 +57,65 @@ func ParseChannelIDFromEvents(events sdk.Events) (string, error) {
return "", fmt.Errorf("channel identifier event attribute not found")
}

// ParsePacketFromEvents parses events emitted from a MsgRecvPacket and returns the
// acknowledgement.
func ParsePacketFromEvents(events sdk.Events) (channeltypes.Packet, error) {
for _, ev := range events {
if ev.Type == channeltypes.EventTypeSendPacket {
packet := channeltypes.Packet{}
for _, attr := range ev.Attributes {

switch string(attr.Key) {
case channeltypes.AttributeKeyData:
packet.Data = attr.Value

case channeltypes.AttributeKeySequence:
seq, err := strconv.ParseUint(string(attr.Value), 10, 64)
if err != nil {
return channeltypes.Packet{}, err
}

packet.Sequence = seq

case channeltypes.AttributeKeySrcPort:
packet.SourcePort = string(attr.Value)

case channeltypes.AttributeKeySrcChannel:
packet.SourceChannel = string(attr.Value)

case channeltypes.AttributeKeyDstPort:
packet.DestinationPort = string(attr.Value)

case channeltypes.AttributeKeyDstChannel:
packet.DestinationChannel = string(attr.Value)

case channeltypes.AttributeKeyTimeoutHeight:
height, err := clienttypes.ParseHeight(string(attr.Value))
if err != nil {
return channeltypes.Packet{}, err
}

packet.TimeoutHeight = height

case channeltypes.AttributeKeyTimeoutTimestamp:
timestamp, err := strconv.ParseUint(string(attr.Value), 10, 64)
if err != nil {
return channeltypes.Packet{}, err
}

packet.TimeoutTimestamp = timestamp

default:
continue
}
}

return packet, nil
}
}
return channeltypes.Packet{}, fmt.Errorf("acknowledgement event attribute not found")
}

// ParseAckFromEvents parses events emitted from a MsgRecvPacket and returns the
// acknowledgement.
func ParseAckFromEvents(events sdk.Events) ([]byte, error) {
Expand Down

0 comments on commit c27d5b5

Please sign in to comment.