diff --git a/jail/jail.go b/jail/jail.go index a52e6f78e..19b008191 100644 --- a/jail/jail.go +++ b/jail/jail.go @@ -91,6 +91,9 @@ func (jail *Jail) Parse(chatId string, js string) string { jethObj, _ := vm.Get("jeth") jethObj.Object().Set("send", sendHandler) jethObj.Object().Set("sendAsync", sendHandler) + jethObj.Object().Set("isConnected", func(call otto.FunctionCall) (response otto.Value) { + return jail.IsConnected(call) + }) jjs := Web3_JS + ` var Web3 = require('web3'); @@ -143,6 +146,26 @@ func (jail *Jail) GetVM(chatId string) (*otto.Otto, error) { 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. func (jail *Jail) Send(chatId string, call otto.FunctionCall) (response otto.Value) { client, err := jail.RPCClient() @@ -300,7 +323,7 @@ func (jail *Jail) RequestQueue() (*geth.JailedRequestQueue, error) { func newErrorResponse(call otto.FunctionCall, code int, msg string, id interface{}) otto.Value { // Bundle the error into a JSON RPC call response - m := map[string]interface{}{"version": "2.0", "id": id, "error": map[string]interface{}{"code": code, msg: msg}} + m := map[string]interface{}{"jsonrpc": "2.0", "id": id, "error": map[string]interface{}{"code": code, msg: msg}} res, _ := json.Marshal(m) val, _ := call.Otto.Run("(" + string(res) + ")") return val diff --git a/jail/jail_test.go b/jail/jail_test.go index 69eafc9cd..dceed7c6a 100644 --- a/jail/jail_test.go +++ b/jail/jail_test.go @@ -419,3 +419,48 @@ func TestJailGetVM(t *testing.T) { t.Errorf("unexpected error: %v", err) } } + +func TestIsConnected(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 + } + + _, err = vm.Run(` + var responseValue = web3.isConnected(); + responseValue = JSON.stringify(responseValue); + `) + if err != nil { + t.Errorf("cannot run custom code on VM: %v", err) + return + } + + responseValue, err := vm.Get("responseValue") + if err != nil { + t.Errorf("cannot obtain result of isConnected(): %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) { + t.Errorf("expected response is not returned: expected %s, got %s", expectedResponse, response) + return + } +}