Merge pull request #82 from farazdagi/feature/local-storage
Feature/local storage
This commit is contained in:
commit
80510c02d2
|
@ -4,12 +4,11 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// the actual test functions are in non-_test.go files (so that they can use cgo i.e. import "C")
|
// the actual test functions are in non-_test.go files (so that they can use cgo i.e. import "C")
|
||||||
// the only intent of these wrappers is for gotest can find what tests are exposed.
|
// the only intent of these wrappers is for gotest can find what tests are exposed.
|
||||||
func TestExportedAPI(t *testing.T) {
|
func TestExportedAPI(t *testing.T) {
|
||||||
allTestsDone := make(chan struct{}, 1)
|
allTestsDone := make(chan struct{}, 1)
|
||||||
go testExportedAPI(t, allTestsDone)
|
go testExportedAPI(t, allTestsDone)
|
||||||
|
|
||||||
<- allTestsDone
|
<-allTestsDone
|
||||||
}
|
}
|
||||||
|
|
|
@ -537,7 +537,7 @@ func testCompleteTransaction(t *testing.T) bool {
|
||||||
// replace transaction notification handler
|
// replace transaction notification handler
|
||||||
var txHash = ""
|
var txHash = ""
|
||||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
var envelope geth.GethEvent
|
var envelope geth.SignalEnvelope
|
||||||
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||||
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
||||||
return
|
return
|
||||||
|
@ -616,7 +616,7 @@ func testCompleteMultipleQueuedTransactions(t *testing.T) bool {
|
||||||
// replace transaction notification handler
|
// replace transaction notification handler
|
||||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
var txId string
|
var txId string
|
||||||
var envelope geth.GethEvent
|
var envelope geth.SignalEnvelope
|
||||||
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||||
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
||||||
return
|
return
|
||||||
|
@ -745,7 +745,7 @@ func testDiscardTransaction(t *testing.T) bool {
|
||||||
var txId string
|
var txId string
|
||||||
txFailedEventCalled := false
|
txFailedEventCalled := false
|
||||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
var envelope geth.GethEvent
|
var envelope geth.SignalEnvelope
|
||||||
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||||
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
||||||
return
|
return
|
||||||
|
@ -860,7 +860,7 @@ func testDiscardMultipleQueuedTransactions(t *testing.T) bool {
|
||||||
txFailedEventCallCount := 0
|
txFailedEventCallCount := 0
|
||||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
var txId string
|
var txId string
|
||||||
var envelope geth.GethEvent
|
var envelope geth.SignalEnvelope
|
||||||
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||||
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
||||||
return
|
return
|
||||||
|
@ -1072,7 +1072,7 @@ func startTestNode(t *testing.T) <-chan struct{} {
|
||||||
waitForNodeStart := make(chan struct{}, 1)
|
waitForNodeStart := make(chan struct{}, 1)
|
||||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
t.Log(jsonEvent)
|
t.Log(jsonEvent)
|
||||||
var envelope geth.GethEvent
|
var envelope geth.SignalEnvelope
|
||||||
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||||
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
package geth
|
package geth
|
||||||
|
|
||||||
/*
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
extern bool StatusServiceSignalEvent( const char *jsonEvent );
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -304,13 +298,10 @@ func (m *NodeManager) onNodeStarted() {
|
||||||
close(m.node.started)
|
close(m.node.started)
|
||||||
|
|
||||||
// send signal up to native app
|
// send signal up to native app
|
||||||
event := GethEvent{
|
SendSignal(SignalEnvelope{
|
||||||
Type: EventNodeStarted,
|
Type: EventNodeStarted,
|
||||||
Event: struct{}{},
|
Event: struct{}{},
|
||||||
}
|
})
|
||||||
|
|
||||||
body, _ := json.Marshal(&event)
|
|
||||||
C.StatusServiceSignalEvent(C.CString(string(body)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// populateStaticPeers connects current node with our publicly available LES cluster
|
// populateStaticPeers connects current node with our publicly available LES cluster
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
package geth
|
package geth
|
||||||
|
|
||||||
/*
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
extern bool StatusServiceSignalEvent( const char *jsonEvent );
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
@ -35,17 +28,14 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func onSendTransactionRequest(queuedTx status.QueuedTx) {
|
func onSendTransactionRequest(queuedTx status.QueuedTx) {
|
||||||
event := GethEvent{
|
SendSignal(SignalEnvelope{
|
||||||
Type: EventTransactionQueued,
|
Type: EventTransactionQueued,
|
||||||
Event: SendTransactionEvent{
|
Event: SendTransactionEvent{
|
||||||
Id: string(queuedTx.Id),
|
Id: string(queuedTx.Id),
|
||||||
Args: queuedTx.Args,
|
Args: queuedTx.Args,
|
||||||
MessageId: messageIdFromContext(queuedTx.Context),
|
MessageId: messageIdFromContext(queuedTx.Context),
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
|
|
||||||
body, _ := json.Marshal(&event)
|
|
||||||
C.StatusServiceSignalEvent(C.CString(string(body)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func onSendTransactionReturn(queuedTx *status.QueuedTx, err error) {
|
func onSendTransactionReturn(queuedTx *status.QueuedTx, err error) {
|
||||||
|
@ -59,7 +49,7 @@ func onSendTransactionReturn(queuedTx *status.QueuedTx, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// error occurred, signal up to application
|
// error occurred, signal up to application
|
||||||
event := GethEvent{
|
SendSignal(SignalEnvelope{
|
||||||
Type: EventTransactionFailed,
|
Type: EventTransactionFailed,
|
||||||
Event: ReturnSendTransactionEvent{
|
Event: ReturnSendTransactionEvent{
|
||||||
Id: string(queuedTx.Id),
|
Id: string(queuedTx.Id),
|
||||||
|
@ -68,10 +58,7 @@ func onSendTransactionReturn(queuedTx *status.QueuedTx, err error) {
|
||||||
ErrorMessage: err.Error(),
|
ErrorMessage: err.Error(),
|
||||||
ErrorCode: sendTransactionErrorCode(err),
|
ErrorCode: sendTransactionErrorCode(err),
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
|
|
||||||
body, _ := json.Marshal(&event)
|
|
||||||
C.StatusServiceSignalEvent(C.CString(string(body)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendTransactionErrorCode(err error) string {
|
func sendTransactionErrorCode(err error) string {
|
||||||
|
|
|
@ -35,7 +35,7 @@ func TestQueuedTransactions(t *testing.T) {
|
||||||
// replace transaction notification handler
|
// replace transaction notification handler
|
||||||
var txHash = common.Hash{}
|
var txHash = common.Hash{}
|
||||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
var envelope geth.GethEvent
|
var envelope geth.SignalEnvelope
|
||||||
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||||
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
||||||
return
|
return
|
||||||
|
@ -107,7 +107,7 @@ func TestDoubleCompleteQueuedTransactions(t *testing.T) {
|
||||||
txFailedEventCalled := false
|
txFailedEventCalled := false
|
||||||
txHash := common.Hash{}
|
txHash := common.Hash{}
|
||||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
var envelope geth.GethEvent
|
var envelope geth.SignalEnvelope
|
||||||
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||||
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
||||||
return
|
return
|
||||||
|
@ -230,7 +230,7 @@ func TestDiscardQueuedTransactions(t *testing.T) {
|
||||||
var txId string
|
var txId string
|
||||||
txFailedEventCalled := false
|
txFailedEventCalled := false
|
||||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
var envelope geth.GethEvent
|
var envelope geth.SignalEnvelope
|
||||||
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||||
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
||||||
return
|
return
|
||||||
|
@ -345,7 +345,7 @@ func TestCompleteMultipleQueuedTransactions(t *testing.T) {
|
||||||
// replace transaction notification handler
|
// replace transaction notification handler
|
||||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
var txId string
|
var txId string
|
||||||
var envelope geth.GethEvent
|
var envelope geth.SignalEnvelope
|
||||||
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||||
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
||||||
return
|
return
|
||||||
|
@ -471,7 +471,7 @@ func TestDiscardMultipleQueuedTransactions(t *testing.T) {
|
||||||
txFailedEventCallCount := 0
|
txFailedEventCallCount := 0
|
||||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
var txId string
|
var txId string
|
||||||
var envelope geth.GethEvent
|
var envelope geth.SignalEnvelope
|
||||||
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||||
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
||||||
return
|
return
|
||||||
|
@ -613,7 +613,7 @@ func TestNonExistentQueuedTransactions(t *testing.T) {
|
||||||
// replace transaction notification handler
|
// replace transaction notification handler
|
||||||
var txHash = common.Hash{}
|
var txHash = common.Hash{}
|
||||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
var envelope geth.GethEvent
|
var envelope geth.SignalEnvelope
|
||||||
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||||
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
||||||
return
|
return
|
||||||
|
@ -667,7 +667,7 @@ func TestEvictionOfQueuedTransactions(t *testing.T) {
|
||||||
// replace transaction notification handler
|
// replace transaction notification handler
|
||||||
var txHash = common.Hash{}
|
var txHash = common.Hash{}
|
||||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
var envelope geth.GethEvent
|
var envelope geth.SignalEnvelope
|
||||||
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||||
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
||||||
return
|
return
|
||||||
|
|
|
@ -5,6 +5,11 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/les/status"
|
"github.com/ethereum/go-ethereum/les/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type SignalEnvelope struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Event interface{} `json:"event"`
|
||||||
|
}
|
||||||
|
|
||||||
type AccountInfo struct {
|
type AccountInfo struct {
|
||||||
Address string `json:"address"`
|
Address string `json:"address"`
|
||||||
PubKey string `json:"pubkey"`
|
PubKey string `json:"pubkey"`
|
||||||
|
@ -77,9 +82,9 @@ type DiscardTransactionsResult struct {
|
||||||
Results map[string]DiscardTransactionResult `json:"results"`
|
Results map[string]DiscardTransactionResult `json:"results"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GethEvent struct {
|
type LocalStorageSetEvent struct {
|
||||||
Type string `json:"type"`
|
ChatId string `json:"chat_id"`
|
||||||
Event interface{} `json:"event"`
|
Data string `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RPCCall struct {
|
type RPCCall struct {
|
||||||
|
|
|
@ -8,6 +8,7 @@ extern bool StatusServiceSignalEvent(const char *jsonEvent);
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
@ -39,12 +40,18 @@ func SetDefaultNodeNotificationHandler(fn NodeNotificationHandler) {
|
||||||
notificationHandler = fn
|
notificationHandler = fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SendSignal sends application signal (JSON, normally) upwards
|
||||||
|
func SendSignal(signal SignalEnvelope) {
|
||||||
|
data, _ := json.Marshal(&signal)
|
||||||
|
C.StatusServiceSignalEvent(C.CString(string(data)))
|
||||||
|
}
|
||||||
|
|
||||||
//export NotifyNode
|
//export NotifyNode
|
||||||
func NotifyNode(jsonEvent *C.char) {
|
func NotifyNode(jsonEvent *C.char) {
|
||||||
notificationHandler(C.GoString(jsonEvent))
|
notificationHandler(C.GoString(jsonEvent))
|
||||||
}
|
}
|
||||||
|
|
||||||
// export TriggerTestSignal
|
//export TriggerTestSignal
|
||||||
func TriggerTestSignal() {
|
func TriggerTestSignal() {
|
||||||
C.StatusServiceSignalEvent(C.CString(`{"answer": 42}`))
|
C.StatusServiceSignalEvent(C.CString(`{"answer": 42}`))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,6 @@
|
||||||
package geth
|
package geth
|
||||||
|
|
||||||
/*
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
extern bool StatusServiceSignalEvent( const char *jsonEvent );
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
@ -20,7 +13,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func onWhisperMessage(message *whisper.Message) {
|
func onWhisperMessage(message *whisper.Message) {
|
||||||
event := GethEvent{
|
SendSignal(SignalEnvelope{
|
||||||
Type: "whisper",
|
Type: "whisper",
|
||||||
Event: WhisperMessageEvent{
|
Event: WhisperMessageEvent{
|
||||||
Payload: string(message.Payload),
|
Payload: string(message.Payload),
|
||||||
|
@ -30,9 +23,7 @@ func onWhisperMessage(message *whisper.Message) {
|
||||||
TTL: int64(message.TTL / time.Second),
|
TTL: int64(message.TTL / time.Second),
|
||||||
Hash: common.ToHex(message.Hash.Bytes()),
|
Hash: common.ToHex(message.Hash.Bytes()),
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
body, _ := json.Marshal(&event)
|
|
||||||
C.StatusServiceSignalEvent(C.CString(string(body)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddWhisperFilter(args whisper.NewFilterArgs) int {
|
func AddWhisperFilter(args whisper.NewFilterArgs) int {
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
package jail
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/robertkrimen/otto"
|
||||||
|
"github.com/status-im/status-go/geth"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
EventLocalStorageSet = "local_storage.set"
|
||||||
|
LocalStorageMaxDataLen = 256
|
||||||
|
)
|
||||||
|
|
||||||
|
// makeSendHandler returns jeth.send() and jeth.sendAsync() handler
|
||||||
|
func makeSendHandler(jail *Jail, chatId string) func(call otto.FunctionCall) (response otto.Value) {
|
||||||
|
return func(call otto.FunctionCall) (response otto.Value) {
|
||||||
|
return jail.Send(chatId, call)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// makeJethIsConnectedHandler returns jeth.isConnected() handler
|
||||||
|
func makeJethIsConnectedHandler(jail *Jail) func(call otto.FunctionCall) (response otto.Value) {
|
||||||
|
return func(call otto.FunctionCall) otto.Value {
|
||||||
|
client, err := jail.RPCClient()
|
||||||
|
if err != nil {
|
||||||
|
return newErrorResponse(call, -32603, err.Error(), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
var netListeningResult bool
|
||||||
|
if err := client.Call(&netListeningResult, "net_listening"); err != nil {
|
||||||
|
return newErrorResponse(call, -32603, err.Error(), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if netListeningResult != true {
|
||||||
|
return newErrorResponse(call, -32603, geth.ErrInvalidGethNode.Error(), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
return newResultResponse(call, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// makeLocalStorageSetHandler returns localStorage.set() handler
|
||||||
|
func makeLocalStorageSetHandler(chatId string) func(call otto.FunctionCall) (response otto.Value) {
|
||||||
|
return func(call otto.FunctionCall) otto.Value {
|
||||||
|
data := call.Argument(0).String()
|
||||||
|
if len(data) > LocalStorageMaxDataLen { // cap input string
|
||||||
|
data = data[:LocalStorageMaxDataLen]
|
||||||
|
}
|
||||||
|
|
||||||
|
geth.SendSignal(geth.SignalEnvelope{
|
||||||
|
Type: EventLocalStorageSet,
|
||||||
|
Event: geth.LocalStorageSetEvent{
|
||||||
|
ChatId: chatId,
|
||||||
|
Data: data,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return newResultResponse(call, true)
|
||||||
|
}
|
||||||
|
}
|
47
jail/jail.go
47
jail/jail.go
|
@ -82,18 +82,18 @@ func (jail *Jail) Parse(chatId string, js string) string {
|
||||||
|
|
||||||
initJjs := jail.statusJS + ";"
|
initJjs := jail.statusJS + ";"
|
||||||
_, err := vm.Run(initJjs)
|
_, err := vm.Run(initJjs)
|
||||||
|
|
||||||
|
// jeth and its handlers
|
||||||
vm.Set("jeth", struct{}{})
|
vm.Set("jeth", struct{}{})
|
||||||
|
|
||||||
sendHandler := func(call otto.FunctionCall) (response otto.Value) {
|
|
||||||
return jail.Send(chatId, call)
|
|
||||||
}
|
|
||||||
|
|
||||||
jethObj, _ := vm.Get("jeth")
|
jethObj, _ := vm.Get("jeth")
|
||||||
jethObj.Object().Set("send", sendHandler)
|
jethObj.Object().Set("send", makeSendHandler(jail, chatId))
|
||||||
jethObj.Object().Set("sendAsync", sendHandler)
|
jethObj.Object().Set("sendAsync", makeSendHandler(jail, chatId))
|
||||||
jethObj.Object().Set("isConnected", func(call otto.FunctionCall) (response otto.Value) {
|
jethObj.Object().Set("isConnected", makeJethIsConnectedHandler(jail))
|
||||||
return jail.IsConnected(call)
|
|
||||||
})
|
// localStorage and its handlers
|
||||||
|
vm.Set("localStorage", struct{}{})
|
||||||
|
localStorage, _ := vm.Get("localStorage")
|
||||||
|
localStorage.Object().Set("set", makeLocalStorageSetHandler(chatId))
|
||||||
|
|
||||||
jjs := Web3_JS + `
|
jjs := Web3_JS + `
|
||||||
var Web3 = require('web3');
|
var Web3 = require('web3');
|
||||||
|
@ -146,26 +146,6 @@ func (jail *Jail) GetVM(chatId string) (*otto.Otto, error) {
|
||||||
return cell.vm, nil
|
return cell.vm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (jail *Jail) IsConnected(call otto.FunctionCall) otto.Value {
|
|
||||||
resp, _ := call.Otto.Object(`({"jsonrpc":"2.0", "result": "true"})`)
|
|
||||||
|
|
||||||
client, err := jail.RPCClient()
|
|
||||||
if err != nil {
|
|
||||||
return newErrorResponse(call, -32603, err.Error(), nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
var netListeningResult bool
|
|
||||||
if err := client.Call(&netListeningResult, "net_listening"); err != nil {
|
|
||||||
return newErrorResponse(call, -32603, err.Error(), nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
if netListeningResult != true {
|
|
||||||
return newErrorResponse(call, -32603, geth.ErrInvalidGethNode.Error(), nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
return resp.Value()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send will serialize the first argument, send it to the node and returns the response.
|
// Send will serialize the first argument, send it to the node and returns the response.
|
||||||
func (jail *Jail) Send(chatId string, call otto.FunctionCall) (response otto.Value) {
|
func (jail *Jail) Send(chatId string, call otto.FunctionCall) (response otto.Value) {
|
||||||
client, err := jail.RPCClient()
|
client, err := jail.RPCClient()
|
||||||
|
@ -329,6 +309,13 @@ func newErrorResponse(call otto.FunctionCall, code int, msg string, id interface
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newResultResponse(call otto.FunctionCall, result interface{}) otto.Value {
|
||||||
|
resp, _ := call.Otto.Object(`({"jsonrpc":"2.0"})`)
|
||||||
|
resp.Set("result", result)
|
||||||
|
|
||||||
|
return resp.Value()
|
||||||
|
}
|
||||||
|
|
||||||
// throwJSException panics on an otto.Value. The Otto VM will recover from the
|
// throwJSException panics on an otto.Value. The Otto VM will recover from the
|
||||||
// Go panic and throw msg as a JavaScript error.
|
// Go panic and throw msg as a JavaScript error.
|
||||||
func throwJSException(msg interface{}) otto.Value {
|
func throwJSException(msg interface{}) otto.Value {
|
||||||
|
|
|
@ -221,7 +221,7 @@ func TestJailSendQueuedTransaction(t *testing.T) {
|
||||||
// replace transaction notification handler
|
// replace transaction notification handler
|
||||||
requireMessageId := false
|
requireMessageId := false
|
||||||
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
var envelope geth.GethEvent
|
var envelope geth.SignalEnvelope
|
||||||
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||||
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
||||||
return
|
return
|
||||||
|
@ -458,7 +458,99 @@ func TestIsConnected(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedResponse := `{"jsonrpc":"2.0","result":"true"}`
|
expectedResponse := `{"jsonrpc":"2.0","result":true}`
|
||||||
|
if !reflect.DeepEqual(response, expectedResponse) {
|
||||||
|
t.Errorf("expected response is not returned: expected %s, got %s", expectedResponse, response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLocalStorageSet(t *testing.T) {
|
||||||
|
err := geth.PrepareTestNode()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
jailInstance := jail.Init("")
|
||||||
|
jailInstance.Parse(CHAT_ID_CALL, "")
|
||||||
|
|
||||||
|
// obtain VM for a given chat (to send custom JS to jailed version of Send())
|
||||||
|
vm, err := jailInstance.GetVM(CHAT_ID_CALL)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("cannot get VM: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
testData := "foobar"
|
||||||
|
|
||||||
|
opCompletedSuccessfully := make(chan struct{}, 1)
|
||||||
|
|
||||||
|
// replace transaction notification handler
|
||||||
|
geth.SetDefaultNodeNotificationHandler(func(jsonEvent string) {
|
||||||
|
var envelope geth.SignalEnvelope
|
||||||
|
if err := json.Unmarshal([]byte(jsonEvent), &envelope); err != nil {
|
||||||
|
t.Errorf("cannot unmarshal event's JSON: %s", jsonEvent)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if envelope.Type == jail.EventLocalStorageSet {
|
||||||
|
event := envelope.Event.(map[string]interface{})
|
||||||
|
chatId, ok := event["chat_id"].(string)
|
||||||
|
if !ok {
|
||||||
|
t.Error("Chat id is required, but not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if chatId != CHAT_ID_CALL {
|
||||||
|
t.Errorf("incorrect chat id: expected %q, got: %q", CHAT_ID_CALL, chatId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
actualData, ok := event["data"].(string)
|
||||||
|
if !ok {
|
||||||
|
t.Error("Data field is required, but not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if actualData != testData {
|
||||||
|
t.Errorf("incorrect data: expected %q, got: %q", testData, actualData)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("event processed: %s", jsonEvent)
|
||||||
|
opCompletedSuccessfully <- struct{}{} // so that timeout is aborted
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err = vm.Run(`
|
||||||
|
var responseValue = localStorage.set("` + testData + `");
|
||||||
|
responseValue = JSON.stringify(responseValue);
|
||||||
|
`)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("cannot run custom code on VM: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure that signal is sent (and its parameters are correct)
|
||||||
|
select {
|
||||||
|
case <-opCompletedSuccessfully:
|
||||||
|
// pass
|
||||||
|
case <-time.After(3 * time.Second):
|
||||||
|
t.Error("operation timed out")
|
||||||
|
}
|
||||||
|
|
||||||
|
responseValue, err := vm.Get("responseValue")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("cannot obtain result of localStorage.set(): %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := responseValue.ToString()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("cannot parse result: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedResponse := `{"jsonrpc":"2.0","result":true}`
|
||||||
if !reflect.DeepEqual(response, expectedResponse) {
|
if !reflect.DeepEqual(response, expectedResponse) {
|
||||||
t.Errorf("expected response is not returned: expected %s, got %s", expectedResponse, response)
|
t.Errorf("expected response is not returned: expected %s, got %s", expectedResponse, response)
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue