* Use ICS4Wrapper to send raw IBC packets & fix Fee in wasm stack (cherry picked from commit 6dfa5cb41c52180d30c2d0e1aed3fa2685a68c33) # Conflicts: # app/app.go # x/wasm/keeper/handler_plugin.go # x/wasm/keeper/keeper_cgo.go # x/wasm/keeper/keeper_test.go # x/wasm/keeper/options_test.go # x/wasm/keeper/test_common.go * Fix merge conflicts * Inline ibc packet sender interface and minor chore * Rename IBCPacketSender --------- Co-authored-by: Assaf Morami <assaf.morami@gmail.com> Co-authored-by: Alex Peters <alpe@users.noreply.github.com>
This commit is contained in:
@@ -591,6 +591,7 @@ func NewWasmApp(
|
||||
app.BankKeeper,
|
||||
app.StakingKeeper,
|
||||
distrkeeper.NewQuerier(app.DistrKeeper),
|
||||
app.IBCFeeKeeper, // ISC4 Wrapper: fee IBC middleware
|
||||
app.IBCKeeper.ChannelKeeper,
|
||||
&app.IBCKeeper.PortKeeper,
|
||||
scopedWasmKeeper,
|
||||
|
||||
@@ -4,11 +4,12 @@ import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"errors"
|
||||
"github.com/cometbft/cometbft/libs/rand"
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/cometbft/cometbft/libs/rand"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
|
||||
@@ -664,6 +664,7 @@ func setupKeeper(t *testing.T) (*Keeper, sdk.Context) {
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
tempDir,
|
||||
wasmConfig,
|
||||
AvailableCapabilities,
|
||||
|
||||
@@ -34,8 +34,10 @@ type SDKMessageHandler struct {
|
||||
encoders msgEncoder
|
||||
}
|
||||
|
||||
// NewDefaultMessageHandler constructor
|
||||
func NewDefaultMessageHandler(
|
||||
router MessageRouter,
|
||||
ics4Wrapper types.ICS4Wrapper,
|
||||
channelKeeper types.ChannelKeeper,
|
||||
capabilityKeeper types.CapabilityKeeper,
|
||||
bankKeeper types.Burner,
|
||||
@@ -49,7 +51,7 @@ func NewDefaultMessageHandler(
|
||||
}
|
||||
return NewMessageHandlerChain(
|
||||
NewSDKMessageHandler(router, encoders),
|
||||
NewIBCRawPacketHandler(channelKeeper, capabilityKeeper),
|
||||
NewIBCRawPacketHandler(ics4Wrapper, channelKeeper, capabilityKeeper),
|
||||
NewBurnCoinMessageHandler(bankKeeper),
|
||||
)
|
||||
}
|
||||
@@ -142,14 +144,20 @@ func (m MessageHandlerChain) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAd
|
||||
return nil, nil, errorsmod.Wrap(types.ErrUnknownMsg, "no handler found")
|
||||
}
|
||||
|
||||
// IBCRawPacketHandler handels IBC.SendPacket messages which are published to an IBC channel.
|
||||
// IBCRawPacketHandler handles IBC.SendPacket messages which are published to an IBC channel.
|
||||
type IBCRawPacketHandler struct {
|
||||
ics4Wrapper types.ICS4Wrapper
|
||||
channelKeeper types.ChannelKeeper
|
||||
capabilityKeeper types.CapabilityKeeper
|
||||
}
|
||||
|
||||
func NewIBCRawPacketHandler(chk types.ChannelKeeper, cak types.CapabilityKeeper) IBCRawPacketHandler {
|
||||
return IBCRawPacketHandler{channelKeeper: chk, capabilityKeeper: cak}
|
||||
// NewIBCRawPacketHandler constructor
|
||||
func NewIBCRawPacketHandler(ics4Wrapper types.ICS4Wrapper, channelKeeper types.ChannelKeeper, capabilityKeeper types.CapabilityKeeper) IBCRawPacketHandler {
|
||||
return IBCRawPacketHandler{
|
||||
ics4Wrapper: ics4Wrapper,
|
||||
channelKeeper: channelKeeper,
|
||||
capabilityKeeper: capabilityKeeper,
|
||||
}
|
||||
}
|
||||
|
||||
// DispatchMsg publishes a raw IBC packet onto the channel.
|
||||
@@ -169,7 +177,7 @@ func (h IBCRawPacketHandler) DispatchMsg(ctx sdk.Context, _ sdk.AccAddress, cont
|
||||
if !ok {
|
||||
return nil, nil, errorsmod.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability")
|
||||
}
|
||||
seq, err := h.channelKeeper.SendPacket(ctx, channelCap, contractIBCPortID, contractIBCChannelID, ConvertWasmIBCTimeoutHeightToCosmosHeight(msg.IBC.SendPacket.Timeout.Block), msg.IBC.SendPacket.Timeout.Timestamp, msg.IBC.SendPacket.Data)
|
||||
seq, err := h.ics4Wrapper.SendPacket(ctx, channelCap, contractIBCPortID, contractIBCChannelID, ConvertWasmIBCTimeoutHeightToCosmosHeight(msg.IBC.SendPacket.Timeout.Block), msg.IBC.SendPacket.Timeout.Timestamp, msg.IBC.SendPacket.Data)
|
||||
if err != nil {
|
||||
return nil, nil, errorsmod.Wrap(err, "channel")
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ import (
|
||||
"testing"
|
||||
|
||||
errorsmod "cosmossdk.io/errors"
|
||||
"github.com/cometbft/cometbft/libs/log"
|
||||
|
||||
wasmvm "github.com/CosmWasm/wasmvm"
|
||||
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
|
||||
"github.com/cometbft/cometbft/libs/log"
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
@@ -236,15 +236,7 @@ func TestIBCRawPacketHandler(t *testing.T) {
|
||||
}
|
||||
var capturedPacket *CapturedPacket
|
||||
|
||||
chanKeeper := &wasmtesting.MockChannelKeeper{
|
||||
GetChannelFn: func(ctx sdk.Context, srcPort, srcChan string) (channeltypes.Channel, bool) {
|
||||
return channeltypes.Channel{
|
||||
Counterparty: channeltypes.NewCounterparty(
|
||||
"other-port",
|
||||
"other-channel-1",
|
||||
),
|
||||
}, true
|
||||
},
|
||||
capturePacketsSenderMock := &wasmtesting.MockIBCPacketSender{
|
||||
SendPacketFn: func(ctx sdk.Context, channelCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) (uint64, error) {
|
||||
capturedPacket = &CapturedPacket{
|
||||
sourcePort: sourcePort,
|
||||
@@ -256,6 +248,16 @@ func TestIBCRawPacketHandler(t *testing.T) {
|
||||
return 1, nil
|
||||
},
|
||||
}
|
||||
chanKeeper := &wasmtesting.MockChannelKeeper{
|
||||
GetChannelFn: func(ctx sdk.Context, srcPort, srcChan string) (channeltypes.Channel, bool) {
|
||||
return channeltypes.Channel{
|
||||
Counterparty: channeltypes.NewCounterparty(
|
||||
"other-port",
|
||||
"other-channel-1",
|
||||
),
|
||||
}, true
|
||||
},
|
||||
}
|
||||
capKeeper := &wasmtesting.MockCapabilityKeeper{
|
||||
GetCapabilityFn: func(ctx sdk.Context, name string) (*capabilitytypes.Capability, bool) {
|
||||
return &capabilitytypes.Capability{}, true
|
||||
@@ -303,7 +305,7 @@ func TestIBCRawPacketHandler(t *testing.T) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
capturedPacket = nil
|
||||
// when
|
||||
h := NewIBCRawPacketHandler(spec.chanKeeper, spec.capKeeper)
|
||||
h := NewIBCRawPacketHandler(capturePacketsSenderMock, spec.chanKeeper, spec.capKeeper)
|
||||
evts, data, gotErr := h.DispatchMsg(ctx, RandomAccountAddress(t), ibcPort, wasmvmtypes.CosmosMsg{IBC: &wasmvmtypes.IBCMsg{SendPacket: &spec.srcMsg}})
|
||||
// then
|
||||
require.True(t, spec.expErr.Is(gotErr), "exp %v but got %#+v", spec.expErr, gotErr)
|
||||
|
||||
@@ -22,6 +22,7 @@ func NewKeeper(
|
||||
bankKeeper types.BankKeeper,
|
||||
stakingKeeper types.StakingKeeper,
|
||||
distrKeeper types.DistributionKeeper,
|
||||
ics4Wrapper types.ICS4Wrapper,
|
||||
channelKeeper types.ChannelKeeper,
|
||||
portKeeper types.PortKeeper,
|
||||
capabilityKeeper types.CapabilityKeeper,
|
||||
@@ -48,7 +49,7 @@ func NewKeeper(
|
||||
accountPruner: NewVestingCoinBurner(bankKeeper),
|
||||
portKeeper: portKeeper,
|
||||
capabilityKeeper: capabilityKeeper,
|
||||
messenger: NewDefaultMessageHandler(router, channelKeeper, capabilityKeeper, bankKeeper, cdc, portSource),
|
||||
messenger: NewDefaultMessageHandler(router, ics4Wrapper, channelKeeper, capabilityKeeper, bankKeeper, cdc, portSource),
|
||||
queryGasLimit: wasmConfig.SmartQueryGasLimit,
|
||||
gasRegister: NewDefaultWasmGasRegister(),
|
||||
maxQueryStackSize: types.DefaultMaxQueryStackSize,
|
||||
|
||||
@@ -18,6 +18,7 @@ func NewKeeper(
|
||||
bankKeeper types.BankKeeper,
|
||||
stakingKeeper types.StakingKeeper,
|
||||
distrKeeper types.DistributionKeeper,
|
||||
ics4Wrapper types.ICS4Wrapper,
|
||||
channelKeeper types.ChannelKeeper,
|
||||
portKeeper types.PortKeeper,
|
||||
capabilityKeeper types.CapabilityKeeper,
|
||||
|
||||
@@ -752,7 +752,7 @@ func TestInstantiateWithContractFactoryChildQueriesParent(t *testing.T) {
|
||||
router := baseapp.NewMsgServiceRouter()
|
||||
router.SetInterfaceRegistry(keepers.EncodingConfig.InterfaceRegistry)
|
||||
types.RegisterMsgServer(router, NewMsgServerImpl(keeper))
|
||||
keeper.messenger = NewDefaultMessageHandler(router, nil, nil, nil, keepers.EncodingConfig.Marshaler, nil)
|
||||
keeper.messenger = NewDefaultMessageHandler(router, nil, nil, nil, nil, keepers.EncodingConfig.Marshaler, nil)
|
||||
// overwrite wasmvm in response handler
|
||||
keeper.wasmVMResponseHandler = NewDefaultWasmVMContractResponseHandler(NewMessageDispatcher(keeper.messenger, keeper))
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ func TestConstructorOptions(t *testing.T) {
|
||||
}
|
||||
for name, spec := range specs {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
k := NewKeeper(nil, nil, authkeeper.AccountKeeper{}, &bankkeeper.BaseKeeper{}, stakingkeeper.Keeper{}, nil, nil, nil, nil, nil, nil, nil, "tempDir", types.DefaultWasmConfig(), AvailableCapabilities, "", spec.srcOpt)
|
||||
k := NewKeeper(nil, nil, authkeeper.AccountKeeper{}, &bankkeeper.BaseKeeper{}, stakingkeeper.Keeper{}, nil, nil, nil, nil, nil, nil, nil, nil, "tempDir", types.DefaultWasmConfig(), AvailableCapabilities, "", spec.srcOpt)
|
||||
spec.verify(t, k)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -425,6 +425,7 @@ func createTestInput(
|
||||
bankKeeper,
|
||||
stakingKeeper,
|
||||
distributionkeeper.NewQuerier(distKeeper),
|
||||
ibcKeeper.ChannelKeeper, // ICS4Wrapper
|
||||
ibcKeeper.ChannelKeeper,
|
||||
&ibcKeeper.PortKeeper,
|
||||
scopedWasmKeeper,
|
||||
|
||||
@@ -10,12 +10,12 @@ import (
|
||||
)
|
||||
|
||||
type MockChannelKeeper struct {
|
||||
GetChannelFn func(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool)
|
||||
SendPacketFn func(ctx sdk.Context, channelCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) (uint64, error)
|
||||
ChanCloseInitFn func(ctx sdk.Context, portID, channelID string, chanCap *capabilitytypes.Capability) error
|
||||
GetAllChannelsFn func(ctx sdk.Context) []channeltypes.IdentifiedChannel
|
||||
IterateChannelsFn func(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool)
|
||||
SetChannelFn func(ctx sdk.Context, portID, channelID string, channel channeltypes.Channel)
|
||||
GetChannelFn func(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool)
|
||||
GetNextSequenceSendFn func(ctx sdk.Context, portID, channelID string) (uint64, bool)
|
||||
ChanCloseInitFn func(ctx sdk.Context, portID, channelID string, chanCap *capabilitytypes.Capability) error
|
||||
GetAllChannelsFn func(ctx sdk.Context) []channeltypes.IdentifiedChannel
|
||||
IterateChannelsFn func(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool)
|
||||
SetChannelFn func(ctx sdk.Context, portID, channelID string, channel channeltypes.Channel)
|
||||
}
|
||||
|
||||
func (m *MockChannelKeeper) GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool) {
|
||||
@@ -32,11 +32,11 @@ func (m *MockChannelKeeper) GetAllChannels(ctx sdk.Context) []channeltypes.Ident
|
||||
return m.GetAllChannelsFn(ctx)
|
||||
}
|
||||
|
||||
func (m *MockChannelKeeper) SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) (uint64, error) {
|
||||
if m.SendPacketFn == nil {
|
||||
func (m *MockChannelKeeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) {
|
||||
if m.GetNextSequenceSendFn == nil {
|
||||
panic("not supposed to be called!")
|
||||
}
|
||||
return m.SendPacketFn(ctx, channelCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data)
|
||||
return m.GetNextSequenceSendFn(ctx, portID, channelID)
|
||||
}
|
||||
|
||||
func (m *MockChannelKeeper) ChanCloseInit(ctx sdk.Context, portID, channelID string, chanCap *capabilitytypes.Capability) error {
|
||||
@@ -60,6 +60,17 @@ func (m *MockChannelKeeper) SetChannel(ctx sdk.Context, portID, channelID string
|
||||
m.SetChannelFn(ctx, portID, channelID, channel)
|
||||
}
|
||||
|
||||
type MockIBCPacketSender struct {
|
||||
SendPacketFn func(ctx sdk.Context, channelCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) (uint64, error)
|
||||
}
|
||||
|
||||
func (m *MockIBCPacketSender) SendPacket(ctx sdk.Context, channelCap *capabilitytypes.Capability, sourcePort string, sourceChannel string, timeoutHeight clienttypes.Height, timeoutTimestamp uint64, data []byte) (uint64, error) {
|
||||
if m.SendPacketFn == nil {
|
||||
panic("not supposed to be called!")
|
||||
}
|
||||
return m.SendPacketFn(ctx, channelCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data)
|
||||
}
|
||||
|
||||
func MockChannelKeeperIterator(s []channeltypes.IdentifiedChannel) func(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool) {
|
||||
return func(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool) {
|
||||
for _, channel := range s {
|
||||
|
||||
@@ -3,12 +3,13 @@ package types
|
||||
import (
|
||||
"context"
|
||||
|
||||
clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
|
||||
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
|
||||
connectiontypes "github.com/cosmos/ibc-go/v7/modules/core/03-connection/types"
|
||||
channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types"
|
||||
ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported"
|
||||
@@ -72,7 +73,21 @@ type StakingKeeper interface {
|
||||
// ChannelKeeper defines the expected IBC channel keeper
|
||||
type ChannelKeeper interface {
|
||||
GetChannel(ctx sdk.Context, srcPort, srcChan string) (channel channeltypes.Channel, found bool)
|
||||
GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool)
|
||||
ChanCloseInit(ctx sdk.Context, portID, channelID string, chanCap *capabilitytypes.Capability) error
|
||||
GetAllChannels(ctx sdk.Context) (channels []channeltypes.IdentifiedChannel)
|
||||
IterateChannels(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool)
|
||||
SetChannel(ctx sdk.Context, portID, channelID string, channel channeltypes.Channel)
|
||||
}
|
||||
|
||||
// ICS4Wrapper defines the method for an IBC data package to be submitted.
|
||||
// The interface is implemented by the channel keeper on the lowest level in ibc-go. Middlewares or other abstractions
|
||||
// can add functionality on top of it. See ics4Wrapper in ibc-go.
|
||||
// It is important to choose the right implementation that is configured for any middleware used in the ibc-stack of wasm.
|
||||
//
|
||||
// For example, when ics-29 fee middleware is set up for the wasm ibc-stack, then the IBCFeeKeeper should be used, so
|
||||
// that they are in sync.
|
||||
type ICS4Wrapper interface {
|
||||
// SendPacket is called by a module in order to send an IBC packet on a channel.
|
||||
// The packet sequence generated for the packet to be sent is returned. An error
|
||||
// is returned if one occurs.
|
||||
@@ -85,10 +100,6 @@ type ChannelKeeper interface {
|
||||
timeoutTimestamp uint64,
|
||||
data []byte,
|
||||
) (uint64, error)
|
||||
ChanCloseInit(ctx sdk.Context, portID, channelID string, chanCap *capabilitytypes.Capability) error
|
||||
GetAllChannels(ctx sdk.Context) (channels []channeltypes.IdentifiedChannel)
|
||||
IterateChannels(ctx sdk.Context, cb func(channeltypes.IdentifiedChannel) bool)
|
||||
SetChannel(ctx sdk.Context, portID, channelID string, channel channeltypes.Channel)
|
||||
}
|
||||
|
||||
// ClientKeeper defines the expected IBC client keeper
|
||||
|
||||
Reference in New Issue
Block a user