Commit b663e8b2 authored by obscuren's avatar obscuren

Merge branch 'rpcfrontier' into develop

parents f1fcda4f e3b64d70
...@@ -131,6 +131,7 @@ type Ethereum struct { ...@@ -131,6 +131,7 @@ type Ethereum struct {
Mining bool Mining bool
DataDir string DataDir string
version string
} }
func New(config *Config) (*Ethereum, error) { func New(config *Config) (*Ethereum, error) {
...@@ -165,6 +166,7 @@ func New(config *Config) (*Ethereum, error) { ...@@ -165,6 +166,7 @@ func New(config *Config) (*Ethereum, error) {
logger: servlogger, logger: servlogger,
accountManager: config.AccountManager, accountManager: config.AccountManager,
DataDir: config.DataDir, DataDir: config.DataDir,
version: config.Name, // TODO should separate from Name
} }
eth.chainManager = core.NewChainManager(blockDb, stateDb, eth.EventMux()) eth.chainManager = core.NewChainManager(blockDb, stateDb, eth.EventMux())
...@@ -236,6 +238,7 @@ func (s *Ethereum) IsListening() bool { return true } // Alwa ...@@ -236,6 +238,7 @@ func (s *Ethereum) IsListening() bool { return true } // Alwa
func (s *Ethereum) PeerCount() int { return s.net.PeerCount() } func (s *Ethereum) PeerCount() int { return s.net.PeerCount() }
func (s *Ethereum) Peers() []*p2p.Peer { return s.net.Peers() } func (s *Ethereum) Peers() []*p2p.Peer { return s.net.Peers() }
func (s *Ethereum) MaxPeers() int { return s.net.MaxPeers } func (s *Ethereum) MaxPeers() int { return s.net.MaxPeers }
func (s *Ethereum) Version() string { return s.version }
// Start the ethereum // Start the ethereum
func (s *Ethereum) Start() error { func (s *Ethereum) Start() error {
......
...@@ -176,7 +176,7 @@ func (self *EthereumApi) UninstallFilter(id int, reply *interface{}) error { ...@@ -176,7 +176,7 @@ func (self *EthereumApi) UninstallFilter(id int, reply *interface{}) error {
return nil return nil
} }
func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error { func (self *EthereumApi) NewFilterString(args *FilterStringArgs, reply *interface{}) error {
var id int var id int
filter := core.NewFilter(self.xeth().Backend()) filter := core.NewFilter(self.xeth().Backend())
...@@ -186,10 +186,14 @@ func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error ...@@ -186,10 +186,14 @@ func (self *EthereumApi) NewFilterString(args string, reply *interface{}) error
self.logs[id].add(&state.StateLog{}) self.logs[id].add(&state.StateLog{})
} }
if args == "pending" {
switch args.Word {
case "pending":
filter.PendingCallback = callback filter.PendingCallback = callback
} else if args == "chain" { case "latest":
filter.BlockCallback = callback filter.BlockCallback = callback
default:
return NewValidationError("Word", "Must be `latest` or `pending`")
} }
id = self.filterManager.InstallFilter(filter) id = self.filterManager.InstallFilter(filter)
...@@ -477,6 +481,10 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error ...@@ -477,6 +481,10 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
return err return err
} }
*reply = toHex(crypto.Sha3(fromHex(args.Data))) *reply = toHex(crypto.Sha3(fromHex(args.Data)))
case "web3_clientVersion":
*reply = p.xeth().Backend().Version()
case "net_version":
return NewNotImplementedError(req.Method)
case "net_listening": case "net_listening":
*reply = p.xeth().IsListening() *reply = p.xeth().IsListening()
case "net_peerCount": case "net_peerCount":
...@@ -578,7 +586,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error ...@@ -578,7 +586,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
} }
return p.Call(args, reply) return p.Call(args, reply)
case "eth_flush": case "eth_flush":
return errNotImplemented return NewNotImplementedError(req.Method)
case "eth_getBlockByHash": case "eth_getBlockByHash":
args := new(GetBlockByHashArgs) args := new(GetBlockByHashArgs)
if err := json.Unmarshal(req.Params, &args); err != nil { if err := json.Unmarshal(req.Params, &args); err != nil {
...@@ -618,7 +626,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error ...@@ -618,7 +626,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
return err return err
} }
if args.Index > int64(len(v.Transactions)) || args.Index < 0 { if args.Index > int64(len(v.Transactions)) || args.Index < 0 {
return NewErrorWithMessage(errDecodeArgs, "Transaction index does not exist") return NewValidationError("Index", "does not exist")
} }
*reply = v.Transactions[args.Index] *reply = v.Transactions[args.Index]
case "eth_getTransactionByBlockNumberAndIndex": case "eth_getTransactionByBlockNumberAndIndex":
...@@ -632,7 +640,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error ...@@ -632,7 +640,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
return err return err
} }
if args.Index > int64(len(v.Transactions)) || args.Index < 0 { if args.Index > int64(len(v.Transactions)) || args.Index < 0 {
return NewErrorWithMessage(errDecodeArgs, "Transaction index does not exist") return NewValidationError("Index", "does not exist")
} }
*reply = v.Transactions[args.Index] *reply = v.Transactions[args.Index]
case "eth_getUncleByBlockHashAndIndex": case "eth_getUncleByBlockHashAndIndex":
...@@ -646,7 +654,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error ...@@ -646,7 +654,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
return err return err
} }
if args.Index > int64(len(v.Uncles)) || args.Index < 0 { if args.Index > int64(len(v.Uncles)) || args.Index < 0 {
return NewErrorWithMessage(errDecodeArgs, "Uncle index does not exist") return NewValidationError("Index", "does not exist")
} }
uncle, err := p.GetBlockByHash(toHex(v.Uncles[args.Index]), false) uncle, err := p.GetBlockByHash(toHex(v.Uncles[args.Index]), false)
...@@ -665,7 +673,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error ...@@ -665,7 +673,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
return err return err
} }
if args.Index > int64(len(v.Uncles)) || args.Index < 0 { if args.Index > int64(len(v.Uncles)) || args.Index < 0 {
return NewErrorWithMessage(errDecodeArgs, "Uncle index does not exist") return NewValidationError("Index", "does not exist")
} }
uncle, err := p.GetBlockByHash(toHex(v.Uncles[args.Index]), false) uncle, err := p.GetBlockByHash(toHex(v.Uncles[args.Index]), false)
...@@ -675,10 +683,8 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error ...@@ -675,10 +683,8 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
*reply = uncle *reply = uncle
case "eth_getCompilers": case "eth_getCompilers":
return p.GetCompilers(reply) return p.GetCompilers(reply)
case "eth_compileSolidity": case "eth_compileSolidity", "eth_compileLLL", "eth_compileSerpent":
case "eth_compileLLL": return NewNotImplementedError(req.Method)
case "eth_compileSerpent":
return errNotImplemented
case "eth_newFilter": case "eth_newFilter":
args := new(FilterOptions) args := new(FilterOptions)
if err := json.Unmarshal(req.Params, &args); err != nil { if err := json.Unmarshal(req.Params, &args); err != nil {
...@@ -690,7 +696,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error ...@@ -690,7 +696,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
if err := json.Unmarshal(req.Params, &args); err != nil { if err := json.Unmarshal(req.Params, &args); err != nil {
return err return err
} }
return p.NewFilterString(args.Word, reply) return p.NewFilterString(args, reply)
case "eth_uninstallFilter": case "eth_uninstallFilter":
args := new(FilterIdArgs) args := new(FilterIdArgs)
if err := json.Unmarshal(req.Params, &args); err != nil { if err := json.Unmarshal(req.Params, &args); err != nil {
...@@ -715,21 +721,22 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error ...@@ -715,21 +721,22 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
return err return err
} }
return p.AllLogs(args, reply) return p.AllLogs(args, reply)
case "eth_getWork": case "eth_getWork", "eth_submitWork":
case "eth_submitWork": return NewNotImplementedError(req.Method)
return errNotImplemented case "db_putString":
case "db_put":
args := new(DbArgs) args := new(DbArgs)
if err := json.Unmarshal(req.Params, &args); err != nil { if err := json.Unmarshal(req.Params, &args); err != nil {
return err return err
} }
return p.DbPut(args, reply) return p.DbPut(args, reply)
case "db_get": case "db_getString":
args := new(DbArgs) args := new(DbArgs)
if err := json.Unmarshal(req.Params, &args); err != nil { if err := json.Unmarshal(req.Params, &args); err != nil {
return err return err
} }
return p.DbGet(args, reply) return p.DbGet(args, reply)
case "db_putHex", "db_getHex":
return NewNotImplementedError(req.Method)
case "shh_post": case "shh_post":
args := new(WhisperMessageArgs) args := new(WhisperMessageArgs)
if err := json.Unmarshal(req.Params, &args); err != nil { if err := json.Unmarshal(req.Params, &args); err != nil {
...@@ -744,9 +751,8 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error ...@@ -744,9 +751,8 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
return err return err
} }
return p.HasWhisperIdentity(args.Identity, reply) return p.HasWhisperIdentity(args.Identity, reply)
case "shh_newGroup": case "shh_newGroup", "shh_addToGroup":
case "shh_addToGroup": return NewNotImplementedError(req.Method)
return errNotImplemented
case "shh_newFilter": case "shh_newFilter":
args := new(WhisperFilterArgs) args := new(WhisperFilterArgs)
if err := json.Unmarshal(req.Params, &args); err != nil { if err := json.Unmarshal(req.Params, &args); err != nil {
...@@ -790,7 +796,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error ...@@ -790,7 +796,7 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
// } // }
// return p.WatchTx(args, reply) // return p.WatchTx(args, reply)
default: default:
return NewErrorWithMessage(errNotImplemented, req.Method) return NewNotImplementedError(req.Method)
} }
rpclogger.DebugDetailf("Reply: %T %s", reply, reply) rpclogger.DebugDetailf("Reply: %T %s", reply, reply)
......
This diff is collapsed.
...@@ -25,22 +25,39 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler { ...@@ -25,22 +25,39 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler {
rpchttplogger.DebugDetailln("Handling request") rpchttplogger.DebugDetailln("Handling request")
if req.ContentLength > maxSizeReqLength { if req.ContentLength > maxSizeReqLength {
jsonerr := &RpcErrorObject{-32700, "Error: Request too large"} jsonerr := &RpcErrorObject{-32700, "Request too large"}
json.Send(w, &RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr}) json.Send(w, &RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr})
return return
} }
reqParsed, reqerr := json.ParseRequestBody(req) reqParsed, reqerr := json.ParseRequestBody(req)
if reqerr != nil { switch reqerr.(type) {
jsonerr := &RpcErrorObject{-32700, "Error: Could not parse request"} case nil:
break
case *DecodeParamError, *InsufficientParamsError, *ValidationError:
jsonerr := &RpcErrorObject{-32602, reqerr.Error()}
json.Send(w, &RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr})
return
default:
jsonerr := &RpcErrorObject{-32700, "Could not parse request"}
json.Send(w, &RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr}) json.Send(w, &RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr})
return return
} }
var response interface{} var response interface{}
reserr := api.GetRequestReply(&reqParsed, &response) reserr := api.GetRequestReply(&reqParsed, &response)
if reserr != nil { switch reserr.(type) {
rpchttplogger.Warnln(reserr) case nil:
break
case *NotImplementedError:
jsonerr := &RpcErrorObject{-32601, reserr.Error()}
json.Send(w, &RpcErrorResponse{JsonRpc: jsonrpcver, ID: reqParsed.ID, Error: jsonerr})
return
case *DecodeParamError, *InsufficientParamsError, *ValidationError:
jsonerr := &RpcErrorObject{-32602, reserr.Error()}
json.Send(w, &RpcErrorResponse{JsonRpc: jsonrpcver, ID: reqParsed.ID, Error: jsonerr})
return
default:
jsonerr := &RpcErrorObject{-32603, reserr.Error()} jsonerr := &RpcErrorObject{-32603, reserr.Error()}
json.Send(w, &RpcErrorResponse{JsonRpc: jsonrpcver, ID: reqParsed.ID, Error: jsonerr}) json.Send(w, &RpcErrorResponse{JsonRpc: jsonrpcver, ID: reqParsed.ID, Error: jsonerr})
return return
......
...@@ -18,16 +18,69 @@ package rpc ...@@ -18,16 +18,69 @@ package rpc
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
) )
var ( type InsufficientParamsError struct {
errArguments = errors.New("Error: Insufficient arguments") have int
errNotImplemented = errors.New("Error: Method not implemented") want int
errUnknown = errors.New("Error: Unknown error") }
errDecodeArgs = errors.New("Error: Could not decode arguments")
) func (e *InsufficientParamsError) Error() string {
return fmt.Sprintf("insufficient params, want %d have %d", e.want, e.have)
}
func NewInsufficientParamsError(have int, want int) *InsufficientParamsError {
return &InsufficientParamsError{
have: have,
want: want,
}
}
type NotImplementedError struct {
Method string
}
func (e *NotImplementedError) Error() string {
return fmt.Sprintf("%s method not implemented", e.Method)
}
func NewNotImplementedError(method string) *NotImplementedError {
return &NotImplementedError{
Method: method,
}
}
type DecodeParamError struct {
err string
}
func (e *DecodeParamError) Error() string {
return fmt.Sprintf("could not decode, %s", e.err)
}
func NewDecodeParamError(errstr string) error {
return &DecodeParamError{
err: errstr,
}
}
type ValidationError struct {
ParamName string
msg string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("%s not valid, %s", e.ParamName, e.msg)
}
func NewValidationError(param string, msg string) error {
return &ValidationError{
ParamName: param,
msg: msg,
}
}
type RpcRequest struct { type RpcRequest struct {
ID interface{} `json:"id"` ID interface{} `json:"id"`
...@@ -53,35 +106,3 @@ type RpcErrorObject struct { ...@@ -53,35 +106,3 @@ type RpcErrorObject struct {
Message string `json:"message"` Message string `json:"message"`
// Data interface{} `json:"data"` // Data interface{} `json:"data"`
} }
func NewErrorWithMessage(err error, msg string) error {
return fmt.Errorf("%s: %s", err.Error(), msg)
}
// func (req *RpcRequest) ToRegisterArgs() (string, error) {
// if len(req.Params) < 1 {
// return "", errArguments
// }
// var args string
// err := json.Unmarshal(req.Params, &args)
// if err != nil {
// return "", err
// }
// return args, nil
// }
// func (req *RpcRequest) ToWatchTxArgs() (string, error) {
// if len(req.Params) < 1 {
// return "", errArguments
// }
// var args string
// err := json.Unmarshal(req.Params, &args)
// if err != nil {
// return "", err
// }
// return args, nil
// }
...@@ -42,7 +42,7 @@ type JsonWrapper struct{} ...@@ -42,7 +42,7 @@ type JsonWrapper struct{}
func UnmarshalRawMessages(b []byte, iface interface{}, number *int64) (err error) { func UnmarshalRawMessages(b []byte, iface interface{}, number *int64) (err error) {
var data []json.RawMessage var data []json.RawMessage
if err = json.Unmarshal(b, &data); err != nil && len(data) == 0 { if err = json.Unmarshal(b, &data); err != nil && len(data) == 0 {
return errDecodeArgs return NewDecodeParamError(err.Error())
} }
// Number index determines the index in the array for a possible block number // Number index determines the index in the array for a possible block number
...@@ -74,7 +74,7 @@ func UnmarshalRawMessages(b []byte, iface interface{}, number *int64) (err error ...@@ -74,7 +74,7 @@ func UnmarshalRawMessages(b []byte, iface interface{}, number *int64) (err error
fallthrough fallthrough
default: default:
if err = json.Unmarshal(data[0], iface); err != nil { if err = json.Unmarshal(data[0], iface); err != nil {
return errDecodeArgs return NewDecodeParamError(err.Error())
} }
numberIndex = 1 numberIndex = 1
} }
...@@ -82,7 +82,7 @@ func UnmarshalRawMessages(b []byte, iface interface{}, number *int64) (err error ...@@ -82,7 +82,7 @@ func UnmarshalRawMessages(b []byte, iface interface{}, number *int64) (err error
// <0 index means out of bound for block number // <0 index means out of bound for block number
if numberIndex >= 0 && len(data) > numberIndex { if numberIndex >= 0 && len(data) > numberIndex {
if err = blockNumber(data[numberIndex], number); err != nil { if err = blockNumber(data[numberIndex], number); err != nil {
return errDecodeArgs return NewDecodeParamError(err.Error())
} }
} }
......
...@@ -39,6 +39,7 @@ type Backend interface { ...@@ -39,6 +39,7 @@ type Backend interface {
IsMining() bool IsMining() bool
StartMining() error StartMining() error
StopMining() StopMining()
Version() string
} }
// Frontend should be implemented by users of XEth. Its methods are // Frontend should be implemented by users of XEth. Its methods are
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment