From 5757f547a6339c770a6d85ad067107d34878858f Mon Sep 17 00:00:00 2001
From: Taylor Gerring <taylor.gerring@gmail.com>
Date: Mon, 16 Mar 2015 10:38:57 -0400
Subject: 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 7ed482c30..9ec2ed8a4 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 47d79cc32..d6e4bee62 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)
-- 
cgit v1.2.3


From 03ac0f18ae8bcc9c2f843841b8fe322717616a21 Mon Sep 17 00:00:00 2001
From: Taylor Gerring <taylor.gerring@gmail.com>
Date: Mon, 16 Mar 2015 14:46:46 -0400
Subject: 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 1846e7db5..b2d04cee6 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 13209f9a6..c80ba3c8e 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 76bf8012a..eb5fc789c 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)),
-- 
cgit v1.2.3


From 719effa7ecdef925a5a8fa61ac060e2ec5f0d612 Mon Sep 17 00:00:00 2001
From: Taylor Gerring <taylor.gerring@gmail.com>
Date: Mon, 16 Mar 2015 15:30:31 -0400
Subject: 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 9ec2ed8a4..fee44c4e0 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())
-- 
cgit v1.2.3


From 0339a138625aca8647e5d51488e6d679202cdddb Mon Sep 17 00:00:00 2001
From: Taylor Gerring <taylor.gerring@gmail.com>
Date: Mon, 16 Mar 2015 16:21:51 -0400
Subject: 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 d6e4bee62..bdf05cad1 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)
-- 
cgit v1.2.3


From 176115e22ecc5e86179784ba5027c84e538423c4 Mon Sep 17 00:00:00 2001
From: Taylor Gerring <taylor.gerring@gmail.com>
Date: Mon, 16 Mar 2015 16:49:51 -0400
Subject: 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 bdf05cad1..61b9dad25 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 08f404c99..e5610dc2c 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
 
-- 
cgit v1.2.3


From fe819f3b9f7a2d8d842c53b7269ccceace533569 Mon Sep 17 00:00:00 2001
From: Taylor Gerring <taylor.gerring@gmail.com>
Date: Tue, 17 Mar 2015 09:11:01 -0400
Subject: 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 b2d04cee6..079347192 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 c80ba3c8e..908df973c 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 eb5fc789c..c0be4c392 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{
-- 
cgit v1.2.3