From 5757f547a6339c770a6d85ad067107d34878858f Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Mon, 16 Mar 2015 10:38:57 -0400 Subject: [PATCH 1/6] Allow latest/pending in filter options --- rpc/args.go | 62 +++++++++++++++++------------------------------- rpc/args_test.go | 23 ++++++++++++++++++ 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 7ed482c301..9ec2ed8a49 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,26 @@ 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 { + if fromstr == "latest" { + args.Earliest = 0 + } else { + args.Earliest = int64(common.Big(obj[0].FromBlock.(string)).Int64()) + } + } + + tostr, ok := obj[0].ToBlock.(string) + if ok { + if tostr == "latest" { + args.Latest = 0 + } else if tostr == "pending" { + args.Latest = -1 + } else { + 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 47d79cc322..d6e4bee62c 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -286,6 +286,29 @@ 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 TestDbArgs(t *testing.T) { input := `["0x74657374","0x6b6579","0x6d79537472696e67"]` expected := new(DbArgs) From 03ac0f18ae8bcc9c2f843841b8fe322717616a21 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Mon, 16 Mar 2015 14:46:46 -0400 Subject: [PATCH 2/6] Initial support to remove Whisper identities per #491 --- rpc/api.go | 13 ++++++++++++- whisper/whisper.go | 9 +++++++++ xeth/whisper.go | 6 +++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 1846e7db5a..b2d04cee64 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -9,11 +9,11 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event/filter" "github.com/ethereum/go-ethereum/state" @@ -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/whisper/whisper.go b/whisper/whisper.go index 13209f9a6e..c80ba3c8ec 100644 --- a/whisper/whisper.go +++ b/whisper/whisper.go @@ -116,6 +116,15 @@ func (self *Whisper) GetIdentity(key *ecdsa.PublicKey) *ecdsa.PrivateKey { return self.keys[string(crypto.FromECDSAPub(key))] } +func (self *Whisper) RemoveIdentity(key *ecdsa.PublicKey) bool { + k := string(crypto.FromECDSAPub(key)) + if _, ok := self.keys[k]; ok { + delete(self.keys, k) + return true + } + return false +} + func (self *Whisper) Watch(opts Filter) int { return self.filters.Install(filter.Generic{ Str1: string(crypto.FromECDSAPub(opts.To)), diff --git a/xeth/whisper.go b/xeth/whisper.go index 76bf8012af..eb5fc789ca 100644 --- a/xeth/whisper.go +++ b/xeth/whisper.go @@ -4,8 +4,8 @@ import ( "errors" "time" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/whisper" ) @@ -63,6 +63,10 @@ func (self *Whisper) HasIdentity(key string) bool { return self.Whisper.HasIdentity(crypto.ToECDSAPub(common.FromHex(key))) } +func (self *Whisper) RemoveIdentity(key string) bool { + return self.Whisper.RemoveIdentity(crypto.ToECDSAPub(common.FromHex(key))) +} + func (self *Whisper) Watch(opts *Options) int { filter := whisper.Filter{ To: crypto.ToECDSAPub(common.FromHex(opts.To)), From 719effa7ecdef925a5a8fa61ac060e2ec5f0d612 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Mon, 16 Mar 2015 15:30:31 -0400 Subject: [PATCH 3/6] Return error when filter params are not strings --- rpc/args.go | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 9ec2ed8a49..fee44c4e09 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -359,23 +359,29 @@ func (args *FilterOptions) UnmarshalJSON(b []byte) (err error) { } fromstr, ok := obj[0].FromBlock.(string) - if ok { - if fromstr == "latest" { - args.Earliest = 0 - } else { - args.Earliest = int64(common.Big(obj[0].FromBlock.(string)).Int64()) - } + 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 { - if tostr == "latest" { - args.Latest = 0 - } else if tostr == "pending" { - args.Latest = -1 - } else { - args.Latest = int64(common.Big(obj[0].ToBlock.(string)).Int64()) - } + 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()) From 0339a138625aca8647e5d51488e6d679202cdddb Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Mon, 16 Mar 2015 16:21:51 -0400 Subject: [PATCH 4/6] RPC empty args tests --- rpc/args_test.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/rpc/args_test.go b/rpc/args_test.go index d6e4bee62c..bdf05cad14 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", @@ -309,6 +329,33 @@ func TestFilterOptionsWords(t *testing.T) { } } +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) From 176115e22ecc5e86179784ba5027c84e538423c4 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Mon, 16 Mar 2015 16:49:51 -0400 Subject: [PATCH 5/6] More empty param tests --- rpc/args_test.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ rpc/util.go | 5 +++++ 2 files changed, 55 insertions(+) diff --git a/rpc/args_test.go b/rpc/args_test.go index bdf05cad14..61b9dad25e 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -159,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) @@ -183,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) @@ -212,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) @@ -236,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) @@ -260,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", diff --git a/rpc/util.go b/rpc/util.go index 08f404c998..e5610dc2c2 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 From fe819f3b9f7a2d8d842c53b7269ccceace533569 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Tue, 17 Mar 2015 09:11:01 -0400 Subject: [PATCH 6/6] Comment out whisper remove identity stubs --- rpc/api.go | 20 ++++++++++---------- whisper/whisper.go | 16 ++++++++-------- xeth/whisper.go | 6 +++--- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index b2d04cee64..079347192e 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -371,10 +371,10 @@ 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) 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 @@ -756,12 +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_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/whisper/whisper.go b/whisper/whisper.go index c80ba3c8ec..908df973c0 100644 --- a/whisper/whisper.go +++ b/whisper/whisper.go @@ -116,14 +116,14 @@ func (self *Whisper) GetIdentity(key *ecdsa.PublicKey) *ecdsa.PrivateKey { return self.keys[string(crypto.FromECDSAPub(key))] } -func (self *Whisper) RemoveIdentity(key *ecdsa.PublicKey) bool { - k := string(crypto.FromECDSAPub(key)) - if _, ok := self.keys[k]; ok { - delete(self.keys, k) - return true - } - return false -} +// func (self *Whisper) RemoveIdentity(key *ecdsa.PublicKey) bool { +// k := string(crypto.FromECDSAPub(key)) +// if _, ok := self.keys[k]; ok { +// delete(self.keys, k) +// return true +// } +// return false +// } func (self *Whisper) Watch(opts Filter) int { return self.filters.Install(filter.Generic{ diff --git a/xeth/whisper.go b/xeth/whisper.go index eb5fc789ca..c0be4c392c 100644 --- a/xeth/whisper.go +++ b/xeth/whisper.go @@ -63,9 +63,9 @@ func (self *Whisper) HasIdentity(key string) bool { return self.Whisper.HasIdentity(crypto.ToECDSAPub(common.FromHex(key))) } -func (self *Whisper) RemoveIdentity(key string) bool { - return self.Whisper.RemoveIdentity(crypto.ToECDSAPub(common.FromHex(key))) -} +// func (self *Whisper) RemoveIdentity(key string) bool { +// return self.Whisper.RemoveIdentity(crypto.ToECDSAPub(common.FromHex(key))) +// } func (self *Whisper) Watch(opts *Options) int { filter := whisper.Filter{