From d2fa6e7753deb0f7fe5e1d802460c88c2885b954 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Wed, 18 Mar 2015 20:56:06 -0700 Subject: [PATCH 01/54] vm: explicit error checks in ecrecover. closes #505 --- vm/address.go | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/vm/address.go b/vm/address.go index 215f4bc8fa..e4c33ec808 100644 --- a/vm/address.go +++ b/vm/address.go @@ -3,8 +3,8 @@ package vm import ( "math/big" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" ) type Address interface { @@ -61,15 +61,29 @@ func ripemd160Func(in []byte) []byte { return common.LeftPadBytes(crypto.Ripemd160(in), 32) } +const EcRecoverInputLength = 128 + func ecrecoverFunc(in []byte) []byte { - // In case of an invalid sig. Defaults to return nil - defer func() { recover() }() - + // "in" is (hash, v, r, s), each 32 bytes + // but for ecrecover we want (r, s, v) + if len(in) < EcRecoverInputLength { + return nil + } hash := in[:32] - v := common.BigD(in[32:64]).Bytes()[0] - 27 + // v is only a bit, but comes as 32 bytes from vm. We only need least significant byte + encodedV := in[32:64] + v := encodedV[31] - 27 + if !(v == 0 || v == 1) { + return nil + } sig := append(in[64:], v) - - return common.LeftPadBytes(crypto.Sha3(crypto.Ecrecover(append(hash, sig...))[1:])[12:], 32) + pubKey := crypto.Ecrecover(append(hash, sig...)) + // secp256.go returns either nil or 65 bytes + if pubKey == nil || len(pubKey) != 65 { + return nil + } + // the first byte of pubkey is bitcoin heritage + return common.LeftPadBytes(crypto.Sha3(pubKey[1:])[12:], 32) } func memCpy(in []byte) []byte { From c7dc379da5a02fb8ac92788fa317379fbde00d20 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Thu, 26 Mar 2015 10:14:52 +0100 Subject: [PATCH 02/54] 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 aa5b54199f..8d1a412d14 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 5b655024ca..9a51959f41 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 5cbafd4b2f..c6d3a558b5 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 bf30fc2fcc..92e73c7d5c 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 03/54] 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 8d1a412d14..b5f7597115 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 9a51959f41..2446e778f4 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 c6d3a558b5..328eab0eca 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 04/54] 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 b5f7597115..f5ce8acb61 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 2446e778f4..8d7427f6fc 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 328eab0eca..20930a3d8d 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 05/54] 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 20930a3d8d..b6d592a094 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 06/54] 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 8d7427f6fc..7504293a4b 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 b6d592a094..b9a68d8bc5 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 07/54] 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 7504293a4b..fc7307b838 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 08/54] 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 fc7307b838..82ee00d252 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 b9a68d8bc5..e5a27e38a3 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 09/54] 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 f5ce8acb61..10d2e529ec 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 82ee00d252..84c9ee0f7a 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 e5a27e38a3..dea34b956c 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 10/54] 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 10d2e529ec..6f3e78cc0b 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 84c9ee0f7a..93af3258ff 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 dea34b956c..e13549d000 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 11/54] 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 6f3e78cc0b..aba47eee25 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 93af3258ff..81343dd018 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 e13549d000..4792f4f889 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 12/54] 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 7f5ebab11b..5c498234f9 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 5274c91e42..91f0152dc8 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 13/54] 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 81343dd018..30ed1a17c2 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 4792f4f889..7dec5d8f47 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 14/54] 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 aba47eee25..0f5bac6574 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 30ed1a17c2..2b62811e30 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 7dec5d8f47..b8df084133 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 15/54] 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 2b62811e30..34ed84fc20 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 b8df084133..82bdcd2573 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 16/54] 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 0f5bac6574..ff166264b4 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 34ed84fc20..d3449928bd 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 82bdcd2573..ab74721b39 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 17/54] 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 ab74721b39..fa46f65150 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 18/54] 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 d3449928bd..b23216c987 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 fa46f65150..0c7360c53b 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 19/54] 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 b23216c987..206472aa2c 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 0c7360c53b..2622891b99 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 20/54] 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 206472aa2c..78e60c1f4b 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 21/54] 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 2622891b99..f28bdbbd34 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 22/54] 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 78e60c1f4b..459c6546b6 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 f28bdbbd34..90b2838917 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 23/54] 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 ff166264b4..bde24847fe 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 459c6546b6..96188d02eb 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 90b2838917..9325b1c9b5 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 24/54] 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 96188d02eb..921d8e98cc 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 9325b1c9b5..7bbf729f22 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 25/54] 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 921d8e98cc..c11ffa3cce 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 7bbf729f22..b3df3ba386 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 26/54] 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 b3df3ba386..0b243e7603 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 27/54] 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 c11ffa3cce..0169ece583 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 0b243e7603..7cb63b67e5 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 28/54] 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 bde24847fe..ad48b86078 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 0169ece583..5ad971cedc 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 7cb63b67e5..f668dfdd4e 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 29/54] 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 5ad971cedc..3637aff66d 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 f668dfdd4e..da98071e94 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 30/54] 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 ad48b86078..4ae0ff668b 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 3637aff66d..19258263c5 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 da98071e94..71f1a7058b 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 92e73c7d5c..bf30fc2fcc 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 31/54] 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 ad48b86078..339de44328 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 92e73c7d5c..bf30fc2fcc 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 32/54] 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 cdd95c888d..76fa9b9df6 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 19258263c5..416c672b08 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 71f1a7058b..c5d407c973 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 33/54] 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 65707aa372..806efb9ccc 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 c5d407c973..b658eed68e 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 34/54] 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 806efb9ccc..78cbca5a98 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 b658eed68e..dee72b86ff 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 35/54] 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 dee72b86ff..cb1d1904b3 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 36/54] 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 bf30fc2fcc..445303997e 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 8e7549db0bedd5c319687f80452180bb0d19c46a Mon Sep 17 00:00:00 2001 From: aperseghin Date: Fri, 27 Mar 2015 08:38:20 -0400 Subject: [PATCH 37/54] Minor fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 22b331cbd2..a163e67c7a 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Mist (GUI): Geth (CLI): -`go get github.com/ethereum/go-ethereum/cmd/ethereum` +`go get github.com/ethereum/go-ethereum/cmd/geth` As of POC-8, go-ethereum uses [Godep](https://github.com/tools/godep) to manage dependencies. Assuming you have [your environment all set up](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum), switch to the go-ethereum repository root folder, and build/install the executable you need: From db1c52918fb517416842d05c41beb68d828fbe63 Mon Sep 17 00:00:00 2001 From: aperseghin Date: Fri, 27 Mar 2015 09:29:35 -0400 Subject: [PATCH 38/54] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 22b331cbd2..a163e67c7a 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Mist (GUI): Geth (CLI): -`go get github.com/ethereum/go-ethereum/cmd/ethereum` +`go get github.com/ethereum/go-ethereum/cmd/geth` As of POC-8, go-ethereum uses [Godep](https://github.com/tools/godep) to manage dependencies. Assuming you have [your environment all set up](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum), switch to the go-ethereum repository root folder, and build/install the executable you need: From 9f84c78eb5cceb5f413fbdeafe63786f1b958e83 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Fri, 27 Mar 2015 15:54:54 +0100 Subject: [PATCH 39/54] 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 76fa9b9df6..534b6fc5d4 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 78cbca5a98..a075f1a596 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 cb1d1904b3..602631b677 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 40/54] 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 ba5d5e14e7..1dca5501dd 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 f755f07bd9..8803c28dd9 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 5bb271591f..7e1548964e 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() } From 47af2f02cb6b03d1fec1b0cecff8cab965b33edc Mon Sep 17 00:00:00 2001 From: Kobi Gurkan Date: Fri, 27 Mar 2015 22:22:13 +0300 Subject: [PATCH 41/54] eth_getTransactionCount now returns a hex string --- rpc/api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index f2915f658e..2b81fdd2ba 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -122,8 +122,8 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err if err != nil { return err } - - *reply = api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address) + count := api.xethAtStateNum(args.BlockNumber).TxCountAt(args.Address) + *reply = common.ToHex(big.NewInt(int64(count)).Bytes()) case "eth_getBlockTransactionCountByHash": args := new(GetBlockByHashArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From a4cbd1c7be5187a27ff70adeeabc82888d3d7cfd Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Sat, 28 Mar 2015 00:32:23 +0100 Subject: [PATCH 42/54] ethereum -> geth --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 22b331cbd2..a163e67c7a 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Mist (GUI): Geth (CLI): -`go get github.com/ethereum/go-ethereum/cmd/ethereum` +`go get github.com/ethereum/go-ethereum/cmd/geth` As of POC-8, go-ethereum uses [Godep](https://github.com/tools/godep) to manage dependencies. Assuming you have [your environment all set up](https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum), switch to the go-ethereum repository root folder, and build/install the executable you need: From 3b7e4173ce00fb82ee2f186350dd2aca528ea60d Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 28 Mar 2015 20:03:25 +0100 Subject: [PATCH 43/54] Cleanup VM --- core/execution.go | 27 +++++++++++++++------------ core/vm/common.go | 10 ++++++++++ core/vm/context.go | 14 +++++--------- core/vm/vm.go | 8 +++++++- core/vm_env.go | 10 +++------- 5 files changed, 40 insertions(+), 29 deletions(-) diff --git a/core/execution.go b/core/execution.go index 72eb22bd5c..24e085e6dd 100644 --- a/core/execution.go +++ b/core/execution.go @@ -11,14 +11,18 @@ import ( ) type Execution struct { - env vm.Environment - address *common.Address - input []byte + env vm.Environment + address *common.Address + input []byte + evm vm.VirtualMachine + Gas, price, value *big.Int } func NewExecution(env vm.Environment, address *common.Address, input []byte, gas, gasPrice, value *big.Int) *Execution { - return &Execution{env: env, address: address, input: input, Gas: gas, price: gasPrice, value: value} + exe := &Execution{env: env, address: address, input: input, Gas: gas, price: gasPrice, value: value} + exe.evm = vm.NewVm(env) + return exe } func (self *Execution) Call(codeAddr common.Address, caller vm.ContextRef) ([]byte, error) { @@ -28,11 +32,17 @@ func (self *Execution) Call(codeAddr common.Address, caller vm.ContextRef) ([]by return self.exec(&codeAddr, code, caller) } +func (self *Execution) Create(caller vm.ContextRef) (ret []byte, err error, account *state.StateObject) { + ret, err = self.exec(nil, self.input, caller) + account = self.env.State().GetStateObject(*self.address) + return +} + func (self *Execution) exec(contextAddr *common.Address, code []byte, caller vm.ContextRef) (ret []byte, err error) { start := time.Now() env := self.env - evm := vm.NewVm(env) + evm := self.evm if env.Depth() == vm.MaxCallDepth { caller.ReturnGas(self.Gas, self.price) @@ -70,10 +80,3 @@ func (self *Execution) exec(contextAddr *common.Address, code []byte, caller vm. return } - -func (self *Execution) Create(caller vm.ContextRef) (ret []byte, err error, account *state.StateObject) { - ret, err = self.exec(nil, self.input, caller) - account = self.env.State().GetStateObject(*self.address) - - return -} diff --git a/core/vm/common.go b/core/vm/common.go index 8d8f4253fc..5226f48283 100644 --- a/core/vm/common.go +++ b/core/vm/common.go @@ -80,3 +80,13 @@ func getData(data []byte, start, size *big.Int) []byte { e := common.BigMin(new(big.Int).Add(s, size), dlen) return common.RightPadBytes(data[s.Uint64():e.Uint64()], int(size.Uint64())) } + +func UseGas(gas, amount *big.Int) bool { + if gas.Cmp(amount) < 0 { + return false + } + + // Sub the amount of gas from the remaining + gas.Sub(gas, amount) + return true +} diff --git a/core/vm/context.go b/core/vm/context.go index e73199b779..e4b94b6009 100644 --- a/core/vm/context.go +++ b/core/vm/context.go @@ -74,16 +74,12 @@ func (c *Context) Return(ret []byte) []byte { /* * Gas functions */ -func (c *Context) UseGas(gas *big.Int) bool { - if c.Gas.Cmp(gas) < 0 { - return false +func (c *Context) UseGas(gas *big.Int) (ok bool) { + ok = UseGas(c.Gas, gas) + if ok { + c.UsedGas.Add(c.UsedGas, gas) } - - // Sub the amount of gas from the remaining - c.Gas.Sub(c.Gas, gas) - c.UsedGas.Add(c.UsedGas, gas) - - return true + return } // Implement the caller interface diff --git a/core/vm/vm.go b/core/vm/vm.go index 88fbdf7638..eceb6e3a90 100644 --- a/core/vm/vm.go +++ b/core/vm/vm.go @@ -24,6 +24,9 @@ type Vm struct { Fn string Recoverable bool + + // Will be called before the vm returns + After func(*Context, error) } func New(env Environment) *Vm { @@ -47,6 +50,10 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) { // User defer pattern to check for an error and, based on the error being nil or not, use all gas and return. defer func() { + if self.After != nil { + self.After(context, err) + } + if err != nil { self.Printf(" %v", err).Endl() // In case of a VM exception (known exceptions) all gas consumed (panics NOT included). @@ -647,7 +654,6 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) { self.Printf(" (*) 0x0 %v", suberr) } else { - // gas < len(ret) * CreateDataGas == NO_CODE dataGas := big.NewInt(int64(len(ret))) dataGas.Mul(dataGas, GasCreateByte) diff --git a/core/vm_env.go b/core/vm_env.go index 52e8b20a95..6a604fccd3 100644 --- a/core/vm_env.go +++ b/core/vm_env.go @@ -54,21 +54,17 @@ func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error { return vm.Transfer(from, to, amount) } -func (self *VMEnv) vm(addr *common.Address, data []byte, gas, price, value *big.Int) *Execution { - return NewExecution(self, addr, data, gas, price, value) -} - func (self *VMEnv) Call(me vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { - exe := self.vm(&addr, data, gas, price, value) + exe := NewExecution(self, &addr, data, gas, price, value) return exe.Call(addr, me) } func (self *VMEnv) CallCode(me vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) { maddr := me.Address() - exe := self.vm(&maddr, data, gas, price, value) + exe := NewExecution(self, &maddr, data, gas, price, value) return exe.Call(addr, me) } func (self *VMEnv) Create(me vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) { - exe := self.vm(nil, data, gas, price, value) + exe := NewExecution(self, nil, data, gas, price, value) return exe.Create(me) } From 368ebe63a95c870a90dba8635d3a5c3863c43330 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 28 Mar 2015 20:30:16 +0100 Subject: [PATCH 44/54] Cleanup VM. * CALLDATA use getData * removed old context get range value * removed casting big => int for some cases * pc now big int #457 --- core/vm/analysis.go | 24 ++++++++++++++++---- core/vm/common.go | 1 + core/vm/context.go | 20 ++++------------- core/vm/vm.go | 54 ++++++++++++++++----------------------------- 4 files changed, 44 insertions(+), 55 deletions(-) diff --git a/core/vm/analysis.go b/core/vm/analysis.go index 411df56861..264d55cb92 100644 --- a/core/vm/analysis.go +++ b/core/vm/analysis.go @@ -1,9 +1,25 @@ package vm -import "gopkg.in/fatih/set.v0" +import ( + "math/big" -func analyseJumpDests(code []byte) (dests *set.Set) { - dests = set.New() + "gopkg.in/fatih/set.v0" +) + +type destinations struct { + set *set.Set +} + +func (d *destinations) Has(dest *big.Int) bool { + return d.set.Has(string(dest.Bytes())) +} + +func (d *destinations) Add(dest *big.Int) { + d.set.Add(string(dest.Bytes())) +} + +func analyseJumpDests(code []byte) (dests *destinations) { + dests = &destinations{set.New()} for pc := uint64(0); pc < uint64(len(code)); pc++ { var op OpCode = OpCode(code[pc]) @@ -13,7 +29,7 @@ func analyseJumpDests(code []byte) (dests *set.Set) { pc += a case JUMPDEST: - dests.Add(pc) + dests.Add(big.NewInt(int64(pc))) } } return diff --git a/core/vm/common.go b/core/vm/common.go index 5226f48283..5ff4e05f2d 100644 --- a/core/vm/common.go +++ b/core/vm/common.go @@ -33,6 +33,7 @@ var ( S256 = common.S256 Zero = common.Big0 + One = common.Big1 max = big.NewInt(math.MaxInt64) ) diff --git a/core/vm/context.go b/core/vm/context.go index e4b94b6009..29bb9f74e1 100644 --- a/core/vm/context.go +++ b/core/vm/context.go @@ -1,7 +1,6 @@ package vm import ( - "math" "math/big" "github.com/ethereum/go-ethereum/common" @@ -41,29 +40,18 @@ func NewContext(caller ContextRef, object ContextRef, value, gas, price *big.Int return c } -func (c *Context) GetOp(n uint64) OpCode { +func (c *Context) GetOp(n *big.Int) OpCode { return OpCode(c.GetByte(n)) } -func (c *Context) GetByte(n uint64) byte { - if n < uint64(len(c.Code)) { - return c.Code[n] +func (c *Context) GetByte(n *big.Int) byte { + if n.Cmp(big.NewInt(int64(len(c.Code)))) < 0 { + return c.Code[n.Int64()] } return 0 } -func (c *Context) GetBytes(x, y int) []byte { - return c.GetRangeValue(uint64(x), uint64(y)) -} - -func (c *Context) GetRangeValue(x, size uint64) []byte { - x = uint64(math.Min(float64(x), float64(len(c.Code)))) - y := uint64(math.Min(float64(x+size), float64(len(c.Code)))) - - return common.RightPadBytes(c.Code[x:y], int(size)) -} - func (c *Context) Return(ret []byte) []byte { // Return the remaining gas to the caller c.caller.ReturnGas(c.Gas, c.Price) diff --git a/core/vm/vm.go b/core/vm/vm.go index eceb6e3a90..6c3dd240a0 100644 --- a/core/vm/vm.go +++ b/core/vm/vm.go @@ -72,23 +72,20 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) { var ( op OpCode - destinations = analyseJumpDests(context.Code) - mem = NewMemory() - stack = newStack() - pc uint64 = 0 - step = 0 - statedb = self.env.State() + destinations = analyseJumpDests(context.Code) + mem = NewMemory() + stack = newStack() + pc = new(big.Int) + statedb = self.env.State() - jump = func(from uint64, to *big.Int) error { - p := to.Uint64() - - nop := context.GetOp(p) - if !destinations.Has(p) { - return fmt.Errorf("invalid jump destination (%v) %v", nop, p) + jump = func(from *big.Int, to *big.Int) error { + nop := context.GetOp(to) + if !destinations.Has(to) { + return fmt.Errorf("invalid jump destination (%v) %v", nop, to) } self.Printf(" ~> %v", to) - pc = to.Uint64() + pc = to self.Endl() @@ -105,7 +102,6 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) { // The base for all big integer arithmetic base := new(big.Int) - step++ // Get the memory location of pc op = context.GetOp(pc) @@ -428,22 +424,11 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) { self.Printf(" => %v", value) case CALLDATALOAD: - var ( - offset = stack.pop() - data = make([]byte, 32) - lenData = big.NewInt(int64(len(callData))) - ) - - if lenData.Cmp(offset) >= 0 { - length := new(big.Int).Add(offset, common.Big32) - length = common.BigMin(length, lenData) - - copy(data, callData[offset.Int64():length.Int64()]) - } + data := getData(callData, stack.pop(), common.Big32) self.Printf(" => 0x%x", data) - stack.push(common.BigD(data)) + stack.push(common.Bytes2Big(data)) case CALLDATASIZE: l := int64(len(callData)) stack.push(big.NewInt(l)) @@ -542,13 +527,11 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) { // 0x50 range case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32: - a := uint64(op - PUSH1 + 1) - byts := context.GetRangeValue(pc+1, a) + a := big.NewInt(int64(op - PUSH1 + 1)) + byts := getData(code, new(big.Int).Add(pc, big.NewInt(1)), a) // push value to stack - stack.push(common.BigD(byts)) - pc += a - - step += int(op) - int(PUSH1) + 1 + stack.push(common.Bytes2Big(byts)) + pc.Add(pc, a) self.Printf(" => 0x%x", byts) case POP: @@ -628,7 +611,8 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) { case JUMPDEST: case PC: - stack.push(big.NewInt(int64(pc))) + //stack.push(big.NewInt(int64(pc))) + stack.push(pc) case MSIZE: stack.push(big.NewInt(int64(mem.Len()))) case GAS: @@ -734,7 +718,7 @@ func (self *Vm) Run(context *Context, callData []byte) (ret []byte, err error) { return nil, fmt.Errorf("Invalid opcode %x", op) } - pc++ + pc.Add(pc, One) self.Endl() } From 29930da52272b8fd644c38cc303ba6aa66e49182 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Sat, 28 Mar 2015 21:27:50 +0100 Subject: [PATCH 45/54] eth_getStorageAt output hex should begin with 0x --- rpc/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/api.go b/rpc/api.go index 78e464c990..05c264b6f2 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -99,7 +99,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err state := api.xethAtStateNum(args.BlockNumber).State().SafeGet(args.Address) value := state.StorageString(args.Key) - *reply = common.Bytes2Hex(value.Bytes()) + *reply = common.ToHex(value.Bytes()) case "eth_getTransactionCount": args := new(GetTxCountArgs) if err := json.Unmarshal(req.Params, &args); err != nil { From e80ef9ff34562410fbab63ccf173b17508b026ed Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Sat, 28 Mar 2015 21:41:34 +0100 Subject: [PATCH 46/54] Cleanup --- rpc/api.go | 1 - rpc/args.go | 21 +++++++-------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 05c264b6f2..5020791777 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -13,7 +13,6 @@ import ( type EthereumApi struct { eth *xeth.XEth xethMu sync.RWMutex - db common.Database } func NewEthereumApi(xeth *xeth.XEth) *EthereumApi { diff --git a/rpc/args.go b/rpc/args.go index a075f1a596..25a6c7a4f9 100644 --- a/rpc/args.go +++ b/rpc/args.go @@ -1,9 +1,7 @@ package rpc import ( - "bytes" "encoding/json" - // "errors" "fmt" "math/big" @@ -105,8 +103,8 @@ type GetBlockByHashArgs struct { func (args *GetBlockByHashArgs) 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()) } @@ -134,8 +132,7 @@ type GetBlockByNumberArgs struct { func (args *GetBlockByNumberArgs) 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()) } @@ -405,8 +402,7 @@ type BlockNumIndexArgs struct { func (args *BlockNumIndexArgs) 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()) } @@ -436,8 +432,7 @@ type HashIndexArgs struct { func (args *HashIndexArgs) 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()) } @@ -468,8 +463,7 @@ type Sha3Args struct { func (args *Sha3Args) 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()) } @@ -798,8 +792,7 @@ type FilterStringArgs struct { func (args *FilterStringArgs) 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()) } From d9f8b1e0c145e9bd46fe3a78570310ed3bd7d09d Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Sat, 28 Mar 2015 21:42:44 +0100 Subject: [PATCH 47/54] Report InvalidTypeError as -32602 to JSON RPC --- rpc/http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/http.go b/rpc/http.go index 879ffce3b9..919c567bd5 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -76,7 +76,7 @@ func RpcResponse(api *EthereumApi, request *RpcRequest) *interface{} { case *NotImplementedError: jsonerr := &RpcErrorObject{-32601, reserr.Error()} response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr} - case *DecodeParamError, *InsufficientParamsError, *ValidationError: + case *DecodeParamError, *InsufficientParamsError, *ValidationError, *InvalidTypeError: jsonerr := &RpcErrorObject{-32602, reserr.Error()} response = &RpcErrorResponse{Jsonrpc: jsonrpcver, Id: request.Id, Error: jsonerr} default: From 129fabddb27e21e503240ee250b2cbeb9e396cdc Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Sat, 28 Mar 2015 21:47:16 +0100 Subject: [PATCH 48/54] Prefer hex prefixed with 0x --- rpc/responses.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/responses.go b/rpc/responses.go index f5f3a33f3d..d219ebd72d 100644 --- a/rpc/responses.go +++ b/rpc/responses.go @@ -243,8 +243,8 @@ func (l *LogRes) MarshalJSON() ([]byte, error) { } ext.Address = l.Address.Hex() - ext.Data = common.Bytes2Hex(l.Data) - ext.Number = common.Bytes2Hex(big.NewInt(int64(l.Number)).Bytes()) + ext.Data = common.ToHex(l.Data) + ext.Number = common.ToHex(big.NewInt(int64(l.Number)).Bytes()) ext.Topics = make([]string, len(l.Topics)) for i, v := range l.Topics { ext.Topics[i] = v.Hex() From 82eeb5e02a4601edba05a2c7da7342a1fa808832 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Sat, 28 Mar 2015 22:04:36 +0100 Subject: [PATCH 49/54] Added Coveralls badges --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a163e67c7a..dc965a15c9 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ Ethereum Go Client © 2014 Jeffrey Wilcke. | Linux | OSX | Windows | Tests ----------|---------|-----|---------|------ -develop | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](https://build.ethdev.com/builders/Linux%20Go%20develop%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](https://build.ethdev.com/builders/OSX%20Go%20develop%20branch/builds/-1) | N/A | [![Buildr+Status](https://travis-ci.org/ethereum/go-ethereum.svg?branch=develop)](https://travis-ci.org/ethereum/go-ethereum) -master | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20master%20branch)](https://build.ethdev.com/builders/Linux%20Go%20master%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=OSX%20Go%20master%20branch)](https://build.ethdev.com/builders/OSX%20Go%20master%20branch/builds/-1) | N/A | [![Buildr+Status](https://travis-ci.org/ethereum/go-ethereum.svg?branch=master)](https://travis-ci.org/ethereum/go-ethereum) +develop | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](https://build.ethdev.com/builders/Linux%20Go%20develop%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20develop%20branch)](https://build.ethdev.com/builders/OSX%20Go%20develop%20branch/builds/-1) | N/A | [![Buildr+Status](https://travis-ci.org/ethereum/go-ethereum.svg?branch=develop)](https://travis-ci.org/ethereum/go-ethereum) [![Coverage Status](https://coveralls.io/repos/ethereum/go-ethereum/badge.svg?branch=develop)](https://coveralls.io/r/ethereum/go-ethereum?branch=develop) +master | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20Go%20master%20branch)](https://build.ethdev.com/builders/Linux%20Go%20master%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=OSX%20Go%20master%20branch)](https://build.ethdev.com/builders/OSX%20Go%20master%20branch/builds/-1) | N/A | [![Buildr+Status](https://travis-ci.org/ethereum/go-ethereum.svg?branch=master)](https://travis-ci.org/ethereum/go-ethereum) [![Coverage Status](https://coveralls.io/repos/ethereum/go-ethereum/badge.svg?branch=master)](https://coveralls.io/r/ethereum/go-ethereum?branch=master) [![Bugs](https://badge.waffle.io/ethereum/go-ethereum.png?label=bug&title=Bugs)](https://waffle.io/ethereum/go-ethereum) [![Stories in Ready](https://badge.waffle.io/ethereum/go-ethereum.png?label=ready&title=Ready)](https://waffle.io/ethereum/go-ethereum) From 2ca6a800adbb5c43f96df5918be0d55ed3aa1867 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Sat, 28 Mar 2015 22:16:04 +0100 Subject: [PATCH 50/54] Remove old go cover location --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7e47281cf4..d6954e0cb7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ install: # - go get code.google.com/p/go.tools/cmd/goimports # - go get github.com/golang/lint/golint # - go get golang.org/x/tools/cmd/vet - - if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi + - go get golang.org/x/tools/cmd/cover - go get github.com/mattn/goveralls before_script: # - gofmt -l -w . From eb79938060fff279dbac5fc2a599bb27b52c085c Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Sat, 28 Mar 2015 22:17:08 +0100 Subject: [PATCH 51/54] Docker rename ethereum to geth --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 966614e71d..fcd564a34a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,10 +30,10 @@ RUN mkdir -p $GOPATH/src/github.com/ethereum/ RUN git clone https://github.com/ethereum/go-ethereum $GOPATH/src/github.com/ethereum/go-ethereum WORKDIR $GOPATH/src/github.com/ethereum/go-ethereum RUN git checkout develop -RUN GOPATH=$GOPATH:$GOPATH/src/github.com/ethereum/go-ethereum/Godeps/_workspace go install -v ./cmd/ethereum +RUN GOPATH=$GOPATH:$GOPATH/src/github.com/ethereum/go-ethereum/Godeps/_workspace go install -v ./cmd/geth ## Run & expose JSON RPC -ENTRYPOINT ["ethereum", "-rpc=true", "-rpcport=8545"] +ENTRYPOINT ["geth", "-rpc=true", "-rpcport=8545"] EXPOSE 8545 From 391d79ef44ad2e76754ef8dfb5e9dfbdd5a69acd Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Sun, 29 Mar 2015 12:08:52 +0200 Subject: [PATCH 52/54] Add ExtraData field to RPC output --- rpc/responses.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/responses.go b/rpc/responses.go index d219ebd72d..9767cac3b2 100644 --- a/rpc/responses.go +++ b/rpc/responses.go @@ -70,7 +70,7 @@ func (b *BlockRes) MarshalJSON() ([]byte, error) { ext.Difficulty = common.ToHex(b.Difficulty.Bytes()) ext.TotalDifficulty = common.ToHex(b.TotalDifficulty.Bytes()) ext.Size = common.ToHex(b.Size.Bytes()) - // ext.ExtraData = common.ToHex(b.ExtraData) + ext.ExtraData = common.ToHex(b.ExtraData) ext.GasLimit = common.ToHex(b.GasLimit.Bytes()) // ext.MinGasPrice = common.ToHex(big.NewInt(b.MinGasPrice).Bytes()) ext.GasUsed = common.ToHex(b.GasUsed.Bytes()) @@ -111,7 +111,7 @@ func NewBlockRes(block *types.Block) *BlockRes { res.Difficulty = block.Difficulty() res.TotalDifficulty = block.Td res.Size = big.NewInt(int64(block.Size())) - // res.ExtraData = + res.ExtraData = []byte(block.Header().Extra) res.GasLimit = block.GasLimit() // res.MinGasPrice = res.GasUsed = block.GasUsed() From 61c5edcb57a200764bfa37e3a7da909727a7852b Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 29 Mar 2015 15:02:49 +0200 Subject: [PATCH 53/54] Cleanup. --- core/vm/address.go | 23 +++++++++++++---------- crypto/crypto.go | 16 +++++++--------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/core/vm/address.go b/core/vm/address.go index e4c33ec808..0b3a95dd08 100644 --- a/core/vm/address.go +++ b/core/vm/address.go @@ -61,27 +61,30 @@ func ripemd160Func(in []byte) []byte { return common.LeftPadBytes(crypto.Ripemd160(in), 32) } -const EcRecoverInputLength = 128 +const ecRecoverInputLength = 128 func ecrecoverFunc(in []byte) []byte { // "in" is (hash, v, r, s), each 32 bytes // but for ecrecover we want (r, s, v) - if len(in) < EcRecoverInputLength { + if len(in) < ecRecoverInputLength { return nil } - hash := in[:32] - // v is only a bit, but comes as 32 bytes from vm. We only need least significant byte - encodedV := in[32:64] - v := encodedV[31] - 27 - if !(v == 0 || v == 1) { + + // Treat V as a 256bit integer + v := new(big.Int).Sub(common.Bytes2Big(in[32:64]), big.NewInt(27)) + // Ethereum requires V to be either 0 or 1 => (27 || 28) + if !(v.Cmp(Zero) == 0 || v.Cmp(One) == 0) { return nil } - sig := append(in[64:], v) - pubKey := crypto.Ecrecover(append(hash, sig...)) - // secp256.go returns either nil or 65 bytes + + // v needs to be moved to the end + rsv := append(in[64:128], byte(v.Uint64())) + pubKey := crypto.Ecrecover(in[:32], rsv) + // make sure the public key is a valid one if pubKey == nil || len(pubKey) != 65 { return nil } + // the first byte of pubkey is bitcoin heritage return common.LeftPadBytes(crypto.Sha3(pubKey[1:])[12:], 32) } diff --git a/crypto/crypto.go b/crypto/crypto.go index 442942c6c5..9a1559fbfb 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -68,13 +68,8 @@ func Ripemd160(data []byte) []byte { return ripemd.Sum(nil) } -func Ecrecover(data []byte) []byte { - var in = struct { - hash []byte - sig []byte - }{data[:32], data[32:]} - - r, _ := secp256k1.RecoverPubkey(in.hash, in.sig) +func Ecrecover(hash, sig []byte) []byte { + r, _ := secp256k1.RecoverPubkey(hash, sig) return r } @@ -151,9 +146,12 @@ func GenerateKey() (*ecdsa.PrivateKey, error) { } func SigToPub(hash, sig []byte) *ecdsa.PublicKey { - s := Ecrecover(append(hash, sig...)) - x, y := elliptic.Unmarshal(S256(), s) + s := Ecrecover(hash, sig) + if s == nil || len(s) != 65 { + return nil + } + x, y := elliptic.Unmarshal(S256(), s) return &ecdsa.PublicKey{S256(), x, y} } From f23529c5cde47f713ada745629a7bdc8e1506fa7 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Mon, 30 Mar 2015 09:18:22 +0200 Subject: [PATCH 54/54] General repo cleanup --- .gitignore | 6 +++++- .gitmodules | 3 --- .mailmap | 4 +++- update-license.go | 4 ++-- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 706d953bff..e5a5d2fbe8 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,8 @@ .ethtest */**/*tx_database* */**/*dapps* +Godeps/_workspace/pkg +Godeps/_workspace/bin #* .#* @@ -21,7 +23,9 @@ .project .settings -cmd/ethereum/ethereum +geth +mist +cmd/geth/geth cmd/mist/mist deploy/osx/Mist.app deploy/osx/Mist\ Installer.dmg diff --git a/.gitmodules b/.gitmodules index 461a5a7489..3284c329d5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "ethereal/assets/samplecoin"] - path = ethereal/assets/samplecoin - url = git@github.com:obscuren/SampleCoin.git [submodule "cmd/mist/assets/ext/ethereum.js"] path = cmd/mist/assets/ext/ethereum.js url = https://github.com/ethereum/ethereum.js diff --git a/.mailmap b/.mailmap index cc9834bb9f..a3a3020acf 100644 --- a/.mailmap +++ b/.mailmap @@ -9,4 +9,6 @@ Joseph Goulden Nick Savers -Maran Hidskes \ No newline at end of file +Maran Hidskes + +Taylor Gerring diff --git a/update-license.go b/update-license.go index 832a94712f..e55732a53f 100644 --- a/update-license.go +++ b/update-license.go @@ -40,7 +40,7 @@ var ( extensions = []string{".go", ".js", ".qml"} // paths with any of these prefixes will be skipped - skipPrefixes = []string{"tests/files/", "cmd/mist/assets/ext/", "cmd/mist/assets/muted/"} + skipPrefixes = []string{"Godeps/", "tests/files/", "cmd/mist/assets/ext/", "cmd/mist/assets/muted/"} // paths with this prefix are licensed as GPL. all other files are LGPL. gplPrefixes = []string{"cmd/"} @@ -190,7 +190,7 @@ func fileInfo(file string) (*info, error) { break } } - cmd := exec.Command("git", "log", "--follow", "--find-copies", "--pretty=format:%aI | %aN <%aE>", "--", file) + cmd := exec.Command("git", "log", "--follow", "--find-copies", "--pretty=format:%ai | %aN <%aE>", "--", file) err := doLines(cmd, func(line string) { sep := strings.IndexByte(line, '|') year, name := line[:4], line[sep+2:]