aboutsummaryrefslogtreecommitdiffstats
path: root/rpc
diff options
context:
space:
mode:
authorBas van Kervel <basvankervel@ziggo.nl>2015-06-08 18:43:58 +0800
committerBas van Kervel <basvankervel@gmail.com>2015-06-11 20:01:39 +0800
commita1a475fb9296e214292840d89811123292c7953c (patch)
treebe92dc0faa0f62276fbb6b1fef529cec8280a12c /rpc
parent2a0d888326036be9cabe6680617ce2d1a27761d3 (diff)
downloadgo-tangerine-a1a475fb9296e214292840d89811123292c7953c.tar
go-tangerine-a1a475fb9296e214292840d89811123292c7953c.tar.gz
go-tangerine-a1a475fb9296e214292840d89811123292c7953c.tar.bz2
go-tangerine-a1a475fb9296e214292840d89811123292c7953c.tar.lz
go-tangerine-a1a475fb9296e214292840d89811123292c7953c.tar.xz
go-tangerine-a1a475fb9296e214292840d89811123292c7953c.tar.zst
go-tangerine-a1a475fb9296e214292840d89811123292c7953c.zip
added console command
Diffstat (limited to 'rpc')
-rw-r--r--rpc/api/api.go14
-rw-r--r--rpc/api/eth.go4
-rw-r--r--rpc/api/mergedapi.go56
-rw-r--r--rpc/api/mergedapi_js.go1
-rw-r--r--rpc/api/utils.go47
-rw-r--r--rpc/api/web3.go84
-rw-r--r--rpc/api/web3_args.go5
-rw-r--r--rpc/jeth.go63
8 files changed, 213 insertions, 61 deletions
diff --git a/rpc/api/api.go b/rpc/api/api.go
index 93dc3058c..153c73f48 100644
--- a/rpc/api/api.go
+++ b/rpc/api/api.go
@@ -4,14 +4,26 @@ import "github.com/ethereum/go-ethereum/rpc/shared"
const (
// List with all API's which are offered over the IPC interface by default
- DefaultIpcApis = "eth"
+ DefaultIpcApis = "eth,web3"
+
+ EthApiName = "eth"
+ MergedApiName = "merged"
+ Web3ApiName = "web3"
)
// Ethereum RPC API interface
type EthereumApi interface {
+ // API identifier
+ Name() string
+
// Execute the given request and returns the response or an error
Execute(*shared.Request) (interface{}, error)
// List of supported RCP methods this API provides
Methods() []string
}
+
+// Merge multiple API's to a single API instance
+func Merge(apis ...EthereumApi) EthereumApi {
+ return newMergedApi(apis...)
+}
diff --git a/rpc/api/eth.go b/rpc/api/eth.go
index fa14aa41e..0a8cecdbc 100644
--- a/rpc/api/eth.go
+++ b/rpc/api/eth.go
@@ -93,6 +93,10 @@ func (self *EthApi) Execute(req *shared.Request) (interface{}, error) {
return nil, shared.NewNotImplementedError(req.Method)
}
+func (self *EthApi) Name() string {
+ return EthApiName
+}
+
func (self *EthApi) Accounts(req *shared.Request) (interface{}, error) {
return self.xeth.Accounts(), nil
}
diff --git a/rpc/api/mergedapi.go b/rpc/api/mergedapi.go
new file mode 100644
index 000000000..7784661d7
--- /dev/null
+++ b/rpc/api/mergedapi.go
@@ -0,0 +1,56 @@
+package api
+
+import "github.com/ethereum/go-ethereum/rpc/shared"
+
+// combines multiple API's
+type mergedApi struct {
+ apis []string
+ methods map[string]EthereumApi
+}
+
+// create new merged api instance
+func newMergedApi(apis ...EthereumApi) *mergedApi {
+ mergedApi := new(mergedApi)
+ mergedApi.apis = make([]string, len(apis))
+ mergedApi.methods = make(map[string]EthereumApi)
+
+ for i, api := range apis {
+ mergedApi.apis[i] = api.Name()
+ for _, method := range api.Methods() {
+ mergedApi.methods[method] = api
+ }
+ }
+ return mergedApi
+}
+
+// Supported RPC methods
+func (self *mergedApi) Methods() []string {
+ all := make([]string, len(self.methods))
+ for method, _ := range self.methods {
+ all = append(all, method)
+ }
+ return all
+}
+
+// Call the correct API's Execute method for the given request
+func (self *mergedApi) Execute(req *shared.Request) (interface{}, error) {
+ if res, _ := self.handle(req); res != nil {
+ return res, nil
+ }
+ if api, found := self.methods[req.Method]; found {
+ return api.Execute(req)
+ }
+ return nil, shared.NewNotImplementedError(req.Method)
+}
+
+func (self *mergedApi) Name() string {
+ return MergedApiName
+}
+
+func (self *mergedApi) handle(req *shared.Request) (interface{}, error) {
+ if req.Method == "support_apis" { // provided API's
+ return self.apis, nil
+ }
+
+ return nil, nil
+}
diff --git a/rpc/api/mergedapi_js.go b/rpc/api/mergedapi_js.go
new file mode 100644
index 000000000..778f64ec1
--- /dev/null
+++ b/rpc/api/mergedapi_js.go
@@ -0,0 +1 @@
+package api
diff --git a/rpc/api/utils.go b/rpc/api/utils.go
index a62058140..7024365e4 100644
--- a/rpc/api/utils.go
+++ b/rpc/api/utils.go
@@ -8,11 +8,6 @@ import (
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/rpc/codec"
"github.com/ethereum/go-ethereum/xeth"
- "github.com/ethereum/go-ethereum/rpc/shared"
-)
-
-const (
- EthApiName = "eth"
)
// Parse a comma separated API string to individual api's
@@ -28,6 +23,8 @@ func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.
switch strings.ToLower(strings.TrimSpace(name)) {
case EthApiName:
apis[i] = NewEthApi(xeth, codec)
+ case Web3ApiName:
+ apis[i] = NewWeb3(xeth, codec)
default:
return nil, fmt.Errorf("Unknown API '%s'", name)
}
@@ -35,43 +32,3 @@ func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.
return apis, nil
}
-
-// combines multiple API's
-type mergedApi struct {
- apis map[string]EthereumApi
-}
-
-// create new merged api instance
-func newMergedApi(apis ...EthereumApi) *mergedApi {
- mergedApi := new(mergedApi)
- mergedApi.apis = make(map[string]EthereumApi)
-
- for _, api := range apis {
- for _, method := range api.Methods() {
- mergedApi.apis[method] = api
- }
- }
- return mergedApi
-}
-
-// Supported RPC methods
-func (self *mergedApi) Methods() []string {
- all := make([]string, len(self.apis))
- for method, _ := range self.apis {
- all = append(all, method)
- }
- return all
-}
-
-// Call the correct API's Execute method for the given request
-func (self *mergedApi) Execute(req *shared.Request) (interface{}, error) {
- if api, found := self.apis[req.Method]; found {
- return api.Execute(req)
- }
- return nil, shared.NewNotImplementedError(req.Method)
-}
-
-// Merge multiple API's to a single API instance
-func Merge(apis ...EthereumApi) EthereumApi {
- return newMergedApi(apis...)
-}
diff --git a/rpc/api/web3.go b/rpc/api/web3.go
new file mode 100644
index 000000000..4c51c4a97
--- /dev/null
+++ b/rpc/api/web3.go
@@ -0,0 +1,84 @@
+package api
+
+import (
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/rpc/codec"
+ "github.com/ethereum/go-ethereum/rpc/shared"
+ "github.com/ethereum/go-ethereum/xeth"
+)
+
+const (
+ Web3Version = "1.0.0"
+)
+
+var (
+// mapping between methods and handlers
+ Web3Mapping = map[string]web3handler{
+ "web3_sha3": (*web3).Sha3,
+ "web3_clientVersion": (*web3).ClientVersion,
+ }
+)
+
+// web3 callback handler
+type web3handler func(*web3, *shared.Request) (interface{}, error)
+
+// web3 api provider
+type web3 struct {
+ xeth *xeth.XEth
+ methods map[string]web3handler
+ codec codec.ApiCoder
+}
+
+// create a new web3 api instance
+func NewWeb3(xeth *xeth.XEth, coder codec.Codec) *web3 {
+ return &web3{
+ xeth: xeth,
+ methods: Web3Mapping,
+ codec: coder.New(nil),
+ }
+}
+
+// collection with supported methods
+func (self *web3) Methods() []string {
+ methods := make([]string, len(self.methods))
+ i := 0
+ for k := range self.methods {
+ methods[i] = k
+ i++
+ }
+ return methods
+}
+
+// Execute given request
+func (self *web3) Execute(req *shared.Request) (interface{}, error) {
+ if callback, ok := self.methods[req.Method]; ok {
+ return callback(self, req)
+ }
+
+ return nil, &shared.NotImplementedError{req.Method}
+}
+
+func (self *web3) Name() string {
+ return Web3ApiName
+}
+
+// Version of the API this instance provides
+func (self *web3) Version() string {
+ return Web3Version
+}
+
+// Calculates the sha3 over req.Params.Data
+func (self *web3) Sha3(req *shared.Request) (interface{}, error) {
+ args := new(Sha3Args)
+ if err := self.codec.Decode(req.Params, &args); err != nil {
+ return nil, err
+ }
+
+ return common.ToHex(crypto.Sha3(common.FromHex(args.Data))), nil
+}
+
+// returns the xeth client vrsion
+func (self *web3) ClientVersion(req *shared.Request) (interface{}, error) {
+ return self.xeth.ClientVersion(), nil
+}
diff --git a/rpc/api/web3_args.go b/rpc/api/web3_args.go
new file mode 100644
index 000000000..5455a6c8e
--- /dev/null
+++ b/rpc/api/web3_args.go
@@ -0,0 +1,5 @@
+package api
+
+type Sha3Args struct {
+ Data string
+}
diff --git a/rpc/jeth.go b/rpc/jeth.go
index 61be60dc7..d4f6dd460 100644
--- a/rpc/jeth.go
+++ b/rpc/jeth.go
@@ -6,15 +6,20 @@ import (
"github.com/ethereum/go-ethereum/jsre"
"github.com/robertkrimen/otto"
+ "github.com/ethereum/go-ethereum/rpc/comms"
+ "github.com/ethereum/go-ethereum/rpc/codec"
+ "github.com/ethereum/go-ethereum/rpc/shared"
+ "reflect"
)
type Jeth struct {
- ethApi *EthereumApi
- re *jsre.JSRE
+ ethApi *EthereumApi
+ re *jsre.JSRE
+ ipcpath string
}
-func NewJeth(ethApi *EthereumApi, re *jsre.JSRE) *Jeth {
- return &Jeth{ethApi, re}
+func NewJeth(ethApi *EthereumApi, re *jsre.JSRE, ipcpath string) *Jeth {
+ return &Jeth{ethApi, re, ipcpath}
}
func (self *Jeth) err(call otto.FunctionCall, code int, msg string, id interface{}) (response otto.Value) {
@@ -34,6 +39,13 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) {
return self.err(call, -32700, err.Error(), nil)
}
+ client, err := comms.NewIpcClient(comms.IpcConfig{self.ipcpath}, codec.JSON)
+ if err != nil {
+ fmt.Println("Unable to connect to geth.")
+ return self.err(call, -32603, err.Error(), -1)
+ }
+ defer client.Close()
+
jsonreq, err := json.Marshal(reqif)
var reqs []RpcRequest
batch := true
@@ -48,22 +60,43 @@ func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) {
call.Otto.Run("var ret_response = new Array(response_len);")
for i, req := range reqs {
- var respif interface{}
- err = self.ethApi.GetRequestReply(&req, &respif)
+ err := client.Send(&req)
if err != nil {
- fmt.Println("Error response:", err)
+ fmt.Println("Error send request:", err)
return self.err(call, -32603, err.Error(), req.Id)
}
- call.Otto.Set("ret_jsonrpc", jsonrpcver)
- call.Otto.Set("ret_id", req.Id)
- res, _ := json.Marshal(respif)
+ respif, err := client.Recv()
+ if err != nil {
+ fmt.Println("Error recv response:", err)
+ return self.err(call, -32603, err.Error(), req.Id)
+ }
- call.Otto.Set("ret_result", string(res))
- call.Otto.Set("response_idx", i)
- response, err = call.Otto.Run(`
- ret_response[response_idx] = { jsonrpc: ret_jsonrpc, id: ret_id, result: JSON.parse(ret_result) };
- `)
+ if res, ok := respif.(shared.SuccessResponse); ok {
+ call.Otto.Set("ret_id", res.Id)
+ call.Otto.Set("ret_jsonrpc", res.Jsonrpc)
+ resObj, _ := json.Marshal(res.Result)
+ call.Otto.Set("ret_result", string(resObj))
+ call.Otto.Set("response_idx", i)
+
+ response, err = call.Otto.Run(`
+ ret_response[response_idx] = { jsonrpc: ret_jsonrpc, id: ret_id, result: JSON.parse(ret_result) };
+ `)
+ } else if res, ok := respif.(shared.ErrorResponse); ok {
+ fmt.Printf("Error: %s (%d)\n", res.Error.Message, res.Error.Code)
+
+ call.Otto.Set("ret_id", res.Id)
+ call.Otto.Set("ret_jsonrpc", res.Jsonrpc)
+ call.Otto.Set("ret_error", res.Error)
+ call.Otto.Set("response_idx", i)
+
+ response, _ = call.Otto.Run(`
+ ret_response = { jsonrpc: ret_jsonrpc, id: ret_id, error: ret_error };
+ `)
+ return
+ } else {
+ fmt.Printf("unexpected response\n", reflect.TypeOf(respif))
+ }
}
if !batch {