mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
signer: use goja instead of otto
This commit is contained in:
parent
38f5ae7534
commit
f37ed2f975
2 changed files with 24 additions and 27 deletions
|
|
@ -22,12 +22,12 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/dop251/goja"
|
||||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/signer/core"
|
"github.com/ethereum/go-ethereum/signer/core"
|
||||||
"github.com/ethereum/go-ethereum/signer/rules/deps"
|
"github.com/ethereum/go-ethereum/signer/rules/deps"
|
||||||
"github.com/ethereum/go-ethereum/signer/storage"
|
"github.com/ethereum/go-ethereum/signer/storage"
|
||||||
"github.com/robertkrimen/otto"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -36,13 +36,13 @@ var (
|
||||||
|
|
||||||
// consoleOutput is an override for the console.log and console.error methods to
|
// consoleOutput is an override for the console.log and console.error methods to
|
||||||
// stream the output into the configured output stream instead of stdout.
|
// stream the output into the configured output stream instead of stdout.
|
||||||
func consoleOutput(call otto.FunctionCall) otto.Value {
|
func consoleOutput(call goja.FunctionCall) goja.Value {
|
||||||
output := []string{"JS:> "}
|
output := []string{"JS:> "}
|
||||||
for _, argument := range call.ArgumentList {
|
for _, argument := range call.Arguments {
|
||||||
output = append(output, fmt.Sprintf("%v", argument))
|
output = append(output, fmt.Sprintf("%v", argument))
|
||||||
}
|
}
|
||||||
fmt.Fprintln(os.Stderr, strings.Join(output, " "))
|
fmt.Fprintln(os.Stderr, strings.Join(output, " "))
|
||||||
return otto.Value{}
|
return goja.Undefined()
|
||||||
}
|
}
|
||||||
|
|
||||||
// rulesetUI provides an implementation of UIClientAPI that evaluates a javascript
|
// rulesetUI provides an implementation of UIClientAPI that evaluates a javascript
|
||||||
|
|
@ -70,45 +70,46 @@ func (r *rulesetUI) Init(javascriptRules string) error {
|
||||||
r.jsRules = javascriptRules
|
r.jsRules = javascriptRules
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (r *rulesetUI) execute(jsfunc string, jsarg interface{}) (otto.Value, error) {
|
func (r *rulesetUI) execute(jsfunc string, jsarg interface{}) (goja.Value, error) {
|
||||||
|
|
||||||
// Instantiate a fresh vm engine every time
|
// Instantiate a fresh vm engine every time
|
||||||
vm := otto.New()
|
vm := goja.New()
|
||||||
|
|
||||||
// Set the native callbacks
|
// Set the native callbacks
|
||||||
consoleObj, _ := vm.Get("console")
|
vm.Set("console", struct{}{})
|
||||||
consoleObj.Object().Set("log", consoleOutput)
|
consoleObj := vm.Get("console").ToObject(vm)
|
||||||
consoleObj.Object().Set("error", consoleOutput)
|
consoleObj.Set("log", consoleOutput)
|
||||||
|
consoleObj.Set("error", consoleOutput)
|
||||||
|
|
||||||
vm.Set("storage", struct{}{})
|
vm.Set("storage", struct{}{})
|
||||||
storageObj, _ := vm.Get("storage")
|
storageObj := vm.Get("storage").ToObject(vm)
|
||||||
storageObj.Object().Set("put", func(call otto.FunctionCall) otto.Value {
|
storageObj.Set("put", func(call goja.FunctionCall) goja.Value {
|
||||||
key, val := call.Argument(0).String(), call.Argument(1).String()
|
key, val := call.Argument(0).String(), call.Argument(1).String()
|
||||||
if val == "" {
|
if val == "" {
|
||||||
r.storage.Del(key)
|
r.storage.Del(key)
|
||||||
} else {
|
} else {
|
||||||
r.storage.Put(key, val)
|
r.storage.Put(key, val)
|
||||||
}
|
}
|
||||||
return otto.NullValue()
|
return goja.Null()
|
||||||
})
|
})
|
||||||
storageObj.Object().Set("get", func(call otto.FunctionCall) otto.Value {
|
storageObj.Set("get", func(call goja.FunctionCall) goja.Value {
|
||||||
goval, _ := r.storage.Get(call.Argument(0).String())
|
goval, _ := r.storage.Get(call.Argument(0).String())
|
||||||
jsval, _ := otto.ToValue(goval)
|
jsval := vm.ToValue(goval)
|
||||||
return jsval
|
return jsval
|
||||||
})
|
})
|
||||||
// Load bootstrap libraries
|
// Load bootstrap libraries
|
||||||
script, err := vm.Compile("bignumber.js", BigNumber_JS)
|
script, err := goja.Compile("bignumber.js", string(BigNumber_JS), true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Failed loading libraries", "err", err)
|
log.Warn("Failed loading libraries", "err", err)
|
||||||
return otto.UndefinedValue(), err
|
return goja.Undefined(), err
|
||||||
}
|
}
|
||||||
vm.Run(script)
|
vm.RunProgram(script)
|
||||||
|
|
||||||
// Run the actual rule implementation
|
// Run the actual rule implementation
|
||||||
_, err = vm.Run(r.jsRules)
|
_, err = vm.RunString(r.jsRules)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Execution failed", "err", err)
|
log.Warn("Execution failed", "err", err)
|
||||||
return otto.UndefinedValue(), err
|
return goja.Undefined(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// And the actual call
|
// And the actual call
|
||||||
|
|
@ -119,7 +120,7 @@ func (r *rulesetUI) execute(jsfunc string, jsarg interface{}) (otto.Value, error
|
||||||
jsonbytes, err := json.Marshal(jsarg)
|
jsonbytes, err := json.Marshal(jsarg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("failed marshalling data", "data", jsarg)
|
log.Warn("failed marshalling data", "data", jsarg)
|
||||||
return otto.UndefinedValue(), err
|
return goja.Undefined(), err
|
||||||
}
|
}
|
||||||
// Now, we call foobar(JSON.parse(<jsondata>)).
|
// Now, we call foobar(JSON.parse(<jsondata>)).
|
||||||
var call string
|
var call string
|
||||||
|
|
@ -128,7 +129,7 @@ func (r *rulesetUI) execute(jsfunc string, jsarg interface{}) (otto.Value, error
|
||||||
} else {
|
} else {
|
||||||
call = fmt.Sprintf("%v()", jsfunc)
|
call = fmt.Sprintf("%v()", jsfunc)
|
||||||
}
|
}
|
||||||
return vm.Run(call)
|
return vm.RunString(call)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *rulesetUI) checkApproval(jsfunc string, jsarg []byte, err error) (bool, error) {
|
func (r *rulesetUI) checkApproval(jsfunc string, jsarg []byte, err error) (bool, error) {
|
||||||
|
|
@ -140,11 +141,7 @@ func (r *rulesetUI) checkApproval(jsfunc string, jsarg []byte, err error) (bool,
|
||||||
log.Info("error occurred during execution", "error", err)
|
log.Info("error occurred during execution", "error", err)
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
result, err := v.ToString()
|
result := v.ToString().String()
|
||||||
if err != nil {
|
|
||||||
log.Info("error occurred during response unmarshalling", "error", err)
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if result == "Approve" {
|
if result == "Approve" {
|
||||||
log.Info("Op approved")
|
log.Info("Op approved")
|
||||||
return true, nil
|
return true, nil
|
||||||
|
|
|
||||||
|
|
@ -337,7 +337,7 @@ func TestStorage(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error %v", err)
|
t.Errorf("Unexpected error %v", err)
|
||||||
}
|
}
|
||||||
retval, err := v.ToString()
|
retval := v.ToString().String()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error %v", err)
|
t.Errorf("Unexpected error %v", err)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue