From e0781c2548aec596e6ce1140c5b871555a75f3cb Mon Sep 17 00:00:00 2001
From: Taylor Gerring <taylor.gerring@gmail.com>
Date: Fri, 27 Mar 2015 00:07:28 +0100
Subject: [PATCH] NewTxArgs accept numbers or strings for value/gas/gasprice

---
 rpc/args.go      |  40 ++++++++++++--
 rpc/args_test.go | 138 ++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 162 insertions(+), 16 deletions(-)

diff --git a/rpc/args.go b/rpc/args.go
index 806efb9cc..78cbca5a9 100644
--- a/rpc/args.go
+++ b/rpc/args.go
@@ -166,7 +166,14 @@ type NewTxArgs struct {
 
 func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
 	var obj []json.RawMessage
-	var ext struct{ From, To, Value, Gas, GasPrice, Data string }
+	var ext struct {
+		From     string
+		To       string
+		Value    interface{}
+		Gas      interface{}
+		GasPrice interface{}
+		Data     string
+	}
 
 	// Decode byte slice to array of RawMessages
 	if err := json.Unmarshal(b, &obj); err != nil {
@@ -189,11 +196,36 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
 
 	args.From = ext.From
 	args.To = ext.To
-	args.Value = common.String2Big(ext.Value)
-	args.Gas = common.String2Big(ext.Gas)
-	args.GasPrice = common.String2Big(ext.GasPrice)
 	args.Data = ext.Data
 
+	var num int64
+	if ext.Value == nil {
+		return NewValidationError("value", "is required")
+	} else {
+		if err := numString(ext.Value, &num); err != nil {
+			return err
+		}
+	}
+	args.Value = big.NewInt(num)
+
+	if ext.Gas == nil {
+		return NewValidationError("gas", "is required")
+	} else {
+		if err := numString(ext.Gas, &num); err != nil {
+			return err
+		}
+	}
+	args.Gas = big.NewInt(num)
+
+	if ext.GasPrice == nil {
+		return NewValidationError("gasprice", "is required")
+	} else {
+		if err := numString(ext.GasPrice, &num); err != nil {
+			return err
+		}
+	}
+	args.GasPrice = big.NewInt(num)
+
 	// Check for optional BlockNumber param
 	if len(obj) > 1 {
 		if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil {
diff --git a/rpc/args_test.go b/rpc/args_test.go
index b658eed68..dee72b86f 100644
--- a/rpc/args_test.go
+++ b/rpc/args_test.go
@@ -351,31 +351,98 @@ 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))
+	if len(str) > 0 {
+		t.Error(str)
+	}
+}
+
+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))
@@ -384,6 +451,53 @@ func TestNewTxArgsBlockInvalid(t *testing.T) {
 	}
 }
 
+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 := `[]`
 
-- 
GitLab