diff options
Diffstat (limited to 'rpc')
-rw-r--r-- | rpc/api.go | 11 | ||||
-rw-r--r-- | rpc/args.go | 68 | ||||
-rw-r--r-- | rpc/args_test.go | 120 | ||||
-rw-r--r-- | rpc/http.go | 14 | ||||
-rw-r--r-- | rpc/jeth.go | 43 | ||||
-rw-r--r-- | rpc/messages.go | 12 | ||||
-rw-r--r-- | rpc/util.go | 5 |
7 files changed, 220 insertions, 53 deletions
diff --git a/rpc/api.go b/rpc/api.go index 7ce360f86..57075bffc 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -371,6 +371,11 @@ func (p *EthereumApi) NewWhisperIdentity(reply *interface{}) error { return nil } +// func (p *EthereumApi) RemoveWhisperIdentity(args *WhisperIdentityArgs, reply *interface{}) error { +// *reply = p.xeth().Whisper().RemoveIdentity(args.Identity) +// return nil +// } + func (p *EthereumApi) NewWhisperFilter(args *WhisperFilterArgs, reply *interface{}) error { var id int opts := new(xeth.Options) @@ -751,6 +756,12 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error return p.WhisperPost(args, reply) case "shh_newIdentity": return p.NewWhisperIdentity(reply) + // case "shh_removeIdentity": + // args := new(WhisperIdentityArgs) + // if err := json.Unmarshal(req.Params, &args); err != nil { + // return err + // } + // return p.RemoveWhisperIdentity(args, reply) case "shh_hasIdentity": args := new(WhisperIdentityArgs) if err := json.Unmarshal(req.Params, &args); err != nil { diff --git a/rpc/args.go b/rpc/args.go index 7ed482c30..fee44c4e0 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -331,42 +331,6 @@ func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) { return nil } -// type FilterArgs struct { -// FromBlock uint64 -// ToBlock uint64 -// Limit uint64 -// Offset uint64 -// Address string -// Topics []string -// } - -// func (args *FilterArgs) UnmarshalJSON(b []byte) (err error) { -// var obj []struct { -// FromBlock string `json:"fromBlock"` -// ToBlock string `json:"toBlock"` -// Limit string `json:"limit"` -// Offset string `json:"offset"` -// Address string `json:"address"` -// Topics []string `json:"topics"` -// } - -// if err = json.Unmarshal(b, &obj); err != nil { -// return errDecodeArgs -// } - -// if len(obj) < 1 { -// return errArguments -// } -// args.FromBlock = uint64(common.Big(obj[0].FromBlock).Int64()) -// args.ToBlock = uint64(common.Big(obj[0].ToBlock).Int64()) -// args.Limit = uint64(common.Big(obj[0].Limit).Int64()) -// args.Offset = uint64(common.Big(obj[0].Offset).Int64()) -// args.Address = obj[0].Address -// args.Topics = obj[0].Topics - -// return nil -// } - type FilterOptions struct { Earliest int64 Latest int64 @@ -378,8 +342,8 @@ type FilterOptions struct { func (args *FilterOptions) UnmarshalJSON(b []byte) (err error) { var obj []struct { - FromBlock string `json:"fromBlock"` - ToBlock string `json:"toBlock"` + FromBlock interface{} `json:"fromBlock"` + ToBlock interface{} `json:"toBlock"` Limit string `json:"limit"` Offset string `json:"offset"` Address string `json:"address"` @@ -394,8 +358,32 @@ func (args *FilterOptions) UnmarshalJSON(b []byte) (err error) { return NewInsufficientParamsError(len(obj), 1) } - args.Earliest = int64(common.Big(obj[0].FromBlock).Int64()) - args.Latest = int64(common.Big(obj[0].ToBlock).Int64()) + fromstr, ok := obj[0].FromBlock.(string) + if !ok { + return NewDecodeParamError("FromBlock is not a string") + } + + switch fromstr { + case "latest": + args.Earliest = 0 + default: + args.Earliest = int64(common.Big(obj[0].FromBlock.(string)).Int64()) + } + + tostr, ok := obj[0].ToBlock.(string) + if !ok { + return NewDecodeParamError("ToBlock is not a string") + } + + switch tostr { + case "latest": + args.Latest = 0 + case "pending": + args.Latest = -1 + default: + args.Latest = int64(common.Big(obj[0].ToBlock.(string)).Int64()) + } + args.Max = int(common.Big(obj[0].Limit).Int64()) args.Skip = int(common.Big(obj[0].Offset).Int64()) args.Address = obj[0].Address diff --git a/rpc/args_test.go b/rpc/args_test.go index 47d79cc32..61b9dad25 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -74,6 +74,16 @@ func TestGetBlockByHashArgs(t *testing.T) { } } +func TestGetBlockByHashEmpty(t *testing.T) { + input := `[]` + + args := new(GetBlockByHashArgs) + err := json.Unmarshal([]byte(input), &args) + if err == nil { + t.Error("Expected error but didn't get one") + } +} + func TestGetBlockByNumberArgs(t *testing.T) { input := `["0x1b4", false]` expected := new(GetBlockByNumberArgs) @@ -94,6 +104,16 @@ func TestGetBlockByNumberArgs(t *testing.T) { } } +func TestGetBlockByNumberEmpty(t *testing.T) { + input := `[]` + + args := new(GetBlockByNumberArgs) + err := json.Unmarshal([]byte(input), &args) + if err == nil { + t.Error("Expected error but didn't get one") + } +} + func TestNewTxArgs(t *testing.T) { input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", @@ -139,6 +159,16 @@ func TestNewTxArgs(t *testing.T) { } } +func TestNewTxArgsEmpty(t *testing.T) { + input := `[]` + + args := new(NewTxArgs) + err := json.Unmarshal([]byte(input), &args) + if err == nil { + t.Error("Expected error but didn't get one") + } +} + func TestGetStorageArgs(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"]` expected := new(GetStorageArgs) @@ -163,6 +193,16 @@ func TestGetStorageArgs(t *testing.T) { } } +func TestGetStorageEmptyArgs(t *testing.T) { + input := `[]` + + args := new(GetStorageArgs) + err := json.Unmarshal([]byte(input), &args) + if err == nil { + t.Error("Expected error but didn't get one") + } +} + func TestGetStorageAtArgs(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x0", "0x2"]` expected := new(GetStorageAtArgs) @@ -192,6 +232,16 @@ func TestGetStorageAtArgs(t *testing.T) { } } +func TestGetStorageAtEmptyArgs(t *testing.T) { + input := `[]` + + args := new(GetStorageAtArgs) + err := json.Unmarshal([]byte(input), &args) + if err == nil { + t.Error("Expected error but didn't get one") + } +} + func TestGetTxCountArgs(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"]` expected := new(GetTxCountArgs) @@ -216,6 +266,16 @@ func TestGetTxCountArgs(t *testing.T) { } } +func TestGetTxCountEmptyArgs(t *testing.T) { + input := `[]` + + args := new(GetTxCountArgs) + err := json.Unmarshal([]byte(input), &args) + if err == nil { + t.Error("Expected error but didn't get one") + } +} + func TestGetDataArgs(t *testing.T) { input := `["0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", "latest"]` expected := new(GetDataArgs) @@ -240,6 +300,16 @@ func TestGetDataArgs(t *testing.T) { } } +func TestGetDataEmptyArgs(t *testing.T) { + input := `[]` + + args := new(GetDataArgs) + err := json.Unmarshal([]byte(input), &args) + if err == nil { + t.Error("Expected error but didn't get one") + } +} + func TestFilterOptions(t *testing.T) { input := `[{ "fromBlock": "0x1", @@ -286,6 +356,56 @@ func TestFilterOptions(t *testing.T) { // } } +func TestFilterOptionsWords(t *testing.T) { + input := `[{ + "fromBlock": "latest", + "toBlock": "pending" + }]` + expected := new(FilterOptions) + expected.Earliest = 0 + expected.Latest = -1 + + args := new(FilterOptions) + if err := json.Unmarshal([]byte(input), &args); err != nil { + t.Error(err) + } + + if expected.Earliest != args.Earliest { + t.Errorf("Earliest shoud be %#v but is %#v", expected.Earliest, args.Earliest) + } + + if expected.Latest != args.Latest { + t.Errorf("Latest shoud be %#v but is %#v", expected.Latest, args.Latest) + } +} + +func TestFilterOptionsNums(t *testing.T) { + input := `[{ + "fromBlock": 2, + "toBlock": 3 + }]` + + args := new(FilterOptions) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case *DecodeParamError: + break + default: + t.Errorf("Should have *DecodeParamError but instead have %T", err) + } + +} + +func TestFilterOptionsEmptyArgs(t *testing.T) { + input := `[]` + + args := new(FilterOptions) + err := json.Unmarshal([]byte(input), &args) + if err == nil { + t.Error("Expected error but didn't get one") + } +} + func TestDbArgs(t *testing.T) { input := `["0x74657374","0x6b6579","0x6d79537472696e67"]` expected := new(DbArgs) diff --git a/rpc/http.go b/rpc/http.go index 8dcd55ad1..b6edb7cd7 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -26,7 +26,7 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler { if req.ContentLength > maxSizeReqLength { 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 } @@ -36,11 +36,11 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler { break case *DecodeParamError, *InsufficientParamsError, *ValidationError: jsonerr := &RpcErrorObject{-32602, reqerr.Error()} - json.Send(w, &RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr}) + 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 } @@ -51,19 +51,19 @@ func JSONRPC(pipe *xeth.XEth, dataDir string) http.Handler { break case *NotImplementedError: jsonerr := &RpcErrorObject{-32601, 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 case *DecodeParamError, *InsufficientParamsError, *ValidationError: jsonerr := &RpcErrorObject{-32602, 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 default: 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 } rpchttplogger.DebugDetailf("Generated response: %T %s", response, response) - json.Send(w, &RpcSuccessResponse{JsonRpc: jsonrpcver, ID: reqParsed.ID, Result: response}) + json.Send(w, &RpcSuccessResponse{Jsonrpc: jsonrpcver, Id: reqParsed.Id, Result: response}) }) } diff --git a/rpc/jeth.go b/rpc/jeth.go new file mode 100644 index 000000000..11d4599c9 --- /dev/null +++ b/rpc/jeth.go @@ -0,0 +1,43 @@ +package rpc + +import ( + "encoding/json" + // "fmt" + "github.com/obscuren/otto" +) + +type Jeth struct { + ethApi *EthereumApi + toVal func(interface{}) otto.Value +} + +func NewJeth(ethApi *EthereumApi, toVal func(interface{}) otto.Value) *Jeth { + return &Jeth{ethApi, toVal} +} + +func (self *Jeth) err(code int, msg string, id interface{}) otto.Value { + rpcerr := &RpcErrorObject{code, msg} + rpcresponse := &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: id, Error: rpcerr} + return self.toVal(rpcresponse) +} + +func (self *Jeth) Send(call otto.FunctionCall) (response otto.Value) { + reqif, err := call.Argument(0).Export() + if err != nil { + return self.err(-32700, err.Error(), nil) + } + + jsonreq, err := json.Marshal(reqif) + + var req RpcRequest + err = json.Unmarshal(jsonreq, &req) + + var respif interface{} + err = self.ethApi.GetRequestReply(&req, &respif) + if err != nil { + return self.err(-32603, err.Error(), req.Id) + } + rpcresponse := &RpcSuccessResponse{Jsonrpc: jsonrpcver, Id: req.Id, Result: respif} + response = self.toVal(rpcresponse) + return +} diff --git a/rpc/messages.go b/rpc/messages.go index 781394196..7f5ebab11 100644 --- a/rpc/messages.go +++ b/rpc/messages.go @@ -83,21 +83,21 @@ func NewValidationError(param string, msg string) error { } type RpcRequest struct { - ID interface{} `json:"id"` - JsonRpc string `json:"jsonrpc"` + Id interface{} `json:"id"` + Jsonrpc string `json:"jsonrpc"` Method string `json:"method"` Params json.RawMessage `json:"params"` } type RpcSuccessResponse struct { - ID interface{} `json:"id"` - JsonRpc string `json:"jsonrpc"` + Id interface{} `json:"id"` + Jsonrpc string `json:"jsonrpc"` Result interface{} `json:"result"` } type RpcErrorResponse struct { - ID interface{} `json:"id"` - JsonRpc string `json:"jsonrpc"` + Id interface{} `json:"id"` + Jsonrpc string `json:"jsonrpc"` Error *RpcErrorObject `json:"error"` } diff --git a/rpc/util.go b/rpc/util.go index 6afefbf61..9de8311d6 100644 --- a/rpc/util.go +++ b/rpc/util.go @@ -45,6 +45,11 @@ func UnmarshalRawMessages(b []byte, iface interface{}, number *int64) (err error return NewDecodeParamError(err.Error()) } + // Hrm... Occurs when no params + if len(data) == 0 { + return NewDecodeParamError("No data") + } + // Number index determines the index in the array for a possible block number numberIndex := 0 |