-
Notifications
You must be signed in to change notification settings - Fork 580
/
vm.go
148 lines (134 loc) · 4.61 KB
/
vm.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
140
141
142
143
144
145
146
147
148
package types
import (
cosmwasm "github.com/CosmWasm/wasmvm"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
sdk "github.com/cosmos/cosmos-sdk/types"
clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
"github.com/cosmos/ibc-go/v7/modules/core/exported"
)
var (
WasmVM *cosmwasm.VM
VMGasRegister = NewDefaultWasmGasRegister()
)
type queryResponse struct {
Status exported.Status `json:"status,omitempty"`
GenesisMetadata []clienttypes.GenesisMetadata `json:"genesis_metadata,omitempty"`
}
type ClientCreateRequest struct {
ClientCreateRequest ClientState `json:"client_create_request,omitempty"`
}
type ContractResult interface {
Validate() bool
Error() string
}
type contractResult struct {
IsValid bool `json:"is_valid,omitempty"`
ErrorMsg string `json:"error_msg,omitempty"`
Data []byte `json:"data,omitempty"`
FoundMisbehaviour bool `json:"found_misbehaviour"`
}
func (r contractResult) Validate() bool {
return r.IsValid
}
func (r contractResult) Error() string {
return r.ErrorMsg
}
// Calls vm.Init with appropriate arguments
func initContract(codeID []byte, ctx sdk.Context, store sdk.KVStore) (*wasmvmtypes.Response, error) {
sdkGasMeter := ctx.GasMeter()
multipliedGasMeter := NewMultipliedGasMeter(sdkGasMeter, VMGasRegister)
gasLimit := VMGasRegister.runtimeGasForContract(ctx)
chainID := ctx.BlockHeader().ChainID
height := ctx.BlockHeader().Height
// safety checks before casting below
if height < 0 {
panic("Block height must never be negative")
}
nsec := ctx.BlockTime().UnixNano()
if nsec < 0 {
panic("Block (unix) time must never be negative ")
}
env := wasmvmtypes.Env{
Block: wasmvmtypes.BlockInfo{
Height: uint64(height),
Time: uint64(nsec),
ChainID: chainID,
},
Contract: wasmvmtypes.ContractInfo{
Address: "",
},
}
msgInfo := wasmvmtypes.MessageInfo{
Sender: "",
Funds: nil,
}
initMsg := []byte("{}")
ctx.GasMeter().ConsumeGas(VMGasRegister.NewContractInstanceCosts(len(initMsg)), "Loading CosmWasm module: instantiate")
response, gasUsed, err := WasmVM.Instantiate(codeID, env, msgInfo, initMsg, NewStoreAdapter(store), cosmwasm.GoAPI{}, nil, multipliedGasMeter, gasLimit, costJSONDeserialization)
VMGasRegister.consumeRuntimeGas(ctx, gasUsed)
return response, err
}
// Calls vm.Execute with internally constructed Gas meter and environment
func callContract(codeID []byte, ctx sdk.Context, store sdk.KVStore, msg []byte) (*wasmvmtypes.Response, error) {
sdkGasMeter := ctx.GasMeter()
multipliedGasMeter := NewMultipliedGasMeter(sdkGasMeter, VMGasRegister)
gasLimit := VMGasRegister.runtimeGasForContract(ctx)
chainID := ctx.BlockHeader().ChainID
height := ctx.BlockHeader().Height
// safety checks before casting below
if height < 0 {
panic("Block height must never be negative")
}
nsec := ctx.BlockTime().UnixNano()
if nsec < 0 {
panic("Block (unix) time must never be negative ")
}
env := wasmvmtypes.Env{
Block: wasmvmtypes.BlockInfo{
Height: uint64(height),
Time: uint64(nsec),
ChainID: chainID,
},
Contract: wasmvmtypes.ContractInfo{
Address: "",
},
}
msgInfo := wasmvmtypes.MessageInfo{
Sender: "",
Funds: nil,
}
ctx.GasMeter().ConsumeGas(VMGasRegister.InstantiateContractCosts(len(msg)), "Loading CosmWasm module: execute")
resp, gasUsed, err := WasmVM.Execute(codeID, env, msgInfo, msg, NewStoreAdapter(store), cosmwasm.GoAPI{}, nil, multipliedGasMeter, gasLimit, costJSONDeserialization)
VMGasRegister.consumeRuntimeGas(ctx, gasUsed)
return resp, err
}
// Call vm.Query
func queryContractWithStore(codeID cosmwasm.Checksum, ctx sdk.Context, store sdk.KVStore, msg []byte) ([]byte, error) {
sdkGasMeter := ctx.GasMeter()
multipliedGasMeter := NewMultipliedGasMeter(sdkGasMeter, VMGasRegister)
gasLimit := VMGasRegister.runtimeGasForContract(ctx)
chainID := ctx.BlockHeader().ChainID
height := ctx.BlockHeader().Height
// safety checks before casting below
if height < 0 {
panic("Block height must never be negative")
}
nsec := ctx.BlockTime().UnixNano()
if nsec < 0 {
panic("Block (unix) time must never be negative ")
}
env := wasmvmtypes.Env{
Block: wasmvmtypes.BlockInfo{
Height: uint64(height),
Time: uint64(nsec),
ChainID: chainID,
},
Contract: wasmvmtypes.ContractInfo{
Address: "",
},
}
ctx.GasMeter().ConsumeGas(VMGasRegister.InstantiateContractCosts(len(msg)), "Loading CosmWasm module: query")
resp, gasUsed, err := WasmVM.Query(codeID, env, msg, NewStoreAdapter(store), cosmwasm.GoAPI{}, nil, multipliedGasMeter, gasLimit, costJSONDeserialization)
VMGasRegister.consumeRuntimeGas(ctx, gasUsed)
return resp, err
}