Handle non default ibc tranfer port

This commit is contained in:
Alex Peters
2021-03-18 15:27:18 +01:00
parent 8e35dc260b
commit 6996f72b38
10 changed files with 77 additions and 47 deletions

View File

@@ -366,6 +366,7 @@ func NewWasmApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b
app.ibcKeeper.ChannelKeeper,
&app.ibcKeeper.PortKeeper,
scopedWasmKeeper,
app.transferKeeper,
app.Router(),
app.GRPCQueryRouter(),
wasmDir,
@@ -442,6 +443,7 @@ func NewWasmApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b
capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName,
slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName, crisistypes.ModuleName,
ibchost.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, ibctransfertypes.ModuleName,
// wasm after ibc transfer
wasm.ModuleName,
)

View File

@@ -643,7 +643,7 @@ func setupKeeper(t *testing.T) (*Keeper, sdk.Context, []sdk.StoreKey) {
wasmConfig := wasmTypes.DefaultWasmConfig()
pk := paramskeeper.NewKeeper(encodingConfig.Marshaler, encodingConfig.Amino, keyParams, tkeyParams)
srcKeeper := NewKeeper(encodingConfig.Marshaler, keyWasm, pk.Subspace(wasmTypes.DefaultParamspace), authkeeper.AccountKeeper{}, nil, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, tempDir, wasmConfig, SupportedFeatures)
srcKeeper := NewKeeper(encodingConfig.Marshaler, keyWasm, pk.Subspace(wasmTypes.DefaultParamspace), authkeeper.AccountKeeper{}, nil, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, nil, tempDir, wasmConfig, SupportedFeatures)
return &srcKeeper, ctx, []sdk.StoreKey{keyWasm, keyParams}
}

View File

@@ -24,8 +24,8 @@ type SDKMessageHandler struct {
encoders msgEncoder
}
func NewDefaultMessageHandler(router sdk.Router, channelKeeper types.ChannelKeeper, capabilityKeeper types.CapabilityKeeper, unpacker codectypes.AnyUnpacker, customEncoders ...*MessageEncoders) messenger {
encoders := DefaultEncoders(unpacker)
func NewDefaultMessageHandler(router sdk.Router, channelKeeper types.ChannelKeeper, capabilityKeeper types.CapabilityKeeper, unpacker codectypes.AnyUnpacker, portSource types.ICS20TransferPortSource, customEncoders ...*MessageEncoders) messenger {
encoders := DefaultEncoders(unpacker, portSource)
for _, e := range customEncoders {
encoders = encoders.Merge(e)
}

View File

@@ -32,11 +32,11 @@ type MessageEncoders struct {
Wasm func(sender sdk.AccAddress, msg *wasmvmtypes.WasmMsg) ([]sdk.Msg, error)
}
func DefaultEncoders(unpacker codectypes.AnyUnpacker) MessageEncoders {
func DefaultEncoders(unpacker codectypes.AnyUnpacker, portSource types.ICS20TransferPortSource) MessageEncoders {
return MessageEncoders{
Bank: EncodeBankMsg,
Custom: NoCustomMsg,
IBC: EncodeIBCMsg,
IBC: EncodeIBCMsg(portSource),
Staking: EncodeStakingMsg,
Stargate: EncodeStargateMsg(unpacker),
Wasm: EncodeWasmMsg,
@@ -225,32 +225,33 @@ func EncodeWasmMsg(sender sdk.AccAddress, msg *wasmvmtypes.WasmMsg) ([]sdk.Msg,
}
}
func EncodeIBCMsg(ctx sdk.Context, sender sdk.AccAddress, contractIBCPortID string, msg *wasmvmtypes.IBCMsg) ([]sdk.Msg, error) {
switch {
case msg.CloseChannel != nil:
return []sdk.Msg{&channeltypes.MsgChannelCloseInit{
PortId: PortIDForContract(sender),
ChannelId: msg.CloseChannel.ChannelID,
Signer: sender.String(),
}}, nil
case msg.Transfer != nil:
amount, err := convertWasmCoinToSdkCoin(msg.Transfer.Amount)
if err != nil {
return nil, sdkerrors.Wrap(err, "amount")
func EncodeIBCMsg(portSource types.ICS20TransferPortSource) func(ctx sdk.Context, sender sdk.AccAddress, contractIBCPortID string, msg *wasmvmtypes.IBCMsg) ([]sdk.Msg, error) {
return func(ctx sdk.Context, sender sdk.AccAddress, contractIBCPortID string, msg *wasmvmtypes.IBCMsg) ([]sdk.Msg, error) {
switch {
case msg.CloseChannel != nil:
return []sdk.Msg{&channeltypes.MsgChannelCloseInit{
PortId: PortIDForContract(sender),
ChannelId: msg.CloseChannel.ChannelID,
Signer: sender.String(),
}}, nil
case msg.Transfer != nil:
amount, err := convertWasmCoinToSdkCoin(msg.Transfer.Amount)
if err != nil {
return nil, sdkerrors.Wrap(err, "amount")
}
msg := &ibctransfertypes.MsgTransfer{
SourcePort: portSource.GetPort(ctx),
SourceChannel: msg.Transfer.ChannelID,
Token: amount,
Sender: sender.String(),
Receiver: msg.Transfer.ToAddress,
TimeoutHeight: convertWasmIBCTimeoutHeightToCosmosHeight(msg.Transfer.TimeoutBlock),
TimeoutTimestamp: convertWasmIBCTimeoutTimestampToCosmosTimestamp(msg.Transfer.TimeoutTimestamp),
}
return []sdk.Msg{msg}, nil
default:
return nil, sdkerrors.Wrap(types.ErrUnknownMsg, "Unknown variant of IBC")
}
portID := ibctransfertypes.ModuleName //todo: port can be customized in genesis. make this more flexible
msg := &ibctransfertypes.MsgTransfer{
SourcePort: portID,
SourceChannel: msg.Transfer.ChannelID,
Token: amount,
Sender: sender.String(),
Receiver: msg.Transfer.ToAddress,
TimeoutHeight: convertWasmIBCTimeoutHeightToCosmosHeight(msg.Transfer.TimeoutBlock),
TimeoutTimestamp: convertWasmIBCTimeoutTimestampToCosmosTimestamp(msg.Transfer.TimeoutTimestamp),
}
return []sdk.Msg{msg}, nil
default:
return nil, sdkerrors.Wrap(types.ErrUnknownMsg, "Unknown variant of IBC")
}
}

View File

@@ -2,6 +2,7 @@ package keeper
import (
"encoding/json"
"github.com/CosmWasm/wasmd/x/wasm/internal/keeper/wasmtesting"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
ibctransfertypes "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types"
@@ -55,9 +56,10 @@ func TestEncoding(t *testing.T) {
require.NoError(t, err)
cases := map[string]struct {
sender sdk.AccAddress
srcMsg wasmvmtypes.CosmosMsg
srcIBCPort string
sender sdk.AccAddress
srcMsg wasmvmtypes.CosmosMsg
srcContractIBCPort string
transferPortSource types.ICS20TransferPortSource
// set if valid
output []sdk.Msg
// set if invalid
@@ -349,8 +351,8 @@ func TestEncoding(t *testing.T) {
isError: true,
},
"IBC transfer with block timeout": {
sender: addr1,
srcIBCPort: "myIBCPort",
sender: addr1,
srcContractIBCPort: "myIBCPort",
srcMsg: wasmvmtypes.CosmosMsg{
IBC: &wasmvmtypes.IBCMsg{
Transfer: &wasmvmtypes.TransferMsg{
@@ -364,9 +366,12 @@ func TestEncoding(t *testing.T) {
},
},
},
transferPortSource: wasmtesting.MockIBCTransferKeeper{GetPortFn: func(ctx sdk.Context) string {
return "myTransferPort"
}},
output: []sdk.Msg{
&ibctransfertypes.MsgTransfer{
SourcePort: "transfer",
SourcePort: "myTransferPort",
SourceChannel: "myChanID",
Token: sdk.Coin{
Denom: "ALX",
@@ -379,8 +384,8 @@ func TestEncoding(t *testing.T) {
},
},
"IBC transfer with time timeout": {
sender: addr1,
srcIBCPort: "myIBCPort",
sender: addr1,
srcContractIBCPort: "myIBCPort",
srcMsg: wasmvmtypes.CosmosMsg{
IBC: &wasmvmtypes.IBCMsg{
Transfer: &wasmvmtypes.TransferMsg{
@@ -394,6 +399,9 @@ func TestEncoding(t *testing.T) {
},
},
},
transferPortSource: wasmtesting.MockIBCTransferKeeper{GetPortFn: func(ctx sdk.Context) string {
return "transfer"
}},
output: []sdk.Msg{
&ibctransfertypes.MsgTransfer{
SourcePort: "transfer",
@@ -409,8 +417,8 @@ func TestEncoding(t *testing.T) {
},
},
"IBC close channel": {
sender: addr1,
srcIBCPort: "myIBCPort",
sender: addr1,
srcContractIBCPort: "myIBCPort",
srcMsg: wasmvmtypes.CosmosMsg{
IBC: &wasmvmtypes.IBCMsg{
CloseChannel: &wasmvmtypes.CloseChannelMsg{
@@ -428,12 +436,11 @@ func TestEncoding(t *testing.T) {
},
}
encodingConfig := MakeEncodingConfig(t)
encoder := DefaultEncoders(encodingConfig.Marshaler)
for name, tc := range cases {
tc := tc
t.Run(name, func(t *testing.T) {
var ctx sdk.Context
res, err := encoder.Encode(ctx, tc.sender, tc.srcIBCPort, tc.srcMsg)
encoder := DefaultEncoders(encodingConfig.Marshaler, tc.transferPortSource)
res, err := encoder.Encode(ctx, tc.sender, tc.srcContractIBCPort, tc.srcMsg)
if tc.isError {
require.Error(t, err)
} else {

View File

@@ -97,6 +97,7 @@ func NewKeeper(
channelKeeper types.ChannelKeeper,
portKeeper types.PortKeeper,
capabilityKeeper types.CapabilityKeeper,
portSource types.ICS20TransferPortSource,
router sdk.Router,
queryRouter GRPCQueryRouter,
homeDir string,
@@ -122,7 +123,7 @@ func NewKeeper(
ChannelKeeper: channelKeeper,
portKeeper: portKeeper,
capabilityKeeper: capabilityKeeper,
messenger: NewDefaultMessageHandler(router, channelKeeper, capabilityKeeper, cdc),
messenger: NewDefaultMessageHandler(router, channelKeeper, capabilityKeeper, cdc, portSource),
queryGasLimit: wasmConfig.SmartQueryGasLimit,
authZPolicy: DefaultAuthorizationPolicy{},
paramSpace: paramSpace,

View File

@@ -43,7 +43,7 @@ func TestConstructorOptions(t *testing.T) {
}
for name, spec := range specs {
t.Run(name, func(t *testing.T) {
k := NewKeeper(nil, nil, paramtypes.NewSubspace(nil, nil, nil, nil, ""), authkeeper.AccountKeeper{}, nil, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, "tempDir", types.DefaultWasmConfig(), SupportedFeatures, spec.srcOpt)
k := NewKeeper(nil, nil, paramtypes.NewSubspace(nil, nil, nil, nil, ""), authkeeper.AccountKeeper{}, nil, stakingkeeper.Keeper{}, distributionkeeper.Keeper{}, nil, nil, nil, nil, nil, nil, "tempDir", types.DefaultWasmConfig(), SupportedFeatures, spec.srcOpt)
spec.verify(k)
})
}

View File

@@ -4,6 +4,7 @@ import (
"encoding/binary"
"encoding/json"
"fmt"
"github.com/CosmWasm/wasmd/x/wasm/internal/keeper/wasmtesting"
types "github.com/CosmWasm/wasmd/x/wasm/internal/types"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
@@ -292,6 +293,7 @@ func createTestInput(
ibcKeeper.ChannelKeeper,
&ibcKeeper.PortKeeper,
scopedWasmKeeper,
wasmtesting.MockIBCTransferKeeper{},
router,
querier,
tempDir,

View File

@@ -1,6 +1,7 @@
package wasmtesting
import (
"github.com/CosmWasm/wasmd/x/wasm/internal/types"
sdk "github.com/cosmos/cosmos-sdk/types"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
channeltypes "github.com/cosmos/cosmos-sdk/x/ibc/core/04-channel/types"
@@ -87,7 +88,6 @@ func (m MockCapabilityKeeper) ClaimCapability(ctx sdk.Context, cap *capabilityty
panic("not supposed to be called!")
}
return m.ClaimCapabilityFn(ctx, cap, name)
}
func (m MockCapabilityKeeper) AuthenticateCapability(ctx sdk.Context, capability *capabilitytypes.Capability, name string) bool {
@@ -95,5 +95,17 @@ func (m MockCapabilityKeeper) AuthenticateCapability(ctx sdk.Context, capability
panic("not supposed to be called!")
}
return m.AuthenticateCapabilityFn(ctx, capability, name)
}
var _ types.ICS20TransferPortSource = &MockIBCTransferKeeper{}
type MockIBCTransferKeeper struct {
GetPortFn func(ctx sdk.Context) string
}
func (m MockIBCTransferKeeper) GetPort(ctx sdk.Context) string {
if m.GetPortFn == nil {
panic("not expected to be called")
}
return m.GetPortFn(ctx)
}

View File

@@ -88,3 +88,8 @@ type CapabilityKeeper interface {
ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) error
AuthenticateCapability(ctx sdk.Context, capability *capabilitytypes.Capability, name string) bool
}
// ICS20TransferPortSource is a subset of the ibc transfer keeper.
type ICS20TransferPortSource interface {
GetPort(ctx sdk.Context) string
}