From 2b9b9e77040bd35e6c5eb1d1eaeeef7abb1d93c1 Mon Sep 17 00:00:00 2001
From: Taylor Gerring <taylor.gerring@gmail.com>
Date: Sat, 4 Apr 2015 13:25:47 +0200
Subject: Allow "earliest" block height

---
 rpc/args.go | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/rpc/args.go b/rpc/args.go
index cebabf4ba..5b1c271cc 100644
--- a/rpc/args.go
+++ b/rpc/args.go
@@ -36,6 +36,8 @@ func blockHeight(raw interface{}, number *int64) error {
 	}
 
 	switch str {
+	case "earliest":
+		*number = 0
 	case "latest":
 		*number = -1
 	case "pending":
-- 
cgit v1.2.3


From 71e62eb62026899955e9466cbc2d0c79ee8cd7a2 Mon Sep 17 00:00:00 2001
From: Taylor Gerring <taylor.gerring@gmail.com>
Date: Sat, 4 Apr 2015 14:08:35 +0200
Subject: More test coverage for responses

---
 rpc/responses_test.go | 145 ++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 111 insertions(+), 34 deletions(-)

diff --git a/rpc/responses_test.go b/rpc/responses_test.go
index 2ec6d9d15..ab80f8274 100644
--- a/rpc/responses_test.go
+++ b/rpc/responses_test.go
@@ -26,13 +26,6 @@ const (
 )
 
 func TestNewBlockRes(t *testing.T) {
-	parentHash := common.HexToHash("0x01")
-	coinbase := common.HexToAddress("0x01")
-	root := common.HexToHash("0x01")
-	difficulty := common.Big1
-	nonce := uint64(1)
-	extra := ""
-	block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, extra)
 	tests := map[string]string{
 		"number":           reNum,
 		"hash":             reHash,
@@ -55,16 +48,8 @@ func TestNewBlockRes(t *testing.T) {
 		// "uncles":       reListHash,
 	}
 
-	to := common.HexToAddress("0x02")
-	amount := big.NewInt(1)
-	gasAmount := big.NewInt(1)
-	gasPrice := big.NewInt(1)
-	data := []byte{1, 2, 3}
-	tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data)
-
+	block := makeBlock()
 	v := NewBlockRes(block, false)
-	v.Transactions = make([]*TransactionRes, 1)
-	v.Transactions[0] = NewTransactionRes(tx)
 	j, _ := json.Marshal(v)
 
 	for k, re := range tests {
@@ -75,14 +60,7 @@ func TestNewBlockRes(t *testing.T) {
 	}
 }
 
-func TestNewBlockResWithTrans(t *testing.T) {
-	parentHash := common.HexToHash("0x01")
-	coinbase := common.HexToAddress("0x01")
-	root := common.HexToHash("0x01")
-	difficulty := common.Big1
-	nonce := uint64(1)
-	extra := ""
-	block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, extra)
+func TestNewBlockResTxFull(t *testing.T) {
 	tests := map[string]string{
 		"number":           reNum,
 		"hash":             reHash,
@@ -101,20 +79,12 @@ func TestNewBlockResWithTrans(t *testing.T) {
 		// "minGasPrice":  "0x",
 		"gasUsed":   reNum,
 		"timestamp": reNum,
-		// "transactions": `[{.*}]`,
+		// "transactions": reListHash,
 		// "uncles":       reListHash,
 	}
 
-	to := common.HexToAddress("0x02")
-	amount := big.NewInt(1)
-	gasAmount := big.NewInt(1)
-	gasPrice := big.NewInt(1)
-	data := []byte{1, 2, 3}
-	tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data)
-
+	block := makeBlock()
 	v := NewBlockRes(block, true)
-	v.Transactions = make([]*TransactionRes, 1)
-	v.Transactions[0] = NewTransactionRes(tx)
 	j, _ := json.Marshal(v)
 
 	for k, re := range tests {
@@ -125,6 +95,16 @@ func TestNewBlockResWithTrans(t *testing.T) {
 	}
 }
 
+func TestBlockNil(t *testing.T) {
+	var block *types.Block
+	block = nil
+	u := NewBlockRes(block, false)
+	j, _ := json.Marshal(u)
+	if string(j) != "null" {
+		t.Errorf("Expected null but got %v", string(j))
+	}
+}
+
 func TestNewTransactionRes(t *testing.T) {
 	to := common.HexToAddress("0x02")
 	amount := big.NewInt(1)
@@ -161,6 +141,55 @@ func TestNewTransactionRes(t *testing.T) {
 
 }
 
+func TestTransactionNil(t *testing.T) {
+	var tx *types.Transaction
+	tx = nil
+	u := NewTransactionRes(tx)
+	j, _ := json.Marshal(u)
+	if string(j) != "null" {
+		t.Errorf("Expected null but got %v", string(j))
+	}
+}
+
+func TestNewUncleRes(t *testing.T) {
+	header := makeHeader()
+	u := NewUncleRes(header)
+	tests := map[string]string{
+		"number":           reNum,
+		"hash":             reHash,
+		"parentHash":       reHash,
+		"nonce":            reData,
+		"sha3Uncles":       reHash,
+		"receiptHash":      reHash,
+		"transactionsRoot": reHash,
+		"stateRoot":        reHash,
+		"miner":            reAddress,
+		"difficulty":       reNum,
+		"extraData":        reData,
+		"gasLimit":         reNum,
+		"gasUsed":          reNum,
+		"timestamp":        reNum,
+	}
+
+	j, _ := json.Marshal(u)
+	for k, re := range tests {
+		match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j))
+		if !match {
+			t.Error(fmt.Sprintf("`%s` output json does not match format %s. Source %s", k, re, j))
+		}
+	}
+}
+
+func TestUncleNil(t *testing.T) {
+	var header *types.Header
+	header = nil
+	u := NewUncleRes(header)
+	j, _ := json.Marshal(u)
+	if string(j) != "null" {
+		t.Errorf("Expected null but got %v", string(j))
+	}
+}
+
 func TestNewLogRes(t *testing.T) {
 	log := makeStateLog(0)
 	tests := map[string]string{
@@ -217,3 +246,51 @@ func makeStateLog(num int) state.Log {
 	log := state.NewLog(address, topics, data, number)
 	return log
 }
+
+func makeHeader() *types.Header {
+	header := &types.Header{
+		ParentHash:  common.StringToHash("0x00"),
+		UncleHash:   common.StringToHash("0x00"),
+		Coinbase:    common.StringToAddress("0x00"),
+		Root:        common.StringToHash("0x00"),
+		TxHash:      common.StringToHash("0x00"),
+		ReceiptHash: common.StringToHash("0x00"),
+		// Bloom:
+		Difficulty: big.NewInt(88888888),
+		Number:     big.NewInt(16),
+		GasLimit:   big.NewInt(70000),
+		GasUsed:    big.NewInt(25000),
+		Time:       124356789,
+		Extra:      "",
+		MixDigest:  common.StringToHash("0x00"),
+		Nonce:      [8]byte{0, 1, 2, 3, 4, 5, 6, 7},
+	}
+	return header
+}
+
+func makeBlock() *types.Block {
+	parentHash := common.HexToHash("0x01")
+	coinbase := common.HexToAddress("0x01")
+	root := common.HexToHash("0x01")
+	difficulty := common.Big1
+	nonce := uint64(1)
+	extra := ""
+	block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, extra)
+
+	txto := common.HexToAddress("0x02")
+	txamount := big.NewInt(1)
+	txgasAmount := big.NewInt(1)
+	txgasPrice := big.NewInt(1)
+	txdata := []byte{1, 2, 3}
+
+	tx := types.NewTransactionMessage(txto, txamount, txgasAmount, txgasPrice, txdata)
+	txs := make([]*types.Transaction, 1)
+	txs[0] = tx
+	block.SetTransactions(txs)
+
+	uncles := make([]*types.Header, 1)
+	uncles[0] = makeHeader()
+	block.SetUncles(uncles)
+
+	return block
+}
-- 
cgit v1.2.3


From 435378e953212813ec90b639d8d22b1d602447ea Mon Sep 17 00:00:00 2001
From: Taylor Gerring <taylor.gerring@gmail.com>
Date: Sat, 4 Apr 2015 15:09:30 +0200
Subject: Improved test coverage for rpc types

---
 rpc/types.go      |  18 ++-----
 rpc/types_test.go | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 158 insertions(+), 14 deletions(-)

diff --git a/rpc/types.go b/rpc/types.go
index 806c9c8a4..bc9a46ed5 100644
--- a/rpc/types.go
+++ b/rpc/types.go
@@ -43,16 +43,11 @@ func (d *hexdata) MarshalJSON() ([]byte, error) {
 	return json.Marshal(d.String())
 }
 
-func (d *hexdata) UnmarshalJSON(b []byte) (err error) {
-	d.data = common.FromHex(string(b))
-	return nil
-}
-
 func newHexData(input interface{}) *hexdata {
 	d := new(hexdata)
 
 	if input == nil {
-		d.data = nil
+		d.isNil = true
 		return d
 	}
 	switch input := input.(type) {
@@ -105,19 +100,19 @@ func newHexData(input interface{}) *hexdata {
 	case int16:
 		d.data = big.NewInt(int64(input)).Bytes()
 	case uint16:
-		buff := make([]byte, 8)
+		buff := make([]byte, 2)
 		binary.BigEndian.PutUint16(buff, input)
 		d.data = buff
 	case int32:
 		d.data = big.NewInt(int64(input)).Bytes()
 	case uint32:
-		buff := make([]byte, 8)
+		buff := make([]byte, 4)
 		binary.BigEndian.PutUint32(buff, input)
 		d.data = buff
 	case string: // hexstring
 		d.data = common.Big(input).Bytes()
 	default:
-		d.data = nil
+		d.isNil = true
 	}
 
 	return d
@@ -147,11 +142,6 @@ func (d *hexnum) MarshalJSON() ([]byte, error) {
 	return json.Marshal(d.String())
 }
 
-func (d *hexnum) UnmarshalJSON(b []byte) (err error) {
-	d.data = common.FromHex(string(b))
-	return nil
-}
-
 func newHexNum(input interface{}) *hexnum {
 	d := new(hexnum)
 
diff --git a/rpc/types_test.go b/rpc/types_test.go
index 91f0152dc..9ef7b8d38 100644
--- a/rpc/types_test.go
+++ b/rpc/types_test.go
@@ -1,7 +1,13 @@
 package rpc
 
 import (
+	"bytes"
+	"encoding/json"
+	"math/big"
 	"testing"
+
+	"github.com/ethereum/go-ethereum/common"
+	"github.com/ethereum/go-ethereum/core/types"
 )
 
 func TestInvalidTypeError(t *testing.T) {
@@ -48,3 +54,151 @@ func TestValidationError(t *testing.T) {
 		t.Error(err.Error())
 	}
 }
+
+func TestHexdataMarshalNil(t *testing.T) {
+	hd := newHexData([]byte{})
+	hd.isNil = true
+	v, _ := json.Marshal(hd)
+	if string(v) != "null" {
+		t.Errorf("Expected null, got %s", v)
+	}
+}
+
+func TestHexnumMarshalNil(t *testing.T) {
+	hn := newHexNum([]byte{})
+	hn.isNil = true
+	v, _ := json.Marshal(hn)
+	if string(v) != "null" {
+		t.Errorf("Expected null, got %s", v)
+	}
+}
+
+func TestHexdataNil(t *testing.T) {
+	v := newHexData(nil)
+	if v.isNil != true {
+		t.Errorf("Expected isNil to be true, but is %v", v.isNil)
+	}
+}
+
+func TestHexdataPtrHash(t *testing.T) {
+	in := common.Hash{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}
+	v := newHexData(&in)
+	if bytes.Compare(in.Bytes(), v.data) != 0 {
+		t.Errorf("Got % x expected % x", in, v.data)
+	}
+}
+
+func TestHexdataPtrHashNil(t *testing.T) {
+	var in *common.Hash
+	in = nil
+	v := newHexData(in)
+	if !v.isNil {
+		t.Errorf("Expect isNil to be true, but is %v", v.isNil)
+	}
+}
+
+func TestHexdataPtrAddress(t *testing.T) {
+	in := common.Address{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
+	v := newHexData(&in)
+	if bytes.Compare(in.Bytes(), v.data) != 0 {
+		t.Errorf("Got % x expected % x", in, v.data)
+	}
+}
+
+func TestHexdataPtrAddressNil(t *testing.T) {
+	var in *common.Address
+	in = nil
+	v := newHexData(in)
+	if !v.isNil {
+		t.Errorf("Expect isNil to be true, but is %v", v.isNil)
+	}
+}
+
+func TestHexdataPtrBloom(t *testing.T) {
+	in := types.Bloom{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
+	v := newHexData(&in)
+	if bytes.Compare(in.Bytes(), v.data) != 0 {
+		t.Errorf("Got % x expected % x", in, v.data)
+	}
+}
+
+func TestHexdataPtrBloomNil(t *testing.T) {
+	var in *types.Bloom
+	in = nil
+	v := newHexData(in)
+	if !v.isNil {
+		t.Errorf("Expect isNil to be true, but is %v", v.isNil)
+	}
+}
+
+func TestHexdataBigintNil(t *testing.T) {
+	var in *big.Int
+	in = nil
+	v := newHexData(in)
+	if !v.isNil {
+		t.Errorf("Expect isNil to be true, but is %v", v.isNil)
+	}
+}
+
+func TestHexdataUint(t *testing.T) {
+	var in = uint(16)
+	var expected = []byte{0x10}
+	v := newHexData(in)
+	if bytes.Compare(expected, v.data) != 0 {
+		t.Errorf("Expected % x got % x", expected, v.data)
+	}
+}
+
+func TestHexdataInt8(t *testing.T) {
+	var in = int8(16)
+	var expected = []byte{0x10}
+	v := newHexData(in)
+	if bytes.Compare(expected, v.data) != 0 {
+		t.Errorf("Expected % x got % x", expected, v.data)
+	}
+}
+
+func TestHexdataUint8(t *testing.T) {
+	var in = uint8(16)
+	var expected = []byte{0x10}
+	v := newHexData(in)
+	if bytes.Compare(expected, v.data) != 0 {
+		t.Errorf("Expected % x got % x", expected, v.data)
+	}
+}
+
+func TestHexdataInt16(t *testing.T) {
+	var in = int16(16)
+	var expected = []byte{0x10}
+	v := newHexData(in)
+	if bytes.Compare(expected, v.data) != 0 {
+		t.Errorf("Expected % x got % x", expected, v.data)
+	}
+}
+
+func TestHexdataUint16(t *testing.T) {
+	var in = uint16(16)
+	var expected = []byte{0x0, 0x10}
+	v := newHexData(in)
+	if bytes.Compare(expected, v.data) != 0 {
+		t.Errorf("Expected % x got % x", expected, v.data)
+	}
+}
+
+func TestHexdataInt32(t *testing.T) {
+	var in = int32(16)
+	var expected = []byte{0x10}
+	v := newHexData(in)
+	if bytes.Compare(expected, v.data) != 0 {
+		t.Errorf("Expected % x got % x", expected, v.data)
+	}
+}
+
+func TestHexdataUint32(t *testing.T) {
+	var in = uint32(16)
+	var expected = []byte{0x0, 0x0, 0x0, 0x10}
+	v := newHexData(in)
+	if bytes.Compare(expected, v.data) != 0 {
+		t.Errorf("Expected % x got % x", expected, v.data)
+	}
+}
-- 
cgit v1.2.3


From 5c988c8ea0be0c100f315f15a91d86e28f22125b Mon Sep 17 00:00:00 2001
From: Taylor Gerring <taylor.gerring@gmail.com>
Date: Sat, 4 Apr 2015 11:58:23 -0500
Subject: Increased test coverage for args

---
 rpc/args_test.go | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 214 insertions(+)

diff --git a/rpc/args_test.go b/rpc/args_test.go
index b88bab280..050f8e472 100644
--- a/rpc/args_test.go
+++ b/rpc/args_test.go
@@ -8,6 +8,61 @@ import (
 	"testing"
 )
 
+func TestBlockheightInvalidString(t *testing.T) {
+	v := "foo"
+	var num int64
+
+	str := ExpectInvalidTypeError(blockHeight(v, &num))
+	if len(str) > 0 {
+		t.Error(str)
+	}
+}
+
+func TestBlockheightEarliest(t *testing.T) {
+	v := "earliest"
+	e := int64(0)
+	var num int64
+
+	err := blockHeight(v, &num)
+	if err != nil {
+		t.Error(err)
+	}
+
+	if num != e {
+		t.Errorf("Expected %s but got %s", e, num)
+	}
+}
+
+func TestBlockheightLatest(t *testing.T) {
+	v := "latest"
+	e := int64(-1)
+	var num int64
+
+	err := blockHeight(v, &num)
+	if err != nil {
+		t.Error(err)
+	}
+
+	if num != e {
+		t.Errorf("Expected %s but got %s", e, num)
+	}
+}
+
+func TestBlockheightPending(t *testing.T) {
+	v := "pending"
+	e := int64(-2)
+	var num int64
+
+	err := blockHeight(v, &num)
+	if err != nil {
+		t.Error(err)
+	}
+
+	if num != e {
+		t.Errorf("Expected %s but got %s", e, num)
+	}
+}
+
 func ExpectValidationError(err error) string {
 	var str string
 	switch err.(type) {
@@ -121,6 +176,26 @@ func TestGetBalanceArgs(t *testing.T) {
 	}
 }
 
+func TestGetBalanceArgsBlocknumMissing(t *testing.T) {
+	input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1"]`
+	expected := new(GetBalanceArgs)
+	expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1"
+	expected.BlockNumber = -1
+
+	args := new(GetBalanceArgs)
+	if err := json.Unmarshal([]byte(input), &args); err != nil {
+		t.Error(err)
+	}
+
+	if args.Address != expected.Address {
+		t.Errorf("Address should be %v but is %v", expected.Address, args.Address)
+	}
+
+	if args.BlockNumber != expected.BlockNumber {
+		t.Errorf("BlockNumber should be %v but is %v", expected.BlockNumber, args.BlockNumber)
+	}
+}
+
 func TestGetBalanceArgsLatest(t *testing.T) {
 	input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"]`
 	expected := new(GetBalanceArgs)
@@ -231,6 +306,16 @@ func TestGetBlockByHashArgsHashInt(t *testing.T) {
 	}
 }
 
+func TestGetBlockByHashArgsHashBool(t *testing.T) {
+	input := `[false, true]`
+
+	args := new(GetBlockByHashArgs)
+	str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args))
+	if len(str) > 0 {
+		t.Error(str)
+	}
+}
+
 func TestGetBlockByNumberArgsBlockNum(t *testing.T) {
 	input := `[436, false]`
 	expected := new(GetBlockByNumberArgs)
@@ -850,6 +935,26 @@ func TestGetStorageArgs(t *testing.T) {
 	}
 }
 
+func TestGetStorageArgsMissingBlocknum(t *testing.T) {
+	input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1"]`
+	expected := new(GetStorageArgs)
+	expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1"
+	expected.BlockNumber = -1
+
+	args := new(GetStorageArgs)
+	if err := json.Unmarshal([]byte(input), &args); err != nil {
+		t.Error(err)
+	}
+
+	if expected.Address != args.Address {
+		t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address)
+	}
+
+	if expected.BlockNumber != args.BlockNumber {
+		t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber)
+	}
+}
+
 func TestGetStorageInvalidArgs(t *testing.T) {
 	input := `{}`
 
@@ -915,6 +1020,31 @@ func TestGetStorageAtArgs(t *testing.T) {
 	}
 }
 
+func TestGetStorageAtArgsMissingBlocknum(t *testing.T) {
+	input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x0"]`
+	expected := new(GetStorageAtArgs)
+	expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1"
+	expected.Key = "0x0"
+	expected.BlockNumber = -1
+
+	args := new(GetStorageAtArgs)
+	if err := json.Unmarshal([]byte(input), &args); err != nil {
+		t.Error(err)
+	}
+
+	if expected.Address != args.Address {
+		t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address)
+	}
+
+	if expected.Key != args.Key {
+		t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address)
+	}
+
+	if expected.BlockNumber != args.BlockNumber {
+		t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber)
+	}
+}
+
 func TestGetStorageAtEmptyArgs(t *testing.T) {
 	input := `[]`
 
@@ -1015,6 +1145,26 @@ func TestGetTxCountAddressNotString(t *testing.T) {
 	}
 }
 
+func TestGetTxCountBlockheightMissing(t *testing.T) {
+	input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1"]`
+	expected := new(GetTxCountArgs)
+	expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1"
+	expected.BlockNumber = -1
+
+	args := new(GetTxCountArgs)
+	if err := json.Unmarshal([]byte(input), &args); err != nil {
+		t.Error(err)
+	}
+
+	if expected.Address != args.Address {
+		t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address)
+	}
+
+	if expected.BlockNumber != args.BlockNumber {
+		t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber)
+	}
+}
+
 func TestGetTxCountBlockheightInvalid(t *testing.T) {
 	input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", {}]`
 
@@ -1045,6 +1195,26 @@ func TestGetDataArgs(t *testing.T) {
 	}
 }
 
+func TestGetDataArgsBlocknumMissing(t *testing.T) {
+	input := `["0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"]`
+	expected := new(GetDataArgs)
+	expected.Address = "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"
+	expected.BlockNumber = -1
+
+	args := new(GetDataArgs)
+	if err := json.Unmarshal([]byte(input), &args); err != nil {
+		t.Error(err)
+	}
+
+	if expected.Address != args.Address {
+		t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address)
+	}
+
+	if expected.BlockNumber != args.BlockNumber {
+		t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber)
+	}
+}
+
 func TestGetDataArgsEmpty(t *testing.T) {
 	input := `[]`
 
@@ -1995,6 +2165,50 @@ func TestWhisperIdentityArgsInt(t *testing.T) {
 	}
 }
 
+func TestBlockNumArgs(t *testing.T) {
+	input := `["0x29a"]`
+	expected := new(BlockNumIndexArgs)
+	expected.BlockNumber = 666
+
+	args := new(BlockNumArg)
+	if err := json.Unmarshal([]byte(input), &args); err != nil {
+		t.Error(err)
+	}
+
+	if expected.BlockNumber != args.BlockNumber {
+		t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber)
+	}
+}
+
+func TestBlockNumArgsInvalid(t *testing.T) {
+	input := `{}`
+
+	args := new(BlockNumArg)
+	str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args))
+	if len(str) > 0 {
+		t.Error(str)
+	}
+}
+
+func TestBlockNumArgsEmpty(t *testing.T) {
+	input := `[]`
+
+	args := new(BlockNumArg)
+	str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args))
+	if len(str) > 0 {
+		t.Error(str)
+	}
+}
+func TestBlockNumArgsBool(t *testing.T) {
+	input := `[true]`
+
+	args := new(BlockNumArg)
+	str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args))
+	if len(str) > 0 {
+		t.Error(str)
+	}
+}
+
 func TestBlockNumIndexArgs(t *testing.T) {
 	input := `["0x29a", "0x0"]`
 	expected := new(BlockNumIndexArgs)
-- 
cgit v1.2.3


From 1aaeae292db02aec1b16cf313fdcc874deac9603 Mon Sep 17 00:00:00 2001
From: Taylor Gerring <taylor.gerring@gmail.com>
Date: Tue, 7 Apr 2015 06:10:00 -0500
Subject: Output format and nil fixes

---
 rpc/api.go | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/rpc/api.go b/rpc/api.go
index 30ba1ddc1..91142e387 100644
--- a/rpc/api.go
+++ b/rpc/api.go
@@ -53,28 +53,21 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
 	case "net_listening":
 		*reply = api.xeth().IsListening()
 	case "net_peerCount":
-		v := api.xeth().PeerCount()
-		*reply = common.ToHex(big.NewInt(int64(v)).Bytes())
+		*reply = newHexNum(api.xeth().PeerCount())
 	case "eth_protocolVersion":
 		*reply = api.xeth().EthVersion()
 	case "eth_coinbase":
-		// TODO handling of empty coinbase due to lack of accounts
-		res := api.xeth().Coinbase()
-		if res == "0x" || res == "0x0" {
-			*reply = nil
-		} else {
-			*reply = res
-		}
+		*reply = newHexData(api.xeth().Coinbase())
 	case "eth_mining":
 		*reply = api.xeth().IsMining()
 	case "eth_gasPrice":
 		v := xeth.DefaultGas()
-		*reply = common.ToHex(v.Bytes())
+		*reply = newHexData(v.Bytes())
 	case "eth_accounts":
 		*reply = api.xeth().Accounts()
 	case "eth_blockNumber":
 		v := api.xeth().CurrentBlock().Number()
-		*reply = common.ToHex(v.Bytes())
+		*reply = newHexNum(v.Bytes())
 	case "eth_getBalance":
 		args := new(GetBalanceArgs)
 		if err := json.Unmarshal(req.Params, &args); err != nil {
@@ -125,6 +118,11 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
 		}
 
 		block := NewBlockRes(api.xeth().EthBlockByNumber(args.BlockNumber), false)
+		if block == nil {
+			*reply = nil
+			break
+		}
+
 		*reply = common.ToHex(big.NewInt(int64(len(block.Transactions))).Bytes())
 	case "eth_getUncleCountByBlockHash":
 		args := new(HashArgs)
@@ -134,6 +132,11 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
 
 		block := api.xeth().EthBlockByHash(args.Hash)
 		br := NewBlockRes(block, false)
+		if br == nil {
+			*reply = nil
+			break
+		}
+
 		*reply = common.ToHex(big.NewInt(int64(len(br.Uncles))).Bytes())
 	case "eth_getUncleCountByBlockNumber":
 		args := new(BlockNumArg)
@@ -143,6 +146,11 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
 
 		block := api.xeth().EthBlockByNumber(args.BlockNumber)
 		br := NewBlockRes(block, false)
+		if br == nil {
+			*reply = nil
+			break
+		}
+
 		*reply = common.ToHex(big.NewInt(int64(len(br.Uncles))).Bytes())
 	case "eth_getData", "eth_getCode":
 		args := new(GetDataArgs)
@@ -219,6 +227,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
 		br := NewBlockRes(block, true)
 		if br == nil {
 			*reply = nil
+			break
 		}
 
 		if args.Index >= int64(len(br.Transactions)) || args.Index < 0 {
@@ -237,6 +246,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
 		v := NewBlockRes(block, true)
 		if v == nil {
 			*reply = nil
+			break
 		}
 
 		if args.Index >= int64(len(v.Transactions)) || args.Index < 0 {
-- 
cgit v1.2.3


From d0c3f127eee44274f72377085535d4c25e8b0f55 Mon Sep 17 00:00:00 2001
From: Taylor Gerring <taylor.gerring@gmail.com>
Date: Tue, 7 Apr 2015 06:49:31 -0500
Subject: More type fixes

---
 rpc/api.go | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/rpc/api.go b/rpc/api.go
index 91142e387..6e2ae2e93 100644
--- a/rpc/api.go
+++ b/rpc/api.go
@@ -98,7 +98,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
 		}
 
 		count := api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address)
-		*reply = common.ToHex(big.NewInt(int64(count)).Bytes())
+		*reply = newHexNum(big.NewInt(int64(count)).Bytes())
 	case "eth_getBlockTransactionCountByHash":
 		args := new(HashArgs)
 		if err := json.Unmarshal(req.Params, &args); err != nil {
@@ -109,7 +109,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
 		if block == nil {
 			*reply = nil
 		} else {
-			*reply = common.ToHex(big.NewInt(int64(len(block.Transactions))).Bytes())
+			*reply = newHexNum(big.NewInt(int64(len(block.Transactions))).Bytes())
 		}
 	case "eth_getBlockTransactionCountByNumber":
 		args := new(BlockNumArg)
@@ -123,7 +123,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
 			break
 		}
 
-		*reply = common.ToHex(big.NewInt(int64(len(block.Transactions))).Bytes())
+		*reply = newHexNum(big.NewInt(int64(len(block.Transactions))).Bytes())
 	case "eth_getUncleCountByBlockHash":
 		args := new(HashArgs)
 		if err := json.Unmarshal(req.Params, &args); err != nil {
@@ -137,7 +137,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
 			break
 		}
 
-		*reply = common.ToHex(big.NewInt(int64(len(br.Uncles))).Bytes())
+		*reply = newHexNum(big.NewInt(int64(len(br.Uncles))).Bytes())
 	case "eth_getUncleCountByBlockNumber":
 		args := new(BlockNumArg)
 		if err := json.Unmarshal(req.Params, &args); err != nil {
@@ -151,7 +151,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
 			break
 		}
 
-		*reply = common.ToHex(big.NewInt(int64(len(br.Uncles))).Bytes())
+		*reply = newHexNum(big.NewInt(int64(len(br.Uncles))).Bytes())
 	case "eth_getData", "eth_getCode":
 		args := new(GetDataArgs)
 		if err := json.Unmarshal(req.Params, &args); err != nil {
@@ -305,14 +305,13 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
 		}
 
 		id := api.xeth().RegisterFilter(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics)
-		*reply = common.ToHex(big.NewInt(int64(id)).Bytes())
+		*reply = newHexNum(big.NewInt(int64(id)).Bytes())
 	case "eth_newBlockFilter":
 		args := new(FilterStringArgs)
 		if err := json.Unmarshal(req.Params, &args); err != nil {
 			return err
 		}
-		id := api.xeth().NewFilterString(args.Word)
-		*reply = common.ToHex(big.NewInt(int64(id)).Bytes())
+		*reply = newHexNum(api.xeth().NewFilterString(args.Word))
 	case "eth_uninstallFilter":
 		args := new(FilterIdArgs)
 		if err := json.Unmarshal(req.Params, &args); err != nil {
@@ -394,7 +393,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
 		}
 
 		res, _ := api.xeth().DbGet([]byte(args.Database + args.Key))
-		*reply = common.ToHex(res)
+		*reply = newHexData(res)
 	case "shh_version":
 		*reply = api.xeth().WhisperVersion()
 	case "shh_post":
@@ -435,7 +434,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
 		opts.To = args.To
 		opts.Topics = args.Topics
 		id := api.xeth().NewWhisperFilter(opts)
-		*reply = common.ToHex(big.NewInt(int64(id)).Bytes())
+		*reply = newHexNum(big.NewInt(int64(id)).Bytes())
 	case "shh_uninstallFilter":
 		args := new(FilterIdArgs)
 		if err := json.Unmarshal(req.Params, &args); err != nil {
-- 
cgit v1.2.3