mirror of
https://github.com/status-im/status-go.git
synced 2025-01-09 22:26:30 +00:00
d4496332f9
This PR fixes regression from 3540972 and adds check for callback validity before putting it into event loop for sendAsync calls.
138 lines
3.6 KiB
Go
138 lines
3.6 KiB
Go
package jail
|
|
|
|
import (
|
|
"os"
|
|
|
|
"github.com/robertkrimen/otto"
|
|
"github.com/status-im/status-go/geth/common"
|
|
"github.com/status-im/status-go/geth/jail/console"
|
|
"github.com/status-im/status-go/geth/node"
|
|
"github.com/status-im/status-go/geth/signal"
|
|
)
|
|
|
|
// signals
|
|
const (
|
|
EventSignal = "jail.signal"
|
|
|
|
// EventConsoleLog defines the event type for the console.log call.
|
|
eventConsoleLog = "vm.console.log"
|
|
)
|
|
|
|
// registerHandlers augments and transforms a given jail cell's underlying VM,
|
|
// by adding and replacing method handlers.
|
|
func registerHandlers(jail *Jail, cell common.JailCell, chatID string) error {
|
|
jeth, err := cell.Get("jeth")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
registerHandler := jeth.Object().Set
|
|
|
|
if err = registerHandler("console", map[string]interface{}{
|
|
"log": func(fn otto.FunctionCall) otto.Value {
|
|
return console.Write(fn, os.Stdout, eventConsoleLog)
|
|
},
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
|
|
// register send handler
|
|
if err = registerHandler("send", makeSendHandler(jail, cell)); err != nil {
|
|
return err
|
|
}
|
|
|
|
// register sendAsync handler
|
|
if err = registerHandler("sendAsync", makeAsyncSendHandler(jail, cell)); err != nil {
|
|
return err
|
|
}
|
|
|
|
// register isConnected handler
|
|
if err = registerHandler("isConnected", makeJethIsConnectedHandler(jail, cell)); err != nil {
|
|
return err
|
|
}
|
|
|
|
// register sendMessage/showSuggestions handlers
|
|
if err = cell.Set("statusSignals", struct{}{}); err != nil {
|
|
return err
|
|
}
|
|
statusSignals, err := cell.Get("statusSignals")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
registerHandler = statusSignals.Object().Set
|
|
if err = registerHandler("sendSignal", makeSignalHandler(chatID)); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// makeAsyncSendHandler returns jeth.sendAsync() handler.
|
|
func makeAsyncSendHandler(jail *Jail, cellInt common.JailCell) func(call otto.FunctionCall) otto.Value {
|
|
// FIXME(tiabc): Get rid of this.
|
|
cell := cellInt.(*Cell)
|
|
return func(call otto.FunctionCall) otto.Value {
|
|
go func() {
|
|
response := jail.Send(call)
|
|
|
|
callback := call.Argument(1)
|
|
if callback.Class() == "Function" {
|
|
// run callback asyncronously with args (error, response)
|
|
err := otto.NullValue()
|
|
cell.CallAsync(callback, err, response)
|
|
}
|
|
}()
|
|
return otto.UndefinedValue()
|
|
}
|
|
}
|
|
|
|
// makeSendHandler returns jeth.send() and jeth.sendAsync() handler
|
|
// TODO(tiabc): get rid of an extra parameter.
|
|
func makeSendHandler(jail *Jail, cellInt common.JailCell) func(call otto.FunctionCall) otto.Value {
|
|
return func(call otto.FunctionCall) otto.Value {
|
|
return jail.Send(call)
|
|
}
|
|
}
|
|
|
|
// makeJethIsConnectedHandler returns jeth.isConnected() handler
|
|
func makeJethIsConnectedHandler(jail *Jail, cellInt common.JailCell) func(call otto.FunctionCall) (response otto.Value) {
|
|
// FIXME(tiabc): Get rid of this.
|
|
cell := cellInt.(*Cell)
|
|
return func(call otto.FunctionCall) otto.Value {
|
|
client := jail.nodeManager.RPCClient()
|
|
|
|
var netListeningResult bool
|
|
if err := client.Call(&netListeningResult, "net_listening"); err != nil {
|
|
return newErrorResponseOtto(cell.VM, err.Error(), nil)
|
|
}
|
|
|
|
if !netListeningResult {
|
|
return newErrorResponseOtto(cell.VM, node.ErrNoRunningNode.Error(), nil)
|
|
}
|
|
|
|
return newResultResponse(call.Otto, true)
|
|
}
|
|
}
|
|
|
|
// SignalEvent wraps Jail send signals
|
|
type SignalEvent struct {
|
|
ChatID string `json:"chat_id"`
|
|
Data string `json:"data"`
|
|
}
|
|
|
|
func makeSignalHandler(chatID string) func(call otto.FunctionCall) otto.Value {
|
|
return func(call otto.FunctionCall) otto.Value {
|
|
message := call.Argument(0).String()
|
|
|
|
signal.Send(signal.Envelope{
|
|
Type: EventSignal,
|
|
Event: SignalEvent{
|
|
ChatID: chatID,
|
|
Data: message,
|
|
},
|
|
})
|
|
|
|
return newResultResponse(call.Otto, true)
|
|
}
|
|
}
|