From 79fa06b26cdfcc786d28bb20521c62af11a39520 Mon Sep 17 00:00:00 2001 From: colin axner <25233464+colin-axner@users.noreply.github.com> Date: Mon, 20 Jul 2020 17:25:57 +0200 Subject: [PATCH] remove IBC ante handler in favor of using handler (#6793) * remove IBC ante handler, add calls to handler * move some events upstream to handler * remove change log entry * move ante handler tests to handler * fix build * update docs Co-authored-by: Alexander Bezobchuk --- CHANGELOG.md | 1 - docs/ibc/integration.md | 23 --- simapp/app.go | 2 +- x/auth/ante/ante.go | 5 +- x/auth/ante/ante_test.go | 2 +- x/auth/ante/testutil_test.go | 2 +- x/ibc/02-client/handler.go | 21 ++- x/ibc/02-client/keeper/client.go | 21 +-- x/ibc/ante/ante.go | 66 --------- x/ibc/handler.go | 52 +++++-- x/ibc/{ante/ante_test.go => handler_test.go} | 146 +++++++++---------- x/ibc/spec/README.md | 4 - x/ibc/testing/chain.go | 8 + 13 files changed, 136 insertions(+), 217 deletions(-) delete mode 100644 x/ibc/ante/ante.go rename x/ibc/{ante/ante_test.go => handler_test.go} (70%) diff --git a/CHANGELOG.md b/CHANGELOG.md index c46c5f3365..2c071f7b1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -167,7 +167,6 @@ be used to retrieve the actual proposal `Content`. Also the `NewMsgSubmitProposa * [ICS 007 - Tendermint Client](https://github.com/cosmos/ics/blob/master/spec/ics-007-tendermint-client) subpackage * [ICS 020 - Fungible Token Transfer](https://github.com/cosmos/ics/tree/master/spec/ics-020-fungible-token-transfer) module * [ICS 023 - Vector Commitments](https://github.com/cosmos/ics/tree/master/spec/ics-023-vector-commitments) subpackage - * (ibc/ante) Implement IBC `AnteHandler` as per [ADR 15 - IBC Packet Receiver](https://github.com/cosmos/tree/master/docs/architecture/adr-015-ibc-packet-receiver.md). * (x/capability) [\#5828](https://github.com/cosmos/cosmos-sdk/pull/5828) Capability module integration as outlined in [ADR 3 - Dynamic Capability Store](https://github.com/cosmos/tree/master/docs/architecture/adr-003-dynamic-capability-store.md). * (x/params) [\#6005](https://github.com/cosmos/cosmos-sdk/pull/6005) Add new CLI command for querying raw x/params parameters by subspace and key. * (x/ibc) [\#5769](https://github.com/cosmos/cosmos-sdk/pull/5769) [ICS 009 - Loopback Client](https://github.com/cosmos/ics/tree/master/spec/ics-009-loopback-client) subpackage diff --git a/docs/ibc/integration.md b/docs/ibc/integration.md index 595a566b1c..e3c2554997 100644 --- a/docs/ibc/integration.md +++ b/docs/ibc/integration.md @@ -21,7 +21,6 @@ Integrating the IBC module to your SDK-based application is straighforward. The - Add the modules to the module `Manager` - Add modules to `Begin/EndBlockers` and `InitGenesis` - Update the module `SimulationManager` to enable simulations -- Add IBC `Keeper` to the `AnteHandler` ### Module `BasicManager` and `ModuleAccount` permissions @@ -244,28 +243,6 @@ func NewApp(...args) *App { **IMPORTANT**: The capability module **must** be declared first in `SetOrderInitGenesis` ::: -### IBC AnteHandler - -The IBC module defines `ProofVerificationDecorator` that handles messages that contains application -specific packet types. This is mostly to perform stateful packet execution. For more context, please -refer to [ADR 15 - IBC Packet Receiver](./../architecture/adr-015-ibc-packet-receiver.md). - -```go -// app.go -func NewApp(...args) *App { - // .. continuation from above - - app.SetAnteHandler( - ante.NewAnteHandler( - app.AccountKeeper, app.BankKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer, - ), - ) - - // ... - return app -} -``` - That's it! You have now wired up the IBC module and are now able to send fungible tokens across different chains. If you want to have a broader view of the changes take a look into the SDK's [`SimApp`](https://github.com/cosmos/cosmos-sdk/blob/master/simapp/app.go). diff --git a/simapp/app.go b/simapp/app.go index b7ca02d91e..8b326a0d76 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -365,7 +365,7 @@ func NewSimApp( app.SetBeginBlocker(app.BeginBlocker) app.SetAnteHandler( ante.NewAnteHandler( - app.AccountKeeper, app.BankKeeper, *app.IBCKeeper, ante.DefaultSigVerificationGasConsumer, + app.AccountKeeper, app.BankKeeper, ante.DefaultSigVerificationGasConsumer, authtypes.LegacyAminoJSONHandler{}, ), ) diff --git a/x/auth/ante/ante.go b/x/auth/ante/ante.go index 6e62dbea63..3dca0acd50 100644 --- a/x/auth/ante/ante.go +++ b/x/auth/ante/ante.go @@ -4,15 +4,13 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth/signing" "github.com/cosmos/cosmos-sdk/x/auth/types" - ibcante "github.com/cosmos/cosmos-sdk/x/ibc/ante" - ibckeeper "github.com/cosmos/cosmos-sdk/x/ibc/keeper" ) // NewAnteHandler returns an AnteHandler that checks and increments sequence // numbers, checks signatures & account numbers, and deducts fees from the first // signer. func NewAnteHandler( - ak AccountKeeper, bankKeeper types.BankKeeper, ibcKeeper ibckeeper.Keeper, + ak AccountKeeper, bankKeeper types.BankKeeper, sigGasConsumer SignatureVerificationGasConsumer, signModeHandler signing.SignModeHandler, ) sdk.AnteHandler { @@ -28,6 +26,5 @@ func NewAnteHandler( NewSigGasConsumeDecorator(ak, sigGasConsumer), NewSigVerificationDecorator(ak, signModeHandler), NewIncrementSequenceDecorator(ak), - ibcante.NewProofVerificationDecorator(ibcKeeper.ClientKeeper, ibcKeeper.ChannelKeeper), // innermost AnteDecorator ) } diff --git a/x/auth/ante/ante_test.go b/x/auth/ante/ante_test.go index 0f22285155..a6f565f520 100644 --- a/x/auth/ante/ante_test.go +++ b/x/auth/ante/ante_test.go @@ -980,7 +980,7 @@ func (suite *AnteTestSuite) TestCustomSignatureVerificationGasConsumer() { suite.SetupTest(true) // setup // setup an ante handler that only accepts PubKeyEd25519 - suite.anteHandler = ante.NewAnteHandler(suite.app.AccountKeeper, suite.app.BankKeeper, *suite.app.IBCKeeper, func(meter sdk.GasMeter, sig signing.SignatureV2, params types.Params) error { + suite.anteHandler = ante.NewAnteHandler(suite.app.AccountKeeper, suite.app.BankKeeper, func(meter sdk.GasMeter, sig signing.SignatureV2, params types.Params) error { switch pubkey := sig.PubKey.(type) { case ed25519.PubKeyEd25519: meter.ConsumeGas(params.SigVerifyCostED25519, "ante verify: ed25519") diff --git a/x/auth/ante/testutil_test.go b/x/auth/ante/testutil_test.go index 0df768ad80..b82844d882 100644 --- a/x/auth/ante/testutil_test.go +++ b/x/auth/ante/testutil_test.go @@ -40,7 +40,7 @@ type AnteTestSuite struct { func (suite *AnteTestSuite) SetupTest(isCheckTx bool) { suite.app, suite.ctx = createTestApp(isCheckTx) suite.ctx = suite.ctx.WithBlockHeight(1) - suite.anteHandler = ante.NewAnteHandler(suite.app.AccountKeeper, suite.app.BankKeeper, *suite.app.IBCKeeper, ante.DefaultSigVerificationGasConsumer, types.LegacyAminoJSONHandler{}) + suite.anteHandler = ante.NewAnteHandler(suite.app.AccountKeeper, suite.app.BankKeeper, ante.DefaultSigVerificationGasConsumer, types.LegacyAminoJSONHandler{}) // set up the TxBuilder encodingConfig := simappparams.MakeEncodingConfig() diff --git a/x/ibc/02-client/handler.go b/x/ibc/02-client/handler.go index 99e3a4daf3..8a9fe58837 100644 --- a/x/ibc/02-client/handler.go +++ b/x/ibc/02-client/handler.go @@ -76,6 +76,13 @@ func HandleMsgUpdateClient(ctx sdk.Context, k keeper.Keeper, msg exported.MsgUpd return nil, err } + ctx.EventManager().EmitEvent( + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + ), + ) + return &sdk.Result{ Events: ctx.EventManager().Events().ToABCIEvents(), }, nil @@ -92,6 +99,18 @@ func HandlerClientMisbehaviour(k keeper.Keeper) evidencetypes.Handler { ) } - return k.CheckMisbehaviourAndUpdateState(ctx, misbehaviour) + if err := k.CheckMisbehaviourAndUpdateState(ctx, misbehaviour); err != nil { + return sdkerrors.Wrap(err, "failed to process misbehaviour for IBC client") + } + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeSubmitMisbehaviour, + sdk.NewAttribute(types.AttributeKeyClientID, misbehaviour.GetClientID()), + sdk.NewAttribute(types.AttributeKeyClientType, misbehaviour.ClientType().String()), + sdk.NewAttribute(types.AttributeKeyConsensusHeight, fmt.Sprintf("%d", uint64(misbehaviour.GetHeight()))), + ), + ) + return nil } } diff --git a/x/ibc/02-client/keeper/client.go b/x/ibc/02-client/keeper/client.go index 81f0e0a453..49e6446d9d 100644 --- a/x/ibc/02-client/keeper/client.go +++ b/x/ibc/02-client/keeper/client.go @@ -100,7 +100,7 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H k.Logger(ctx).Info(fmt.Sprintf("client %s updated to height %d", clientID, clientState.GetLatestHeight())) - // Emit events in keeper so antehandler emits them as well + // emitting events in the keeper emits for both begin block and handler client updates ctx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeUpdateClient, @@ -110,16 +110,6 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H ), ) - // localhost client is not updated though messages - if clientType != exported.Localhost { - ctx.EventManager().EmitEvent( - sdk.NewEvent( - sdk.EventTypeMessage, - sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), - ), - ) - } - return clientState, nil } @@ -154,14 +144,5 @@ func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, misbehaviour ex k.SetClientState(ctx, clientState) k.Logger(ctx).Info(fmt.Sprintf("client %s frozen due to misbehaviour", misbehaviour.GetClientID())) - ctx.EventManager().EmitEvent( - sdk.NewEvent( - types.EventTypeSubmitMisbehaviour, - sdk.NewAttribute(types.AttributeKeyClientID, misbehaviour.GetClientID()), - sdk.NewAttribute(types.AttributeKeyClientType, misbehaviour.ClientType().String()), - sdk.NewAttribute(types.AttributeKeyConsensusHeight, fmt.Sprintf("%d", consensusState.GetHeight())), - ), - ) - return nil } diff --git a/x/ibc/ante/ante.go b/x/ibc/ante/ante.go deleted file mode 100644 index 41a2759159..0000000000 --- a/x/ibc/ante/ante.go +++ /dev/null @@ -1,66 +0,0 @@ -package ante - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" - clientkeeper "github.com/cosmos/cosmos-sdk/x/ibc/02-client/keeper" - channelkeeper "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/keeper" - channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" -) - -// ProofVerificationDecorator handles messages that contains application specific packet types, -// including MsgPacket, MsgAcknowledgement, MsgTimeout. -// MsgUpdateClients are also handled here to perform atomic multimsg transaction -type ProofVerificationDecorator struct { - clientKeeper clientkeeper.Keeper - channelKeeper channelkeeper.Keeper -} - -// NewProofVerificationDecorator constructs new ProofverificationDecorator -func NewProofVerificationDecorator(clientKeeper clientkeeper.Keeper, channelKeeper channelkeeper.Keeper) ProofVerificationDecorator { - return ProofVerificationDecorator{ - clientKeeper: clientKeeper, - channelKeeper: channelKeeper, - } -} - -// AnteHandle executes MsgUpdateClient, MsgPacket, MsgAcknowledgement, MsgTimeout. -// The packet execution messages are then passed to the respective application handlers. -func (pvr ProofVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { - for _, msg := range tx.GetMsgs() { - var err error - switch msg := msg.(type) { - case clientexported.MsgUpdateClient: - _, err = pvr.clientKeeper.UpdateClient(ctx, msg.GetClientID(), msg.GetHeader()) - case *channeltypes.MsgPacket: - err = pvr.channelKeeper.RecvPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight) - case *channeltypes.MsgAcknowledgement: - err = pvr.channelKeeper.AcknowledgePacket(ctx, msg.Packet, msg.Acknowledgement, msg.Proof, msg.ProofHeight) - case *channeltypes.MsgTimeout: - err = pvr.channelKeeper.TimeoutPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight, msg.NextSequenceRecv) - default: - // don't emit sender event for other msg types - continue - } - - attributes := make([]sdk.Attribute, len(msg.GetSigners())) - - for i, signer := range msg.GetSigners() { - attributes[i] = sdk.NewAttribute(sdk.AttributeKeySender, signer.String()) - } - - ctx.EventManager().EmitEvents(sdk.Events{ - sdk.NewEvent( - sdk.EventTypeMessage, - attributes..., - ), - }) - - if err != nil { - return ctx, err - } - - } - - return next(ctx, tx, simulate) -} diff --git a/x/ibc/handler.go b/x/ibc/handler.go index 47343a1f13..ac58ef23df 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -24,9 +24,11 @@ func NewHandler(k keeper.Keeper) sdk.Handler { return client.HandleMsgCreateClient(ctx, k.ClientKeeper, msg) case clientexported.MsgUpdateClient: - return &sdk.Result{}, nil + return client.HandleMsgUpdateClient(ctx, k.ClientKeeper, msg) - // IBC connection msgs + // Client Misbehaviour is handled by the evidence module + + // IBC connection msgs case *connectiontypes.MsgConnectionOpenInit: return connection.HandleMsgConnectionOpenInit(ctx, k.ConnectionKeeper, msg) @@ -51,13 +53,14 @@ func NewHandler(k keeper.Keeper) sdk.Handler { if err != nil { return nil, err } + // Retrieve callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } - err = cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, cap, msg.Channel.Counterparty, msg.Channel.Version) - if err != nil { + + if err = cbs.OnChanOpenInit(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, cap, msg.Channel.Counterparty, msg.Channel.Version); err != nil { return nil, sdkerrors.Wrap(err, "channel open init callback failed") } @@ -69,17 +72,19 @@ func NewHandler(k keeper.Keeper) sdk.Handler { if err != nil { return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") } + res, cap, err := channel.HandleMsgChannelOpenTry(ctx, k.ChannelKeeper, portCap, msg) if err != nil { return nil, err } + // Retrieve callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } - err = cbs.OnChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, cap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion) - if err != nil { + + if err = cbs.OnChanOpenTry(ctx, msg.Channel.Ordering, msg.Channel.ConnectionHops, msg.PortID, msg.ChannelID, cap, msg.Channel.Counterparty, msg.Channel.Version, msg.CounterpartyVersion); err != nil { return nil, sdkerrors.Wrap(err, "channel open try callback failed") } @@ -91,16 +96,17 @@ func NewHandler(k keeper.Keeper) sdk.Handler { if err != nil { return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") } + // Retrieve callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } - err = cbs.OnChanOpenAck(ctx, msg.PortID, msg.ChannelID, msg.CounterpartyVersion) - if err != nil { + if err = cbs.OnChanOpenAck(ctx, msg.PortID, msg.ChannelID, msg.CounterpartyVersion); err != nil { return nil, sdkerrors.Wrap(err, "channel open ack callback failed") } + return channel.HandleMsgChannelOpenAck(ctx, k.ChannelKeeper, cap, msg) case *channeltypes.MsgChannelOpenConfirm: @@ -109,16 +115,17 @@ func NewHandler(k keeper.Keeper) sdk.Handler { if err != nil { return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") } + // Retrieve callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } - err = cbs.OnChanOpenConfirm(ctx, msg.PortID, msg.ChannelID) - if err != nil { + if err = cbs.OnChanOpenConfirm(ctx, msg.PortID, msg.ChannelID); err != nil { return nil, sdkerrors.Wrap(err, "channel open confirm callback failed") } + return channel.HandleMsgChannelOpenConfirm(ctx, k.ChannelKeeper, cap, msg) case *channeltypes.MsgChannelCloseInit: @@ -127,16 +134,17 @@ func NewHandler(k keeper.Keeper) sdk.Handler { if err != nil { return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") } + // Retrieve callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } - err = cbs.OnChanCloseInit(ctx, msg.PortID, msg.ChannelID) - if err != nil { + if err = cbs.OnChanCloseInit(ctx, msg.PortID, msg.ChannelID); err != nil { return nil, sdkerrors.Wrap(err, "channel close init callback failed") } + return channel.HandleMsgChannelCloseInit(ctx, k.ChannelKeeper, cap, msg) case *channeltypes.MsgChannelCloseConfirm: @@ -145,16 +153,17 @@ func NewHandler(k keeper.Keeper) sdk.Handler { if err != nil { return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") } + // Retrieve callbacks from router cbs, ok := k.Router.GetRoute(module) if !ok { return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } - err = cbs.OnChanCloseConfirm(ctx, msg.PortID, msg.ChannelID) - if err != nil { + if err = cbs.OnChanCloseConfirm(ctx, msg.PortID, msg.ChannelID); err != nil { return nil, sdkerrors.Wrap(err, "channel close confirm callback failed") } + return channel.HandleMsgChannelCloseConfirm(ctx, k.ChannelKeeper, cap, msg) // IBC packet msgs get routed to the appropriate module callback @@ -171,6 +180,11 @@ func NewHandler(k keeper.Keeper) sdk.Handler { return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } + // Perform TAO verification + if err := k.ChannelKeeper.RecvPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight); err != nil { + return nil, sdkerrors.Wrap(err, "receive packet verification failed") + } + // Perform application logic callback res, ack, err := cbs.OnRecvPacket(ctx, msg.Packet) if err != nil { @@ -197,6 +211,11 @@ func NewHandler(k keeper.Keeper) sdk.Handler { return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } + // Perform TAO verification + if err := k.ChannelKeeper.AcknowledgePacket(ctx, msg.Packet, msg.Acknowledgement, msg.Proof, msg.ProofHeight); err != nil { + return nil, sdkerrors.Wrap(err, "acknowledge packet verification failed") + } + // Perform application logic callback res, err := cbs.OnAcknowledgementPacket(ctx, msg.Packet, msg.Acknowledgement) if err != nil { @@ -223,6 +242,11 @@ func NewHandler(k keeper.Keeper) sdk.Handler { return nil, sdkerrors.Wrapf(porttypes.ErrInvalidRoute, "route not found to module: %s", module) } + // Perform TAO verification + if err := k.ChannelKeeper.TimeoutPacket(ctx, msg.Packet, msg.Proof, msg.ProofHeight, msg.NextSequenceRecv); err != nil { + return nil, sdkerrors.Wrap(err, "timeout packet verification failed") + } + // Perform application logic callback res, err := cbs.OnTimeoutPacket(ctx, msg.Packet) if err != nil { diff --git a/x/ibc/ante/ante_test.go b/x/ibc/handler_test.go similarity index 70% rename from x/ibc/ante/ante_test.go rename to x/ibc/handler_test.go index 3fa1a009a1..5fa3b99468 100644 --- a/x/ibc/ante/ante_test.go +++ b/x/ibc/handler_test.go @@ -1,16 +1,15 @@ -package ante_test +package ibc_test import ( "testing" "github.com/stretchr/testify/suite" - sdk "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/cosmos/cosmos-sdk/x/ibc" + ibctransfertypes "github.com/cosmos/cosmos-sdk/x/ibc-transfer/types" clientexported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported" channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types" host "github.com/cosmos/cosmos-sdk/x/ibc/24-host" - "github.com/cosmos/cosmos-sdk/x/ibc/ante" ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing" ) @@ -34,17 +33,15 @@ func (suite *HandlerTestSuite) SetupTest() { suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(1)) } -func newTx(msg sdk.Msg) sdk.Tx { - return authtypes.StdTx{ - Msgs: []sdk.Msg{msg}, - } +func TestHandlerTestSuite(t *testing.T) { + suite.Run(t, new(HandlerTestSuite)) } -// tests the ante handler receiving a packet on ordered and unordered channels. -// It verifies that no state changes occur as the storing of an acknowledgement -// should occur in the 'PacketExecuted' function. It test high level properties -// like ordering and basic sanity checks. More rigorous testing of 'RecvPacket' -// can be found in the 04-channel/keeper/packet_test.go. +// tests the IBC handler receiving a packet on ordered and unordered channels. +// It verifies that the storing of an acknowledgement on success occurs. It +// tests high level properties like ordering and basic sanity checks. More +// rigorous testing of 'RecvPacket' and 'PacketExecuted' can be found in the +// 04-channel/keeper/packet_test.go. func (suite *HandlerTestSuite) TestHandleRecvPacket() { var ( packet channeltypes.Packet @@ -58,14 +55,14 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { {"success: ORDERED", func() { _, clientB, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, clientexported.Tendermint) channelA, channelB := suite.coordinator.CreateChannel(suite.chainA, suite.chainB, connA, connB, channeltypes.ORDERED) - packet = channeltypes.NewPacket(ibctesting.TestHash, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) }, true}, {"success: UNORDERED", func() { _, clientB, _, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB) - packet = channeltypes.NewPacket(ibctesting.TestHash, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -76,7 +73,7 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { // attempts to receive packet with sequence 10 without receiving packet with sequence 1 for i := uint64(1); i < 10; i++ { - packet = channeltypes.NewPacket(ibctesting.TestHash, i, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), i, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -88,7 +85,7 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { // attempts to receive packet with sequence 10 without receiving packet with sequence 1 for i := uint64(1); i < 10; i++ { - packet = channeltypes.NewPacket(ibctesting.TestHash, i, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), i, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -100,12 +97,12 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { }, false}, {"packet not sent", func() { _, _, _, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB) - packet = channeltypes.NewPacket(ibctesting.TestHash, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) }, false}, {"ORDERED: packet already received (replay)", func() { clientA, clientB, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, clientexported.Tendermint) channelA, channelB := suite.coordinator.CreateChannel(suite.chainA, suite.chainB, connA, connB, channeltypes.ORDERED) - packet = channeltypes.NewPacket(ibctesting.TestHash, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -116,7 +113,7 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { {"UNORDERED: packet already received (replay)", func() { clientA, clientB, _, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB) - packet = channeltypes.NewPacket(ibctesting.TestHash, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -132,10 +129,7 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { suite.Run(tc.name, func() { suite.SetupTest() // reset - handler := sdk.ChainAnteDecorators(ante.NewProofVerificationDecorator( - suite.chainB.App.IBCKeeper.ClientKeeper, - suite.chainB.App.IBCKeeper.ChannelKeeper, - )) + handler := ibc.NewHandler(*suite.chainB.App.IBCKeeper) tc.malleate() @@ -146,19 +140,19 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { msg := channeltypes.NewMsgPacket(packet, proof, proofHeight, suite.chainB.SenderAccount.GetAddress()) // ante-handle RecvPacket - _, err := handler(suite.chainB.GetContext(), newTx(msg), false) + _, err := handler(suite.chainB.GetContext(), msg) if tc.expPass { suite.Require().NoError(err) - // replay should return same result since there is no state changes - _, err := handler(suite.chainB.GetContext(), newTx(msg), false) - suite.Require().NoError(err) - // verify ack was not written + // replay should fail since state changes occur + _, err := handler(suite.chainB.GetContext(), msg) + suite.Require().Error(err) + + // verify ack was written ack, found := suite.chainB.App.IBCKeeper.ChannelKeeper.GetPacketAcknowledgement(suite.chainB.GetContext(), packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) - suite.Require().Nil(ack) - suite.Require().False(found) - + suite.Require().NotNil(ack) + suite.Require().True(found) } else { suite.Require().Error(err) } @@ -166,12 +160,11 @@ func (suite *HandlerTestSuite) TestHandleRecvPacket() { } } -// tests the ante handler acknowledging a packet on ordered and unordered -// channels. It verifies that no state changes occur as the deleting of packet -// commitments from state should occur in the 'AcknowledgementExecuted' -// function. It test high level properties like ordering and basic sanity -// checks. More rigorous testing of 'AcknowledgePacket' can be found in -// the 04-channel/keeper/packet_test.go. +// tests the IBC handler acknowledgement of a packet on ordered and unordered +// channels. It verifies that the deletion of packet commitments from state +// occurs. It test high level properties like ordering and basic sanity +// checks. More rigorous testing of 'AcknowledgePacket' and 'AcknowledgementExecuted' +// can be found in the 04-channel/keeper/packet_test.go. func (suite *HandlerTestSuite) TestHandleAcknowledgePacket() { var ( packet channeltypes.Packet @@ -185,7 +178,7 @@ func (suite *HandlerTestSuite) TestHandleAcknowledgePacket() { {"success: ORDERED", func() { clientA, clientB, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, clientexported.Tendermint) channelA, channelB := suite.coordinator.CreateChannel(suite.chainA, suite.chainB, connA, connB, channeltypes.ORDERED) - packet = channeltypes.NewPacket(ibctesting.TestHash, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -195,7 +188,7 @@ func (suite *HandlerTestSuite) TestHandleAcknowledgePacket() { }, true}, {"success: UNORDERED", func() { clientA, clientB, _, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB) - packet = channeltypes.NewPacket(ibctesting.TestHash, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -209,7 +202,7 @@ func (suite *HandlerTestSuite) TestHandleAcknowledgePacket() { // attempts to acknowledge ack with sequence 10 without acknowledging ack with sequence 1 (removing packet commitment) for i := uint64(1); i < 10; i++ { - packet = channeltypes.NewPacket(ibctesting.TestHash, i, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), i, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -225,7 +218,7 @@ func (suite *HandlerTestSuite) TestHandleAcknowledgePacket() { // attempts to acknowledge ack with sequence 10 without acknowledging ack with sequence 1 (removing packet commitment for i := uint64(1); i < 10; i++ { - packet = channeltypes.NewPacket(ibctesting.TestHash, i, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), i, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -240,7 +233,7 @@ func (suite *HandlerTestSuite) TestHandleAcknowledgePacket() { }, false}, {"packet not received", func() { _, clientB, _, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB) - packet = channeltypes.NewPacket(ibctesting.TestHash, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -248,7 +241,7 @@ func (suite *HandlerTestSuite) TestHandleAcknowledgePacket() { {"ORDERED: packet already acknowledged (replay)", func() { clientA, clientB, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, clientexported.Tendermint) channelA, channelB := suite.coordinator.CreateChannel(suite.chainA, suite.chainB, connA, connB, channeltypes.ORDERED) - packet = channeltypes.NewPacket(ibctesting.TestHash, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -262,7 +255,7 @@ func (suite *HandlerTestSuite) TestHandleAcknowledgePacket() { {"UNORDERED: packet already received (replay)", func() { clientA, clientB, _, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB) - packet = channeltypes.NewPacket(ibctesting.TestHash, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -280,11 +273,9 @@ func (suite *HandlerTestSuite) TestHandleAcknowledgePacket() { suite.Run(tc.name, func() { suite.SetupTest() // reset + ibctesting.TestHash = ibctransfertypes.FungibleTokenPacketAcknowledgement{true, ""}.GetBytes() - handler := sdk.ChainAnteDecorators(ante.NewProofVerificationDecorator( - suite.chainA.App.IBCKeeper.ClientKeeper, - suite.chainA.App.IBCKeeper.ChannelKeeper, - )) + handler := ibc.NewHandler(*suite.chainA.App.IBCKeeper) tc.malleate() @@ -295,18 +286,18 @@ func (suite *HandlerTestSuite) TestHandleAcknowledgePacket() { msg := channeltypes.NewMsgAcknowledgement(packet, ack, proof, proofHeight, suite.chainA.SenderAccount.GetAddress()) - // ante-handle RecvPacket - _, err := handler(suite.chainA.GetContext(), newTx(msg), false) + _, err := handler(suite.chainA.GetContext(), msg) if tc.expPass { suite.Require().NoError(err) - // replay should return same result since there is no state changes - _, err := handler(suite.chainA.GetContext(), newTx(msg), false) - suite.Require().NoError(err) - // verify packet commitment was not deleted + // replay should an error + _, err := handler(suite.chainA.GetContext(), msg) + suite.Require().Error(err) + + // verify packet commitment was deleted has := suite.chainA.App.IBCKeeper.ChannelKeeper.HasPacketCommitment(suite.chainA.GetContext(), packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) - suite.Require().True(has) + suite.Require().False(has) } else { suite.Require().Error(err) @@ -315,12 +306,11 @@ func (suite *HandlerTestSuite) TestHandleAcknowledgePacket() { } } -// tests the ante handler timing out a packet on ordered and unordered channels. -// It verifies that no state changes occur as the deleting of packet -// commitments from state should occur in the 'TimeoutExecuted' function. It -// tests high level properties like ordering and basic sanity -// checks. More rigorous testing of 'TimeoutPacket' can be found in the -// 04-channel/keeper/timeout_test.go. +// tests the IBC handler timing out a packet on ordered and unordered channels. +// It verifies that the deletion of a packet commitment occurs. It tests +// high level properties like ordering and basic sanity checks. More +// rigorous testing of 'TimeoutPacket' and 'TimeoutExecuted' can be found in +// the 04-channel/keeper/timeout_test.go. func (suite *HandlerTestSuite) TestHandleTimeoutPacket() { var ( packet channeltypes.Packet @@ -335,7 +325,7 @@ func (suite *HandlerTestSuite) TestHandleTimeoutPacket() { {"success: ORDERED", func() { clientA, clientB, connA, connB := suite.coordinator.SetupClientConnections(suite.chainA, suite.chainB, clientexported.Tendermint) channelA, channelB := suite.coordinator.CreateChannel(suite.chainA, suite.chainB, connA, connB, channeltypes.ORDERED) - packet = channeltypes.NewPacket(ibctesting.TestHash, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, uint64(suite.chainB.GetContext().BlockHeight()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, uint64(suite.chainB.GetContext().BlockHeight()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -346,7 +336,7 @@ func (suite *HandlerTestSuite) TestHandleTimeoutPacket() { }, true}, {"success: UNORDERED", func() { clientA, clientB, _, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB) - packet = channeltypes.NewPacket(ibctesting.TestHash, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, uint64(suite.chainB.GetContext().BlockHeight()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, uint64(suite.chainB.GetContext().BlockHeight()), uint64(suite.chainB.GetContext().BlockTime().UnixNano())) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -360,7 +350,7 @@ func (suite *HandlerTestSuite) TestHandleTimeoutPacket() { // attempts to timeout packet with sequence 10 without timing out packet with sequence 1 for i := uint64(1); i < 10; i++ { - packet = channeltypes.NewPacket(ibctesting.TestHash, i, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, uint64(suite.chainB.GetContext().BlockHeight()), 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), i, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, uint64(suite.chainB.GetContext().BlockHeight()), 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -376,7 +366,7 @@ func (suite *HandlerTestSuite) TestHandleTimeoutPacket() { // attempts to timeout packet with sequence 10 without timing out packet with sequence 1 for i := uint64(1); i < 10; i++ { - packet = channeltypes.NewPacket(ibctesting.TestHash, i, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, uint64(suite.chainB.GetContext().BlockHeight()), 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), i, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, uint64(suite.chainB.GetContext().BlockHeight()), 0) err := suite.coordinator.SendPacket(suite.chainA, suite.chainB, packet, clientB) suite.Require().NoError(err) @@ -394,7 +384,7 @@ func (suite *HandlerTestSuite) TestHandleTimeoutPacket() { }, false}, {"UNORDERED: packet not sent", func() { _, _, _, _, channelA, channelB := suite.coordinator.Setup(suite.chainA, suite.chainB) - packet = channeltypes.NewPacket(ibctesting.TestHash, 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) + packet = channeltypes.NewPacket(suite.chainA.GetPacketData(suite.chainB), 1, channelA.PortID, channelA.ID, channelB.PortID, channelB.ID, timeoutHeight, 0) packetKey = host.KeyPacketAcknowledgement(packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) }, false}, } @@ -405,10 +395,7 @@ func (suite *HandlerTestSuite) TestHandleTimeoutPacket() { suite.Run(tc.name, func() { suite.SetupTest() // reset - handler := sdk.ChainAnteDecorators(ante.NewProofVerificationDecorator( - suite.chainA.App.IBCKeeper.ClientKeeper, - suite.chainA.App.IBCKeeper.ChannelKeeper, - )) + handler := ibc.NewHandler(*suite.chainA.App.IBCKeeper) tc.malleate() @@ -416,18 +403,18 @@ func (suite *HandlerTestSuite) TestHandleTimeoutPacket() { msg := channeltypes.NewMsgTimeout(packet, 1, proof, proofHeight, suite.chainA.SenderAccount.GetAddress()) - // ante-handle RecvPacket - _, err := handler(suite.chainA.GetContext(), newTx(msg), false) + _, err := handler(suite.chainA.GetContext(), msg) if tc.expPass { suite.Require().NoError(err) - // replay should return same result since there is no state changes - _, err := handler(suite.chainA.GetContext(), newTx(msg), false) - suite.Require().NoError(err) - // verify packet commitment was not deleted + // replay should return an error + _, err := handler(suite.chainA.GetContext(), msg) + suite.Require().Error(err) + + // verify packet commitment was deleted has := suite.chainA.App.IBCKeeper.ChannelKeeper.HasPacketCommitment(suite.chainA.GetContext(), packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) - suite.Require().True(has) + suite.Require().False(has) } else { suite.Require().Error(err) @@ -435,6 +422,3 @@ func (suite *HandlerTestSuite) TestHandleTimeoutPacket() { }) } } -func TestHandlerTestSuite(t *testing.T) { - suite.Run(t, new(HandlerTestSuite)) -} diff --git a/x/ibc/spec/README.md b/x/ibc/spec/README.md index 3a8ea44804..6207665ae2 100644 --- a/x/ibc/spec/README.md +++ b/x/ibc/spec/README.md @@ -55,8 +55,6 @@ which call each ICS submodule's handlers (i.e `x/ibc/{XX-ICS}/handler.go`). The following ADR provide the design and architecture decision of IBC-related components. -* [ADR 10 - Modular AnteHandler](../../../docs/architecture/adr-010-modular-antehandler.md): Introduces a decorator pattern for the [`AnteHandler`](../../../docs/basics/gas-fees.md#antehandler), making it modular. -* [ADR 15 - IBC Packet Receiver](../../../docs/architecture/adr-015-ibc-packet-receiver.md): replaces the ICS26 routing module with [`AnteHandler`](../../../docs/basics/gas-fees.md#antehandler) logic within IBC. This is implemented using the `AnteDecorators` defined in [ADR10]((../../../docs/architecture/adr-010-modular-antehandler.md)) * [ADR 17 - Historical Header Module](../../../docs/architecture/adr-017-historical-header-module.md): Introduces the ability to introspect past consensus states in order to verify their membership in the counterparty clients. * [ADR 19 - Protobuf State Encoding](../../../docs/architecture/adr-019-protobuf-state-encoding.md): Migration from Amino to Protobuf for state encoding. @@ -91,8 +89,6 @@ x/ │ ├── 09-localhost/ │ ├── 23-commitment/ │ ├── 24-host/ -│ ├── ante -│ │ └── ante.go │ ├── client │  │ ├── cli │  │ │   └── cli.go diff --git a/x/ibc/testing/chain.go b/x/ibc/testing/chain.go index b7df7cf826..9e81d9465d 100644 --- a/x/ibc/testing/chain.go +++ b/x/ibc/testing/chain.go @@ -589,6 +589,14 @@ func (chain *TestChain) ChanCloseInit( return chain.SendMsg(msg) } +// GetPacketData returns a ibc-transfer marshalled packet to be used for +// callback testing +func (chain *TestChain) GetPacketData(counterparty *TestChain) []byte { + packet := ibctransfertypes.NewFungibleTokenPacketData(sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100))), chain.SenderAccount.GetAddress().String(), counterparty.SenderAccount.GetAddress().String()) + + return packet.GetBytes() +} + // SendPacket simulates sending a packet through the channel keeper. No message needs to be // passed since this call is made from a module. func (chain *TestChain) SendPacket(