Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/duktape migration #94

Merged
merged 26 commits into from
Sep 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a777559
[vm] Switched Validator to duktape
borjantrajanoski Aug 27, 2018
0b9d7b0
[vm] Switched randBytes to duktape
borjantrajanoski Aug 27, 2018
7f0d1d2
[vm] Switched sendEthTx module to duktape without throttling
borjantrajanoski Aug 27, 2018
c7aeb71
[vm] Switched logger module to duktape without method overriding
borjantrajanoski Aug 27, 2018
4b1f914
[vm] Switched ethAddress module to duktape without named call
borjantrajanoski Aug 27, 2018
928e3a2
[vm] Switched uuidv4 module to duktape
borjantrajanoski Aug 27, 2018
23fbe83
[vm] Switched db module to duktape without throttling
borjantrajanoski Aug 27, 2018
1421cc0
[vm] Switched message module to duktape without throttling
borjantrajanoski Aug 27, 2018
0859cd7
[vm] Switched dapp/module/module.go to duktape
borjantrajanoski Aug 27, 2018
eaac36b
[vm] Switched dapp/dapp.go to duktape
borjantrajanoski Aug 27, 2018
e1d29af
[vm] Switched callbacks module to duktape
borjantrajanoski Aug 28, 2018
ab9f7b0
[vm] Switched modal module to duktape
borjantrajanoski Aug 28, 2018
203e253
[vm] Switched renderer/message module to duktape
borjantrajanoski Aug 28, 2018
0101910
[vm] Switched renderer/dapp module to duktape
borjantrajanoski Aug 28, 2018
4947aa9
[vm] Modified dapp.go to make it more compatible with duktape
borjantrajanoski Aug 28, 2018
aab1d3e
[vm] Fixed funcId in TestFuncUnRegisterSuccess
borjantrajanoski Aug 30, 2018
25a0ce2
[vm] Switched randBytes [1 4 6] to more JS compatible 1, 4, 6
borjantrajanoski Aug 30, 2018
130e3ef
[vm] Fixed callback module funcId logic
borjantrajanoski Aug 31, 2018
f7608d0
[vm] Added a way to check for Already called callback
borjantrajanoski Aug 31, 2018
5e64862
[vm] Added error assertion on m.CallFunction
borjantrajanoski Aug 31, 2018
de479c6
[vm] Changed context to vm to be more descriptive
borjantrajanoski Aug 31, 2018
1708d0f
[vm] Added stack manupulation info
borjantrajanoski Aug 31, 2018
e9ecead
[vm] Fixed panic related to filenames containing spaces
borjantrajanoski Aug 31, 2018
171d71a
[vm] Confirmed logic compatibility between duktape.PevalString and ot…
borjantrajanoski Aug 31, 2018
2999e33
[vm] Clarified logic in terms of pushing parameters to the stack and …
borjantrajanoski Aug 31, 2018
a713071
[vm] fixed merge request with develop
Sep 5, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 11 additions & 13 deletions dapp/dapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ import (
storm "github.com/asdine/storm"
log "github.com/ipfs/go-log"
logger "github.com/op/go-logging"
otto "github.com/robertkrimen/otto"
duktape "gopkg.in/olebedev/go-duktape.v3"
)

var sysLog = log.Logger("dapp")

type DApp struct {
vm *otto.Otto
vm *duktape.Context
logger *logger.Logger
app *Data
// will be called when the app shut down
Expand All @@ -34,15 +34,14 @@ type DApp struct {

// close DApp
func (d *DApp) Close() {
d.vm.Interrupt <- func() {
d.logger.Info(fmt.Sprintf("shutting down: %s (%s)", hex.EncodeToString(d.app.UsedSigningKey), d.app.Name))
for _, mod := range d.vmModules {
if err := mod.Close(); err != nil {
sysLog.Error(err)
}
defer d.vm.DestroyHeap()
d.logger.Info(fmt.Sprintf("shutting down: %s (%s)", hex.EncodeToString(d.app.UsedSigningKey), d.app.Name))
for _, mod := range d.vmModules {
if err := mod.Close(); err != nil {
sysLog.Error(err)
}
d.closeChan <- d.app
}
d.closeChan <- d.app
}

func (d *DApp) ID() string {
Expand Down Expand Up @@ -74,8 +73,7 @@ func New(l *logger.Logger, app *Data, vmModules []module.Module, closer chan<- *
}

// create VM
vm := otto.New()
vm.Interrupt = make(chan func(), 1)
vm := duktape.New()

// register all vm modules
for _, m := range vmModules {
Expand Down Expand Up @@ -132,7 +130,8 @@ func New(l *logger.Logger, app *Data, vmModules []module.Module, closer chan<- *

// start the DApp async
go func() {
_, err := vm.Run(app.Code)
// Synonymous to vm.Run in Otto
err := vm.PevalString(string(app.Code))
if err != nil {
l.Errorf(err.Error())
}
Expand All @@ -147,7 +146,6 @@ func New(l *logger.Logger, app *Data, vmModules []module.Module, closer chan<- *
}
return dApp, nil
case <-time.After(timeOut):
vm.Interrupt <- func() {}
closer <- app
return nil, errors.New("timeout - failed to start DApp")
}
Expand Down
2 changes: 1 addition & 1 deletion dapp/dapp_storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ func TestBoltDAppStorage_Get(t *testing.T) {
}

func createDB() *bolt.DB {
dbPath, err := filepath.Abs(os.TempDir() + "/" + time.Now().String())
dbPath, err := filepath.Abs(os.TempDir() + "/" + fmt.Sprint(time.Now().UnixNano()))
if err != nil {
panic(err)
}
Expand Down
104 changes: 53 additions & 51 deletions dapp/module/callbacks/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
validator "github.com/Bit-Nation/panthalassa/dapp/validator"
log "github.com/ipfs/go-log"
logger "github.com/op/go-logging"
otto "github.com/robertkrimen/otto"
duktape "gopkg.in/olebedev/go-duktape.v3"
)

var debugger = log.Logger("callbacks")
Expand All @@ -34,7 +34,7 @@ func New(l *logger.Logger) *Module {

var count uint

functions := map[uint]*otto.Value{}
functions := map[uint]*duktape.Context{}
cbChans := map[*chan error]bool{}

for {
Expand Down Expand Up @@ -110,7 +110,7 @@ func New(l *logger.Logger) *Module {
}

type addFunction struct {
fn *otto.Value
fn *duktape.Context
respChan chan struct {
id uint
error error
Expand All @@ -119,12 +119,12 @@ type addFunction struct {

type fetchFunction struct {
id uint
respChan chan *otto.Value
respChan chan *duktape.Context
}

type Module struct {
logger *logger.Logger
vm *otto.Otto
vm *duktape.Context
reqLim *reqLim.Count
addFunctionChan chan addFunction
fetchFunctionChan chan fetchFunction
Expand All @@ -146,37 +146,33 @@ func (m *Module) Close() error {
// e.g. myRegisteredFunction(payloadObj, cb)
// the callback must be called in order to "return" from the function
func (m *Module) CallFunction(id uint, payload string) error {

debugger.Debug(fmt.Errorf("call function with id: %d and payload: %s", id, payload))

respChan := make(chan *otto.Value)
respChan := make(chan *duktape.Context)
m.fetchFunctionChan <- fetchFunction{
id: id,
respChan: respChan,
}
fn := <-respChan
vm := <-respChan

if fn == nil {
if vm == nil || vm.GetType(0).IsNone() {
return errors.New(fmt.Sprintf("function with id: %d does not exist", id))
}

// check if function is registered
if !fn.IsFunction() {
if !vm.IsFunction(0) {
return errors.New(fmt.Sprintf("function with id: %d does not exist", id))
}

// parse params
objArgs, err := m.vm.Object("(" + payload + ")")
if err != nil {
return err
}
objArgs := "(" + payload + ")"

done := make(chan error, 1)
m.addCBChan <- &done

alreadyCalled := false

_, err = fn.Call(*fn, objArgs, func(call otto.FunctionCall) otto.Value {
_, err := vm.PushGlobalGoFunction("callbackCallFunction", func(context *duktape.Context) int {

defer func() {
m.rmCBChan <- &done
Expand All @@ -185,26 +181,43 @@ func (m *Module) CallFunction(id uint, payload string) error {
// check if callback has already been called
if alreadyCalled {
m.logger.Error("Already called callback")
return m.vm.MakeCustomError("Callback", "Already called callback")
if context.IsFunction(1) {
context.PushString("Callback: Already called callback")
context.Call(1)
}
return 1
}
alreadyCalled = true

// check parameters
err := call.Argument(0)

if !err.IsUndefined() {
done <- errors.New(err.String())
return otto.Value{}
if !context.IsUndefined(0) {
firstParameter := context.ToString(0)
if context.IsFunction(1) {
context.PushString(firstParameter)
context.Call(1)
}
done <- errors.New(firstParameter)
return 1
}

done <- nil
return otto.Value{}
return 0

})
if err != nil {
m.logger.Error(err.Error())
}

// Push objArgs to the stack as first parameter
err = vm.PevalString(objArgs)
if err != nil {
m.logger.Error(err.Error())
}
// Push callbackCallFunction to the stack as second parameter
err = vm.PevalString(`callbackCallFunction`)
if err != nil {
m.logger.Error(err.Error())
}
// Use 2 when calling as we just pushed 2 parameters to the stack
vm.Call(2)
return <-done

}
Expand All @@ -215,43 +228,37 @@ func (m *Module) CallFunction(id uint, payload string) error {
// a registered function will be called with an object containing information
// and a callback that should be called (with an optional error) in order to
// "return"
func (m *Module) Register(vm *otto.Otto) error {
func (m *Module) Register(vm *duktape.Context) error {
m.vm = vm
err := vm.Set("registerFunction", func(call otto.FunctionCall) otto.Value {
_, err := vm.PushGlobalGoFunction("registerFunction", func(context *duktape.Context) int {
// validate function call
v := validator.New()
v.Set(0, &validator.TypeFunction)
if err := v.Validate(vm, call); err != nil {
m.logger.Error(fmt.Sprintf(`registerFunction needs a callback as it's first param %s`, err.String()))
return *err
if err := v.Validate(context); err != nil {
m.logger.Error(fmt.Sprintf(`registerFunction needs a callback as it's first param %s`, err.Error()))
return 1
}

// callback
fn := call.Argument(0)

// add function to stack
idRespChan := make(chan struct {
id uint
error error
}, 1)
m.addFunctionChan <- addFunction{
respChan: idRespChan,
fn: &fn,
fn: context,
}
// response
addResp := <-idRespChan

// exit vm on error
if addResp.error != nil {
m.logger.Error(addResp.error.Error())
return otto.Value{}
return 1
}

// convert function id to otto value
functionId, err := otto.ToValue(addResp.id)
if err != nil {
m.logger.Error(err.Error())
}
// convert function id to int
functionId := int(addResp.id)

return functionId

Expand All @@ -260,27 +267,22 @@ func (m *Module) Register(vm *otto.Otto) error {
return err
}

return vm.Set("unRegisterFunction", func(call otto.FunctionCall) otto.Value {
_, err = vm.PushGlobalGoFunction("unRegisterFunction", func(context *duktape.Context) int {

// validate function call
v := validator.New()
v.Set(0, &validator.TypeNumber)
if err := v.Validate(vm, call); err != nil {
return *err
if err := v.Validate(context); err != nil {
return 1
}

// function id
funcID := call.Argument(0)
id, err := funcID.ToInteger()
if err != nil {
m.logger.Error(err.Error())
return otto.Value{}
}
funcID := context.ToInt(0)

// delete function from channel
m.deleteFunctionChan <- uint(id)
m.deleteFunctionChan <- uint(funcID)

return otto.Value{}
return 0
})

return err
}
Loading