From c7dc379da5a02fb8ac92788fa317379fbde00d20 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 10:14:52 +0100 Subject: [PATCH 01/37] GetBlockByHashArgs --- rpc/api.go | 8 ++++---- rpc/args.go | 4 ++-- rpc/args_test.go | 2 +- xeth/xeth.go | 7 +++++-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index aa5b54199..8d1a412d1 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -245,7 +245,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - block := api.xeth().EthBlockByHash(args.Hash) + block := api.xeth().EthBlockByHexstring(args.Hash) br := NewBlockRes(block) br.fullTx = true @@ -273,14 +273,14 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - br := NewBlockRes(api.xeth().EthBlockByHash(args.Hash)) + br := NewBlockRes(api.xeth().EthBlockByHexstring(args.Hash)) if args.Index > int64(len(br.Uncles)) || args.Index < 0 { return NewValidationError("Index", "does not exist") } uhash := br.Uncles[args.Index].Hex() - uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash)) + uncle := NewBlockRes(api.xeth().EthBlockByHexstring(uhash)) *reply = uncle case "eth_getUncleByBlockNumberAndIndex": @@ -298,7 +298,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err } uhash := v.Uncles[args.Index].Hex() - uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash)) + uncle := NewBlockRes(api.xeth().EthBlockByHexstring(uhash)) *reply = uncle case "eth_getCompilers": diff --git a/rpc/args.go b/rpc/args.go index 5b655024c..9a51959f4 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -35,7 +35,7 @@ func blockHeight(raw interface{}, number *int64) (err error) { } type GetBlockByHashArgs struct { - BlockHash string + BlockHash common.Hash IncludeTxs bool } @@ -54,7 +54,7 @@ func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) { if !ok { return NewDecodeParamError("BlockHash not a string") } - args.BlockHash = argstr + args.BlockHash = common.HexToHash(argstr) if len(obj) > 1 { args.IncludeTxs = obj[1].(bool) diff --git a/rpc/args_test.go b/rpc/args_test.go index 5cbafd4b2..c6d3a558b 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -83,7 +83,7 @@ func TestGetBalanceEmptyArgs(t *testing.T) { func TestGetBlockByHashArgs(t *testing.T) { input := `["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", true]` expected := new(GetBlockByHashArgs) - expected.BlockHash = "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" + expected.BlockHash = common.HexToHash("0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331") expected.IncludeTxs = true args := new(GetBlockByHashArgs) diff --git a/xeth/xeth.go b/xeth/xeth.go index bf30fc2fc..92e73c7d5 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -160,13 +160,16 @@ func (self *XEth) BlockByHash(strHash string) *Block { return NewBlock(block) } -func (self *XEth) EthBlockByHash(strHash string) *types.Block { - hash := common.HexToHash(strHash) +func (self *XEth) EthBlockByHash(hash common.Hash) *types.Block { block := self.backend.ChainManager().GetBlock(hash) return block } +func (self *XEth) EthBlockByHexstring(strHash string) *types.Block { + return self.EthBlockByHash(common.HexToHash(strHash)) +} + func (self *XEth) EthTransactionByHash(hash string) *types.Transaction { data, _ := self.backend.ExtraDb().Get(common.FromHex(hash)) if len(data) != 0 { From 966cfa4bddb0fbe355dadb83541325a3b5c132f8 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 10:34:21 +0100 Subject: [PATCH 02/37] NewTxArgs --- rpc/api.go | 8 ++------ rpc/args.go | 20 ++++++++------------ rpc/args_test.go | 29 ++++++++--------------------- 3 files changed, 18 insertions(+), 39 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 8d1a412d1..b5f759711 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -185,11 +185,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - if err := args.requirements(); err != nil { - return err - } - - v, err := api.xeth().Transact(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) + v, err := api.xeth().Transact(args.From.Hex(), args.To.Hex(), args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) if err != nil { return err } @@ -200,7 +196,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - v, err := api.xethAtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) + v, err := api.xethAtStateNum(args.BlockNumber).Call(args.From.Hex(), args.To.Hex(), args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) if err != nil { return err } diff --git a/rpc/args.go b/rpc/args.go index 9a51959f4..2446e778f 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -93,8 +93,8 @@ func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) { } type NewTxArgs struct { - From string - To string + From common.Address + To common.Address Value *big.Int Gas *big.Int GasPrice *big.Int @@ -122,9 +122,12 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) { return NewDecodeParamError(err.Error()) } - // var ok bool - args.From = ext.From - args.To = ext.To + if len(ext.From) == 0 { + return NewValidationError("from", "is required") + } + + args.From = common.HexToAddress(ext.From) + args.To = common.HexToAddress(ext.To) args.Value = common.String2Big(ext.Value) args.Gas = common.String2Big(ext.Gas) args.GasPrice = common.String2Big(ext.GasPrice) @@ -145,13 +148,6 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) { return nil } -func (args *NewTxArgs) requirements() error { - if len(args.From) == 0 { - return NewValidationError("From", "Is required") - } - return nil -} - type GetStorageArgs struct { Address string BlockNumber int64 diff --git a/rpc/args_test.go b/rpc/args_test.go index c6d3a558b..328eab0ec 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -149,8 +149,8 @@ func TestNewTxArgs(t *testing.T) { "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}, "0x10"]` expected := new(NewTxArgs) - expected.From = "0xb60e8dd61c5d32be8058bb8eb970870f07233155" - expected.To = "0xd46e8dd67c5d32be8058bb8eb970870f072445675" + expected.From = common.HexToAddress("0xb60e8dd61c5d32be8058bb8eb970870f07233155") + expected.To = common.HexToAddress("0xd46e8dd67c5d32be8058bb8eb970870f072445675") expected.Gas = big.NewInt(30400) expected.GasPrice = big.NewInt(10000000000000) expected.Value = big.NewInt(10000000000000) @@ -194,7 +194,7 @@ func TestNewTxArgs(t *testing.T) { func TestNewTxArgsBlockInt(t *testing.T) { input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}, 5]` expected := new(NewTxArgs) - expected.From = "0xb60e8dd61c5d32be8058bb8eb970870f07233155" + expected.From = common.HexToAddress("0xb60e8dd61c5d32be8058bb8eb970870f07233155") expected.BlockNumber = big.NewInt(5).Int64() args := new(NewTxArgs) @@ -221,31 +221,18 @@ func TestNewTxArgsEmpty(t *testing.T) { } } -func TestNewTxArgsReqs(t *testing.T) { +func TestNewTxArgsFromEmpty(t *testing.T) { + input := `[{"to": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}]` + args := new(NewTxArgs) - args.From = "0xb60e8dd61c5d32be8058bb8eb970870f07233155" - - err := args.requirements() - switch err.(type) { - case nil: - break - default: - t.Errorf("Get %T", err) - } -} - -func TestNewTxArgsReqsFromBlank(t *testing.T) { - args := new(NewTxArgs) - args.From = "" - - err := args.requirements() + err := json.Unmarshal([]byte(input), &args) switch err.(type) { case nil: t.Error("Expected error but didn't get one") case *ValidationError: break default: - t.Error("Wrong type of error") + t.Errorf("Expected *rpc.ValidationError, but got %T with message `%s`", err, err.Error()) } } From bd1a54f076935d8d42c1f6df2c54fdd4e7f978ac Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 10:52:32 +0100 Subject: [PATCH 03/37] GetStorageArgs --- rpc/api.go | 6 +---- rpc/args.go | 13 +++-------- rpc/args_test.go | 58 +++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 56 insertions(+), 21 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index b5f759711..f5ce8acb6 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -106,11 +106,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - if err := args.requirements(); err != nil { - return err - } - - *reply = api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage() + *reply = api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address.Hex()).Storage() case "eth_getStorageAt": args := new(GetStorageAtArgs) if err := json.Unmarshal(req.Params, &args); err != nil { diff --git a/rpc/args.go b/rpc/args.go index 2446e778f..8d7427f6f 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -149,7 +149,7 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) { } type GetStorageArgs struct { - Address string + Address common.Address BlockNumber int64 } @@ -165,9 +165,9 @@ func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { addstr, ok := obj[0].(string) if !ok { - return NewDecodeParamError("Address is not a string") + return NewDecodeParamError("address is not a string") } - args.Address = addstr + args.Address = common.HexToAddress(addstr) if len(obj) > 1 { if err := blockHeight(obj[1], &args.BlockNumber); err != nil { @@ -178,13 +178,6 @@ func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { return nil } -func (args *GetStorageArgs) requirements() error { - if len(args.Address) == 0 { - return NewValidationError("Address", "cannot be blank") - } - return nil -} - type GetStorageAtArgs struct { Address string Key string diff --git a/rpc/args_test.go b/rpc/args_test.go index 328eab0ec..20930a3d8 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -239,7 +239,7 @@ func TestNewTxArgsFromEmpty(t *testing.T) { func TestGetStorageArgs(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"]` expected := new(GetStorageArgs) - expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" + expected.Address = common.HexToAddress("0x407d73d8a49eeb85d32cf465507dd71d507100c1") expected.BlockNumber = -1 args := new(GetStorageArgs) @@ -247,10 +247,6 @@ func TestGetStorageArgs(t *testing.T) { t.Error(err) } - if err := args.requirements(); err != nil { - t.Error(err) - } - if expected.Address != args.Address { t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) } @@ -260,13 +256,63 @@ func TestGetStorageArgs(t *testing.T) { } } +func TestGetStorageInvalidArgs(t *testing.T) { + input := `{}` + + args := new(GetStorageArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + } +} + +func TestGetStorageInvalidBlockheight(t *testing.T) { + input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", {}]` + + args := new(GetStorageArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + } +} + func TestGetStorageEmptyArgs(t *testing.T) { input := `[]` args := new(GetStorageArgs) err := json.Unmarshal([]byte(input), &args) - if err == nil { + switch err.(type) { + case nil: t.Error("Expected error but didn't get one") + case *InsufficientParamsError: + break + default: + t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + } +} + +func TestGetStorageAddressInt(t *testing.T) { + input := `[32456785432456, "latest"]` + + args := new(GetStorageArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) } } From 93af30a6f6308fe4e59b3a96f65ef535f1855865 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 11:06:45 +0100 Subject: [PATCH 04/37] improved GetBlockByHashArgs tests --- rpc/args_test.go | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/rpc/args_test.go b/rpc/args_test.go index 20930a3d8..b6d592a09 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -100,13 +100,48 @@ func TestGetBlockByHashArgs(t *testing.T) { } } -func TestGetBlockByHashEmpty(t *testing.T) { +func TestGetBlockByHashArgsEmpty(t *testing.T) { input := `[]` args := new(GetBlockByHashArgs) err := json.Unmarshal([]byte(input), &args) - if err == nil { + switch err.(type) { + case nil: t.Error("Expected error but didn't get one") + case *InsufficientParamsError: + break + default: + t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message %s", err, err.Error()) + } +} + +func TestGetBlockByHashArgsInvalid(t *testing.T) { + input := `{}` + + args := new(GetBlockByHashArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message %s", err, err.Error()) + } +} + +func TestGetBlockByHashArgsHashInt(t *testing.T) { + input := `[8]` + + args := new(GetBlockByHashArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message %s", err, err.Error()) } } From 493e0d7be883bb1acd3b8588b0e3d641ce06c73b Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 11:07:14 +0100 Subject: [PATCH 05/37] improved GetBlockByNumber tests --- rpc/args.go | 4 +++- rpc/args_test.go | 60 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 8d7427f6f..7504293a4 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -81,8 +81,10 @@ func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) { if v, ok := obj[0].(float64); ok { args.BlockNumber = int64(v) + } else if v, ok := obj[0].(string); ok { + args.BlockNumber = common.Big(v).Int64() } else { - args.BlockNumber = common.Big(obj[0].(string)).Int64() + return NewDecodeParamError("blockNumber must be number or string") } if len(obj) > 1 { diff --git a/rpc/args_test.go b/rpc/args_test.go index b6d592a09..b9a68d8bc 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -145,7 +145,27 @@ func TestGetBlockByHashArgsHashInt(t *testing.T) { } } -func TestGetBlockByNumberArgs(t *testing.T) { +func TestGetBlockByNumberArgsBlockNum(t *testing.T) { + input := `[436, false]` + expected := new(GetBlockByNumberArgs) + expected.BlockNumber = 436 + expected.IncludeTxs = false + + args := new(GetBlockByNumberArgs) + if err := json.Unmarshal([]byte(input), &args); err != nil { + t.Error(err) + } + + if args.BlockNumber != expected.BlockNumber { + t.Errorf("BlockNumber should be %v but is %v", expected.BlockNumber, args.BlockNumber) + } + + if args.IncludeTxs != expected.IncludeTxs { + t.Errorf("IncludeTxs should be %v but is %v", expected.IncludeTxs, args.IncludeTxs) + } +} + +func TestGetBlockByNumberArgsBlockHex(t *testing.T) { input := `["0x1b4", false]` expected := new(GetBlockByNumberArgs) expected.BlockNumber = 436 @@ -157,7 +177,7 @@ func TestGetBlockByNumberArgs(t *testing.T) { } if args.BlockNumber != expected.BlockNumber { - t.Errorf("BlockHash should be %v but is %v", expected.BlockNumber, args.BlockNumber) + t.Errorf("BlockNumber should be %v but is %v", expected.BlockNumber, args.BlockNumber) } if args.IncludeTxs != expected.IncludeTxs { @@ -170,8 +190,42 @@ func TestGetBlockByNumberEmpty(t *testing.T) { args := new(GetBlockByNumberArgs) err := json.Unmarshal([]byte(input), &args) - if err == nil { + switch err.(type) { + case nil: t.Error("Expected error but didn't get one") + case *InsufficientParamsError: + break + default: + t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + } +} + +func TestGetBlockByNumberBool(t *testing.T) { + input := `[true, true]` + + args := new(GetBlockByNumberArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + } +} +func TestGetBlockByNumberBlockObject(t *testing.T) { + input := `{}` + + args := new(GetBlockByNumberArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) } } From ad2089b0a3a495d8584209b6e31dde153cac7088 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 11:59:16 +0100 Subject: [PATCH 06/37] Add blockHeightFromJson convenience function --- rpc/args.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 7504293a4..fc7307b83 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -8,7 +8,15 @@ import ( "github.com/ethereum/go-ethereum/common" ) -func blockHeight(raw interface{}, number *int64) (err error) { +func blockHeightFromJson(msg json.RawMessage, number *int64) error { + var raw interface{} + if err := json.Unmarshal(msg, &raw); err != nil { + return NewDecodeParamError(err.Error()) + } + return blockHeight(raw, number) +} + +func blockHeight(raw interface{}, number *int64) error { // Parse as integer num, ok := raw.(float64) if ok { @@ -19,7 +27,7 @@ func blockHeight(raw interface{}, number *int64) (err error) { // Parse as string/hexstring str, ok := raw.(string) if !ok { - return NewDecodeParamError("BlockNumber is not a string") + return NewDecodeParamError("BlockNumber is not a number or string") } switch str { From 300d36b8640cf195db0f7997cc946ab5f164828f Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 11:59:35 +0100 Subject: [PATCH 07/37] improved NewTxArgs tests --- rpc/args.go | 7 +----- rpc/args_test.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index fc7307b83..82ee00d25 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -145,12 +145,7 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) { // Check for optional BlockNumber param if len(obj) > 1 { - var raw interface{} - if err = json.Unmarshal(obj[1], &raw); err != nil { - return NewDecodeParamError(err.Error()) - } - - if err := blockHeight(raw, &args.BlockNumber); err != nil { + if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil { return err } } diff --git a/rpc/args_test.go b/rpc/args_test.go index b9a68d8bc..e5a27e38a 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -300,13 +300,66 @@ func TestNewTxArgsBlockInt(t *testing.T) { } } +func TestNewTxArgsBlockInvalid(t *testing.T) { + input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}, false]` + expected := new(NewTxArgs) + expected.From = common.HexToAddress("0xb60e8dd61c5d32be8058bb8eb970870f07233155") + expected.BlockNumber = big.NewInt(5).Int64() + + args := new(NewTxArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expeted *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + } + +} + func TestNewTxArgsEmpty(t *testing.T) { input := `[]` args := new(NewTxArgs) err := json.Unmarshal([]byte(input), &args) - if err == nil { + switch err.(type) { + case nil: t.Error("Expected error but didn't get one") + case *InsufficientParamsError: + break + default: + t.Errorf("Expeted *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + } +} + +func TestNewTxArgsInvalid(t *testing.T) { + input := `{}` + + args := new(NewTxArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expeted *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + } +} +func TestNewTxArgsNotStrings(t *testing.T) { + input := `[{"from":6}]` + + args := new(NewTxArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expeted *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) } } From 9c4504dc41bbedb590db20519030224df66ce4b1 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 12:11:28 +0100 Subject: [PATCH 08/37] GetStorageAtArgs --- rpc/api.go | 7 ++--- rpc/args.go | 19 +++--------- rpc/args_test.go | 75 +++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 74 insertions(+), 27 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index f5ce8acb6..10d2e529e 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -112,12 +112,9 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err if err := json.Unmarshal(req.Params, &args); err != nil { return err } - if err := args.requirements(); err != nil { - return err - } - state := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address) - value := state.StorageString(args.Key) + state := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address.Hex()) + value := state.StorageString(args.Key.Hex()) *reply = common.Bytes2Hex(value.Bytes()) case "eth_getTransactionCount": diff --git a/rpc/args.go b/rpc/args.go index 82ee00d25..84c9ee0f7 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -184,8 +184,8 @@ func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { } type GetStorageAtArgs struct { - Address string - Key string + Address common.Address + Key common.Hash BlockNumber int64 } @@ -203,13 +203,13 @@ func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) { if !ok { return NewDecodeParamError("Address is not a string") } - args.Address = addstr + args.Address = common.HexToAddress(addstr) keystr, ok := obj[1].(string) if !ok { return NewDecodeParamError("Key is not a string") } - args.Key = keystr + args.Key = common.HexToHash(keystr) if len(obj) > 2 { if err := blockHeight(obj[2], &args.BlockNumber); err != nil { @@ -220,17 +220,6 @@ func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) { return nil } -func (args *GetStorageAtArgs) requirements() error { - if len(args.Address) == 0 { - return NewValidationError("Address", "cannot be blank") - } - - if len(args.Key) == 0 { - return NewValidationError("Key", "cannot be blank") - } - return nil -} - type GetTxCountArgs struct { Address string BlockNumber int64 diff --git a/rpc/args_test.go b/rpc/args_test.go index e5a27e38a..dea34b956 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -461,8 +461,8 @@ func TestGetStorageAddressInt(t *testing.T) { func TestGetStorageAtArgs(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x0", "0x2"]` expected := new(GetStorageAtArgs) - expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" - expected.Key = "0x0" + expected.Address = common.HexToAddress("0x407d73d8a49eeb85d32cf465507dd71d507100c1") + expected.Key = common.HexToHash("0x0") expected.BlockNumber = 2 args := new(GetStorageAtArgs) @@ -470,10 +470,6 @@ func TestGetStorageAtArgs(t *testing.T) { t.Error(err) } - if err := args.requirements(); err != nil { - t.Error(err) - } - if expected.Address != args.Address { t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) } @@ -492,8 +488,73 @@ func TestGetStorageAtEmptyArgs(t *testing.T) { args := new(GetStorageAtArgs) err := json.Unmarshal([]byte(input), &args) - if err == nil { + switch err.(type) { + case nil: t.Error("Expected error but didn't get one") + case *InsufficientParamsError: + break + default: + t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + } +} + +func TestGetStorageAtArgsInvalid(t *testing.T) { + input := `{}` + + args := new(GetStorageAtArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + } +} + +func TestGetStorageAtArgsAddressNotString(t *testing.T) { + input := `[true, "0x0", "0x2"]` + + args := new(GetStorageAtArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + } +} + +func TestGetStorageAtArgsKeyNotString(t *testing.T) { + input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", true, "0x2"]` + + args := new(GetStorageAtArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + } +} + +func TestGetStorageAtArgsValueNotString(t *testing.T) { + input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x1", true]` + + args := new(GetStorageAtArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) } } From 4523a00b91dbe98c6cb03acef362c5592973bcd3 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 12:47:00 +0100 Subject: [PATCH 09/37] GetTxCountArgs --- rpc/api.go | 7 +----- rpc/args.go | 11 ++------- rpc/args_test.go | 62 +++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 57 insertions(+), 23 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 10d2e529e..6f3e78cc0 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -123,12 +123,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - err := args.requirements() - if err != nil { - return err - } - - *reply = api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address) + *reply = api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address.Hex()) case "eth_getBlockTransactionCountByHash": args := new(GetBlockByHashArgs) if err := json.Unmarshal(req.Params, &args); err != nil { diff --git a/rpc/args.go b/rpc/args.go index 84c9ee0f7..93af3258f 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -221,7 +221,7 @@ func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) { } type GetTxCountArgs struct { - Address string + Address common.Address BlockNumber int64 } @@ -239,7 +239,7 @@ func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { if !ok { return NewDecodeParamError("Address is not a string") } - args.Address = addstr + args.Address = common.HexToAddress(addstr) if len(obj) > 1 { if err := blockHeight(obj[1], &args.BlockNumber); err != nil { @@ -250,13 +250,6 @@ func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { return nil } -func (args *GetTxCountArgs) requirements() error { - if len(args.Address) == 0 { - return NewValidationError("Address", "cannot be blank") - } - return nil -} - type GetBalanceArgs struct { Address string BlockNumber int64 diff --git a/rpc/args_test.go b/rpc/args_test.go index dea34b956..e13549d00 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -559,20 +559,16 @@ func TestGetStorageAtArgsValueNotString(t *testing.T) { } func TestGetTxCountArgs(t *testing.T) { - input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"]` + input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "pending"]` expected := new(GetTxCountArgs) - expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" - expected.BlockNumber = -1 + expected.Address = common.HexToAddress("0x407d73d8a49eeb85d32cf465507dd71d507100c1") + expected.BlockNumber = -2 args := new(GetTxCountArgs) if err := json.Unmarshal([]byte(input), &args); err != nil { t.Error(err) } - if err := args.requirements(); err != nil { - t.Error(err) - } - if expected.Address != args.Address { t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) } @@ -587,8 +583,58 @@ func TestGetTxCountEmptyArgs(t *testing.T) { args := new(GetTxCountArgs) err := json.Unmarshal([]byte(input), &args) - if err == nil { + switch err.(type) { + case nil: t.Error("Expected error but didn't get one") + case *InsufficientParamsError: + break + default: + t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + } +} + +func TestGetTxCountEmptyArgsInvalid(t *testing.T) { + input := `false` + + args := new(GetTxCountArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + } +} + +func TestGetTxCountAddressNotString(t *testing.T) { + input := `[false, "pending"]` + + args := new(GetTxCountArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + } +} + +func TestGetTxCountBlockheightInvalid(t *testing.T) { + input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", {}]` + + args := new(GetTxCountArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) } } From c139af582663d760f58e7b50dcb9f355c47ef47e Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 13:10:31 +0100 Subject: [PATCH 10/37] GetBalanceArgs --- rpc/api.go | 6 +---- rpc/args.go | 11 ++------ rpc/args_test.go | 65 +++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 56 insertions(+), 26 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 6f3e78cc0..aba47eee2 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -94,11 +94,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - if err := args.requirements(); err != nil { - return err - } - - v := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance() + v := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address.Hex()).Balance() *reply = common.ToHex(v.Bytes()) case "eth_getStorage", "eth_storageAt": args := new(GetStorageArgs) diff --git a/rpc/args.go b/rpc/args.go index 93af3258f..81343dd01 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -251,7 +251,7 @@ func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { } type GetBalanceArgs struct { - Address string + Address common.Address BlockNumber int64 } @@ -269,7 +269,7 @@ func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) { if !ok { return NewDecodeParamError("Address is not a string") } - args.Address = addstr + args.Address = common.HexToAddress(addstr) if len(obj) > 1 { if err := blockHeight(obj[1], &args.BlockNumber); err != nil { @@ -280,13 +280,6 @@ func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) { return nil } -func (args *GetBalanceArgs) requirements() error { - if len(args.Address) == 0 { - return NewValidationError("Address", "cannot be blank") - } - return nil -} - type GetDataArgs struct { Address string BlockNumber int64 diff --git a/rpc/args_test.go b/rpc/args_test.go index e13549d00..4792f4f88 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -24,7 +24,7 @@ func TestSha3(t *testing.T) { func TestGetBalanceArgs(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x1f"]` expected := new(GetBalanceArgs) - expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" + expected.Address = common.HexToAddress("0x407d73d8a49eeb85d32cf465507dd71d507100c1") expected.BlockNumber = 31 args := new(GetBalanceArgs) @@ -32,10 +32,6 @@ func TestGetBalanceArgs(t *testing.T) { t.Error(err) } - if err := args.requirements(); err != nil { - t.Error(err) - } - if args.Address != expected.Address { t.Errorf("Address should be %v but is %v", expected.Address, args.Address) } @@ -48,7 +44,7 @@ func TestGetBalanceArgs(t *testing.T) { func TestGetBalanceArgsLatest(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"]` expected := new(GetBalanceArgs) - expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" + expected.Address = common.HexToAddress("0x407d73d8a49eeb85d32cf465507dd71d507100c1") expected.BlockNumber = -1 args := new(GetBalanceArgs) @@ -56,10 +52,6 @@ func TestGetBalanceArgsLatest(t *testing.T) { t.Error(err) } - if err := args.requirements(); err != nil { - t.Error(err) - } - if args.Address != expected.Address { t.Errorf("Address should be %v but is %v", expected.Address, args.Address) } @@ -69,15 +61,64 @@ func TestGetBalanceArgsLatest(t *testing.T) { } } -func TestGetBalanceEmptyArgs(t *testing.T) { +func TestGetBalanceArgsEmpty(t *testing.T) { input := `[]` args := new(GetBalanceArgs) err := json.Unmarshal([]byte(input), &args) - if err == nil { + switch err.(type) { + case nil: t.Error("Expected error but didn't get one") + case *InsufficientParamsError: + break + default: + t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message %s", err, err.Error()) } +} +func TestGetBalanceArgsInvalid(t *testing.T) { + input := `6` + + args := new(GetBalanceArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message %s", err, err.Error()) + } +} + +func TestGetBalanceArgsBlockInvalid(t *testing.T) { + input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", false]` + + args := new(GetBalanceArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message %s", err, err.Error()) + } +} + +func TestGetBalanceArgsAddressInvalid(t *testing.T) { + input := `[-9, "latest"]` + + args := new(GetBalanceArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message %s", err, err.Error()) + } } func TestGetBlockByHashArgs(t *testing.T) { From ca03e976976a03d278da227fe1ec9966f23484ba Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 13:33:44 +0100 Subject: [PATCH 11/37] Add InvalidTypeError --- rpc/messages.go | 16 ++++++++++++++++ rpc/messages_test.go | 9 +++++++++ 2 files changed, 25 insertions(+) diff --git a/rpc/messages.go b/rpc/messages.go index 7f5ebab11..5c498234f 100644 --- a/rpc/messages.go +++ b/rpc/messages.go @@ -21,6 +21,22 @@ import ( "fmt" ) +type InvalidTypeError struct { + method string + msg string +} + +func (e *InvalidTypeError) Error() string { + return fmt.Sprintf("invalid type on field %s: %s", e.method, e.msg) +} + +func NewInvalidTypeError(method, msg string) *InvalidTypeError { + return &InvalidTypeError{ + method: method, + msg: msg, + } +} + type InsufficientParamsError struct { have int want int diff --git a/rpc/messages_test.go b/rpc/messages_test.go index 5274c91e4..91f0152dc 100644 --- a/rpc/messages_test.go +++ b/rpc/messages_test.go @@ -4,6 +4,15 @@ import ( "testing" ) +func TestInvalidTypeError(t *testing.T) { + err := NewInvalidTypeError("testField", "not string") + expected := "invalid type on field testField: not string" + + if err.Error() != expected { + t.Error(err.Error()) + } +} + func TestInsufficientParamsError(t *testing.T) { err := NewInsufficientParamsError(0, 1) expected := "insufficient params, want 1 have 0" From a49c81547ce32125917c0127c94c9845750e9e30 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 13:45:06 +0100 Subject: [PATCH 12/37] DecodeParamError -> InvalidTypeError for unexpected input type --- rpc/args.go | 54 ++++++++++++++++++++++++------------------------ rpc/args_test.go | 52 +++++++++++++++++++++++----------------------- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 81343dd01..30ed1a17c 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -27,7 +27,7 @@ func blockHeight(raw interface{}, number *int64) error { // Parse as string/hexstring str, ok := raw.(string) if !ok { - return NewDecodeParamError("BlockNumber is not a number or string") + return NewInvalidTypeError("blockNumber", "not a number or string") } switch str { @@ -60,7 +60,7 @@ func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) { argstr, ok := obj[0].(string) if !ok { - return NewDecodeParamError("BlockHash not a string") + return NewInvalidTypeError("blockHash", "not a string") } args.BlockHash = common.HexToHash(argstr) @@ -92,7 +92,7 @@ func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) { } else if v, ok := obj[0].(string); ok { args.BlockNumber = common.Big(v).Int64() } else { - return NewDecodeParamError("blockNumber must be number or string") + return NewInvalidTypeError("blockNumber", "not a number or string") } if len(obj) > 1 { @@ -170,7 +170,7 @@ func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { addstr, ok := obj[0].(string) if !ok { - return NewDecodeParamError("address is not a string") + return NewInvalidTypeError("address", "not a string") } args.Address = common.HexToAddress(addstr) @@ -201,13 +201,13 @@ func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) { addstr, ok := obj[0].(string) if !ok { - return NewDecodeParamError("Address is not a string") + return NewInvalidTypeError("address", "not a string") } args.Address = common.HexToAddress(addstr) keystr, ok := obj[1].(string) if !ok { - return NewDecodeParamError("Key is not a string") + return NewInvalidTypeError("key", "not a string") } args.Key = common.HexToHash(keystr) @@ -237,7 +237,7 @@ func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { addstr, ok := obj[0].(string) if !ok { - return NewDecodeParamError("Address is not a string") + return NewInvalidTypeError("address", "not a string") } args.Address = common.HexToAddress(addstr) @@ -267,7 +267,7 @@ func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) { addstr, ok := obj[0].(string) if !ok { - return NewDecodeParamError("Address is not a string") + return NewInvalidTypeError("address", "not a string") } args.Address = common.HexToAddress(addstr) @@ -297,7 +297,7 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) { addstr, ok := obj[0].(string) if !ok { - return NewDecodeParamError("Address is not a string") + return NewInvalidTypeError("address", "not a string") } args.Address = addstr @@ -335,14 +335,14 @@ func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) { arg0, ok := obj[0].(string) if !ok { - return NewDecodeParamError("BlockNumber is not string") + return NewInvalidTypeError("blockNumber", "not a string") } args.BlockNumber = common.Big(arg0).Int64() if len(obj) > 1 { arg1, ok := obj[1].(string) if !ok { - return NewDecodeParamError("Index not a string") + return NewInvalidTypeError("index", "not a string") } args.Index = common.Big(arg1).Int64() } @@ -368,14 +368,14 @@ func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) { arg0, ok := obj[0].(string) if !ok { - return NewDecodeParamError("Hash not a string") + return NewInvalidTypeError("hash", "not a string") } args.Hash = arg0 if len(obj) > 1 { arg1, ok := obj[1].(string) if !ok { - return NewDecodeParamError("Index not a string") + return NewInvalidTypeError("index", "not a string") } args.Index = common.Big(arg1).Int64() } @@ -431,7 +431,7 @@ func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) { fromstr, ok := obj[0].FromBlock.(string) if !ok { - return NewDecodeParamError("FromBlock is not a string") + return NewInvalidTypeError("fromBlock", "is not a string") } switch fromstr { @@ -443,7 +443,7 @@ func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) { tostr, ok := obj[0].ToBlock.(string) if !ok { - return NewDecodeParamError("ToBlock is not a string") + return NewInvalidTypeError("toBlock", "not a string") } switch tostr { @@ -483,19 +483,19 @@ func (args *DbArgs) UnmarshalJSON(b []byte) (err error) { var ok bool if objstr, ok = obj[0].(string); !ok { - return NewDecodeParamError("Database is not a string") + return NewInvalidTypeError("database", "not a string") } args.Database = objstr if objstr, ok = obj[1].(string); !ok { - return NewDecodeParamError("Key is not a string") + return NewInvalidTypeError("key", "not a string") } args.Key = objstr if len(obj) > 2 { objstr, ok = obj[2].(string) if !ok { - return NewDecodeParamError("Value is not a string") + return NewInvalidTypeError("value", "not a string") } args.Value = []byte(objstr) @@ -534,19 +534,19 @@ func (args *DbHexArgs) UnmarshalJSON(b []byte) (err error) { var ok bool if objstr, ok = obj[0].(string); !ok { - return NewDecodeParamError("Database is not a string") + return NewInvalidTypeError("database", "not a string") } args.Database = objstr if objstr, ok = obj[1].(string); !ok { - return NewDecodeParamError("Key is not a string") + return NewInvalidTypeError("key", "not a string") } args.Key = objstr if len(obj) > 2 { objstr, ok = obj[2].(string) if !ok { - return NewDecodeParamError("Value is not a string") + return NewInvalidTypeError("value", "not a string") } args.Value = common.FromHex(objstr) @@ -557,10 +557,10 @@ func (args *DbHexArgs) UnmarshalJSON(b []byte) (err error) { func (a *DbHexArgs) requirements() error { if len(a.Database) == 0 { - return NewValidationError("Database", "cannot be blank") + return NewInvalidTypeError("Database", "cannot be blank") } if len(a.Key) == 0 { - return NewValidationError("Key", "cannot be blank") + return NewInvalidTypeError("Key", "cannot be blank") } return nil } @@ -637,7 +637,7 @@ func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) { var argstr string argstr, ok := obj[0].(string) if !ok { - return NewDecodeParamError("Filter is not a string") + return NewInvalidTypeError("filter", "not a string") } args.Word = argstr @@ -741,18 +741,18 @@ func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) { var objstr string var ok bool if objstr, ok = obj[0].(string); !ok { - return NewDecodeParamError("Nonce is not a string") + return NewInvalidTypeError("nonce", "not a string") } args.Nonce = common.String2Big(objstr).Uint64() if objstr, ok = obj[1].(string); !ok { - return NewDecodeParamError("Header is not a string") + return NewInvalidTypeError("header", "not a string") } args.Header = common.HexToHash(objstr) if objstr, ok = obj[2].(string); !ok { - return NewDecodeParamError("Digest is not a string") + return NewInvalidTypeError("digest", "not a string") } args.Digest = common.HexToHash(objstr) diff --git a/rpc/args_test.go b/rpc/args_test.go index 4792f4f88..7dec5d8f4 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -99,10 +99,10 @@ func TestGetBalanceArgsBlockInvalid(t *testing.T) { switch err.(type) { case nil: t.Error("Expected error but didn't get one") - case *DecodeParamError: + case *InvalidTypeError: break default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message %s", err, err.Error()) + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message %s", err, err.Error()) } } @@ -114,10 +114,10 @@ func TestGetBalanceArgsAddressInvalid(t *testing.T) { switch err.(type) { case nil: t.Error("Expected error but didn't get one") - case *DecodeParamError: + case *InvalidTypeError: break default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message %s", err, err.Error()) + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message %s", err, err.Error()) } } @@ -179,10 +179,10 @@ func TestGetBlockByHashArgsHashInt(t *testing.T) { switch err.(type) { case nil: t.Error("Expected error but didn't get one") - case *DecodeParamError: + case *InvalidTypeError: break default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message %s", err, err.Error()) + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message %s", err, err.Error()) } } @@ -249,10 +249,10 @@ func TestGetBlockByNumberBool(t *testing.T) { switch err.(type) { case nil: t.Error("Expected error but didn't get one") - case *DecodeParamError: + case *InvalidTypeError: break default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) } } func TestGetBlockByNumberBlockObject(t *testing.T) { @@ -352,10 +352,10 @@ func TestNewTxArgsBlockInvalid(t *testing.T) { switch err.(type) { case nil: t.Error("Expected error but didn't get one") - case *DecodeParamError: + case *InvalidTypeError: break default: - t.Errorf("Expeted *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + t.Errorf("Expeted *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) } } @@ -462,10 +462,10 @@ func TestGetStorageInvalidBlockheight(t *testing.T) { switch err.(type) { case nil: t.Error("Expected error but didn't get one") - case *DecodeParamError: + case *InvalidTypeError: break default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) } } @@ -492,10 +492,10 @@ func TestGetStorageAddressInt(t *testing.T) { switch err.(type) { case nil: t.Error("Expected error but didn't get one") - case *DecodeParamError: + case *InvalidTypeError: break default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) } } @@ -562,10 +562,10 @@ func TestGetStorageAtArgsAddressNotString(t *testing.T) { switch err.(type) { case nil: t.Error("Expected error but didn't get one") - case *DecodeParamError: + case *InvalidTypeError: break default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) } } @@ -577,10 +577,10 @@ func TestGetStorageAtArgsKeyNotString(t *testing.T) { switch err.(type) { case nil: t.Error("Expected error but didn't get one") - case *DecodeParamError: + case *InvalidTypeError: break default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) } } @@ -592,10 +592,10 @@ func TestGetStorageAtArgsValueNotString(t *testing.T) { switch err.(type) { case nil: t.Error("Expected error but didn't get one") - case *DecodeParamError: + case *InvalidTypeError: break default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) } } @@ -657,10 +657,10 @@ func TestGetTxCountAddressNotString(t *testing.T) { switch err.(type) { case nil: t.Error("Expected error but didn't get one") - case *DecodeParamError: + case *InvalidTypeError: break default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) } } @@ -672,10 +672,10 @@ func TestGetTxCountBlockheightInvalid(t *testing.T) { switch err.(type) { case nil: t.Error("Expected error but didn't get one") - case *DecodeParamError: + case *InvalidTypeError: break default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) } } @@ -791,10 +791,10 @@ func TestBlockFilterArgsNums(t *testing.T) { args := new(BlockFilterArgs) err := json.Unmarshal([]byte(input), &args) switch err.(type) { - case *DecodeParamError: + case *InvalidTypeError: break default: - t.Errorf("Should have *DecodeParamError but instead have %T", err) + t.Errorf("Should have *rpc.InvalidTypeError but instead have %T", err) } } From cd6b3fd28a0624ac27cecf9f3e331a027b9c7e67 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 13:50:22 +0100 Subject: [PATCH 13/37] GetDataArgs --- rpc/api.go | 5 +--- rpc/args.go | 11 ++------- rpc/args_test.go | 60 ++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 56 insertions(+), 20 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index aba47eee2..0f5bac657 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -159,10 +159,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err if err := json.Unmarshal(req.Params, &args); err != nil { return err } - if err := args.requirements(); err != nil { - return err - } - *reply = api.xethAtStateNum(args.BlockNumber).CodeAt(args.Address) + *reply = api.xethAtStateNum(args.BlockNumber).CodeAt(args.Address.Hex()) case "eth_sendTransaction", "eth_transact": args := new(NewTxArgs) if err := json.Unmarshal(req.Params, &args); err != nil { diff --git a/rpc/args.go b/rpc/args.go index 30ed1a17c..2b62811e3 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -281,7 +281,7 @@ func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) { } type GetDataArgs struct { - Address string + Address common.Address BlockNumber int64 } @@ -299,7 +299,7 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) { if !ok { return NewInvalidTypeError("address", "not a string") } - args.Address = addstr + args.Address = common.HexToAddress(addstr) if len(obj) > 1 { if err := blockHeight(obj[1], &args.BlockNumber); err != nil { @@ -310,13 +310,6 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) { return nil } -func (args *GetDataArgs) requirements() error { - if len(args.Address) == 0 { - return NewValidationError("Address", "cannot be blank") - } - return nil -} - type BlockNumIndexArgs struct { BlockNumber int64 Index int64 diff --git a/rpc/args_test.go b/rpc/args_test.go index 7dec5d8f4..b8df08413 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -682,7 +682,7 @@ func TestGetTxCountBlockheightInvalid(t *testing.T) { func TestGetDataArgs(t *testing.T) { input := `["0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", "latest"]` expected := new(GetDataArgs) - expected.Address = "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8" + expected.Address = common.HexToAddress("0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8") expected.BlockNumber = -1 args := new(GetDataArgs) @@ -690,10 +690,6 @@ func TestGetDataArgs(t *testing.T) { t.Error(err) } - if err := args.requirements(); err != nil { - t.Error(err) - } - if expected.Address != args.Address { t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) } @@ -703,13 +699,63 @@ func TestGetDataArgs(t *testing.T) { } } -func TestGetDataEmptyArgs(t *testing.T) { +func TestGetDataArgsEmpty(t *testing.T) { input := `[]` args := new(GetDataArgs) err := json.Unmarshal([]byte(input), &args) - if err == nil { + switch err.(type) { + case nil: t.Error("Expected error but didn't get one") + case *InsufficientParamsError: + break + default: + t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + } +} + +func TestGetDataArgsInvalid(t *testing.T) { + input := `{}` + + args := new(GetDataArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + } +} + +func TestGetDataArgsAddressNotString(t *testing.T) { + input := `[12, "latest"]` + + args := new(GetDataArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *InvalidTypeError: + break + default: + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + } +} + +func TestGetDataArgsBlocknumberNotString(t *testing.T) { + input := `["0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", false]` + + args := new(GetDataArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *InvalidTypeError: + break + default: + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) } } From cb103c089a7c9238326e6a9bb336e375281ca622 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 13:57:41 +0100 Subject: [PATCH 14/37] BlockNumIndexArgs --- rpc/args.go | 6 ++--- rpc/args_test.go | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 2b62811e3..34ed84fc2 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -326,11 +326,9 @@ func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) { return NewInsufficientParamsError(len(obj), 1) } - arg0, ok := obj[0].(string) - if !ok { - return NewInvalidTypeError("blockNumber", "not a string") + if err := blockHeight(obj[0], &args.BlockNumber); err != nil { + return err } - args.BlockNumber = common.Big(arg0).Int64() if len(obj) > 1 { arg1, ok := obj[1].(string) diff --git a/rpc/args_test.go b/rpc/args_test.go index b8df08413..82bdcd257 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -1076,6 +1076,66 @@ func TestBlockNumIndexArgs(t *testing.T) { } } +func TestBlockNumIndexArgsEmpty(t *testing.T) { + input := `[]` + + args := new(BlockNumIndexArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *InsufficientParamsError: + break + default: + t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + } +} + +func TestBlockNumIndexArgsInvalid(t *testing.T) { + input := `"foo"` + + args := new(BlockNumIndexArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + } +} + +func TestBlockNumIndexArgsBlocknumInvalid(t *testing.T) { + input := `[{}, "0x1"]` + + args := new(BlockNumIndexArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *InvalidTypeError: + break + default: + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + } +} + +func TestBlockNumIndexArgsIndexInvalid(t *testing.T) { + input := `["0x29a", 1]` + + args := new(BlockNumIndexArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *InvalidTypeError: + break + default: + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + } +} + func TestHashIndexArgs(t *testing.T) { input := `["0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", "0x1"]` expected := new(HashIndexArgs) From 3472823be94acc5b999dcb8741901b3e0c07f5d6 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 14:17:32 +0100 Subject: [PATCH 15/37] HashIndexArgs --- rpc/api.go | 6 ++--- rpc/args.go | 4 ++-- rpc/args_test.go | 62 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 0f5bac657..ff166264b 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -212,7 +212,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err args := new(HashIndexArgs) if err := json.Unmarshal(req.Params, &args); err != nil { } - tx := api.xeth().EthTransactionByHash(args.Hash) + tx := api.xeth().EthTransactionByHash(args.Hash.Hex()) if tx != nil { *reply = NewTransactionRes(tx) } @@ -222,7 +222,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - block := api.xeth().EthBlockByHexstring(args.Hash) + block := api.xeth().EthBlockByHash(args.Hash) br := NewBlockRes(block) br.fullTx = true @@ -250,7 +250,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - br := NewBlockRes(api.xeth().EthBlockByHexstring(args.Hash)) + br := NewBlockRes(api.xeth().EthBlockByHash(args.Hash)) if args.Index > int64(len(br.Uncles)) || args.Index < 0 { return NewValidationError("Index", "does not exist") diff --git a/rpc/args.go b/rpc/args.go index 34ed84fc2..d3449928b 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -342,7 +342,7 @@ func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) { } type HashIndexArgs struct { - Hash string + Hash common.Hash Index int64 } @@ -361,7 +361,7 @@ func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) { if !ok { return NewInvalidTypeError("hash", "not a string") } - args.Hash = arg0 + args.Hash = common.HexToHash(arg0) if len(obj) > 1 { arg1, ok := obj[1].(string) diff --git a/rpc/args_test.go b/rpc/args_test.go index 82bdcd257..ab74721b3 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -1139,7 +1139,7 @@ func TestBlockNumIndexArgsIndexInvalid(t *testing.T) { func TestHashIndexArgs(t *testing.T) { input := `["0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", "0x1"]` expected := new(HashIndexArgs) - expected.Hash = "0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b" + expected.Hash = common.HexToHash("0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b") expected.Index = 1 args := new(HashIndexArgs) @@ -1156,6 +1156,66 @@ func TestHashIndexArgs(t *testing.T) { } } +func TestHashIndexArgsEmpty(t *testing.T) { + input := `[]` + + args := new(HashIndexArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *InsufficientParamsError: + break + default: + t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + } +} + +func TestHashIndexArgsInvalid(t *testing.T) { + input := `{}` + + args := new(HashIndexArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *DecodeParamError: + break + default: + t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + } +} + +func TestHashIndexArgsInvalidHash(t *testing.T) { + input := `[7, "0x1"]` + + args := new(HashIndexArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *InvalidTypeError: + break + default: + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + } +} + +func TestHashIndexArgsInvalidIndex(t *testing.T) { + input := `["0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", false]` + + args := new(HashIndexArgs) + err := json.Unmarshal([]byte(input), &args) + switch err.(type) { + case nil: + t.Error("Expected error but didn't get one") + case *InvalidTypeError: + break + default: + t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + } +} + func TestSubmitWorkArgs(t *testing.T) { input := `["0x0000000000000001", "0x1234567890abcdef1234567890abcdef", "0xD1GE5700000000000000000000000000"]` expected := new(SubmitWorkArgs) From f695d013548ca3399ac2f2900307bf085290aa61 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 16:16:17 +0100 Subject: [PATCH 16/37] Convert error checks to Expect functions --- rpc/args_test.go | 480 +++++++++++++++++------------------------------ 1 file changed, 168 insertions(+), 312 deletions(-) diff --git a/rpc/args_test.go b/rpc/args_test.go index ab74721b3..fa46f6515 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -3,6 +3,7 @@ package rpc import ( "bytes" "encoding/json" + "fmt" "math/big" "testing" @@ -21,6 +22,58 @@ func TestSha3(t *testing.T) { } } +func ExpectValidationError(err error) string { + var str string + switch err.(type) { + case nil: + str = "Expected error but didn't get one" + case *ValidationError: + break + default: + str = fmt.Sprintf("Expected *rpc.ValidationError but got %T with message `%s`", err, err.Error()) + } + return str +} + +func ExpectInvalidTypeError(err error) string { + var str string + switch err.(type) { + case nil: + str = "Expected error but didn't get one" + case *InvalidTypeError: + break + default: + str = fmt.Sprintf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + } + return str +} + +func ExpectInsufficientParamsError(err error) string { + var str string + switch err.(type) { + case nil: + str = "Expected error but didn't get one" + case *InsufficientParamsError: + break + default: + str = fmt.Sprintf("Expected *rpc.InsufficientParamsError but got %T with message %s", err, err.Error()) + } + return str +} + +func ExpectDecodeParamError(err error) string { + var str string + switch err.(type) { + case nil: + str = "Expected error but didn't get one" + case *DecodeParamError: + break + default: + str = fmt.Sprintf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + } + return str +} + func TestGetBalanceArgs(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x1f"]` expected := new(GetBalanceArgs) @@ -65,14 +118,7 @@ func TestGetBalanceArgsEmpty(t *testing.T) { input := `[]` args := new(GetBalanceArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InsufficientParamsError: - break - default: - t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message %s", err, err.Error()) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) } } @@ -95,14 +141,9 @@ func TestGetBalanceArgsBlockInvalid(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", false]` args := new(GetBalanceArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message %s", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -110,14 +151,9 @@ func TestGetBalanceArgsAddressInvalid(t *testing.T) { input := `[-9, "latest"]` args := new(GetBalanceArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message %s", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -145,14 +181,9 @@ func TestGetBlockByHashArgsEmpty(t *testing.T) { input := `[]` args := new(GetBlockByHashArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InsufficientParamsError: - break - default: - t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message %s", err, err.Error()) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -160,14 +191,9 @@ func TestGetBlockByHashArgsInvalid(t *testing.T) { input := `{}` args := new(GetBlockByHashArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *DecodeParamError: - break - default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message %s", err, err.Error()) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -175,14 +201,9 @@ func TestGetBlockByHashArgsHashInt(t *testing.T) { input := `[8]` args := new(GetBlockByHashArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message %s", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -230,14 +251,9 @@ func TestGetBlockByNumberEmpty(t *testing.T) { input := `[]` args := new(GetBlockByNumberArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InsufficientParamsError: - break - default: - t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -245,28 +261,18 @@ func TestGetBlockByNumberBool(t *testing.T) { input := `[true, true]` args := new(GetBlockByNumberArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } func TestGetBlockByNumberBlockObject(t *testing.T) { input := `{}` args := new(GetBlockByNumberArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *DecodeParamError: - break - default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -348,30 +354,19 @@ func TestNewTxArgsBlockInvalid(t *testing.T) { expected.BlockNumber = big.NewInt(5).Int64() args := new(NewTxArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expeted *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } - } func TestNewTxArgsEmpty(t *testing.T) { input := `[]` args := new(NewTxArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InsufficientParamsError: - break - default: - t.Errorf("Expeted *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -379,28 +374,18 @@ func TestNewTxArgsInvalid(t *testing.T) { input := `{}` args := new(NewTxArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *DecodeParamError: - break - default: - t.Errorf("Expeted *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } func TestNewTxArgsNotStrings(t *testing.T) { input := `[{"from":6}]` args := new(NewTxArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *DecodeParamError: - break - default: - t.Errorf("Expeted *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -443,14 +428,9 @@ func TestGetStorageInvalidArgs(t *testing.T) { input := `{}` args := new(GetStorageArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *DecodeParamError: - break - default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -458,14 +438,9 @@ func TestGetStorageInvalidBlockheight(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", {}]` args := new(GetStorageArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -473,14 +448,9 @@ func TestGetStorageEmptyArgs(t *testing.T) { input := `[]` args := new(GetStorageArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InsufficientParamsError: - break - default: - t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -488,14 +458,9 @@ func TestGetStorageAddressInt(t *testing.T) { input := `[32456785432456, "latest"]` args := new(GetStorageArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -528,14 +493,9 @@ func TestGetStorageAtEmptyArgs(t *testing.T) { input := `[]` args := new(GetStorageAtArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InsufficientParamsError: - break - default: - t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -543,14 +503,9 @@ func TestGetStorageAtArgsInvalid(t *testing.T) { input := `{}` args := new(GetStorageAtArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *DecodeParamError: - break - default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -558,14 +513,9 @@ func TestGetStorageAtArgsAddressNotString(t *testing.T) { input := `[true, "0x0", "0x2"]` args := new(GetStorageAtArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -573,14 +523,9 @@ func TestGetStorageAtArgsKeyNotString(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", true, "0x2"]` args := new(GetStorageAtArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -588,14 +533,9 @@ func TestGetStorageAtArgsValueNotString(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x1", true]` args := new(GetStorageAtArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -623,14 +563,9 @@ func TestGetTxCountEmptyArgs(t *testing.T) { input := `[]` args := new(GetTxCountArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InsufficientParamsError: - break - default: - t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -638,14 +573,9 @@ func TestGetTxCountEmptyArgsInvalid(t *testing.T) { input := `false` args := new(GetTxCountArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *DecodeParamError: - break - default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -653,14 +583,9 @@ func TestGetTxCountAddressNotString(t *testing.T) { input := `[false, "pending"]` args := new(GetTxCountArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -668,14 +593,9 @@ func TestGetTxCountBlockheightInvalid(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", {}]` args := new(GetTxCountArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -703,14 +623,9 @@ func TestGetDataArgsEmpty(t *testing.T) { input := `[]` args := new(GetDataArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InsufficientParamsError: - break - default: - t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -718,14 +633,9 @@ func TestGetDataArgsInvalid(t *testing.T) { input := `{}` args := new(GetDataArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *DecodeParamError: - break - default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -733,14 +643,9 @@ func TestGetDataArgsAddressNotString(t *testing.T) { input := `[12, "latest"]` args := new(GetDataArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -748,14 +653,9 @@ func TestGetDataArgsBlocknumberNotString(t *testing.T) { input := `["0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", false]` args := new(GetDataArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -835,14 +735,10 @@ func TestBlockFilterArgsNums(t *testing.T) { }]` args := new(BlockFilterArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case *InvalidTypeError: - break - default: - t.Errorf("Should have *rpc.InvalidTypeError but instead have %T", err) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } - } func TestBlockFilterArgsEmptyArgs(t *testing.T) { @@ -1080,14 +976,9 @@ func TestBlockNumIndexArgsEmpty(t *testing.T) { input := `[]` args := new(BlockNumIndexArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InsufficientParamsError: - break - default: - t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -1095,14 +986,9 @@ func TestBlockNumIndexArgsInvalid(t *testing.T) { input := `"foo"` args := new(BlockNumIndexArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *DecodeParamError: - break - default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -1110,14 +996,9 @@ func TestBlockNumIndexArgsBlocknumInvalid(t *testing.T) { input := `[{}, "0x1"]` args := new(BlockNumIndexArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -1125,14 +1006,9 @@ func TestBlockNumIndexArgsIndexInvalid(t *testing.T) { input := `["0x29a", 1]` args := new(BlockNumIndexArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -1160,14 +1036,9 @@ func TestHashIndexArgsEmpty(t *testing.T) { input := `[]` args := new(HashIndexArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InsufficientParamsError: - break - default: - t.Errorf("Expected *rpc.InsufficientParamsError but got %T with message `%s`", err, err.Error()) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -1175,14 +1046,9 @@ func TestHashIndexArgsInvalid(t *testing.T) { input := `{}` args := new(HashIndexArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *DecodeParamError: - break - default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message `%s`", err, err.Error()) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -1190,14 +1056,9 @@ func TestHashIndexArgsInvalidHash(t *testing.T) { input := `[7, "0x1"]` args := new(HashIndexArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } @@ -1205,14 +1066,9 @@ func TestHashIndexArgsInvalidIndex(t *testing.T) { input := `["0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", false]` args := new(HashIndexArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *InvalidTypeError: - break - default: - t.Errorf("Expected *rpc.InvalidTypeError but got %T with message `%s`", err, err.Error()) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } From 745dd5b7a517cf0930f96a9b162821d0d631dea9 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 16:19:33 +0100 Subject: [PATCH 17/37] Sha3Args --- rpc/args.go | 6 +++++- rpc/args_test.go | 55 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index d3449928b..b23216c98 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -388,8 +388,12 @@ func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) { if len(obj) < 1 { return NewInsufficientParamsError(len(obj), 1) } - args.Data = obj[0].(string) + argstr, ok := obj[0].(string) + if !ok { + return NewInvalidTypeError("data", "is not a string") + } + args.Data = argstr return nil } diff --git a/rpc/args_test.go b/rpc/args_test.go index fa46f6515..0c7360c53 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -10,18 +10,6 @@ import ( "github.com/ethereum/go-ethereum/common" ) -func TestSha3(t *testing.T) { - input := `["0x68656c6c6f20776f726c64"]` - expected := "0x68656c6c6f20776f726c64" - - args := new(Sha3Args) - json.Unmarshal([]byte(input), &args) - - if args.Data != expected { - t.Error("got %s expected %s", input, expected) - } -} - func ExpectValidationError(err error) string { var str string switch err.(type) { @@ -74,6 +62,47 @@ func ExpectDecodeParamError(err error) string { return str } +func TestSha3(t *testing.T) { + input := `["0x68656c6c6f20776f726c64"]` + expected := "0x68656c6c6f20776f726c64" + + args := new(Sha3Args) + json.Unmarshal([]byte(input), &args) + + if args.Data != expected { + t.Error("got %s expected %s", input, expected) + } +} + +func TestSha3ArgsInvalid(t *testing.T) { + input := `{}` + + args := new(Sha3Args) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestSha3ArgsEmpty(t *testing.T) { + input := `[]` + + args := new(Sha3Args) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} +func TestSha3ArgsDataInvalid(t *testing.T) { + input := `[4]` + + args := new(Sha3Args) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + func TestGetBalanceArgs(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x1f"]` expected := new(GetBalanceArgs) @@ -119,6 +148,8 @@ func TestGetBalanceArgsEmpty(t *testing.T) { args := new(GetBalanceArgs) str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } From 6661bc35efc9c5d5a874e42558d568d9aa183fee Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 17:27:29 +0100 Subject: [PATCH 18/37] Accept number or string for BlockFilterArgs to/fromBlock --- rpc/args.go | 19 +++++++++++-------- rpc/args_test.go | 6 +++--- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index b23216c98..206472aa2 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -424,17 +424,20 @@ func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) { return NewInsufficientParamsError(len(obj), 1) } - fromstr, ok := obj[0].FromBlock.(string) - if !ok { - return NewInvalidTypeError("fromBlock", "is not a string") + var num int64 + if err := blockHeight(obj[0].FromBlock, &num); err != nil { + return err + } + if num < 0 { + args.Earliest = -1 //latest block + } else { + args.Earliest = num } - switch fromstr { - case "latest": - args.Earliest = -1 - default: - args.Earliest = int64(common.Big(obj[0].FromBlock.(string)).Int64()) + if err := blockHeight(obj[0].ToBlock, &num); err != nil { + return err } + args.Latest = num tostr, ok := obj[0].ToBlock.(string) if !ok { diff --git a/rpc/args_test.go b/rpc/args_test.go index 0c7360c53..2622891b9 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -759,10 +759,10 @@ func TestBlockFilterArgsWords(t *testing.T) { } } -func TestBlockFilterArgsNums(t *testing.T) { +func TestBlockFilterArgsBool(t *testing.T) { input := `[{ - "fromBlock": 2, - "toBlock": 3 + "fromBlock": true, + "toBlock": false }]` args := new(BlockFilterArgs) From 3ab9f26943a30ed65da9dac13147ec3aecbaca0a Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 19:17:25 +0100 Subject: [PATCH 19/37] Accept number or string for BlockFilterArgs limit/offset --- rpc/args.go | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 206472aa2..78e60c1f4 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -42,6 +42,24 @@ func blockHeight(raw interface{}, number *int64) error { return nil } +func numString(raw interface{}, number *int64) error { + // Parse as integer + num, ok := raw.(float64) + if ok { + *number = int64(num) + return nil + } + + // Parse as string/hexstring + str, ok := raw.(string) + if !ok { + return NewInvalidTypeError("", "not a number or string") + } + *number = common.String2Big(str).Int64() + + return nil +} + type GetBlockByHashArgs struct { BlockHash common.Hash IncludeTxs bool @@ -410,8 +428,8 @@ func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) { var obj []struct { FromBlock interface{} `json:"fromBlock"` ToBlock interface{} `json:"toBlock"` - Limit string `json:"limit"` - Offset string `json:"offset"` + Limit interface{} `json:"limit"` + Offset interface{} `json:"offset"` Address string `json:"address"` Topics []interface{} `json:"topics"` } @@ -439,22 +457,16 @@ func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) { } args.Latest = num - tostr, ok := obj[0].ToBlock.(string) - if !ok { - return NewInvalidTypeError("toBlock", "not a string") + if err := numString(obj[0].Limit, &num); err != nil { + return err } + args.Max = int(num) - switch tostr { - case "latest": - args.Latest = -1 - case "pending": - args.Latest = -2 - default: - args.Latest = int64(common.Big(obj[0].ToBlock.(string)).Int64()) + if err := numString(obj[0].Offset, &num); err != nil { + return err } + args.Skip = int(num) - args.Max = int(common.Big(obj[0].Limit).Int64()) - args.Skip = int(common.Big(obj[0].Offset).Int64()) args.Address = obj[0].Address args.Topics = obj[0].Topics From f68ca2b6e6b3dafb9f40f5c73ecca3168eb5a090 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 19:34:32 +0100 Subject: [PATCH 20/37] DbArgs tests --- rpc/args_test.go | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/rpc/args_test.go b/rpc/args_test.go index 2622891b9..f28bdbbd3 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -737,6 +737,7 @@ func TestBlockFilterArgs(t *testing.T) { } func TestBlockFilterArgsWords(t *testing.T) { + t.Skip() input := `[{ "fromBlock": "latest", "toBlock": "pending" @@ -811,6 +812,84 @@ func TestDbArgs(t *testing.T) { } } +func TestDbArgsInvalid(t *testing.T) { + input := `{}` + + args := new(DbArgs) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDbArgsEmpty(t *testing.T) { + input := `[]` + + args := new(DbArgs) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDbArgsDatabaseType(t *testing.T) { + input := `[true, "keyval", "valval"]` + + args := new(DbArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDbArgsKeyType(t *testing.T) { + input := `["dbval", 3, "valval"]` + + args := new(DbArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDbArgsValType(t *testing.T) { + input := `["dbval", "keyval", {}]` + + args := new(DbArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDbArgsDatabaseEmpty(t *testing.T) { + input := `["", "keyval", "valval"]` + + args := new(DbArgs) + if err := json.Unmarshal([]byte(input), &args); err != nil { + t.Error(err.Error()) + } + + str := ExpectValidationError(args.requirements()) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDbArgsKeyEmpty(t *testing.T) { + input := `["dbval", "", "valval"]` + + args := new(DbArgs) + if err := json.Unmarshal([]byte(input), &args); err != nil { + t.Error(err.Error()) + } + + str := ExpectValidationError(args.requirements()) + if len(str) > 0 { + t.Error(str) + } +} + func TestDbHexArgs(t *testing.T) { input := `["testDB","myKey","0xbeef"]` expected := new(DbHexArgs) From e21ce9a9b48a651a704a92369712c17113d92ad6 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 19:39:40 +0100 Subject: [PATCH 21/37] DbHexArgs tests --- rpc/args.go | 4 +-- rpc/args_test.go | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 78e60c1f4..459c6546b 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -567,10 +567,10 @@ func (args *DbHexArgs) UnmarshalJSON(b []byte) (err error) { func (a *DbHexArgs) requirements() error { if len(a.Database) == 0 { - return NewInvalidTypeError("Database", "cannot be blank") + return NewValidationError("Database", "cannot be blank") } if len(a.Key) == 0 { - return NewInvalidTypeError("Key", "cannot be blank") + return NewValidationError("Key", "cannot be blank") } return nil } diff --git a/rpc/args_test.go b/rpc/args_test.go index f28bdbbd3..90b283891 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -919,6 +919,84 @@ func TestDbHexArgs(t *testing.T) { } } +func TestDbHexArgsInvalid(t *testing.T) { + input := `{}` + + args := new(DbHexArgs) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDbHexArgsEmpty(t *testing.T) { + input := `[]` + + args := new(DbHexArgs) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDbHexArgsDatabaseType(t *testing.T) { + input := `[true, "keyval", "valval"]` + + args := new(DbHexArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDbHexArgsKeyType(t *testing.T) { + input := `["dbval", 3, "valval"]` + + args := new(DbHexArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDbHexArgsValType(t *testing.T) { + input := `["dbval", "keyval", {}]` + + args := new(DbHexArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDbHexArgsDatabaseEmpty(t *testing.T) { + input := `["", "keyval", "valval"]` + + args := new(DbHexArgs) + if err := json.Unmarshal([]byte(input), &args); err != nil { + t.Error(err.Error()) + } + + str := ExpectValidationError(args.requirements()) + if len(str) > 0 { + t.Error(str) + } +} + +func TestDbHexArgsKeyEmpty(t *testing.T) { + input := `["dbval", "", "valval"]` + + args := new(DbHexArgs) + if err := json.Unmarshal([]byte(input), &args); err != nil { + t.Error(err.Error()) + } + + str := ExpectValidationError(args.requirements()) + if len(str) > 0 { + t.Error(str) + } +} + func TestWhisperMessageArgs(t *testing.T) { input := `[{"from":"0xc931d93e97ab07fe42d923478ba2465f2", "topics": ["0x68656c6c6f20776f726c64"], From 62ebf999bf71ef05e34e234b6e07cc31188970b7 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 20:04:03 +0100 Subject: [PATCH 22/37] FilterStringArgs tests --- rpc/api.go | 4 ---- rpc/args.go | 9 ++------- rpc/args_test.go | 40 +++++++++++++++++++++++++++++++++------- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index ff166264b..bde24847f 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -297,10 +297,6 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err if err := json.Unmarshal(req.Params, &args); err != nil { return err } - if err := args.requirements(); err != nil { - return err - } - id := api.xeth().NewFilterString(args.Word) *reply = common.ToHex(big.NewInt(int64(id)).Bytes()) case "eth_uninstallFilter": diff --git a/rpc/args.go b/rpc/args.go index 459c6546b..96188d02e 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -649,18 +649,13 @@ func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) { if !ok { return NewInvalidTypeError("filter", "not a string") } - args.Word = argstr - - return nil -} - -func (args *FilterStringArgs) requirements() error { - switch args.Word { + switch argstr { case "latest", "pending": break default: return NewValidationError("Word", "Must be `latest` or `pending`") } + args.Word = argstr return nil } diff --git a/rpc/args_test.go b/rpc/args_test.go index 90b283891..9325b1c9b 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -1106,10 +1106,6 @@ func TestFilterStringArgs(t *testing.T) { t.Error(err) } - if err := args.requirements(); err != nil { - t.Error(err) - } - if expected.Word != args.Word { t.Errorf("Word shoud be %#v but is %#v", expected.Word, args.Word) } @@ -1119,9 +1115,39 @@ func TestFilterStringEmptyArgs(t *testing.T) { input := `[]` args := new(FilterStringArgs) - err := json.Unmarshal([]byte(input), &args) - if err == nil { - t.Error("Expected error but didn't get one") + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Errorf(str) + } +} + +func TestFilterStringInvalidArgs(t *testing.T) { + input := `{}` + + args := new(FilterStringArgs) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Errorf(str) + } +} + +func TestFilterStringWordInt(t *testing.T) { + input := `[7]` + + args := new(FilterStringArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Errorf(str) + } +} + +func TestFilterStringWordWrong(t *testing.T) { + input := `["foo"]` + + args := new(FilterStringArgs) + str := ExpectValidationError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Errorf(str) } } From 1f1e98f96b57c0c5c7a9350129f67d425a4c6af4 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 20:10:31 +0100 Subject: [PATCH 23/37] FilterIdArgs --- rpc/args.go | 11 +++++++---- rpc/args_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 96188d02e..921d8e98c 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -664,9 +664,8 @@ type FilterIdArgs struct { } func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) { - var obj []string - r := bytes.NewReader(b) - if err := json.NewDecoder(r).Decode(&obj); err != nil { + var obj []interface{} + if err := json.Unmarshal(b, &obj); err != nil { return NewDecodeParamError(err.Error()) } @@ -674,7 +673,11 @@ func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) { return NewInsufficientParamsError(len(obj), 1) } - args.Id = int(common.Big(obj[0]).Int64()) + var num int64 + if err := numString(obj[0], &num); err != nil { + return err + } + args.Id = int(num) return nil } diff --git a/rpc/args_test.go b/rpc/args_test.go index 9325b1c9b..7bbf729f2 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -1056,6 +1056,36 @@ func TestFilterIdArgs(t *testing.T) { } } +func TestFilterIdArgsInvalid(t *testing.T) { + input := `{}` + + args := new(FilterIdArgs) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Errorf(str) + } +} + +func TestFilterIdArgsEmpty(t *testing.T) { + input := `[]` + + args := new(FilterIdArgs) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Errorf(str) + } +} + +func TestFilterIdArgsBool(t *testing.T) { + input := `[true]` + + args := new(FilterIdArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Errorf(str) + } +} + func TestWhsiperFilterArgs(t *testing.T) { input := `[{"topics": ["0x68656c6c6f20776f726c64"], "to": "0x34ag445g3455b34"}]` expected := new(WhisperFilterArgs) From b414a1303f33aef26b606367ac68163f9b6c87c8 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 20:20:43 +0100 Subject: [PATCH 24/37] WhisperIdentityArgs --- rpc/args.go | 14 ++++++++++---- rpc/args_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 921d8e98c..c11ffa3cc 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -687,9 +687,8 @@ type WhisperIdentityArgs struct { } func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) { - var obj []string - r := bytes.NewReader(b) - if err := json.NewDecoder(r).Decode(&obj); err != nil { + var obj []interface{} + if err := json.Unmarshal(b, &obj); err != nil { return NewDecodeParamError(err.Error()) } @@ -697,7 +696,14 @@ func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) { return NewInsufficientParamsError(len(obj), 1) } - args.Identity = obj[0] + argstr, ok := obj[0].(string) + if !ok { + return NewInvalidTypeError("arg0", "not a string") + } + // if !common.IsHex(argstr) { + // return NewValidationError("arg0", "not a hexstring") + // } + args.Identity = argstr return nil } diff --git a/rpc/args_test.go b/rpc/args_test.go index 7bbf729f2..b3df3ba38 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -1196,6 +1196,36 @@ func TestWhisperIdentityArgs(t *testing.T) { } } +func TestWhisperIdentityArgsInvalid(t *testing.T) { + input := `{}` + + args := new(WhisperIdentityArgs) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Errorf(str) + } +} + +func TestWhisperIdentityArgsEmpty(t *testing.T) { + input := `[]` + + args := new(WhisperIdentityArgs) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Errorf(str) + } +} + +func TestWhisperIdentityArgsInt(t *testing.T) { + input := `[4]` + + args := new(WhisperIdentityArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Errorf(str) + } +} + func TestBlockNumIndexArgs(t *testing.T) { input := `["0x29a", "0x0"]` expected := new(BlockNumIndexArgs) From ddcc8e1673f240556f7a9394d5fbc9ed609a4931 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 20:25:30 +0100 Subject: [PATCH 25/37] SubmitWorkArgs tests --- rpc/args_test.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/rpc/args_test.go b/rpc/args_test.go index b3df3ba38..0b243e760 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -1370,3 +1370,51 @@ func TestSubmitWorkArgs(t *testing.T) { t.Errorf("Digest shoud be %#v but is %#v", expected.Digest, args.Digest) } } + +func TestSubmitWorkArgsInvalid(t *testing.T) { + input := `{}` + + args := new(SubmitWorkArgs) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestSubmitWorkArgsEmpty(t *testing.T) { + input := `[]` + + args := new(SubmitWorkArgs) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestSubmitWorkArgsNonceInt(t *testing.T) { + input := `[1, "0x1234567890abcdef1234567890abcdef", "0xD1GE5700000000000000000000000000"]` + + args := new(SubmitWorkArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} +func TestSubmitWorkArgsHeaderInt(t *testing.T) { + input := `["0x0000000000000001", 1, "0xD1GE5700000000000000000000000000"]` + + args := new(SubmitWorkArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} +func TestSubmitWorkArgsDigestInt(t *testing.T) { + input := `["0x0000000000000001", "0x1234567890abcdef1234567890abcdef", 1]` + + args := new(SubmitWorkArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} From 81f36df910533de63dc5ac66f38b5481961cc0c8 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 20:31:00 +0100 Subject: [PATCH 26/37] CompileArgs --- rpc/args.go | 12 ++++++++---- rpc/args_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index c11ffa3cc..0169ece58 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -617,14 +617,18 @@ type CompileArgs struct { func (args *CompileArgs) UnmarshalJSON(b []byte) (err error) { var obj []interface{} - r := bytes.NewReader(b) - if err := json.NewDecoder(r).Decode(&obj); err != nil { + if err := json.Unmarshal(b, &obj); err != nil { return NewDecodeParamError(err.Error()) } - if len(obj) > 0 { - args.Source = obj[0].(string) + if len(obj) < 1 { + return NewInsufficientParamsError(len(obj), 1) } + argstr, ok := obj[0].(string) + if !ok { + return NewInvalidTypeError("arg0", "is not a string") + } + args.Source = argstr return nil } diff --git a/rpc/args_test.go b/rpc/args_test.go index 0b243e760..7cb63b67e 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -1126,6 +1126,36 @@ func TestCompileArgs(t *testing.T) { } } +func TestCompileArgsInvalid(t *testing.T) { + input := `{}` + + args := new(CompileArgs) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestCompileArgsEmpty(t *testing.T) { + input := `[]` + + args := new(CompileArgs) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestCompileArgsBool(t *testing.T) { + input := `[false]` + + args := new(CompileArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + func TestFilterStringArgs(t *testing.T) { input := `["pending"]` expected := new(FilterStringArgs) From 9ca87afd0ba043043a3d2b4919d72b7f7a39ffe8 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 20:52:09 +0100 Subject: [PATCH 27/37] WhisperFilterArgs --- rpc/api.go | 2 +- rpc/args.go | 24 ++++++++++++++++++------ rpc/args_test.go | 47 +++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index bde24847f..ad48b8607 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -417,7 +417,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } opts := new(xeth.Options) - opts.From = args.From + // opts.From = args.From opts.To = args.To opts.Topics = args.Topics id := api.xeth().NewWhisperFilter(opts) diff --git a/rpc/args.go b/rpc/args.go index 0169ece58..5ad971ced 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -720,9 +720,8 @@ type WhisperFilterArgs struct { func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) { var obj []struct { - To string - From string - Topics []string + To interface{} + Topics []interface{} } if err = json.Unmarshal(b, &obj); err != nil { @@ -733,9 +732,22 @@ func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) { return NewInsufficientParamsError(len(obj), 1) } - args.To = obj[0].To - args.From = obj[0].From - args.Topics = obj[0].Topics + var argstr string + argstr, ok := obj[0].To.(string) + if !ok { + return NewInvalidTypeError("to", "is not a string") + } + args.To = argstr + + t := make([]string, len(obj[0].Topics)) + for i, j := range obj[0].Topics { + argstr, ok := j.(string) + if !ok { + return NewInvalidTypeError("topics["+string(i)+"]", "is not a string") + } + t[i] = argstr + } + args.Topics = t return nil } diff --git a/rpc/args_test.go b/rpc/args_test.go index 7cb63b67e..f668dfdd4 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -1086,10 +1086,9 @@ func TestFilterIdArgsBool(t *testing.T) { } } -func TestWhsiperFilterArgs(t *testing.T) { +func TestWhisperFilterArgs(t *testing.T) { input := `[{"topics": ["0x68656c6c6f20776f726c64"], "to": "0x34ag445g3455b34"}]` expected := new(WhisperFilterArgs) - expected.From = "" expected.To = "0x34ag445g3455b34" expected.Topics = []string{"0x68656c6c6f20776f726c64"} @@ -1098,10 +1097,6 @@ func TestWhsiperFilterArgs(t *testing.T) { t.Error(err) } - if expected.From != args.From { - t.Errorf("From shoud be %#v but is %#v", expected.From, args.From) - } - if expected.To != args.To { t.Errorf("To shoud be %#v but is %#v", expected.To, args.To) } @@ -1111,6 +1106,46 @@ func TestWhsiperFilterArgs(t *testing.T) { // } } +func TestWhisperFilterArgsInvalid(t *testing.T) { + input := `{}` + + args := new(WhisperFilterArgs) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestWhisperFilterArgsEmpty(t *testing.T) { + input := `[]` + + args := new(WhisperFilterArgs) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestWhisperFilterArgsToBool(t *testing.T) { + input := `[{"topics": ["0x68656c6c6f20776f726c64"], "to": false}]` + + args := new(WhisperFilterArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestWhisperFilterArgsTopicInt(t *testing.T) { + input := `[{"topics": [6], "to": "0x34ag445g3455b34"}]` + + args := new(WhisperFilterArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + func TestCompileArgs(t *testing.T) { input := `["contract test { function multiply(uint a) returns(uint d) { return a * 7; } }"]` expected := new(CompileArgs) From 1f3814141b94166cc5bf5b439babe6cc56b3cebf Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 21:07:50 +0100 Subject: [PATCH 28/37] WhisperMessageArgs --- rpc/args.go | 17 ++++++--- rpc/args_test.go | 92 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 104 insertions(+), 5 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 5ad971ced..3637aff66 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -590,8 +590,8 @@ func (args *WhisperMessageArgs) UnmarshalJSON(b []byte) (err error) { To string From string Topics []string - Priority string - Ttl string + Priority interface{} + Ttl interface{} } if err = json.Unmarshal(b, &obj); err != nil { @@ -605,8 +605,17 @@ func (args *WhisperMessageArgs) UnmarshalJSON(b []byte) (err error) { args.To = obj[0].To args.From = obj[0].From args.Topics = obj[0].Topics - args.Priority = uint32(common.Big(obj[0].Priority).Int64()) - args.Ttl = uint32(common.Big(obj[0].Ttl).Int64()) + + var num int64 + if err := numString(obj[0].Priority, &num); err != nil { + return err + } + args.Priority = uint32(num) + + if err := numString(obj[0].Ttl, &num); err != nil { + return err + } + args.Ttl = uint32(num) return nil } diff --git a/rpc/args_test.go b/rpc/args_test.go index f668dfdd4..da98071e9 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -1009,7 +1009,7 @@ func TestWhisperMessageArgs(t *testing.T) { expected.Payload = "0x68656c6c6f20776f726c64" expected.Priority = 100 expected.Ttl = 100 - expected.Topics = []string{"0x68656c6c6f20776f726c64"} + // expected.Topics = []string{"0x68656c6c6f20776f726c64"} args := new(WhisperMessageArgs) if err := json.Unmarshal([]byte(input), &args); err != nil { @@ -1041,6 +1041,96 @@ func TestWhisperMessageArgs(t *testing.T) { // } } +func TestWhisperMessageArgsInt(t *testing.T) { + input := `[{"from":"0xc931d93e97ab07fe42d923478ba2465f2", + "topics": ["0x68656c6c6f20776f726c64"], + "payload":"0x68656c6c6f20776f726c64", + "ttl": 12, + "priority": 16}]` + expected := new(WhisperMessageArgs) + expected.From = "0xc931d93e97ab07fe42d923478ba2465f2" + expected.To = "" + expected.Payload = "0x68656c6c6f20776f726c64" + expected.Priority = 16 + expected.Ttl = 12 + // expected.Topics = []string{"0x68656c6c6f20776f726c64"} + + args := new(WhisperMessageArgs) + if err := json.Unmarshal([]byte(input), &args); err != nil { + t.Error(err) + } + + if expected.From != args.From { + t.Errorf("From shoud be %#v but is %#v", expected.From, args.From) + } + + if expected.To != args.To { + t.Errorf("To shoud be %#v but is %#v", expected.To, args.To) + } + + if expected.Payload != args.Payload { + t.Errorf("Value shoud be %#v but is %#v", expected.Payload, args.Payload) + } + + if expected.Ttl != args.Ttl { + t.Errorf("Ttl shoud be %v but is %v", expected.Ttl, args.Ttl) + } + + if expected.Priority != args.Priority { + t.Errorf("Priority shoud be %v but is %v", expected.Priority, args.Priority) + } + + // if expected.Topics != args.Topics { + // t.Errorf("Topic shoud be %#v but is %#v", expected.Topic, args.Topic) + // } +} + +func TestWhisperMessageArgsInvalid(t *testing.T) { + input := `{}` + + args := new(WhisperMessageArgs) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestWhisperMessageArgsEmpty(t *testing.T) { + input := `[]` + + args := new(WhisperMessageArgs) + str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestWhisperMessageArgsTtlBool(t *testing.T) { + input := `[{"from":"0xc931d93e97ab07fe42d923478ba2465f2", + "topics": ["0x68656c6c6f20776f726c64"], + "payload":"0x68656c6c6f20776f726c64", + "ttl": true, + "priority": "0x64"}]` + args := new(WhisperMessageArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestWhisperMessageArgsPriorityBool(t *testing.T) { + input := `[{"from":"0xc931d93e97ab07fe42d923478ba2465f2", + "topics": ["0x68656c6c6f20776f726c64"], + "payload":"0x68656c6c6f20776f726c64", + "ttl": "0x12", + "priority": true}]` + args := new(WhisperMessageArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), args)) + if len(str) > 0 { + t.Error(str) + } +} + func TestFilterIdArgs(t *testing.T) { input := `["0x7"]` expected := new(FilterIdArgs) From 49a912ce33274f60659ddb3af7e3fec89ee1b59e Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 22:14:31 +0100 Subject: [PATCH 29/37] Undo xeth changes --- rpc/api.go | 6 +++--- rpc/args.go | 8 ++++---- rpc/args_test.go | 4 ++-- xeth/xeth.go | 7 ++----- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index ad48b8607..4ae0ff668 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -212,7 +212,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err args := new(HashIndexArgs) if err := json.Unmarshal(req.Params, &args); err != nil { } - tx := api.xeth().EthTransactionByHash(args.Hash.Hex()) + tx := api.xeth().EthTransactionByHash(args.Hash) if tx != nil { *reply = NewTransactionRes(tx) } @@ -257,7 +257,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err } uhash := br.Uncles[args.Index].Hex() - uncle := NewBlockRes(api.xeth().EthBlockByHexstring(uhash)) + uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash)) *reply = uncle case "eth_getUncleByBlockNumberAndIndex": @@ -275,7 +275,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err } uhash := v.Uncles[args.Index].Hex() - uncle := NewBlockRes(api.xeth().EthBlockByHexstring(uhash)) + uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash)) *reply = uncle case "eth_getCompilers": diff --git a/rpc/args.go b/rpc/args.go index 3637aff66..19258263c 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -61,7 +61,7 @@ func numString(raw interface{}, number *int64) error { } type GetBlockByHashArgs struct { - BlockHash common.Hash + BlockHash string IncludeTxs bool } @@ -80,7 +80,7 @@ func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) { if !ok { return NewInvalidTypeError("blockHash", "not a string") } - args.BlockHash = common.HexToHash(argstr) + args.BlockHash = argstr if len(obj) > 1 { args.IncludeTxs = obj[1].(bool) @@ -360,7 +360,7 @@ func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) { } type HashIndexArgs struct { - Hash common.Hash + Hash string Index int64 } @@ -379,7 +379,7 @@ func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) { if !ok { return NewInvalidTypeError("hash", "not a string") } - args.Hash = common.HexToHash(arg0) + args.Hash = arg0 if len(obj) > 1 { arg1, ok := obj[1].(string) diff --git a/rpc/args_test.go b/rpc/args_test.go index da98071e9..71f1a7058 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -191,7 +191,7 @@ func TestGetBalanceArgsAddressInvalid(t *testing.T) { func TestGetBlockByHashArgs(t *testing.T) { input := `["0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331", true]` expected := new(GetBlockByHashArgs) - expected.BlockHash = common.HexToHash("0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331") + expected.BlockHash = "0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331" expected.IncludeTxs = true args := new(GetBlockByHashArgs) @@ -1444,7 +1444,7 @@ func TestBlockNumIndexArgsIndexInvalid(t *testing.T) { func TestHashIndexArgs(t *testing.T) { input := `["0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", "0x1"]` expected := new(HashIndexArgs) - expected.Hash = common.HexToHash("0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b") + expected.Hash = "0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b" expected.Index = 1 args := new(HashIndexArgs) diff --git a/xeth/xeth.go b/xeth/xeth.go index 92e73c7d5..bf30fc2fc 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -160,16 +160,13 @@ func (self *XEth) BlockByHash(strHash string) *Block { return NewBlock(block) } -func (self *XEth) EthBlockByHash(hash common.Hash) *types.Block { +func (self *XEth) EthBlockByHash(strHash string) *types.Block { + hash := common.HexToHash(strHash) block := self.backend.ChainManager().GetBlock(hash) return block } -func (self *XEth) EthBlockByHexstring(strHash string) *types.Block { - return self.EthBlockByHash(common.HexToHash(strHash)) -} - func (self *XEth) EthTransactionByHash(hash string) *types.Transaction { data, _ := self.backend.ExtraDb().Get(common.FromHex(hash)) if len(data) != 0 { From 2c5a32ebbc60f23e609c8397dad5d09ee38b69bb Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 22:24:48 +0100 Subject: [PATCH 30/37] Undo XEth changes --- rpc/api.go | 14 +++++++------- xeth/xeth.go | 7 ++----- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index ad48b8607..339de4432 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -126,7 +126,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - block := NewBlockRes(api.xeth().EthBlockByHash(args.BlockHash)) + block := NewBlockRes(api.xeth().EthBlockByHash(args.BlockHash.Hex())) *reply = common.ToHex(big.NewInt(int64(len(block.Transactions))).Bytes()) case "eth_getBlockTransactionCountByNumber": args := new(GetBlockByNumberArgs) @@ -142,7 +142,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - block := api.xeth().EthBlockByHash(args.BlockHash) + block := api.xeth().EthBlockByHash(args.BlockHash.Hex()) br := NewBlockRes(block) *reply = common.ToHex(big.NewInt(int64(len(br.Uncles))).Bytes()) case "eth_getUncleCountByBlockNumber": @@ -191,7 +191,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - block := api.xeth().EthBlockByHash(args.BlockHash) + block := api.xeth().EthBlockByHash(args.BlockHash.Hex()) br := NewBlockRes(block) br.fullTx = args.IncludeTxs @@ -222,7 +222,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - block := api.xeth().EthBlockByHash(args.Hash) + block := api.xeth().EthBlockByHash(args.Hash.Hex()) br := NewBlockRes(block) br.fullTx = true @@ -250,14 +250,14 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - br := NewBlockRes(api.xeth().EthBlockByHash(args.Hash)) + br := NewBlockRes(api.xeth().EthBlockByHash(args.Hash.Hex())) if args.Index > int64(len(br.Uncles)) || args.Index < 0 { return NewValidationError("Index", "does not exist") } uhash := br.Uncles[args.Index].Hex() - uncle := NewBlockRes(api.xeth().EthBlockByHexstring(uhash)) + uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash)) *reply = uncle case "eth_getUncleByBlockNumberAndIndex": @@ -275,7 +275,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err } uhash := v.Uncles[args.Index].Hex() - uncle := NewBlockRes(api.xeth().EthBlockByHexstring(uhash)) + uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash)) *reply = uncle case "eth_getCompilers": diff --git a/xeth/xeth.go b/xeth/xeth.go index 92e73c7d5..bf30fc2fc 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -160,16 +160,13 @@ func (self *XEth) BlockByHash(strHash string) *Block { return NewBlock(block) } -func (self *XEth) EthBlockByHash(hash common.Hash) *types.Block { +func (self *XEth) EthBlockByHash(strHash string) *types.Block { + hash := common.HexToHash(strHash) block := self.backend.ChainManager().GetBlock(hash) return block } -func (self *XEth) EthBlockByHexstring(strHash string) *types.Block { - return self.EthBlockByHash(common.HexToHash(strHash)) -} - func (self *XEth) EthTransactionByHash(hash string) *types.Transaction { data, _ := self.backend.ExtraDb().Get(common.FromHex(hash)) if len(data) != 0 { From bb12dbe233db2e064715b329b7ba987c76ba3bfa Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 22:35:42 +0100 Subject: [PATCH 31/37] Prefer args as strings not objects --- rpc/api.go | 36 ++++++++++++++++++------------------ rpc/args.go | 40 ++++++++++++++++++++-------------------- rpc/args_test.go | 28 +++++++++++++--------------- 3 files changed, 51 insertions(+), 53 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index cdd95c888..76fa9b9df 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -94,7 +94,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - v := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address.Hex()).Balance() + v := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Balance() *reply = common.ToHex(v.Bytes()) case "eth_getStorage", "eth_storageAt": args := new(GetStorageArgs) @@ -102,15 +102,15 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - *reply = api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address.Hex()).Storage() + *reply = api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage() case "eth_getStorageAt": args := new(GetStorageAtArgs) if err := json.Unmarshal(req.Params, &args); err != nil { return err } - state := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address.Hex()) - value := state.StorageString(args.Key.Hex()) + state := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address) + value := state.StorageString(args.Key) *reply = common.Bytes2Hex(value.Bytes()) case "eth_getTransactionCount": @@ -119,14 +119,14 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - *reply = api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address.Hex()) + *reply = api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address) case "eth_getBlockTransactionCountByHash": args := new(GetBlockByHashArgs) if err := json.Unmarshal(req.Params, &args); err != nil { return err } - block := NewBlockRes(api.xeth().EthBlockByHash(args.BlockHash.Hex())) + block := NewBlockRes(api.xeth().EthBlockByHash(args.BlockHash)) *reply = common.ToHex(big.NewInt(int64(len(block.Transactions))).Bytes()) case "eth_getBlockTransactionCountByNumber": args := new(GetBlockByNumberArgs) @@ -142,7 +142,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - block := api.xeth().EthBlockByHash(args.BlockHash.Hex()) + block := api.xeth().EthBlockByHash(args.BlockHash) br := NewBlockRes(block) *reply = common.ToHex(big.NewInt(int64(len(br.Uncles))).Bytes()) case "eth_getUncleCountByBlockNumber": @@ -159,14 +159,14 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err if err := json.Unmarshal(req.Params, &args); err != nil { return err } - *reply = api.xethAtStateNum(args.BlockNumber).CodeAt(args.Address.Hex()) + *reply = api.xethAtStateNum(args.BlockNumber).CodeAt(args.Address) case "eth_sendTransaction", "eth_transact": args := new(NewTxArgs) if err := json.Unmarshal(req.Params, &args); err != nil { return err } - v, err := api.xeth().Transact(args.From.Hex(), args.To.Hex(), args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) + v, err := api.xeth().Transact(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) if err != nil { return err } @@ -177,7 +177,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - v, err := api.xethAtStateNum(args.BlockNumber).Call(args.From.Hex(), args.To.Hex(), args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) + v, err := api.xethAtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data) if err != nil { return err } @@ -191,7 +191,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - block := api.xeth().EthBlockByHash(args.BlockHash.Hex()) + block := api.xeth().EthBlockByHash(args.BlockHash) br := NewBlockRes(block) br.fullTx = args.IncludeTxs @@ -222,7 +222,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - block := api.xeth().EthBlockByHash(args.Hash.Hex()) + block := api.xeth().EthBlockByHash(args.Hash) br := NewBlockRes(block) br.fullTx = true @@ -250,14 +250,14 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - br := NewBlockRes(api.xeth().EthBlockByHash(args.Hash.Hex())) + br := NewBlockRes(api.xeth().EthBlockByHash(args.Hash)) if args.Index > int64(len(br.Uncles)) || args.Index < 0 { return NewValidationError("Index", "does not exist") } - uhash := br.Uncles[args.Index].Hex() - uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash)) + uhash := br.Uncles[args.Index] + uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash.Hex())) *reply = uncle case "eth_getUncleByBlockNumberAndIndex": @@ -274,8 +274,8 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return NewValidationError("Index", "does not exist") } - uhash := v.Uncles[args.Index].Hex() - uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash)) + uhash := v.Uncles[args.Index] + uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash.Hex())) *reply = uncle case "eth_getCompilers": @@ -332,7 +332,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err if err := json.Unmarshal(req.Params, &args); err != nil { return err } - *reply = api.xeth().RemoteMining().SubmitWork(args.Nonce, args.Digest, args.Header) + *reply = api.xeth().RemoteMining().SubmitWork(args.Nonce, common.HexToHash(args.Digest), common.HexToHash(args.Header)) case "db_putString": args := new(DbArgs) if err := json.Unmarshal(req.Params, &args); err != nil { diff --git a/rpc/args.go b/rpc/args.go index 19258263c..416c672b0 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -121,8 +121,8 @@ func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) { } type NewTxArgs struct { - From common.Address - To common.Address + From string + To string Value *big.Int Gas *big.Int GasPrice *big.Int @@ -154,8 +154,8 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) { return NewValidationError("from", "is required") } - args.From = common.HexToAddress(ext.From) - args.To = common.HexToAddress(ext.To) + args.From = ext.From + args.To = ext.To args.Value = common.String2Big(ext.Value) args.Gas = common.String2Big(ext.Gas) args.GasPrice = common.String2Big(ext.GasPrice) @@ -172,7 +172,7 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) { } type GetStorageArgs struct { - Address common.Address + Address string BlockNumber int64 } @@ -190,7 +190,7 @@ func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { if !ok { return NewInvalidTypeError("address", "not a string") } - args.Address = common.HexToAddress(addstr) + args.Address = addstr if len(obj) > 1 { if err := blockHeight(obj[1], &args.BlockNumber); err != nil { @@ -202,8 +202,8 @@ func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) { } type GetStorageAtArgs struct { - Address common.Address - Key common.Hash + Address string + Key string BlockNumber int64 } @@ -221,13 +221,13 @@ func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) { if !ok { return NewInvalidTypeError("address", "not a string") } - args.Address = common.HexToAddress(addstr) + args.Address = addstr keystr, ok := obj[1].(string) if !ok { return NewInvalidTypeError("key", "not a string") } - args.Key = common.HexToHash(keystr) + args.Key = keystr if len(obj) > 2 { if err := blockHeight(obj[2], &args.BlockNumber); err != nil { @@ -239,7 +239,7 @@ func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) { } type GetTxCountArgs struct { - Address common.Address + Address string BlockNumber int64 } @@ -257,7 +257,7 @@ func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { if !ok { return NewInvalidTypeError("address", "not a string") } - args.Address = common.HexToAddress(addstr) + args.Address = addstr if len(obj) > 1 { if err := blockHeight(obj[1], &args.BlockNumber); err != nil { @@ -269,7 +269,7 @@ func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) { } type GetBalanceArgs struct { - Address common.Address + Address string BlockNumber int64 } @@ -287,7 +287,7 @@ func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) { if !ok { return NewInvalidTypeError("address", "not a string") } - args.Address = common.HexToAddress(addstr) + args.Address = addstr if len(obj) > 1 { if err := blockHeight(obj[1], &args.BlockNumber); err != nil { @@ -299,7 +299,7 @@ func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) { } type GetDataArgs struct { - Address common.Address + Address string BlockNumber int64 } @@ -317,7 +317,7 @@ func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) { if !ok { return NewInvalidTypeError("address", "not a string") } - args.Address = common.HexToAddress(addstr) + args.Address = addstr if len(obj) > 1 { if err := blockHeight(obj[1], &args.BlockNumber); err != nil { @@ -763,8 +763,8 @@ func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) { type SubmitWorkArgs struct { Nonce uint64 - Header common.Hash - Digest common.Hash + Header string + Digest string } func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) { @@ -788,13 +788,13 @@ func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) { return NewInvalidTypeError("header", "not a string") } - args.Header = common.HexToHash(objstr) + args.Header = objstr if objstr, ok = obj[2].(string); !ok { return NewInvalidTypeError("digest", "not a string") } - args.Digest = common.HexToHash(objstr) + args.Digest = objstr return nil } diff --git a/rpc/args_test.go b/rpc/args_test.go index 71f1a7058..c5d407c97 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -6,8 +6,6 @@ import ( "fmt" "math/big" "testing" - - "github.com/ethereum/go-ethereum/common" ) func ExpectValidationError(err error) string { @@ -106,7 +104,7 @@ func TestSha3ArgsDataInvalid(t *testing.T) { func TestGetBalanceArgs(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x1f"]` expected := new(GetBalanceArgs) - expected.Address = common.HexToAddress("0x407d73d8a49eeb85d32cf465507dd71d507100c1") + expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" expected.BlockNumber = 31 args := new(GetBalanceArgs) @@ -126,7 +124,7 @@ func TestGetBalanceArgs(t *testing.T) { func TestGetBalanceArgsLatest(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"]` expected := new(GetBalanceArgs) - expected.Address = common.HexToAddress("0x407d73d8a49eeb85d32cf465507dd71d507100c1") + expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" expected.BlockNumber = -1 args := new(GetBalanceArgs) @@ -316,8 +314,8 @@ func TestNewTxArgs(t *testing.T) { "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}, "0x10"]` expected := new(NewTxArgs) - expected.From = common.HexToAddress("0xb60e8dd61c5d32be8058bb8eb970870f07233155") - expected.To = common.HexToAddress("0xd46e8dd67c5d32be8058bb8eb970870f072445675") + expected.From = "0xb60e8dd61c5d32be8058bb8eb970870f07233155" + expected.To = "0xd46e8dd67c5d32be8058bb8eb970870f072445675" expected.Gas = big.NewInt(30400) expected.GasPrice = big.NewInt(10000000000000) expected.Value = big.NewInt(10000000000000) @@ -361,7 +359,7 @@ func TestNewTxArgs(t *testing.T) { func TestNewTxArgsBlockInt(t *testing.T) { input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}, 5]` expected := new(NewTxArgs) - expected.From = common.HexToAddress("0xb60e8dd61c5d32be8058bb8eb970870f07233155") + expected.From = "0xb60e8dd61c5d32be8058bb8eb970870f07233155" expected.BlockNumber = big.NewInt(5).Int64() args := new(NewTxArgs) @@ -381,7 +379,7 @@ func TestNewTxArgsBlockInt(t *testing.T) { func TestNewTxArgsBlockInvalid(t *testing.T) { input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}, false]` expected := new(NewTxArgs) - expected.From = common.HexToAddress("0xb60e8dd61c5d32be8058bb8eb970870f07233155") + expected.From = "0xb60e8dd61c5d32be8058bb8eb970870f07233155" expected.BlockNumber = big.NewInt(5).Int64() args := new(NewTxArgs) @@ -438,7 +436,7 @@ func TestNewTxArgsFromEmpty(t *testing.T) { func TestGetStorageArgs(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"]` expected := new(GetStorageArgs) - expected.Address = common.HexToAddress("0x407d73d8a49eeb85d32cf465507dd71d507100c1") + expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" expected.BlockNumber = -1 args := new(GetStorageArgs) @@ -498,8 +496,8 @@ func TestGetStorageAddressInt(t *testing.T) { func TestGetStorageAtArgs(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "0x0", "0x2"]` expected := new(GetStorageAtArgs) - expected.Address = common.HexToAddress("0x407d73d8a49eeb85d32cf465507dd71d507100c1") - expected.Key = common.HexToHash("0x0") + expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" + expected.Key = "0x0" expected.BlockNumber = 2 args := new(GetStorageAtArgs) @@ -573,7 +571,7 @@ func TestGetStorageAtArgsValueNotString(t *testing.T) { func TestGetTxCountArgs(t *testing.T) { input := `["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "pending"]` expected := new(GetTxCountArgs) - expected.Address = common.HexToAddress("0x407d73d8a49eeb85d32cf465507dd71d507100c1") + expected.Address = "0x407d73d8a49eeb85d32cf465507dd71d507100c1" expected.BlockNumber = -2 args := new(GetTxCountArgs) @@ -633,7 +631,7 @@ func TestGetTxCountBlockheightInvalid(t *testing.T) { func TestGetDataArgs(t *testing.T) { input := `["0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", "latest"]` expected := new(GetDataArgs) - expected.Address = common.HexToAddress("0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8") + expected.Address = "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8" expected.BlockNumber = -1 args := new(GetDataArgs) @@ -1505,8 +1503,8 @@ func TestSubmitWorkArgs(t *testing.T) { input := `["0x0000000000000001", "0x1234567890abcdef1234567890abcdef", "0xD1GE5700000000000000000000000000"]` expected := new(SubmitWorkArgs) expected.Nonce = 1 - expected.Header = common.HexToHash("0x1234567890abcdef1234567890abcdef") - expected.Digest = common.HexToHash("0xD1GE5700000000000000000000000000") + expected.Header = "0x1234567890abcdef1234567890abcdef" + expected.Digest = "0xD1GE5700000000000000000000000000" args := new(SubmitWorkArgs) if err := json.Unmarshal([]byte(input), &args); err != nil { From 3fcef54f9b81b49f7af2f06a231cd7e44ea851ba Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 22:58:12 +0100 Subject: [PATCH 32/37] tidy --- rpc/args.go | 13 ++++++++++++- rpc/args_test.go | 11 +++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 65707aa37..806efb9cc 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -29,7 +29,7 @@ func blockHeight(raw interface{}, number *int64) error { // Parse as string/hexstring str, ok := raw.(string) if !ok { - return NewInvalidTypeError("blockNumber", "not a number or string") + return NewInvalidTypeError("", "not a number or string") } switch str { @@ -82,6 +82,17 @@ func numString(raw interface{}, number *int64) error { // } // } +// func hashString(raw interface{}, hash *string) error { +// argstr, ok := raw.(string) +// if !ok { +// return NewInvalidTypeError("", "not a string") +// } +// v := common.IsHex(argstr) +// hash = &argstr + +// return nil +// } + type GetBlockByHashArgs struct { BlockHash string IncludeTxs bool diff --git a/rpc/args_test.go b/rpc/args_test.go index c5d407c97..b658eed68 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -155,14 +155,9 @@ func TestGetBalanceArgsInvalid(t *testing.T) { input := `6` args := new(GetBalanceArgs) - err := json.Unmarshal([]byte(input), &args) - switch err.(type) { - case nil: - t.Error("Expected error but didn't get one") - case *DecodeParamError: - break - default: - t.Errorf("Expected *rpc.DecodeParamError but got %T with message %s", err, err.Error()) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) } } From e0781c2548aec596e6ce1140c5b871555a75f3cb Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 27 Mar 2015 00:07:28 +0100 Subject: [PATCH 33/37] NewTxArgs accept numbers or strings for value/gas/gasprice --- rpc/args.go | 40 ++++++++++++-- rpc/args_test.go | 138 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 162 insertions(+), 16 deletions(-) diff --git a/rpc/args.go b/rpc/args.go index 806efb9cc..78cbca5a9 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -166,7 +166,14 @@ type NewTxArgs struct { func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) { var obj []json.RawMessage - var ext struct{ From, To, Value, Gas, GasPrice, Data string } + var ext struct { + From string + To string + Value interface{} + Gas interface{} + GasPrice interface{} + Data string + } // Decode byte slice to array of RawMessages if err := json.Unmarshal(b, &obj); err != nil { @@ -189,11 +196,36 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) { args.From = ext.From args.To = ext.To - args.Value = common.String2Big(ext.Value) - args.Gas = common.String2Big(ext.Gas) - args.GasPrice = common.String2Big(ext.GasPrice) args.Data = ext.Data + var num int64 + if ext.Value == nil { + return NewValidationError("value", "is required") + } else { + if err := numString(ext.Value, &num); err != nil { + return err + } + } + args.Value = big.NewInt(num) + + if ext.Gas == nil { + return NewValidationError("gas", "is required") + } else { + if err := numString(ext.Gas, &num); err != nil { + return err + } + } + args.Gas = big.NewInt(num) + + if ext.GasPrice == nil { + return NewValidationError("gasprice", "is required") + } else { + if err := numString(ext.GasPrice, &num); err != nil { + return err + } + } + args.GasPrice = big.NewInt(num) + // Check for optional BlockNumber param if len(obj) > 1 { if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil { diff --git a/rpc/args_test.go b/rpc/args_test.go index b658eed68..dee72b86f 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -351,31 +351,50 @@ func TestNewTxArgs(t *testing.T) { } } -func TestNewTxArgsBlockInt(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}, 5]` +func TestNewTxArgsInt(t *testing.T) { + input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", + "gas": 100, + "gasPrice": 50, + "value": 8765456789, + "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}, + 5]` expected := new(NewTxArgs) - expected.From = "0xb60e8dd61c5d32be8058bb8eb970870f07233155" - expected.BlockNumber = big.NewInt(5).Int64() + expected.Gas = big.NewInt(100) + expected.GasPrice = big.NewInt(50) + expected.Value = big.NewInt(8765456789) + expected.BlockNumber = int64(5) args := new(NewTxArgs) if err := json.Unmarshal([]byte(input), &args); err != nil { t.Error(err) } - if expected.From != args.From { - t.Errorf("From shoud be %#v but is %#v", expected.From, args.From) + if bytes.Compare(expected.Gas.Bytes(), args.Gas.Bytes()) != 0 { + t.Errorf("Gas shoud be %v but is %v", expected.Gas, args.Gas) + } + + if bytes.Compare(expected.GasPrice.Bytes(), args.GasPrice.Bytes()) != 0 { + t.Errorf("GasPrice shoud be %v but is %v", expected.GasPrice, args.GasPrice) + } + + if bytes.Compare(expected.Value.Bytes(), args.Value.Bytes()) != 0 { + t.Errorf("Value shoud be %v but is %v", expected.Value, args.Value) } if expected.BlockNumber != args.BlockNumber { - t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber) + t.Errorf("BlockNumber shoud be %v but is %v", expected.BlockNumber, args.BlockNumber) } } -func TestNewTxArgsBlockInvalid(t *testing.T) { - input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}, false]` - expected := new(NewTxArgs) - expected.From = "0xb60e8dd61c5d32be8058bb8eb970870f07233155" - expected.BlockNumber = big.NewInt(5).Int64() +func TestNewTxArgsBlockBool(t *testing.T) { + input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", + "gas": "0x76c0", + "gasPrice": "0x9184e72a000", + "value": "0x9184e72a000", + "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"}, + false]` args := new(NewTxArgs) str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) @@ -384,6 +403,101 @@ func TestNewTxArgsBlockInvalid(t *testing.T) { } } +func TestNewTxArgsGasInvalid(t *testing.T) { + input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", + "gas": false, + "gasPrice": "0x9184e72a000", + "value": "0x9184e72a000", + "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" + }]` + + args := new(NewTxArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestNewTxArgsGaspriceInvalid(t *testing.T) { + input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", + "gas": "0x76c0", + "gasPrice": false, + "value": "0x9184e72a000", + "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" + }]` + + args := new(NewTxArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestNewTxArgsValueInvalid(t *testing.T) { + input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", + "gas": "0x76c0", + "gasPrice": "0x9184e72a000", + "value": false, + "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" + }]` + + args := new(NewTxArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestNewTxArgsGasMissing(t *testing.T) { + input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", + "gasPrice": "0x9184e72a000", + "value": "0x9184e72a000", + "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" + }]` + + args := new(NewTxArgs) + str := ExpectValidationError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestNewTxArgsBlockGaspriceMissing(t *testing.T) { + input := `[{ + "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", + "gas": "0x76c0", + "value": "0x9184e72a000", + "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" + }]` + + args := new(NewTxArgs) + str := ExpectValidationError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestNewTxArgsValueMissing(t *testing.T) { + input := `[{ + "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675", + "gas": "0x76c0", + "gasPrice": "0x9184e72a000", + "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675" + }]` + + args := new(NewTxArgs) + str := ExpectValidationError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + func TestNewTxArgsEmpty(t *testing.T) { input := `[]` From c38630af2330151f7c1f054cd09b38870d0751c8 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 27 Mar 2015 00:13:03 +0100 Subject: [PATCH 34/37] Test blockHeightFromJsonInvalid --- rpc/args_test.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/rpc/args_test.go b/rpc/args_test.go index dee72b86f..cb1d1904b 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -1680,3 +1680,12 @@ func TestSubmitWorkArgsDigestInt(t *testing.T) { t.Error(str) } } + +func TestBlockHeightFromJsonInvalid(t *testing.T) { + var num int64 + var msg json.RawMessage = []byte(`}{`) + str := ExpectDecodeParamError(blockHeightFromJson(msg, &num)) + if len(str) > 0 { + t.Error(str) + } +} From 2788fb4ce51be646946c9dd66a607ab26b2bd6b3 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 27 Mar 2015 11:43:14 +0100 Subject: [PATCH 35/37] More explicit formatting for protocol version --- xeth/xeth.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xeth/xeth.go b/xeth/xeth.go index bf30fc2fc..445303997 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -218,15 +218,15 @@ func (self *XEth) IsMining() bool { } func (self *XEth) EthVersion() string { - return string(self.backend.EthVersion()) + return fmt.Sprintf("%d", self.backend.EthVersion()) } func (self *XEth) NetworkVersion() string { - return string(self.backend.NetVersion()) + return fmt.Sprintf("%d", self.backend.NetVersion()) } func (self *XEth) WhisperVersion() string { - return string(self.backend.ShhVersion()) + return fmt.Sprintf("%d", self.backend.ShhVersion()) } func (self *XEth) ClientVersion() string { From 9f84c78eb5cceb5f413fbdeafe63786f1b958e83 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 27 Mar 2015 15:54:54 +0100 Subject: [PATCH 36/37] BlockFilterArgs --- rpc/api.go | 51 +++++------ rpc/args.go | 116 ++++++++++++++++++++----- rpc/args_test.go | 214 ++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 319 insertions(+), 62 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 76fa9b9df..534b6fc5d 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -471,42 +471,29 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err func toFilterOptions(options *BlockFilterArgs) *core.FilterOptions { var opts core.FilterOptions - // Convert optional address slice/string to byte slice - if str, ok := options.Address.(string); ok { - opts.Address = []common.Address{common.HexToAddress(str)} - } else if slice, ok := options.Address.([]interface{}); ok { - bslice := make([]common.Address, len(slice)) - for i, addr := range slice { - if saddr, ok := addr.(string); ok { - bslice[i] = common.HexToAddress(saddr) - } - } - opts.Address = bslice - } + opts.Address = cAddress(options.Address) + opts.Topics = cTopics(options.Topics) opts.Earliest = options.Earliest opts.Latest = options.Latest - topics := make([][]common.Hash, len(options.Topics)) - for i, topicDat := range options.Topics { - if slice, ok := topicDat.([]interface{}); ok { - topics[i] = make([]common.Hash, len(slice)) - for j, topic := range slice { - topics[i][j] = common.HexToHash(topic.(string)) - } - } else if str, ok := topicDat.(string); ok { - topics[i] = []common.Hash{common.HexToHash(str)} - } - } - opts.Topics = topics - return &opts } -/* - Work() chan<- *types.Block - SetWorkCh(chan<- Work) - Stop() - Start() - Rate() uint64 -*/ +func cAddress(a []string) []common.Address { + bslice := make([]common.Address, len(a)) + for i, addr := range a { + bslice[i] = common.HexToAddress(addr) + } + return bslice +} + +func cTopics(t [][]string) [][]common.Hash { + topics := make([][]common.Hash, len(t)) + for i, iv := range t { + for j, jv := range iv { + topics[i][j] = common.HexToHash(jv) + } + } + return topics +} diff --git a/rpc/args.go b/rpc/args.go index 78cbca5a9..a075f1a59 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -4,12 +4,17 @@ import ( "bytes" "encoding/json" // "errors" - // "fmt" + "fmt" "math/big" "github.com/ethereum/go-ethereum/common" ) +const ( + defaultLogLimit = 100 + defaultLogOffset = 0 +) + func blockHeightFromJson(msg json.RawMessage, number *int64) error { var raw interface{} if err := json.Unmarshal(msg, &raw); err != nil { @@ -483,20 +488,20 @@ func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) { type BlockFilterArgs struct { Earliest int64 Latest int64 - Address interface{} - Topics []interface{} + Address []string + Topics [][]string Skip int Max int } func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) { var obj []struct { - FromBlock interface{} `json:"fromBlock"` - ToBlock interface{} `json:"toBlock"` - Limit interface{} `json:"limit"` - Offset interface{} `json:"offset"` - Address string `json:"address"` - Topics []interface{} `json:"topics"` + FromBlock interface{} `json:"fromBlock"` + ToBlock interface{} `json:"toBlock"` + Limit interface{} `json:"limit"` + Offset interface{} `json:"offset"` + Address interface{} `json:"address"` + Topics interface{} `json:"topics"` } if err = json.Unmarshal(b, &obj); err != nil { @@ -516,33 +521,104 @@ func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) { // return NewDecodeParamError(fmt.Sprintf("ToBlock %v", err)) var num int64 - if err := blockHeight(obj[0].FromBlock, &num); err != nil { - return err + + // if blank then latest + if obj[0].FromBlock == nil { + num = -1 + } else { + if err := blockHeight(obj[0].FromBlock, &num); err != nil { + return err + } } + // if -2 or other "silly" number, use latest if num < 0 { args.Earliest = -1 //latest block } else { args.Earliest = num } - if err := blockHeight(obj[0].ToBlock, &num); err != nil { - return err + // if blank than latest + if obj[0].ToBlock == nil { + num = -1 + } else { + if err := blockHeight(obj[0].ToBlock, &num); err != nil { + return err + } } args.Latest = num - if err := numString(obj[0].Limit, &num); err != nil { - return err + if obj[0].Limit == nil { + num = defaultLogLimit + } else { + if err := numString(obj[0].Limit, &num); err != nil { + return err + } } args.Max = int(num) - if err := numString(obj[0].Offset, &num); err != nil { - return err - + if obj[0].Offset == nil { + num = defaultLogOffset + } else { + if err := numString(obj[0].Offset, &num); err != nil { + return err + } } args.Skip = int(num) - args.Address = obj[0].Address - args.Topics = obj[0].Topics + if obj[0].Address != nil { + marg, ok := obj[0].Address.([]interface{}) + if ok { + v := make([]string, len(marg)) + for i, arg := range marg { + argstr, ok := arg.(string) + if !ok { + return NewInvalidTypeError(fmt.Sprintf("address[%d]", i), "is not a string") + } + v[i] = argstr + } + args.Address = v + } else { + argstr, ok := obj[0].Address.(string) + if ok { + v := make([]string, 1) + v[0] = argstr + args.Address = v + } else { + return NewInvalidTypeError("address", "is not a string or array") + } + } + } + + if obj[0].Topics != nil { + other, ok := obj[0].Topics.([]interface{}) + if ok { + topicdbl := make([][]string, len(other)) + for i, iv := range other { + if argstr, ok := iv.(string); ok { + // Found a string, push into first element of array + topicsgl := make([]string, 1) + topicsgl[0] = argstr + topicdbl[i] = topicsgl + } else if argarray, ok := iv.([]interface{}); ok { + // Found an array of other + topicdbl[i] = make([]string, len(argarray)) + for j, jv := range argarray { + if v, ok := jv.(string); ok { + topicdbl[i][j] = v + } else { + return NewInvalidTypeError(fmt.Sprintf("topic[%d][%d]", i, j), "is not a string") + } + } + } else { + return NewInvalidTypeError(fmt.Sprintf("topic[%d]", i), "not a string or array") + } + } + args.Topics = topicdbl + return nil + } else { + return NewInvalidTypeError("topic", "is not a string or array") + } + } return nil } diff --git a/rpc/args_test.go b/rpc/args_test.go index cb1d1904b..602631b67 100644 --- a/rpc/args_test.go +++ b/rpc/args_test.go @@ -804,14 +804,23 @@ func TestBlockFilterArgs(t *testing.T) { "limit": "0x3", "offset": "0x0", "address": "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", - "topics": ["0x12341234"]}]` + "topics": + [ + ["0xAA", "0xBB"], + ["0xCC", "0xDD"] + ] + }]` + expected := new(BlockFilterArgs) expected.Earliest = 1 expected.Latest = 2 expected.Max = 3 expected.Skip = 0 - expected.Address = "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8" - // expected.Topics = []string{"0x12341234"} + expected.Address = []string{"0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"} + expected.Topics = [][]string{ + []string{"0xAA", "0xBB"}, + []string{"0xCC", "0xDD"}, + } args := new(BlockFilterArgs) if err := json.Unmarshal([]byte(input), &args); err != nil { @@ -834,17 +843,73 @@ func TestBlockFilterArgs(t *testing.T) { t.Errorf("Skip shoud be %#v but is %#v", expected.Skip, args.Skip) } - if expected.Address != args.Address { + if expected.Address[0] != args.Address[0] { t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) } - // if expected.Topics != args.Topics { - // t.Errorf("Topic shoud be %#v but is %#v", expected.Topic, args.Topic) - // } + if expected.Topics[0][0] != args.Topics[0][0] { + t.Errorf("Topics shoud be %#v but is %#v", expected.Topics, args.Topics) + } + if expected.Topics[0][1] != args.Topics[0][1] { + t.Errorf("Topics shoud be %#v but is %#v", expected.Topics, args.Topics) + } + if expected.Topics[1][0] != args.Topics[1][0] { + t.Errorf("Topics shoud be %#v but is %#v", expected.Topics, args.Topics) + } + if expected.Topics[1][1] != args.Topics[1][1] { + t.Errorf("Topics shoud be %#v but is %#v", expected.Topics, args.Topics) + } + +} + +func TestBlockFilterArgsDefaults(t *testing.T) { + input := `[{ + "address": ["0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"], + "topics": ["0xAA","0xBB"] + }]` + expected := new(BlockFilterArgs) + expected.Earliest = -1 + expected.Latest = -1 + expected.Max = 100 + expected.Skip = 0 + expected.Address = []string{"0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"} + expected.Topics = [][]string{[]string{"0xAA"}, []string{"0xBB"}} + + args := new(BlockFilterArgs) + 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) + } + + if expected.Max != args.Max { + t.Errorf("Max shoud be %#v but is %#v", expected.Max, args.Max) + } + + if expected.Skip != args.Skip { + t.Errorf("Skip shoud be %#v but is %#v", expected.Skip, args.Skip) + } + + if expected.Address[0] != args.Address[0] { + t.Errorf("Address shoud be %#v but is %#v", expected.Address, args.Address) + } + + if expected.Topics[0][0] != args.Topics[0][0] { + t.Errorf("Topics shoud be %#v but is %#v", expected.Topics, args.Topics) + } + + if expected.Topics[1][0] != args.Topics[1][0] { + t.Errorf("Topics shoud be %#v but is %#v", expected.Topics, args.Topics) + } } func TestBlockFilterArgsWords(t *testing.T) { - t.Skip() input := `[{ "fromBlock": "latest", "toBlock": "pending" @@ -867,10 +932,33 @@ func TestBlockFilterArgsWords(t *testing.T) { } } -func TestBlockFilterArgsBool(t *testing.T) { +func TestBlockFilterArgsInvalid(t *testing.T) { + input := `{}` + + args := new(BlockFilterArgs) + str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestBlockFilterArgsFromBool(t *testing.T) { input := `[{ "fromBlock": true, - "toBlock": false + "toBlock": "pending" + }]` + + args := new(BlockFilterArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestBlockFilterArgsToBool(t *testing.T) { + input := `[{ + "fromBlock": "pending", + "toBlock": true }]` args := new(BlockFilterArgs) @@ -890,6 +978,112 @@ func TestBlockFilterArgsEmptyArgs(t *testing.T) { } } +func TestBlockFilterArgsLimitInvalid(t *testing.T) { + input := `[{"limit": false}]` + + args := new(BlockFilterArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestBlockFilterArgsOffsetInvalid(t *testing.T) { + input := `[{"offset": true}]` + + args := new(BlockFilterArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestBlockFilterArgsAddressInt(t *testing.T) { + input := `[{ + "address": 1, + "topics": "0x12341234"}]` + + args := new(BlockFilterArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestBlockFilterArgsAddressSliceInt(t *testing.T) { + input := `[{ + "address": [1], + "topics": "0x12341234"}]` + + args := new(BlockFilterArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestBlockFilterArgsTopicInt(t *testing.T) { + input := `[{ + "address": ["0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8"], + "topics": 1}]` + + args := new(BlockFilterArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestBlockFilterArgsTopicSliceInt(t *testing.T) { + input := `[{ + "address": "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", + "topics": [1]}]` + + args := new(BlockFilterArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestBlockFilterArgsTopicSliceInt2(t *testing.T) { + input := `[{ + "address": "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", + "topics": ["0xAA", [1]]}]` + + args := new(BlockFilterArgs) + str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args)) + if len(str) > 0 { + t.Error(str) + } +} + +func TestBlockFilterArgsTopicComplex(t *testing.T) { + input := `[{ + "address": "0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8", + "topics": ["0xAA", ["0xBB", "0xCC"]] + }]` + + args := new(BlockFilterArgs) + if err := json.Unmarshal([]byte(input), &args); err != nil { + t.Error(err) + fmt.Printf("%v\n", args) + return + } + + if args.Topics[0][0] != "0xAA" { + t.Errorf("Topic should be %s but is %s", "0xAA", args.Topics[0][0]) + } + + if args.Topics[1][0] != "0xBB" { + t.Errorf("Topic should be %s but is %s", "0xBB", args.Topics[0][0]) + } + + if args.Topics[1][1] != "0xCC" { + t.Errorf("Topic should be %s but is %s", "0xCC", args.Topics[0][0]) + } +} + func TestDbArgs(t *testing.T) { input := `["testDB","myKey","0xbeef"]` expected := new(DbArgs) From 43d521e90e9516429dd0499ff88bf3f37ec78c48 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 27 Mar 2015 16:36:01 +0100 Subject: [PATCH 37/37] Decouple core from rpc --- core/filter.go | 23 ----------------------- rpc/api.go | 37 ++----------------------------------- xeth/xeth.go | 36 ++++++++++++++++++++++++++++++++---- 3 files changed, 34 insertions(+), 62 deletions(-) diff --git a/core/filter.go b/core/filter.go index ba5d5e14e..1dca5501d 100644 --- a/core/filter.go +++ b/core/filter.go @@ -12,17 +12,6 @@ type AccountChange struct { Address, StateAddress []byte } -type FilterOptions struct { - Earliest int64 - Latest int64 - - Address []common.Address - Topics [][]common.Hash - - Skip int - Max int -} - // Filtering interface type Filter struct { eth Backend @@ -44,18 +33,6 @@ func NewFilter(eth Backend) *Filter { return &Filter{eth: eth} } -// SetOptions copies the filter options to the filter it self. The reason for this "silly" copy -// is simply because named arguments in this case is extremely nice and readable. -func (self *Filter) SetOptions(options *FilterOptions) { - self.earliest = options.Earliest - self.latest = options.Latest - self.skip = options.Skip - self.max = options.Max - self.address = options.Address - self.topics = options.Topics - -} - // Set the earliest and latest block for filtering. // -1 = latest block (i.e., the current block) // hash = particular hash from-to diff --git a/rpc/api.go b/rpc/api.go index f755f07bd..8803c28dd 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -6,7 +6,6 @@ import ( "sync" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/xeth" ) @@ -277,8 +276,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err return err } - opts := toFilterOptions(args) - id := api.xeth().RegisterFilter(opts) + id := api.xeth().RegisterFilter(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics) *reply = common.ToHex(big.NewInt(int64(id)).Bytes()) case "eth_newBlockFilter": args := new(FilterStringArgs) @@ -310,8 +308,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err if err := json.Unmarshal(req.Params, &args); err != nil { return err } - opts := toFilterOptions(args) - *reply = NewLogsRes(api.xeth().AllLogs(opts)) + *reply = NewLogsRes(api.xeth().AllLogs(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics)) case "eth_getWork": api.xeth().SetMining(true) *reply = api.xeth().RemoteMining().GetWork() @@ -456,33 +453,3 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err rpclogger.DebugDetailf("Reply: %T %s", reply, reply) return nil } - -func toFilterOptions(options *BlockFilterArgs) *core.FilterOptions { - var opts core.FilterOptions - - opts.Address = cAddress(options.Address) - opts.Topics = cTopics(options.Topics) - - opts.Earliest = options.Earliest - opts.Latest = options.Latest - - return &opts -} - -func cAddress(a []string) []common.Address { - bslice := make([]common.Address, len(a)) - for i, addr := range a { - bslice[i] = common.HexToAddress(addr) - } - return bslice -} - -func cTopics(t [][]string) [][]common.Hash { - topics := make([][]common.Hash, len(t)) - for i, iv := range t { - for j, jv := range iv { - topics[i][j] = common.HexToHash(jv) - } - } - return topics -} diff --git a/xeth/xeth.go b/xeth/xeth.go index 5bb271591..7e1548964 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -110,6 +110,24 @@ func (self *XEth) stop() { close(self.quit) } +func cAddress(a []string) []common.Address { + bslice := make([]common.Address, len(a)) + for i, addr := range a { + bslice[i] = common.HexToAddress(addr) + } + return bslice +} + +func cTopics(t [][]string) [][]common.Hash { + topics := make([][]common.Hash, len(t)) + for i, iv := range t { + for j, jv := range iv { + topics[i][j] = common.HexToHash(jv) + } + } + return topics +} + func (self *XEth) DefaultGas() *big.Int { return defaultGas } func (self *XEth) DefaultGasPrice() *big.Int { return defaultGasPrice } @@ -301,10 +319,15 @@ func (self *XEth) SecretToAddress(key string) string { return common.ToHex(pair.Address()) } -func (self *XEth) RegisterFilter(args *core.FilterOptions) int { +func (self *XEth) RegisterFilter(earliest, latest int64, skip, max int, address []string, topics [][]string) int { var id int filter := core.NewFilter(self.backend) - filter.SetOptions(args) + filter.SetEarliestBlock(earliest) + filter.SetLatestBlock(latest) + filter.SetSkip(skip) + filter.SetMax(max) + filter.SetAddress(cAddress(address)) + filter.SetTopics(cTopics(topics)) filter.LogsCallback = func(logs state.Logs) { self.logMut.Lock() defer self.logMut.Unlock() @@ -380,9 +403,14 @@ func (self *XEth) Logs(id int) state.Logs { return nil } -func (self *XEth) AllLogs(args *core.FilterOptions) state.Logs { +func (self *XEth) AllLogs(earliest, latest int64, skip, max int, address []string, topics [][]string) state.Logs { filter := core.NewFilter(self.backend) - filter.SetOptions(args) + filter.SetEarliestBlock(earliest) + filter.SetLatestBlock(latest) + filter.SetSkip(skip) + filter.SetMax(max) + filter.SetAddress(cAddress(address)) + filter.SetTopics(cTopics(topics)) return filter.Find() }