Skip to content

Commit 36be273

Browse files
committed
add verify module
1 parent 81fbdfa commit 36be273

File tree

1 file changed

+48
-7
lines changed

1 file changed

+48
-7
lines changed

wasm_interpreter.go

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func NewWasmIntptr(evm *EVM) *WasmIntptr {
5555
}
5656

5757
w.initEEIModule()
58-
if w.evm.vmConfig.Debug {
58+
if w.debug() {
5959
w.initDebugModule()
6060
}
6161

@@ -160,8 +160,9 @@ func (w *WasmIntptr) GetHandlers() map[string]reflect.Value {
160160
return w.handlers
161161
}
162162

163-
func (w *WasmIntptr) GetHandler(name string) reflect.Value {
164-
return w.handlers[name]
163+
func (w *WasmIntptr) GetHandler(name string) (reflect.Value, bool) {
164+
val, ok := w.handlers[name]
165+
return val, ok
165166
}
166167

167168
func (w *WasmIntptr) debug() bool {
@@ -198,10 +199,6 @@ func (w *WasmIntptr) Run(contract *Contract, input []byte) ([]byte, error) {
198199
return nil, err
199200
}
200201

201-
if module.Start != nil {
202-
return nil, fmt.Errorf("A contract should not have a start function: found #%d", module.Start.Index)
203-
}
204-
205202
vm, err := exec.NewVM(module)
206203
if err != nil {
207204
return nil, fmt.Errorf("failed to create vm: %v", err)
@@ -230,6 +227,50 @@ func (w *WasmIntptr) Run(contract *Contract, input []byte) ([]byte, error) {
230227
return nil, errors.New("could not find a valid 'main' function in the code")
231228
}
232229

230+
// verifyModule validates the wasm module resolved by the wagon, check `main` and `memory`
231+
// export and import valid `eei` api. It returns the index of `main` export function and an error.
232+
func (w *WasmIntptr) verifyModule(m *wasm.Module) (int, error) {
233+
if m.Start != nil {
234+
return -1, fmt.Errorf("A contract should not have a start function: found #%d", m.Start.Index)
235+
}
236+
237+
if m.Export == nil {
238+
return -1, fmt.Errorf("module has no exports `main` and `memory`")
239+
}
240+
241+
if c := len(m.Export.Entries); c != 2 {
242+
return -1, fmt.Errorf("module has %d exports instead of 2", c)
243+
}
244+
245+
// Check the existence of the `main` and `memory` exports
246+
mainIndex := -1
247+
for name, entry := range m.Export.Entries {
248+
if name == "main" {
249+
if entry.Kind != wasm.ExternalFunction {
250+
return -1, fmt.Errorf("`main` is not a function in module")
251+
}
252+
mainIndex = int(entry.Index)
253+
} else if name == "memory" {
254+
if entry.Kind != wasm.ExternalMemory {
255+
return -1, fmt.Errorf("`memory` is not a memory in module")
256+
}
257+
}
258+
}
259+
260+
// Validate whether the function imported from `ethereum` module are in the list of eei_api or not
261+
if m.Import != nil {
262+
for _, entry := range m.Import.Entries {
263+
if entry.ModuleName == "ethereum" && entry.Type.Kind() == wasm.ExternalFunction {
264+
if _, exist := w.GetHandler(entry.FieldName); !exist {
265+
return -1, fmt.Errorf("%s is not found in eei api list", entry.FieldName)
266+
}
267+
}
268+
}
269+
}
270+
271+
return mainIndex, nil
272+
}
273+
233274
// CanRun checks the binary for a WASM header and accepts the binary blob
234275
// if it matches.
235276
func (w *WasmIntptr) CanRun(file []byte) bool {

0 commit comments

Comments
 (0)