-
Notifications
You must be signed in to change notification settings - Fork 117
/
wasm.go
139 lines (114 loc) · 4.24 KB
/
wasm.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package app
import (
"encoding/json"
"fmt"
"github.com/CosmWasm/wasmd/x/wasm"
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
ibcexported "github.com/cosmos/ibc-go/v4/modules/core/exported"
"golang.org/x/exp/maps"
"github.com/axelarnetwork/axelar-core/x/ante"
)
//go:generate moq -pkg mock -out ./mock/ibchooks.go . PacketI
type PacketI ibcexported.PacketI
type AnteHandlerMessenger struct {
anteHandle ante.MessageAnteHandler
encoders wasm.MessageEncoders
messenger wasmkeeper.Messenger
}
func (m AnteHandlerMessenger) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddress, contractIBCPortID string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
if err := assertSingleMessageIsSet(msg); err != nil {
return nil, nil, err
}
// burn and ibc send packet cannot be converted into sdk.Msg and are irrelevant for ante handler checks
if !isBankBurnMsg(msg) && !isIBCSendPacketMsg(msg) {
sdkMsgs, err := m.encoders.Encode(ctx, contractAddr, contractIBCPortID, msg)
if err != nil {
return nil, nil, err
}
// we can't know if this is a simulation or not at this stage, so we treat it as a regular execution
ctx, err = m.anteHandle(ctx, sdkMsgs, false)
if err != nil {
return nil, nil, err
}
}
return m.messenger.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg)
}
func assertSingleMessageIsSet(msg wasmvmtypes.CosmosMsg) error {
bz, err := json.Marshal(msg)
if err != nil {
return err
}
var msgs map[string]interface{}
err = json.Unmarshal(bz, &msgs)
if err != nil {
return err
}
msgCount := 0
for msgType, typedMsgs := range msgs {
// custom and stargate msgs are not categorized in CosmosMsg, so the next lower structural level would be message fields and not individual messages,
// so we can safely assume that there is only one message
if msgType == "custom" || msgType == "stargate" {
msgCount++
} else if typedMsgs, ok := typedMsgs.(map[string]interface{}); ok {
msgCount += len(maps.Keys(typedMsgs))
}
}
if msgCount == 0 {
return fmt.Errorf("no message set")
} else if msgCount > 1 {
return fmt.Errorf("only one message can be set, got %d", msgCount)
} else {
return nil
}
}
func WithAnteHandlers(encoders wasmkeeper.MessageEncoders, anteHandler ante.MessageAnteHandler, messenger wasmkeeper.Messenger) wasmkeeper.Messenger {
return AnteHandlerMessenger{
encoders: encoders,
anteHandle: anteHandler,
messenger: messenger,
}
}
type MsgTypeBlacklistMessenger struct {
}
func NewMsgTypeBlacklistMessenger() MsgTypeBlacklistMessenger {
return MsgTypeBlacklistMessenger{}
}
func (m MsgTypeBlacklistMessenger) DispatchMsg(_ sdk.Context, _ sdk.AccAddress, _ string, msg wasmvmtypes.CosmosMsg) (events []sdk.Event, data [][]byte, err error) {
if isIBCSendPacketMsg(msg) || isStargateMsg(msg) {
return nil, nil, fmt.Errorf("ibc send packet and stargate messages are not supported")
}
// this means that this message handler doesn't know how to deal with these messages (i.e. they can pass through),
// other handlers might be able to deal with them
return nil, nil, wasmtypes.ErrUnknownMsg
}
func isBankBurnMsg(msg wasmvmtypes.CosmosMsg) bool {
return msg.Bank != nil && msg.Bank.Burn != nil
}
func isStargateMsg(msg wasmvmtypes.CosmosMsg) bool {
return msg.Stargate != nil
}
func isIBCSendPacketMsg(msg wasmvmtypes.CosmosMsg) bool {
return msg.IBC != nil && msg.IBC.SendPacket != nil
}
type WasmAppModuleBasicOverride struct {
wasm.AppModuleBasic
}
func NewWasmAppModuleBasicOverride(wasmModule wasm.AppModuleBasic) WasmAppModuleBasicOverride {
return WasmAppModuleBasicOverride{
AppModuleBasic: wasmModule,
}
}
// DefaultGenesis returns an override for the wasm module's DefaultGenesis,
// because as soon as the module is initialized the restriction to contract upload and instantiation must hold
func (m WasmAppModuleBasicOverride) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
return cdc.MustMarshalJSON(&wasm.GenesisState{
Params: wasmtypes.Params{
CodeUploadAccess: wasmtypes.AllowNobody,
InstantiateDefaultPermission: wasmtypes.AccessTypeNobody,
},
})
}