Add flattened msgResponses to SubMsgResponse
This commit is contained in:
committed by
Christoph Otter
parent
2887105814
commit
a30e083b90
@@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
|
|
||||||
@@ -66,18 +67,19 @@ func NewSDKMessageHandler(cdc codec.Codec, router MessageRouter, encoders msgEnc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h SDKMessageHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
|
func (h SDKMessageHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, msgResponses [][]*codectypes.Any, err error) {
|
||||||
sdkMsgs, err := h.encoders.Encode(ctx, contractAddr, contractIBCPortID, msg)
|
sdkMsgs, err := h.encoders.Encode(ctx, contractAddr, contractIBCPortID, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
for _, sdkMsg := range sdkMsgs {
|
for _, sdkMsg := range sdkMsgs {
|
||||||
res, err := h.handleSdkMessage(ctx, contractAddr, sdkMsg)
|
res, err := h.handleSdkMessage(ctx, contractAddr, sdkMsg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
// append data
|
// append data and msgResponses
|
||||||
data = append(data, res.Data)
|
data = append(data, res.Data)
|
||||||
|
msgResponses = append(msgResponses, res.MsgResponses)
|
||||||
// append events
|
// append events
|
||||||
sdkEvents := make([]sdk.Event, len(res.Events))
|
sdkEvents := make([]sdk.Event, len(res.Events))
|
||||||
for i := range res.Events {
|
for i := range res.Events {
|
||||||
@@ -141,19 +143,19 @@ func NewMessageHandlerChain(first Messenger, others ...Messenger) *MessageHandle
|
|||||||
// order to find the right one to process given message. If a handler cannot
|
// order to find the right one to process given message. If a handler cannot
|
||||||
// process given message (returns ErrUnknownMsg), its result is ignored and the
|
// process given message (returns ErrUnknownMsg), its result is ignored and the
|
||||||
// next handler is executed.
|
// next handler is executed.
|
||||||
func (m MessageHandlerChain) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) ([]sdk.Event, [][]byte, error) {
|
func (m MessageHandlerChain) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) ([]sdk.Event, [][]byte, [][]*codectypes.Any, error) {
|
||||||
for _, h := range m.handlers {
|
for _, h := range m.handlers {
|
||||||
events, data, err := h.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg)
|
events, data, msgResponses, err := h.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg)
|
||||||
switch {
|
switch {
|
||||||
case err == nil:
|
case err == nil:
|
||||||
return events, data, nil
|
return events, data, msgResponses, nil
|
||||||
case errors.Is(err, types.ErrUnknownMsg):
|
case errors.Is(err, types.ErrUnknownMsg):
|
||||||
continue
|
continue
|
||||||
default:
|
default:
|
||||||
return events, data, err
|
return events, data, msgResponses, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, nil, errorsmod.Wrap(types.ErrUnknownMsg, "no handler found")
|
return nil, nil, nil, errorsmod.Wrap(types.ErrUnknownMsg, "no handler found")
|
||||||
}
|
}
|
||||||
|
|
||||||
// IBCRawPacketHandler handles IBC.SendPacket messages which are published to an IBC channel.
|
// IBCRawPacketHandler handles IBC.SendPacket messages which are published to an IBC channel.
|
||||||
@@ -173,67 +175,69 @@ func NewIBCRawPacketHandler(ics4Wrapper types.ICS4Wrapper, channelKeeper types.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DispatchMsg publishes a raw IBC packet onto the channel.
|
// DispatchMsg publishes a raw IBC packet onto the channel.
|
||||||
func (h IBCRawPacketHandler) DispatchMsg(ctx sdk.Context, _ sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) ([]sdk.Event, [][]byte, error) {
|
func (h IBCRawPacketHandler) DispatchMsg(ctx sdk.Context, _ sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) ([]sdk.Event, [][]byte, [][]*codectypes.Any, error) {
|
||||||
if msg.IBC == nil || msg.IBC.SendPacket == nil {
|
if msg.IBC == nil || msg.IBC.SendPacket == nil {
|
||||||
return nil, nil, types.ErrUnknownMsg
|
return nil, nil, nil, types.ErrUnknownMsg
|
||||||
}
|
}
|
||||||
if contractIBCPortID == "" {
|
if contractIBCPortID == "" {
|
||||||
return nil, nil, errorsmod.Wrapf(types.ErrUnsupportedForContract, "ibc not supported")
|
return nil, nil, nil, errorsmod.Wrapf(types.ErrUnsupportedForContract, "ibc not supported")
|
||||||
}
|
}
|
||||||
contractIBCChannelID := msg.IBC.SendPacket.ChannelID
|
contractIBCChannelID := msg.IBC.SendPacket.ChannelID
|
||||||
if contractIBCChannelID == "" {
|
if contractIBCChannelID == "" {
|
||||||
return nil, nil, errorsmod.Wrapf(types.ErrEmpty, "ibc channel")
|
return nil, nil, nil, errorsmod.Wrapf(types.ErrEmpty, "ibc channel")
|
||||||
}
|
}
|
||||||
|
|
||||||
channelCap, ok := h.capabilityKeeper.GetCapability(ctx, host.ChannelCapabilityPath(contractIBCPortID, contractIBCChannelID))
|
channelCap, ok := h.capabilityKeeper.GetCapability(ctx, host.ChannelCapabilityPath(contractIBCPortID, contractIBCChannelID))
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil, errorsmod.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability")
|
return nil, nil, nil, errorsmod.Wrap(channeltypes.ErrChannelCapabilityNotFound, "module does not own channel capability")
|
||||||
}
|
}
|
||||||
seq, err := h.ics4Wrapper.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 {
|
if err != nil {
|
||||||
return nil, nil, errorsmod.Wrap(err, "channel")
|
return nil, nil, nil, errorsmod.Wrap(err, "channel")
|
||||||
}
|
}
|
||||||
moduleLogger(ctx).Debug("ibc packet set", "seq", seq)
|
moduleLogger(ctx).Debug("ibc packet set", "seq", seq)
|
||||||
|
|
||||||
|
var msgResponse [][]*codectypes.Any
|
||||||
resp := &types.MsgIBCSendResponse{Sequence: seq}
|
resp := &types.MsgIBCSendResponse{Sequence: seq}
|
||||||
val, err := resp.Marshal()
|
val, err := resp.Marshal()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errorsmod.Wrap(err, "failed to marshal IBC send response")
|
return nil, nil, nil, errorsmod.Wrap(err, "failed to marshal IBC send response")
|
||||||
}
|
}
|
||||||
|
// TODO: fill msgResponse
|
||||||
|
|
||||||
return nil, [][]byte{val}, nil
|
return nil, [][]byte{val}, msgResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Messenger = MessageHandlerFunc(nil)
|
var _ Messenger = MessageHandlerFunc(nil)
|
||||||
|
|
||||||
// MessageHandlerFunc is a helper to construct a function based message handler.
|
// MessageHandlerFunc is a helper to construct a function based message handler.
|
||||||
type MessageHandlerFunc func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error)
|
type MessageHandlerFunc func(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, msgResponses [][]*codectypes.Any, err error)
|
||||||
|
|
||||||
// DispatchMsg delegates dispatching of provided message into the MessageHandlerFunc.
|
// DispatchMsg delegates dispatching of provided message into the MessageHandlerFunc.
|
||||||
func (m MessageHandlerFunc) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
|
func (m MessageHandlerFunc) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, msgResponses [][]*codectypes.Any, err error) {
|
||||||
return m(ctx, contractAddr, contractIBCPortID, msg)
|
return m(ctx, contractAddr, contractIBCPortID, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBurnCoinMessageHandler handles wasmvm.BurnMsg messages
|
// NewBurnCoinMessageHandler handles wasmvm.BurnMsg messages
|
||||||
func NewBurnCoinMessageHandler(burner types.Burner) MessageHandlerFunc {
|
func NewBurnCoinMessageHandler(burner types.Burner) MessageHandlerFunc {
|
||||||
return func(ctx sdk.Context, contractAddr sdk.AccAddress, _ string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
|
return func(ctx sdk.Context, contractAddr sdk.AccAddress, _ string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, msgResponses [][]*codectypes.Any, err error) {
|
||||||
if msg.Bank != nil && msg.Bank.Burn != nil {
|
if msg.Bank != nil && msg.Bank.Burn != nil {
|
||||||
coins, err := ConvertWasmCoinsToSdkCoins(msg.Bank.Burn.Amount)
|
coins, err := ConvertWasmCoinsToSdkCoins(msg.Bank.Burn.Amount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
if coins.IsZero() {
|
if coins.IsZero() {
|
||||||
return nil, nil, types.ErrEmpty.Wrap("amount")
|
return nil, nil, nil, types.ErrEmpty.Wrap("amount")
|
||||||
}
|
}
|
||||||
if err := burner.SendCoinsFromAccountToModule(ctx, contractAddr, types.ModuleName, coins); err != nil {
|
if err := burner.SendCoinsFromAccountToModule(ctx, contractAddr, types.ModuleName, coins); err != nil {
|
||||||
return nil, nil, errorsmod.Wrap(err, "transfer to module")
|
return nil, nil, nil, errorsmod.Wrap(err, "transfer to module")
|
||||||
}
|
}
|
||||||
if err := burner.BurnCoins(ctx, types.ModuleName, coins); err != nil {
|
if err := burner.BurnCoins(ctx, types.ModuleName, coins); err != nil {
|
||||||
return nil, nil, errorsmod.Wrap(err, "burn coins")
|
return nil, nil, nil, errorsmod.Wrap(err, "burn coins")
|
||||||
}
|
}
|
||||||
moduleLogger(ctx).Info("Burned", "amount", coins)
|
moduleLogger(ctx).Info("Burned", "amount", coins)
|
||||||
return nil, nil, nil
|
return nil, nil, nil, nil
|
||||||
}
|
}
|
||||||
return nil, nil, types.ErrUnknownMsg
|
return nil, nil, nil, types.ErrUnknownMsg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
errorsmod "cosmossdk.io/errors"
|
errorsmod "cosmossdk.io/errors"
|
||||||
storetypes "cosmossdk.io/store/types"
|
storetypes "cosmossdk.io/store/types"
|
||||||
|
|
||||||
|
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ import (
|
|||||||
// Messenger is an extension point for custom wasmd message handling
|
// Messenger is an extension point for custom wasmd message handling
|
||||||
type Messenger interface {
|
type Messenger interface {
|
||||||
// DispatchMsg encodes the wasmVM message and dispatches it.
|
// DispatchMsg encodes the wasmVM message and dispatches it.
|
||||||
DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error)
|
DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, msgResponses [][]*codectypes.Any, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// replyer is a subset of keeper that can handle replies to submessages
|
// replyer is a subset of keeper that can handle replies to submessages
|
||||||
@@ -42,7 +43,7 @@ func NewMessageDispatcher(messenger Messenger, keeper replyer) *MessageDispatche
|
|||||||
// DispatchMessages sends all messages.
|
// DispatchMessages sends all messages.
|
||||||
func (d MessageDispatcher) DispatchMessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.CosmosMsg) error {
|
func (d MessageDispatcher) DispatchMessages(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msgs []wasmvmtypes.CosmosMsg) error {
|
||||||
for _, msg := range msgs {
|
for _, msg := range msgs {
|
||||||
events, _, err := d.messenger.DispatchMsg(ctx, contractAddr, ibcPort, msg)
|
events, _, _, err := d.messenger.DispatchMsg(ctx, contractAddr, ibcPort, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -53,7 +54,7 @@ func (d MessageDispatcher) DispatchMessages(ctx sdk.Context, contractAddr sdk.Ac
|
|||||||
}
|
}
|
||||||
|
|
||||||
// dispatchMsgWithGasLimit sends a message with gas limit applied
|
// dispatchMsgWithGasLimit sends a message with gas limit applied
|
||||||
func (d MessageDispatcher) dispatchMsgWithGasLimit(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msg wasmvmtypes.CosmosMsg, gasLimit uint64) (events []sdk.Event, data [][]byte, err error) {
|
func (d MessageDispatcher) dispatchMsgWithGasLimit(ctx sdk.Context, contractAddr sdk.AccAddress, ibcPort string, msg wasmvmtypes.CosmosMsg, gasLimit uint64) (events []sdk.Event, data [][]byte, msgResponses [][]*codectypes.Any, err error) {
|
||||||
limitedMeter := storetypes.NewGasMeter(gasLimit)
|
limitedMeter := storetypes.NewGasMeter(gasLimit)
|
||||||
subCtx := ctx.WithGasMeter(limitedMeter)
|
subCtx := ctx.WithGasMeter(limitedMeter)
|
||||||
|
|
||||||
@@ -70,13 +71,13 @@ func (d MessageDispatcher) dispatchMsgWithGasLimit(ctx sdk.Context, contractAddr
|
|||||||
err = errorsmod.Wrap(sdkerrors.ErrOutOfGas, "SubMsg hit gas limit")
|
err = errorsmod.Wrap(sdkerrors.ErrOutOfGas, "SubMsg hit gas limit")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
events, data, err = d.messenger.DispatchMsg(subCtx, contractAddr, ibcPort, msg)
|
events, data, msgResponses, err = d.messenger.DispatchMsg(subCtx, contractAddr, ibcPort, msg)
|
||||||
|
|
||||||
// make sure we charge the parent what was spent
|
// make sure we charge the parent what was spent
|
||||||
spent := subCtx.GasMeter().GasConsumed()
|
spent := subCtx.GasMeter().GasConsumed()
|
||||||
ctx.GasMeter().ConsumeGas(spent, "From limited Sub-Message")
|
ctx.GasMeter().ConsumeGas(spent, "From limited Sub-Message")
|
||||||
|
|
||||||
return events, data, err
|
return events, data, msgResponses, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DispatchSubmessages builds a sandbox to execute these messages and returns the execution result to the contract
|
// DispatchSubmessages builds a sandbox to execute these messages and returns the execution result to the contract
|
||||||
@@ -101,10 +102,11 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk
|
|||||||
var err error
|
var err error
|
||||||
var events []sdk.Event
|
var events []sdk.Event
|
||||||
var data [][]byte
|
var data [][]byte
|
||||||
|
var msgResponses [][]*codectypes.Any
|
||||||
if limitGas {
|
if limitGas {
|
||||||
events, data, err = d.dispatchMsgWithGasLimit(subCtx, contractAddr, ibcPort, msg.Msg, *msg.GasLimit)
|
events, data, msgResponses, err = d.dispatchMsgWithGasLimit(subCtx, contractAddr, ibcPort, msg.Msg, *msg.GasLimit)
|
||||||
} else {
|
} else {
|
||||||
events, data, err = d.messenger.DispatchMsg(subCtx, contractAddr, ibcPort, msg.Msg)
|
events, data, msgResponses, err = d.messenger.DispatchMsg(subCtx, contractAddr, ibcPort, msg.Msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if it succeeds, commit state changes from submessage, and pass on events to Event Manager
|
// if it succeeds, commit state changes from submessage, and pass on events to Event Manager
|
||||||
@@ -142,10 +144,26 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk
|
|||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
responseData = data[0]
|
responseData = data[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For msgResponses we flatten the nested list into a flat list. In the majority of cases
|
||||||
|
// we only expect one message to be emitted and one response per message. But it might be possible
|
||||||
|
// to create multiple SDK messages from one CosmWasm message or we have multiple responses for one message.
|
||||||
|
// See https://github.com/CosmWasm/cosmwasm/issues/2009 for more information.
|
||||||
|
var msgResponsesFlattened []wasmvmtypes.MsgResponse
|
||||||
|
for _, singleMsgResponses := range msgResponses {
|
||||||
|
for _, singleMsgResponse := range singleMsgResponses {
|
||||||
|
msgResponsesFlattened = append(msgResponsesFlattened, wasmvmtypes.MsgResponse{
|
||||||
|
TypeURL: singleMsgResponse.TypeUrl,
|
||||||
|
Value: singleMsgResponse.Value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result = wasmvmtypes.SubMsgResult{
|
result = wasmvmtypes.SubMsgResult{
|
||||||
Ok: &wasmvmtypes.SubMsgResponse{
|
Ok: &wasmvmtypes.SubMsgResponse{
|
||||||
Events: sdkEventsToWasmVMEvents(filteredEvents),
|
Events: sdkEventsToWasmVMEvents(filteredEvents),
|
||||||
Data: responseData,
|
Data: responseData,
|
||||||
|
MsgResponses: msgResponsesFlattened,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user