Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: split testing/mock ibcmodule #516

Merged
merged 5 commits into from
Nov 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 174 additions & 0 deletions testing/mock/ibc_module.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package mock

import (
"bytes"
"errors"
"strconv"

sdk "github.com/cosmos/cosmos-sdk/types"
capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"

channeltypes "github.com/cosmos/ibc-go/v2/modules/core/04-channel/types"
host "github.com/cosmos/ibc-go/v2/modules/core/24-host"
"github.com/cosmos/ibc-go/v2/modules/core/exported"
)

// IBCModule implements the ICS26 callbacks for testing/mock.
type IBCModule struct {
IBCApp *MockIBCApp // base application of an IBC middleware stack
scopedKeeper capabilitykeeper.ScopedKeeper
}

// NewIBCModule creates a new IBCModule given the underlying mock IBC application and scopedKeeper.
func NewIBCModule(app *MockIBCApp, scopedKeeper capabilitykeeper.ScopedKeeper) IBCModule {
return IBCModule{
IBCApp: app,
scopedKeeper: scopedKeeper,
}
}

// OnChanOpenInit implements the IBCModule interface.
func (im IBCModule) OnChanOpenInit(
ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID string,
channelID string, chanCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version string,
) error {
if im.IBCApp.OnChanOpenInit != nil {
return im.IBCApp.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version)

}

// Claim channel capability passed back by IBC module
if err := im.scopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil {
return err
}

return nil
}

// OnChanOpenTry implements the IBCModule interface.
func (im IBCModule) OnChanOpenTry(
ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID string,
channelID string, chanCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version, counterpartyVersion string,
) error {
if im.IBCApp.OnChanOpenTry != nil {
return im.IBCApp.OnChanOpenTry(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version, counterpartyVersion)

}
// Claim channel capability passed back by IBC module
if err := im.scopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil {
return err
}

return nil
}

// OnChanOpenAck implements the IBCModule interface.
func (im IBCModule) OnChanOpenAck(ctx sdk.Context, portID string, channelID string, counterpartyVersion string) error {
if im.IBCApp.OnChanOpenAck != nil {
return im.IBCApp.OnChanOpenAck(ctx, portID, channelID, counterpartyVersion)
}

return nil
}

// OnChanOpenConfirm implements the IBCModule interface.
func (im IBCModule) OnChanOpenConfirm(ctx sdk.Context, portID, channelID string) error {
if im.IBCApp.OnChanOpenConfirm != nil {
return im.IBCApp.OnChanOpenConfirm(ctx, portID, channelID)
}

return nil
}

// OnChanCloseInit implements the IBCModule interface.
func (im IBCModule) OnChanCloseInit(ctx sdk.Context, portID, channelID string) error {
if im.IBCApp.OnChanCloseInit != nil {
return im.IBCApp.OnChanCloseInit(ctx, portID, channelID)
}

return nil
}

// OnChanCloseConfirm implements the IBCModule interface.
func (im IBCModule) OnChanCloseConfirm(ctx sdk.Context, portID, channelID string) error {
if im.IBCApp.OnChanCloseConfirm != nil {
return im.IBCApp.OnChanCloseConfirm(ctx, portID, channelID)
}

return nil
}

// OnRecvPacket implements the IBCModule interface.
func (im IBCModule) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) exported.Acknowledgement {
if im.IBCApp.OnRecvPacket != nil {
return im.IBCApp.OnRecvPacket(ctx, packet, relayer)
}

// set state by claiming capability to check if revert happens return
_, err := im.scopedKeeper.NewCapability(ctx, MockRecvCanaryCapabilityName+strconv.Itoa(int(packet.GetSequence())))
if err != nil {
// application callback called twice on same packet sequence
// must never occur
panic(err)
}
if bytes.Equal(MockPacketData, packet.GetData()) {
return MockAcknowledgement
} else if bytes.Equal(MockAsyncPacketData, packet.GetData()) {
return nil
}

return MockFailAcknowledgement
}

// OnAcknowledgementPacket implements the IBCModule interface.
func (im IBCModule) OnAcknowledgementPacket(ctx sdk.Context, packet channeltypes.Packet, acknowledgement []byte, relayer sdk.AccAddress) error {
if im.IBCApp.OnAcknowledgementPacket != nil {
return im.IBCApp.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer)
}

_, err := im.scopedKeeper.NewCapability(ctx, MockAckCanaryCapabilityName+strconv.Itoa(int(packet.GetSequence())))
if err != nil {
// application callback called twice on same packet sequence
// must never occur
panic(err)
}

return nil
}

// OnTimeoutPacket implements the IBCModule interface.
func (im IBCModule) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) error {
if im.IBCApp.OnTimeoutPacket != nil {
return im.IBCApp.OnTimeoutPacket(ctx, packet, relayer)
}

_, err := im.scopedKeeper.NewCapability(ctx, MockTimeoutCanaryCapabilityName+strconv.Itoa(int(packet.GetSequence())))
if err != nil {
// application callback called twice on same packet sequence
// must never occur
panic(err)
}

return nil
}

// NegotiateAppVersion implements the IBCModule interface.
func (im IBCModule) NegotiateAppVersion(
ctx sdk.Context,
order channeltypes.Order,
connectionID string,
portID string,
counterparty channeltypes.Counterparty,
proposedVersion string,
) (string, error) {
if im.IBCApp.NegotiateAppVersion != nil {
return im.IBCApp.NegotiateAppVersion(ctx, order, connectionID, portID, counterparty, proposedVersion)
}

if proposedVersion != Version { // allow testing of error scenarios
return "", errors.New("failed to negotiate app version")
}

return Version, nil
}
152 changes: 1 addition & 151 deletions testing/mock/mock.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package mock

import (
"bytes"
"encoding/json"
"errors"
"strconv"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
Expand All @@ -21,7 +18,6 @@ import (
channeltypes "github.com/cosmos/ibc-go/v2/modules/core/04-channel/types"
porttypes "github.com/cosmos/ibc-go/v2/modules/core/05-port/types"
host "github.com/cosmos/ibc-go/v2/modules/core/24-host"
"github.com/cosmos/ibc-go/v2/modules/core/exported"
)

const (
Expand All @@ -41,7 +37,7 @@ var (
MockTimeoutCanaryCapabilityName = "mock timeout canary capability name"
)

var _ porttypes.IBCModule = AppModule{}
var _ porttypes.IBCModule = IBCModule{}

// Expected Interface
// PortKeeper defines the expected IBC port keeper
Expand Down Expand Up @@ -94,7 +90,6 @@ type AppModule struct {
AppModuleBasic
scopedKeeper capabilitykeeper.ScopedKeeper
portKeeper PortKeeper
IBCApp MockIBCApp // base application of an IBC middleware stack
}

// NewAppModule returns a mock AppModule instance.
Expand Down Expand Up @@ -151,148 +146,3 @@ func (am AppModule) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) {
func (am AppModule) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) []abci.ValidatorUpdate {
return []abci.ValidatorUpdate{}
}

// OnChanOpenInit implements the IBCModule interface.
func (am AppModule) OnChanOpenInit(
ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID string,
channelID string, chanCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version string,
) error {
if am.IBCApp.OnChanOpenInit != nil {
return am.IBCApp.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version)

}

// Claim channel capability passed back by IBC module
if err := am.scopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil {
return err
}

return nil
}

// OnChanOpenTry implements the IBCModule interface.
func (am AppModule) OnChanOpenTry(
ctx sdk.Context, order channeltypes.Order, connectionHops []string, portID string,
channelID string, chanCap *capabilitytypes.Capability, counterparty channeltypes.Counterparty, version, counterpartyVersion string,
) error {
if am.IBCApp.OnChanOpenTry != nil {
return am.IBCApp.OnChanOpenTry(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, version, counterpartyVersion)

}
// Claim channel capability passed back by IBC module
if err := am.scopedKeeper.ClaimCapability(ctx, chanCap, host.ChannelCapabilityPath(portID, channelID)); err != nil {
return err
}

return nil
}

// OnChanOpenAck implements the IBCModule interface.
func (am AppModule) OnChanOpenAck(ctx sdk.Context, portID string, channelID string, counterpartyVersion string) error {
if am.IBCApp.OnChanOpenAck != nil {
return am.IBCApp.OnChanOpenAck(ctx, portID, channelID, counterpartyVersion)
}

return nil
}

// OnChanOpenConfirm implements the IBCModule interface.
func (am AppModule) OnChanOpenConfirm(ctx sdk.Context, portID, channelID string) error {
if am.IBCApp.OnChanOpenConfirm != nil {
return am.IBCApp.OnChanOpenConfirm(ctx, portID, channelID)
}

return nil
}

// OnChanCloseInit implements the IBCModule interface.
func (am AppModule) OnChanCloseInit(ctx sdk.Context, portID, channelID string) error {
if am.IBCApp.OnChanCloseInit != nil {
return am.IBCApp.OnChanCloseInit(ctx, portID, channelID)
}

return nil
}

// OnChanCloseConfirm implements the IBCModule interface.
func (am AppModule) OnChanCloseConfirm(ctx sdk.Context, portID, channelID string) error {
if am.IBCApp.OnChanCloseConfirm != nil {
return am.IBCApp.OnChanCloseConfirm(ctx, portID, channelID)
}

return nil
}

// OnRecvPacket implements the IBCModule interface.
func (am AppModule) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) exported.Acknowledgement {
if am.IBCApp.OnRecvPacket != nil {
return am.IBCApp.OnRecvPacket(ctx, packet, relayer)
}

// set state by claiming capability to check if revert happens return
_, err := am.scopedKeeper.NewCapability(ctx, MockRecvCanaryCapabilityName+strconv.Itoa(int(packet.GetSequence())))
if err != nil {
// application callback called twice on same packet sequence
// must never occur
panic(err)
}
if bytes.Equal(MockPacketData, packet.GetData()) {
return MockAcknowledgement
} else if bytes.Equal(MockAsyncPacketData, packet.GetData()) {
return nil
}

return MockFailAcknowledgement
}

// OnAcknowledgementPacket implements the IBCModule interface.
func (am AppModule) OnAcknowledgementPacket(ctx sdk.Context, packet channeltypes.Packet, acknowledgement []byte, relayer sdk.AccAddress) error {
if am.IBCApp.OnAcknowledgementPacket != nil {
return am.IBCApp.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer)
}

_, err := am.scopedKeeper.NewCapability(ctx, MockAckCanaryCapabilityName+strconv.Itoa(int(packet.GetSequence())))
if err != nil {
// application callback called twice on same packet sequence
// must never occur
panic(err)
}

return nil
}

// OnTimeoutPacket implements the IBCModule interface.
func (am AppModule) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) error {
if am.IBCApp.OnTimeoutPacket != nil {
return am.IBCApp.OnTimeoutPacket(ctx, packet, relayer)
}

_, err := am.scopedKeeper.NewCapability(ctx, MockTimeoutCanaryCapabilityName+strconv.Itoa(int(packet.GetSequence())))
if err != nil {
// application callback called twice on same packet sequence
// must never occur
panic(err)
}

return nil
}

// NegotiateAppVersion implements the IBCModule interface.
func (am AppModule) NegotiateAppVersion(
ctx sdk.Context,
order channeltypes.Order,
connectionID string,
portID string,
counterparty channeltypes.Counterparty,
proposedVersion string,
) (string, error) {
if am.IBCApp.NegotiateAppVersion != nil {
return am.IBCApp.NegotiateAppVersion(ctx, order, connectionID, portID, counterparty, proposedVersion)
}

if proposedVersion != Version { // allow testing of error scenarios
return "", errors.New("failed to negotiate app version")
}

return Version, nil
}
3 changes: 2 additions & 1 deletion testing/simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,11 +326,12 @@ func NewSimApp(
// NOTE: the IBC mock keeper and application module is used only for testing core IBC. Do
// note replicate if you do not need to test core IBC or light clients.
mockModule := ibcmock.NewAppModule(scopedIBCMockKeeper, &app.IBCKeeper.PortKeeper)
mockIBCModule := ibcmock.NewIBCModule(&ibcmock.MockIBCApp{}, scopedIBCMockKeeper)

// Create static IBC router, add transfer route, then set and seal it
ibcRouter := porttypes.NewRouter()
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferModule)
ibcRouter.AddRoute(ibcmock.ModuleName, mockModule)
ibcRouter.AddRoute(ibcmock.ModuleName, mockIBCModule)
app.IBCKeeper.SetRouter(ibcRouter)

// create evidence keeper with router
Expand Down