New CallArgs
Requirements for calls differ from transactions
This commit is contained in:
parent
f23529c5cd
commit
2f3a968136
|
@ -159,7 +159,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err
|
|||
}
|
||||
*reply = v
|
||||
case "eth_call":
|
||||
args := new(NewTxArgs)
|
||||
args := new(CallArgs)
|
||||
if err := json.Unmarshal(req.Params, &args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
87
rpc/args.go
87
rpc/args.go
|
@ -238,6 +238,93 @@ func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
type CallArgs struct {
|
||||
From string
|
||||
To string
|
||||
Value *big.Int
|
||||
Gas *big.Int
|
||||
GasPrice *big.Int
|
||||
Data string
|
||||
|
||||
BlockNumber int64
|
||||
}
|
||||
|
||||
func (args *CallArgs) UnmarshalJSON(b []byte) (err error) {
|
||||
var obj []json.RawMessage
|
||||
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 {
|
||||
return NewDecodeParamError(err.Error())
|
||||
}
|
||||
|
||||
// Check for sufficient params
|
||||
if len(obj) < 1 {
|
||||
return NewInsufficientParamsError(len(obj), 1)
|
||||
}
|
||||
|
||||
// Decode 0th RawMessage to temporary struct
|
||||
if err := json.Unmarshal(obj[0], &ext); err != nil {
|
||||
return NewDecodeParamError(err.Error())
|
||||
}
|
||||
|
||||
if len(ext.From) == 0 {
|
||||
return NewValidationError("from", "is required")
|
||||
}
|
||||
args.From = ext.From
|
||||
|
||||
if len(ext.To) == 0 {
|
||||
return NewValidationError("to", "is required")
|
||||
}
|
||||
args.To = ext.To
|
||||
|
||||
var num int64
|
||||
if ext.Value == nil {
|
||||
num = int64(0)
|
||||
} else {
|
||||
if err := numString(ext.Value, &num); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
args.Value = big.NewInt(num)
|
||||
|
||||
if ext.Gas == nil {
|
||||
num = int64(0)
|
||||
} else {
|
||||
if err := numString(ext.Gas, &num); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
args.Gas = big.NewInt(num)
|
||||
|
||||
if ext.GasPrice == nil {
|
||||
num = int64(0)
|
||||
} else {
|
||||
if err := numString(ext.GasPrice, &num); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
args.GasPrice = big.NewInt(num)
|
||||
|
||||
args.Data = ext.Data
|
||||
|
||||
// Check for optional BlockNumber param
|
||||
if len(obj) > 1 {
|
||||
if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetStorageArgs struct {
|
||||
Address string
|
||||
BlockNumber int64
|
||||
|
|
277
rpc/args_test.go
277
rpc/args_test.go
|
@ -531,14 +531,275 @@ func TestNewTxArgsFromEmpty(t *testing.T) {
|
|||
input := `[{"to": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}]`
|
||||
|
||||
args := new(NewTxArgs)
|
||||
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.Errorf("Expected *rpc.ValidationError, but got %T with message `%s`", err, err.Error())
|
||||
str := ExpectValidationError(json.Unmarshal([]byte(input), &args))
|
||||
if len(str) > 0 {
|
||||
t.Error(str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallArgs(t *testing.T) {
|
||||
input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
|
||||
"to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675",
|
||||
"gas": "0x76c0",
|
||||
"gasPrice": "0x9184e72a000",
|
||||
"value": "0x9184e72a000",
|
||||
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"},
|
||||
"0x10"]`
|
||||
expected := new(CallArgs)
|
||||
expected.From = "0xb60e8dd61c5d32be8058bb8eb970870f07233155"
|
||||
expected.To = "0xd46e8dd67c5d32be8058bb8eb970870f072445675"
|
||||
expected.Gas = big.NewInt(30400)
|
||||
expected.GasPrice = big.NewInt(10000000000000)
|
||||
expected.Value = big.NewInt(10000000000000)
|
||||
expected.Data = "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
|
||||
expected.BlockNumber = big.NewInt(16).Int64()
|
||||
|
||||
args := new(CallArgs)
|
||||
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 bytes.Compare(expected.Gas.Bytes(), args.Gas.Bytes()) != 0 {
|
||||
t.Errorf("Gas shoud be %#v but is %#v", expected.Gas.Bytes(), args.Gas.Bytes())
|
||||
}
|
||||
|
||||
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.Data != args.Data {
|
||||
t.Errorf("Data shoud be %#v but is %#v", expected.Data, args.Data)
|
||||
}
|
||||
|
||||
if expected.BlockNumber != args.BlockNumber {
|
||||
t.Errorf("BlockNumber shoud be %#v but is %#v", expected.BlockNumber, args.BlockNumber)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallArgsInt(t *testing.T) {
|
||||
input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
|
||||
"to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675",
|
||||
"gas": 100,
|
||||
"gasPrice": 50,
|
||||
"value": 8765456789,
|
||||
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"},
|
||||
5]`
|
||||
expected := new(CallArgs)
|
||||
expected.Gas = big.NewInt(100)
|
||||
expected.GasPrice = big.NewInt(50)
|
||||
expected.Value = big.NewInt(8765456789)
|
||||
expected.BlockNumber = int64(5)
|
||||
|
||||
args := new(CallArgs)
|
||||
if err := json.Unmarshal([]byte(input), &args); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallArgsBlockBool(t *testing.T) {
|
||||
input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
|
||||
"to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675",
|
||||
"gas": "0x76c0",
|
||||
"gasPrice": "0x9184e72a000",
|
||||
"value": "0x9184e72a000",
|
||||
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"},
|
||||
false]`
|
||||
|
||||
args := new(CallArgs)
|
||||
str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args))
|
||||
if len(str) > 0 {
|
||||
t.Error(str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallArgsGasInvalid(t *testing.T) {
|
||||
input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
|
||||
"to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675",
|
||||
"gas": false,
|
||||
"gasPrice": "0x9184e72a000",
|
||||
"value": "0x9184e72a000",
|
||||
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
|
||||
}]`
|
||||
|
||||
args := new(CallArgs)
|
||||
str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args))
|
||||
if len(str) > 0 {
|
||||
t.Error(str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallArgsGaspriceInvalid(t *testing.T) {
|
||||
input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
|
||||
"to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675",
|
||||
"gas": "0x76c0",
|
||||
"gasPrice": false,
|
||||
"value": "0x9184e72a000",
|
||||
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
|
||||
}]`
|
||||
|
||||
args := new(CallArgs)
|
||||
str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args))
|
||||
if len(str) > 0 {
|
||||
t.Error(str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallArgsValueInvalid(t *testing.T) {
|
||||
input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
|
||||
"to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675",
|
||||
"gas": "0x76c0",
|
||||
"gasPrice": "0x9184e72a000",
|
||||
"value": false,
|
||||
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
|
||||
}]`
|
||||
|
||||
args := new(CallArgs)
|
||||
str := ExpectInvalidTypeError(json.Unmarshal([]byte(input), &args))
|
||||
if len(str) > 0 {
|
||||
t.Error(str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallArgsGasMissing(t *testing.T) {
|
||||
input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
|
||||
"to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675",
|
||||
"gasPrice": "0x9184e72a000",
|
||||
"value": "0x9184e72a000",
|
||||
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
|
||||
}]`
|
||||
|
||||
args := new(CallArgs)
|
||||
if err := json.Unmarshal([]byte(input), &args); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
expected := new(CallArgs)
|
||||
expected.Gas = big.NewInt(0)
|
||||
|
||||
if bytes.Compare(expected.Gas.Bytes(), args.Gas.Bytes()) != 0 {
|
||||
t.Errorf("Gas shoud be %v but is %v", expected.Gas, args.Gas)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestCallArgsBlockGaspriceMissing(t *testing.T) {
|
||||
input := `[{
|
||||
"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
|
||||
"to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675",
|
||||
"gas": "0x76c0",
|
||||
"value": "0x9184e72a000",
|
||||
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
|
||||
}]`
|
||||
|
||||
args := new(CallArgs)
|
||||
if err := json.Unmarshal([]byte(input), &args); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
expected := new(CallArgs)
|
||||
expected.GasPrice = big.NewInt(0)
|
||||
|
||||
if bytes.Compare(expected.GasPrice.Bytes(), args.GasPrice.Bytes()) != 0 {
|
||||
t.Errorf("GasPrice shoud be %v but is %v", expected.GasPrice, args.GasPrice)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallArgsValueMissing(t *testing.T) {
|
||||
input := `[{
|
||||
"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
|
||||
"to": "0xd46e8dd67c5d32be8058bb8eb970870f072445675",
|
||||
"gas": "0x76c0",
|
||||
"gasPrice": "0x9184e72a000",
|
||||
"data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
|
||||
}]`
|
||||
|
||||
args := new(CallArgs)
|
||||
if err := json.Unmarshal([]byte(input), &args); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
expected := new(CallArgs)
|
||||
expected.Value = big.NewInt(int64(0))
|
||||
|
||||
if bytes.Compare(expected.Value.Bytes(), args.Value.Bytes()) != 0 {
|
||||
t.Errorf("GasPrice shoud be %v but is %v", expected.Value, args.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallArgsEmpty(t *testing.T) {
|
||||
input := `[]`
|
||||
|
||||
args := new(CallArgs)
|
||||
str := ExpectInsufficientParamsError(json.Unmarshal([]byte(input), &args))
|
||||
if len(str) > 0 {
|
||||
t.Error(str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallArgsInvalid(t *testing.T) {
|
||||
input := `{}`
|
||||
|
||||
args := new(CallArgs)
|
||||
str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args))
|
||||
if len(str) > 0 {
|
||||
t.Error(str)
|
||||
}
|
||||
}
|
||||
func TestCallArgsNotStrings(t *testing.T) {
|
||||
input := `[{"from":6}]`
|
||||
|
||||
args := new(CallArgs)
|
||||
str := ExpectDecodeParamError(json.Unmarshal([]byte(input), &args))
|
||||
if len(str) > 0 {
|
||||
t.Error(str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallArgsFromEmpty(t *testing.T) {
|
||||
input := `[{"to": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}]`
|
||||
|
||||
args := new(CallArgs)
|
||||
str := ExpectValidationError(json.Unmarshal([]byte(input), &args))
|
||||
if len(str) > 0 {
|
||||
t.Error(str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCallArgsToEmpty(t *testing.T) {
|
||||
input := `[{"from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155"}]`
|
||||
|
||||
args := new(CallArgs)
|
||||
str := ExpectValidationError(json.Unmarshal([]byte(input), &args))
|
||||
if len(str) > 0 {
|
||||
t.Error(str)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue