From 2f3a9681360f5326137de3aeb0aa8e2130de562a Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Mon, 30 Mar 2015 16:20:30 +0200 Subject: [PATCH 01/12] New CallArgs Requirements for calls differ from transactions --- rpc/api.go | 2 +- rpc/args.go | 87 +++++++++++++++ rpc/args_test.go | 277 +++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 357 insertions(+), 9 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 5020791777..bcd073ed2a 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -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 } diff --git a/rpc/args.go b/rpc/args.go index 25a6c7a4f9..dd013147d9 100644 --- a/rpc/args.go +++ b/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 diff --git a/rpc/args_test.go b/rpc/args_test.go index 602631b677..3635882c00 100644 --- a/rpc/args_test.go +++ b/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) } } From 3a948b2dbaf22409507a2d3244032751b76432bb Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Tue, 31 Mar 2015 17:39:58 +0200 Subject: [PATCH 02/12] Add hexdata and hexnum types --- rpc/messages.go | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/rpc/messages.go b/rpc/messages.go index 5c498234f9..108a07ed8f 100644 --- a/rpc/messages.go +++ b/rpc/messages.go @@ -19,8 +19,84 @@ package rpc import ( "encoding/json" "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/common" ) +type hexdata struct { + data []byte +} + +func (d *hexdata) MarshalJSON() ([]byte, error) { + v := common.Bytes2Hex(d.data) + return json.Marshal("0x" + v) +} + +func (d *hexdata) UnmarshalJSON(b []byte) (err error) { + d.data = common.FromHex(string(b)) + return nil +} + +func newHexData(input interface{}) *hexdata { + d := new(hexdata) + + switch input.(type) { + case []byte: + d.data = input.([]byte) + case common.Hash: + d.data = input.(common.Hash).Bytes() + case common.Address: + d.data = input.(common.Address).Bytes() + case *big.Int: + d.data = input.(*big.Int).Bytes() + case int64: + d.data = big.NewInt(input.(int64)).Bytes() + case uint64: + d.data = big.NewInt(int64(input.(uint64))).Bytes() + case int: + d.data = big.NewInt(int64(input.(int))).Bytes() + case uint: + d.data = big.NewInt(int64(input.(uint))).Bytes() + case string: + d.data = common.Big(input.(string)).Bytes() + default: + d.data = nil + } + + return d +} + +type hexnum struct { + data []byte +} + +func (d *hexnum) MarshalJSON() ([]byte, error) { + // Get hex string from bytes + out := common.Bytes2Hex(d.data) + // Trim leading 0s + out = strings.Trim(out, "0") + // Output "0x0" when value is 0 + if len(out) == 0 { + out = "0" + } + return json.Marshal("0x" + out) +} + +func (d *hexnum) UnmarshalJSON(b []byte) (err error) { + d.data = common.FromHex(string(b)) + return nil +} + +func newHexNum(input interface{}) *hexnum { + d := new(hexnum) + + d.data = newHexData(input).data + + return d +} + type InvalidTypeError struct { method string msg string From 81aeb789765cde7d84dc8aa74a6cab0851ce8503 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Tue, 31 Mar 2015 17:40:35 +0200 Subject: [PATCH 03/12] Update output types to use hexnum or hexdata Benefits from automatic output formatting differences between quantities and data --- rpc/responses.go | 210 ++++++++++++++++++++++-------------------- rpc/responses_test.go | 8 +- 2 files changed, 112 insertions(+), 106 deletions(-) diff --git a/rpc/responses.go b/rpc/responses.go index 9767cac3b2..d2a6c2984b 100644 --- a/rpc/responses.go +++ b/rpc/responses.go @@ -36,45 +36,45 @@ type BlockRes struct { func (b *BlockRes) MarshalJSON() ([]byte, error) { var ext struct { - BlockNumber string `json:"number"` - BlockHash string `json:"hash"` - ParentHash string `json:"parentHash"` - Nonce string `json:"nonce"` - Sha3Uncles string `json:"sha3Uncles"` - LogsBloom string `json:"logsBloom"` - TransactionRoot string `json:"transactionRoot"` - StateRoot string `json:"stateRoot"` - Miner string `json:"miner"` - Difficulty string `json:"difficulty"` - TotalDifficulty string `json:"totalDifficulty"` - Size string `json:"size"` - ExtraData string `json:"extraData"` - GasLimit string `json:"gasLimit"` - MinGasPrice string `json:"minGasPrice"` - GasUsed string `json:"gasUsed"` - UnixTimestamp string `json:"timestamp"` + BlockNumber *hexnum `json:"number"` + BlockHash *hexdata `json:"hash"` + ParentHash *hexdata `json:"parentHash"` + Nonce *hexnum `json:"nonce"` + Sha3Uncles *hexdata `json:"sha3Uncles"` + LogsBloom *hexdata `json:"logsBloom"` + TransactionRoot *hexdata `json:"transactionRoot"` + StateRoot *hexdata `json:"stateRoot"` + Miner *hexdata `json:"miner"` + Difficulty *hexnum `json:"difficulty"` + TotalDifficulty *hexnum `json:"totalDifficulty"` + Size *hexnum `json:"size"` + ExtraData *hexdata `json:"extraData"` + GasLimit *hexnum `json:"gasLimit"` + MinGasPrice *hexnum `json:"minGasPrice"` + GasUsed *hexnum `json:"gasUsed"` + UnixTimestamp *hexnum `json:"timestamp"` Transactions []interface{} `json:"transactions"` - Uncles []string `json:"uncles"` + Uncles []*hexdata `json:"uncles"` } // convert strict types to hexified strings - ext.BlockNumber = common.ToHex(b.BlockNumber.Bytes()) - ext.BlockHash = b.BlockHash.Hex() - ext.ParentHash = b.ParentHash.Hex() - ext.Nonce = common.ToHex(b.Nonce[:]) - ext.Sha3Uncles = b.Sha3Uncles.Hex() - ext.LogsBloom = common.ToHex(b.LogsBloom[:]) - ext.TransactionRoot = b.TransactionRoot.Hex() - ext.StateRoot = b.StateRoot.Hex() - ext.Miner = b.Miner.Hex() - 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.GasLimit = common.ToHex(b.GasLimit.Bytes()) - // ext.MinGasPrice = common.ToHex(big.NewInt(b.MinGasPrice).Bytes()) - ext.GasUsed = common.ToHex(b.GasUsed.Bytes()) - ext.UnixTimestamp = common.ToHex(big.NewInt(b.UnixTimestamp).Bytes()) + ext.BlockNumber = newHexNum(b.BlockNumber.Bytes()) + ext.BlockHash = newHexData(b.BlockHash.Bytes()) + ext.ParentHash = newHexData(b.ParentHash.Bytes()) + ext.Nonce = newHexNum(b.Nonce[:]) + ext.Sha3Uncles = newHexData(b.Sha3Uncles.Bytes()) + ext.LogsBloom = newHexData(b.LogsBloom.Bytes()) + ext.TransactionRoot = newHexData(b.TransactionRoot.Bytes()) + ext.StateRoot = newHexData(b.StateRoot.Bytes()) + ext.Miner = newHexData(b.Miner.Bytes()) + ext.Difficulty = newHexNum(b.Difficulty.Bytes()) + ext.TotalDifficulty = newHexNum(b.TotalDifficulty.Bytes()) + ext.Size = newHexNum(b.Size.Bytes()) + ext.ExtraData = newHexData(b.ExtraData) + ext.GasLimit = newHexNum(b.GasLimit.Bytes()) + // ext.MinGasPrice = newHexNum(big.NewInt(b.MinGasPrice).Bytes()) + ext.GasUsed = newHexNum(b.GasUsed.Bytes()) + ext.UnixTimestamp = newHexNum(big.NewInt(b.UnixTimestamp).Bytes()) ext.Transactions = make([]interface{}, len(b.Transactions)) if b.fullTx { for i, tx := range b.Transactions { @@ -82,12 +82,12 @@ func (b *BlockRes) MarshalJSON() ([]byte, error) { } } else { for i, tx := range b.Transactions { - ext.Transactions[i] = tx.Hash.Hex() + ext.Transactions[i] = newHexData(tx.Hash.Bytes()) } } - ext.Uncles = make([]string, len(b.Uncles)) + ext.Uncles = make([]*hexdata, len(b.Uncles)) for i, v := range b.Uncles { - ext.Uncles[i] = v.Hex() + ext.Uncles[i] = newHexData(v.Bytes()) } return json.Marshal(ext) @@ -134,9 +134,9 @@ func NewBlockRes(block *types.Block) *BlockRes { type TransactionRes struct { Hash common.Hash `json:"hash"` Nonce uint64 `json:"nonce"` - BlockHash common.Hash `json:"blockHash,omitempty"` - BlockNumber int64 `json:"blockNumber,omitempty"` - TxIndex int64 `json:"transactionIndex,omitempty"` + BlockHash common.Hash `json:"blockHash"` + BlockNumber int64 `json:"blockNumber"` + TxIndex int64 `json:"transactionIndex"` From common.Address `json:"from"` To *common.Address `json:"to"` Value *big.Int `json:"value"` @@ -147,34 +147,30 @@ type TransactionRes struct { func (t *TransactionRes) MarshalJSON() ([]byte, error) { var ext struct { - Hash string `json:"hash"` - Nonce string `json:"nonce"` - BlockHash string `json:"blockHash,omitempty"` - BlockNumber string `json:"blockNumber,omitempty"` - TxIndex string `json:"transactionIndex,omitempty"` - From string `json:"from"` - To interface{} `json:"to"` - Value string `json:"value"` - Gas string `json:"gas"` - GasPrice string `json:"gasPrice"` - Input string `json:"input"` + Hash *hexdata `json:"hash"` + Nonce *hexnum `json:"nonce"` + BlockHash *hexdata `json:"blockHash"` + BlockNumber *hexnum `json:"blockNumber"` + TxIndex *hexnum `json:"transactionIndex"` + From *hexdata `json:"from"` + To *hexdata `json:"to"` + Value *hexnum `json:"value"` + Gas *hexnum `json:"gas"` + GasPrice *hexnum `json:"gasPrice"` + Input *hexdata `json:"input"` } - ext.Hash = t.Hash.Hex() - ext.Nonce = common.ToHex(big.NewInt(int64(t.Nonce)).Bytes()) - ext.BlockHash = t.BlockHash.Hex() - ext.BlockNumber = common.ToHex(big.NewInt(t.BlockNumber).Bytes()) - ext.TxIndex = common.ToHex(big.NewInt(t.TxIndex).Bytes()) - ext.From = t.From.Hex() - if t.To == nil { - ext.To = nil - } else { - ext.To = t.To.Hex() - } - ext.Value = common.ToHex(t.Value.Bytes()) - ext.Gas = common.ToHex(t.Gas.Bytes()) - ext.GasPrice = common.ToHex(t.GasPrice.Bytes()) - ext.Input = common.ToHex(t.Input) + ext.Hash = newHexData(t.Hash.Bytes()) + ext.Nonce = newHexNum(big.NewInt(int64(t.Nonce)).Bytes()) + ext.BlockHash = newHexData(t.BlockHash.Bytes()) + ext.BlockNumber = newHexNum(big.NewInt(t.BlockNumber).Bytes()) + ext.TxIndex = newHexNum(big.NewInt(t.TxIndex).Bytes()) + ext.From = newHexData(t.From.Bytes()) + ext.To = newHexData(t.To.Bytes()) + ext.Value = newHexNum(t.Value.Bytes()) + ext.Gas = newHexNum(t.Gas.Bytes()) + ext.GasPrice = newHexNum(t.GasPrice.Bytes()) + ext.Input = newHexData(t.Input) return json.Marshal(ext) } @@ -192,34 +188,39 @@ func NewTransactionRes(tx *types.Transaction) *TransactionRes { return v } -type FilterLogRes struct { - Hash string `json:"hash"` - Address string `json:"address"` - Data string `json:"data"` - BlockNumber string `json:"blockNumber"` - TransactionHash string `json:"transactionHash"` - BlockHash string `json:"blockHash"` - TransactionIndex string `json:"transactionIndex"` - LogIndex string `json:"logIndex"` -} +// type FilterLogRes struct { +// Hash string `json:"hash"` +// Address string `json:"address"` +// Data string `json:"data"` +// BlockNumber string `json:"blockNumber"` +// TransactionHash string `json:"transactionHash"` +// BlockHash string `json:"blockHash"` +// TransactionIndex string `json:"transactionIndex"` +// LogIndex string `json:"logIndex"` +// } -type FilterWhisperRes struct { - Hash string `json:"hash"` - From string `json:"from"` - To string `json:"to"` - Expiry string `json:"expiry"` - Sent string `json:"sent"` - Ttl string `json:"ttl"` - Topics string `json:"topics"` - Payload string `json:"payload"` - WorkProved string `json:"workProved"` -} +// type FilterWhisperRes struct { +// Hash string `json:"hash"` +// From string `json:"from"` +// To string `json:"to"` +// Expiry string `json:"expiry"` +// Sent string `json:"sent"` +// Ttl string `json:"ttl"` +// Topics string `json:"topics"` +// Payload string `json:"payload"` +// WorkProved string `json:"workProved"` +// } type LogRes struct { - Address common.Address `json:"address"` - Topics []common.Hash `json:"topics"` - Data []byte `json:"data"` - Number uint64 `json:"number"` + Address common.Address `json:"address"` + Topics []common.Hash `json:"topics"` + Data []byte `json:"data"` + BlockNumber uint64 `json:"blockNumber"` + Hash common.Hash `json:"hash"` + LogIndex uint64 `json:"logIndex"` + BlockHash common.Hash `json:"blockHash"` + TransactionHash common.Hash `json:"transactionHash"` + TransactionIndex uint64 `json:"transactionIndex"` } func NewLogRes(log state.Log) LogRes { @@ -227,7 +228,7 @@ func NewLogRes(log state.Log) LogRes { l.Topics = make([]common.Hash, len(log.Topics())) l.Address = log.Address() l.Data = log.Data() - l.Number = log.Number() + l.BlockNumber = log.Number() for j, topic := range log.Topics() { l.Topics[j] = topic } @@ -236,18 +237,23 @@ func NewLogRes(log state.Log) LogRes { func (l *LogRes) MarshalJSON() ([]byte, error) { var ext struct { - Address string `json:"address"` - Topics []string `json:"topics"` - Data string `json:"data"` - Number string `json:"number"` + Address *hexdata `json:"address"` + Topics []*hexdata `json:"topics"` + Data *hexdata `json:"data"` + BlockNumber *hexnum `json:"blockNumber"` + Hash *hexdata `json:"hash"` + LogIndex *hexnum `json:"logIndex"` + BlockHash *hexdata `json:"blockHash"` + TransactionHash *hexdata `json:"transactionHash"` + TransactionIndex *hexnum `json:"transactionIndex"` } - ext.Address = l.Address.Hex() - ext.Data = common.ToHex(l.Data) - ext.Number = common.ToHex(big.NewInt(int64(l.Number)).Bytes()) - ext.Topics = make([]string, len(l.Topics)) + ext.Address = newHexData(l.Address.Bytes()) + ext.Data = newHexData(l.Data) + ext.BlockNumber = newHexNum(l.BlockNumber) + ext.Topics = make([]*hexdata, len(l.Topics)) for i, v := range l.Topics { - ext.Topics[i] = v.Hex() + ext.Topics[i] = newHexData(v) } return json.Marshal(ext) diff --git a/rpc/responses_test.go b/rpc/responses_test.go index 2789398307..80e97a7531 100644 --- a/rpc/responses_test.go +++ b/rpc/responses_test.go @@ -88,10 +88,10 @@ func TestLogRes(t *testing.T) { topics = append(topics, common.HexToHash("0x20")) v := &LogRes{ - Topics: topics, - Address: common.HexToAddress("0x0"), - Data: []byte{1, 2, 3}, - Number: uint64(5), + Topics: topics, + Address: common.HexToAddress("0x0"), + Data: []byte{1, 2, 3}, + BlockNumber: uint64(5), } _, _ = json.Marshal(v) From 8f0e095f4c269c48ac2c182c891e6346929de57b Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Tue, 31 Mar 2015 17:56:06 +0200 Subject: [PATCH 04/12] Index is zero-based #607 --- rpc/api.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index 5020791777..bce9a46e76 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -213,7 +213,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err br := NewBlockRes(block) br.fullTx = true - if args.Index > int64(len(br.Transactions)) || args.Index < 0 { + if args.Index >= int64(len(br.Transactions)) || args.Index < 0 { return NewValidationError("Index", "does not exist") } *reply = br.Transactions[args.Index] @@ -227,7 +227,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err v := NewBlockRes(block) v.fullTx = true - if args.Index > int64(len(v.Transactions)) || args.Index < 0 { + if args.Index >= int64(len(v.Transactions)) || args.Index < 0 { return NewValidationError("Index", "does not exist") } *reply = v.Transactions[args.Index] @@ -239,7 +239,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err br := NewBlockRes(api.xeth().EthBlockByHash(args.Hash)) - if args.Index > int64(len(br.Uncles)) || args.Index < 0 { + if args.Index >= int64(len(br.Uncles)) || args.Index < 0 { return NewValidationError("Index", "does not exist") } @@ -257,7 +257,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err v := NewBlockRes(block) v.fullTx = true - if args.Index > int64(len(v.Uncles)) || args.Index < 0 { + if args.Index >= int64(len(v.Uncles)) || args.Index < 0 { return NewValidationError("Index", "does not exist") } From a2501ecfcd0709db8bd43ecdc4077d072230fb28 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Tue, 31 Mar 2015 19:02:46 +0200 Subject: [PATCH 05/12] Make new types Stringers --- rpc/messages.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/rpc/messages.go b/rpc/messages.go index 108a07ed8f..1ad41654b2 100644 --- a/rpc/messages.go +++ b/rpc/messages.go @@ -29,9 +29,12 @@ type hexdata struct { data []byte } +func (d *hexdata) String() string { + return "0x" + common.Bytes2Hex(d.data) +} + func (d *hexdata) MarshalJSON() ([]byte, error) { - v := common.Bytes2Hex(d.data) - return json.Marshal("0x" + v) + return json.Marshal(d.String()) } func (d *hexdata) UnmarshalJSON(b []byte) (err error) { @@ -72,7 +75,7 @@ type hexnum struct { data []byte } -func (d *hexnum) MarshalJSON() ([]byte, error) { +func (d *hexnum) String() string { // Get hex string from bytes out := common.Bytes2Hex(d.data) // Trim leading 0s @@ -81,7 +84,11 @@ func (d *hexnum) MarshalJSON() ([]byte, error) { if len(out) == 0 { out = "0" } - return json.Marshal("0x" + out) + return "0x" + out +} + +func (d *hexnum) MarshalJSON() ([]byte, error) { + return json.Marshal(d.String()) } func (d *hexnum) UnmarshalJSON(b []byte) (err error) { From 7e3875b52720bf7456c9dd6162caeb7250d3686e Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Tue, 31 Mar 2015 19:04:02 +0200 Subject: [PATCH 06/12] Remove custom MarshalJSON methods Now formats based on underlying hexdata or hexnum type. Fields directly with respective constructors that cover from native types --- rpc/api.go | 4 +- rpc/responses.go | 278 +++++++++++++----------------------------- rpc/responses_test.go | 234 +++++++++++++++++------------------ 3 files changed, 202 insertions(+), 314 deletions(-) diff --git a/rpc/api.go b/rpc/api.go index bce9a46e76..3f5d33da6e 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -244,7 +244,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err } uhash := br.Uncles[args.Index] - uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash.Hex())) + uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash.String())) *reply = uncle case "eth_getUncleByBlockNumberAndIndex": @@ -262,7 +262,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err } uhash := v.Uncles[args.Index] - uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash.Hex())) + uncle := NewBlockRes(api.xeth().EthBlockByHash(uhash.String())) *reply = uncle case "eth_getCompilers": diff --git a/rpc/responses.go b/rpc/responses.go index d2a6c2984b..3e9293fbb1 100644 --- a/rpc/responses.go +++ b/rpc/responses.go @@ -1,11 +1,6 @@ package rpc import ( - "encoding/json" - // "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" ) @@ -13,84 +8,25 @@ import ( type BlockRes struct { fullTx bool - BlockNumber *big.Int `json:"number"` - BlockHash common.Hash `json:"hash"` - ParentHash common.Hash `json:"parentHash"` - Nonce [8]byte `json:"nonce"` - Sha3Uncles common.Hash `json:"sha3Uncles"` - LogsBloom types.Bloom `json:"logsBloom"` - TransactionRoot common.Hash `json:"transactionRoot"` - StateRoot common.Hash `json:"stateRoot"` - Miner common.Address `json:"miner"` - Difficulty *big.Int `json:"difficulty"` - TotalDifficulty *big.Int `json:"totalDifficulty"` - Size *big.Int `json:"size"` - ExtraData []byte `json:"extraData"` - GasLimit *big.Int `json:"gasLimit"` - MinGasPrice int64 `json:"minGasPrice"` - GasUsed *big.Int `json:"gasUsed"` - UnixTimestamp int64 `json:"timestamp"` + BlockNumber *hexnum `json:"number"` + BlockHash *hexdata `json:"hash"` + ParentHash *hexdata `json:"parentHash"` + Nonce *hexnum `json:"nonce"` + Sha3Uncles *hexdata `json:"sha3Uncles"` + LogsBloom *hexdata `json:"logsBloom"` + TransactionRoot *hexdata `json:"transactionRoot"` + StateRoot *hexdata `json:"stateRoot"` + Miner *hexdata `json:"miner"` + Difficulty *hexnum `json:"difficulty"` + TotalDifficulty *hexnum `json:"totalDifficulty"` + Size *hexnum `json:"size"` + ExtraData *hexdata `json:"extraData"` + GasLimit *hexnum `json:"gasLimit"` + MinGasPrice *hexnum `json:"minGasPrice"` + GasUsed *hexnum `json:"gasUsed"` + UnixTimestamp *hexnum `json:"timestamp"` Transactions []*TransactionRes `json:"transactions"` - Uncles []common.Hash `json:"uncles"` -} - -func (b *BlockRes) MarshalJSON() ([]byte, error) { - var ext struct { - BlockNumber *hexnum `json:"number"` - BlockHash *hexdata `json:"hash"` - ParentHash *hexdata `json:"parentHash"` - Nonce *hexnum `json:"nonce"` - Sha3Uncles *hexdata `json:"sha3Uncles"` - LogsBloom *hexdata `json:"logsBloom"` - TransactionRoot *hexdata `json:"transactionRoot"` - StateRoot *hexdata `json:"stateRoot"` - Miner *hexdata `json:"miner"` - Difficulty *hexnum `json:"difficulty"` - TotalDifficulty *hexnum `json:"totalDifficulty"` - Size *hexnum `json:"size"` - ExtraData *hexdata `json:"extraData"` - GasLimit *hexnum `json:"gasLimit"` - MinGasPrice *hexnum `json:"minGasPrice"` - GasUsed *hexnum `json:"gasUsed"` - UnixTimestamp *hexnum `json:"timestamp"` - Transactions []interface{} `json:"transactions"` - Uncles []*hexdata `json:"uncles"` - } - - // convert strict types to hexified strings - ext.BlockNumber = newHexNum(b.BlockNumber.Bytes()) - ext.BlockHash = newHexData(b.BlockHash.Bytes()) - ext.ParentHash = newHexData(b.ParentHash.Bytes()) - ext.Nonce = newHexNum(b.Nonce[:]) - ext.Sha3Uncles = newHexData(b.Sha3Uncles.Bytes()) - ext.LogsBloom = newHexData(b.LogsBloom.Bytes()) - ext.TransactionRoot = newHexData(b.TransactionRoot.Bytes()) - ext.StateRoot = newHexData(b.StateRoot.Bytes()) - ext.Miner = newHexData(b.Miner.Bytes()) - ext.Difficulty = newHexNum(b.Difficulty.Bytes()) - ext.TotalDifficulty = newHexNum(b.TotalDifficulty.Bytes()) - ext.Size = newHexNum(b.Size.Bytes()) - ext.ExtraData = newHexData(b.ExtraData) - ext.GasLimit = newHexNum(b.GasLimit.Bytes()) - // ext.MinGasPrice = newHexNum(big.NewInt(b.MinGasPrice).Bytes()) - ext.GasUsed = newHexNum(b.GasUsed.Bytes()) - ext.UnixTimestamp = newHexNum(big.NewInt(b.UnixTimestamp).Bytes()) - ext.Transactions = make([]interface{}, len(b.Transactions)) - if b.fullTx { - for i, tx := range b.Transactions { - ext.Transactions[i] = tx - } - } else { - for i, tx := range b.Transactions { - ext.Transactions[i] = newHexData(tx.Hash.Bytes()) - } - } - ext.Uncles = make([]*hexdata, len(b.Uncles)) - for i, v := range b.Uncles { - ext.Uncles[i] = newHexData(v.Bytes()) - } - - return json.Marshal(ext) + Uncles []*hexdata `json:"uncles"` } func NewBlockRes(block *types.Block) *BlockRes { @@ -99,92 +35,67 @@ func NewBlockRes(block *types.Block) *BlockRes { } res := new(BlockRes) - res.BlockNumber = block.Number() - res.BlockHash = block.Hash() - res.ParentHash = block.ParentHash() - res.Nonce = block.Header().Nonce - res.Sha3Uncles = block.Header().UncleHash - res.LogsBloom = block.Bloom() - res.TransactionRoot = block.Header().TxHash - res.StateRoot = block.Root() - res.Miner = block.Header().Coinbase - res.Difficulty = block.Difficulty() - res.TotalDifficulty = block.Td - res.Size = big.NewInt(int64(block.Size())) - res.ExtraData = []byte(block.Header().Extra) - res.GasLimit = block.GasLimit() + res.BlockNumber = newHexNum(block.Number()) + res.BlockHash = newHexData(block.Hash()) + res.ParentHash = newHexData(block.ParentHash()) + res.Nonce = newHexNum(block.Header().Nonce) + res.Sha3Uncles = newHexData(block.Header().UncleHash) + res.LogsBloom = newHexData(block.Bloom()) + res.TransactionRoot = newHexData(block.Header().TxHash) + res.StateRoot = newHexData(block.Root()) + res.Miner = newHexData(block.Header().Coinbase) + res.Difficulty = newHexNum(block.Difficulty()) + res.TotalDifficulty = newHexNum(block.Td) + res.Size = newHexNum(block.Size()) + res.ExtraData = newHexData(block.Header().Extra) + res.GasLimit = newHexNum(block.GasLimit()) // res.MinGasPrice = - res.GasUsed = block.GasUsed() - res.UnixTimestamp = block.Time() - res.Transactions = make([]*TransactionRes, len(block.Transactions())) - for i, tx := range block.Transactions() { - v := NewTransactionRes(tx) - v.BlockHash = block.Hash() - v.BlockNumber = block.Number().Int64() - v.TxIndex = int64(i) - res.Transactions[i] = v - } - res.Uncles = make([]common.Hash, len(block.Uncles())) + res.GasUsed = newHexNum(block.GasUsed()) + res.UnixTimestamp = newHexNum(block.Time()) + res.Transactions = NewTransactionsRes(block.Transactions()) + res.Uncles = make([]*hexdata, len(block.Uncles())) for i, uncle := range block.Uncles() { - res.Uncles[i] = uncle.Hash() + res.Uncles[i] = newHexData(uncle.Hash()) } return res } type TransactionRes struct { - Hash common.Hash `json:"hash"` - Nonce uint64 `json:"nonce"` - BlockHash common.Hash `json:"blockHash"` - BlockNumber int64 `json:"blockNumber"` - TxIndex int64 `json:"transactionIndex"` - From common.Address `json:"from"` - To *common.Address `json:"to"` - Value *big.Int `json:"value"` - Gas *big.Int `json:"gas"` - GasPrice *big.Int `json:"gasPrice"` - Input []byte `json:"input"` -} - -func (t *TransactionRes) MarshalJSON() ([]byte, error) { - var ext struct { - Hash *hexdata `json:"hash"` - Nonce *hexnum `json:"nonce"` - BlockHash *hexdata `json:"blockHash"` - BlockNumber *hexnum `json:"blockNumber"` - TxIndex *hexnum `json:"transactionIndex"` - From *hexdata `json:"from"` - To *hexdata `json:"to"` - Value *hexnum `json:"value"` - Gas *hexnum `json:"gas"` - GasPrice *hexnum `json:"gasPrice"` - Input *hexdata `json:"input"` - } - - ext.Hash = newHexData(t.Hash.Bytes()) - ext.Nonce = newHexNum(big.NewInt(int64(t.Nonce)).Bytes()) - ext.BlockHash = newHexData(t.BlockHash.Bytes()) - ext.BlockNumber = newHexNum(big.NewInt(t.BlockNumber).Bytes()) - ext.TxIndex = newHexNum(big.NewInt(t.TxIndex).Bytes()) - ext.From = newHexData(t.From.Bytes()) - ext.To = newHexData(t.To.Bytes()) - ext.Value = newHexNum(t.Value.Bytes()) - ext.Gas = newHexNum(t.Gas.Bytes()) - ext.GasPrice = newHexNum(t.GasPrice.Bytes()) - ext.Input = newHexData(t.Input) - - return json.Marshal(ext) + Hash *hexdata `json:"hash"` + Nonce *hexnum `json:"nonce"` + BlockHash *hexdata `json:"blockHash"` + BlockNumber *hexnum `json:"blockNumber"` + TxIndex *hexnum `json:"transactionIndex"` + From *hexdata `json:"from"` + To *hexdata `json:"to"` + Value *hexnum `json:"value"` + Gas *hexnum `json:"gas"` + GasPrice *hexnum `json:"gasPrice"` + Input *hexdata `json:"input"` } func NewTransactionRes(tx *types.Transaction) *TransactionRes { var v = new(TransactionRes) - v.Hash = tx.Hash() - v.Nonce = tx.Nonce() - v.From, _ = tx.From() - v.To = tx.To() - v.Value = tx.Value() - v.Gas = tx.Gas() - v.GasPrice = tx.GasPrice() - v.Input = tx.Data() + v.Hash = newHexData(tx.Hash()) + v.Nonce = newHexNum(tx.Nonce()) + // v.BlockHash = + // v.BlockNumber = + // v.TxIndex = + from, _ := tx.From() + v.From = newHexData(from) + v.To = newHexData(tx.To()) + v.Value = newHexNum(tx.Value()) + v.Gas = newHexNum(tx.Gas()) + v.GasPrice = newHexNum(tx.GasPrice()) + v.Input = newHexData(tx.Data()) + return v +} + +func NewTransactionsRes(txs []*types.Transaction) []*TransactionRes { + v := make([]*TransactionRes, len(txs)) + for i, tx := range txs { + v[i] = NewTransactionRes(tx) + } return v } @@ -212,51 +123,28 @@ func NewTransactionRes(tx *types.Transaction) *TransactionRes { // } type LogRes struct { - Address common.Address `json:"address"` - Topics []common.Hash `json:"topics"` - Data []byte `json:"data"` - BlockNumber uint64 `json:"blockNumber"` - Hash common.Hash `json:"hash"` - LogIndex uint64 `json:"logIndex"` - BlockHash common.Hash `json:"blockHash"` - TransactionHash common.Hash `json:"transactionHash"` - TransactionIndex uint64 `json:"transactionIndex"` + Address *hexdata `json:"address"` + Topics []*hexdata `json:"topics"` + Data *hexdata `json:"data"` + BlockNumber *hexnum `json:"blockNumber"` + Hash *hexdata `json:"hash"` + LogIndex *hexnum `json:"logIndex"` + BlockHash *hexdata `json:"blockHash"` + TransactionHash *hexdata `json:"transactionHash"` + TransactionIndex *hexnum `json:"transactionIndex"` } func NewLogRes(log state.Log) LogRes { var l LogRes - l.Topics = make([]common.Hash, len(log.Topics())) - l.Address = log.Address() - l.Data = log.Data() - l.BlockNumber = log.Number() + l.Topics = make([]*hexdata, len(log.Topics())) for j, topic := range log.Topics() { - l.Topics[j] = topic - } - return l -} - -func (l *LogRes) MarshalJSON() ([]byte, error) { - var ext struct { - Address *hexdata `json:"address"` - Topics []*hexdata `json:"topics"` - Data *hexdata `json:"data"` - BlockNumber *hexnum `json:"blockNumber"` - Hash *hexdata `json:"hash"` - LogIndex *hexnum `json:"logIndex"` - BlockHash *hexdata `json:"blockHash"` - TransactionHash *hexdata `json:"transactionHash"` - TransactionIndex *hexnum `json:"transactionIndex"` + l.Topics[j] = newHexData(topic) } + l.Address = newHexData(log.Address()) + l.Data = newHexData(log.Data()) + l.BlockNumber = newHexNum(log.Number()) - ext.Address = newHexData(l.Address.Bytes()) - ext.Data = newHexData(l.Data) - ext.BlockNumber = newHexNum(l.BlockNumber) - ext.Topics = make([]*hexdata, len(l.Topics)) - for i, v := range l.Topics { - ext.Topics[i] = newHexData(v) - } - - return json.Marshal(ext) + return l } func NewLogsRes(logs state.Logs) (ls []LogRes) { diff --git a/rpc/responses_test.go b/rpc/responses_test.go index 80e97a7531..18598f0713 100644 --- a/rpc/responses_test.go +++ b/rpc/responses_test.go @@ -1,123 +1,123 @@ package rpc import ( - "encoding/json" - "math/big" - "testing" +// "encoding/json" +// "math/big" +// "testing" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" +// "github.com/ethereum/go-ethereum/common" +// "github.com/ethereum/go-ethereum/core/state" +// "github.com/ethereum/go-ethereum/core/types" ) -func TestNewBlockRes(t *testing.T) { - parentHash := common.HexToHash("0x01") - coinbase := common.HexToAddress("0x01") - root := common.HexToHash("0x01") - difficulty := common.Big1 - nonce := uint64(1) - extra := "" - block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, extra) - - _ = NewBlockRes(block) -} - -func TestBlockRes(t *testing.T) { - v := &BlockRes{ - BlockNumber: big.NewInt(0), - BlockHash: common.HexToHash("0x0"), - ParentHash: common.HexToHash("0x0"), - Nonce: [8]byte{0, 0, 0, 0, 0, 0, 0, 0}, - Sha3Uncles: common.HexToHash("0x0"), - LogsBloom: types.BytesToBloom([]byte{0}), - TransactionRoot: common.HexToHash("0x0"), - StateRoot: common.HexToHash("0x0"), - Miner: common.HexToAddress("0x0"), - Difficulty: big.NewInt(0), - TotalDifficulty: big.NewInt(0), - Size: big.NewInt(0), - ExtraData: []byte{}, - GasLimit: big.NewInt(0), - MinGasPrice: int64(0), - GasUsed: big.NewInt(0), - UnixTimestamp: int64(0), - // Transactions []*TransactionRes `json:"transactions"` - // Uncles []common.Hash `json:"uncles"` - } - - _, _ = json.Marshal(v) - - // fmt.Println(string(j)) - -} - -func TestTransactionRes(t *testing.T) { - a := common.HexToAddress("0x0") - v := &TransactionRes{ - Hash: common.HexToHash("0x0"), - Nonce: uint64(0), - BlockHash: common.HexToHash("0x0"), - BlockNumber: int64(0), - TxIndex: int64(0), - From: common.HexToAddress("0x0"), - To: &a, - Value: big.NewInt(0), - Gas: big.NewInt(0), - GasPrice: big.NewInt(0), - Input: []byte{0}, - } - - _, _ = json.Marshal(v) -} - -func TestNewTransactionRes(t *testing.T) { - to := common.HexToAddress("0x02") - amount := big.NewInt(1) - gasAmount := big.NewInt(1) - gasPrice := big.NewInt(1) - data := []byte{1, 2, 3} - tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data) - - _ = NewTransactionRes(tx) -} - -func TestLogRes(t *testing.T) { - topics := make([]common.Hash, 3) - topics = append(topics, common.HexToHash("0x00")) - topics = append(topics, common.HexToHash("0x10")) - topics = append(topics, common.HexToHash("0x20")) - - v := &LogRes{ - Topics: topics, - Address: common.HexToAddress("0x0"), - Data: []byte{1, 2, 3}, - BlockNumber: uint64(5), - } - - _, _ = json.Marshal(v) -} - -func MakeStateLog(num int) state.Log { - address := common.HexToAddress("0x0") - data := []byte{1, 2, 3} - number := uint64(num) - topics := make([]common.Hash, 3) - topics = append(topics, common.HexToHash("0x00")) - topics = append(topics, common.HexToHash("0x10")) - topics = append(topics, common.HexToHash("0x20")) - log := state.NewLog(address, topics, data, number) - return log -} - -func TestNewLogRes(t *testing.T) { - log := MakeStateLog(0) - _ = NewLogRes(log) -} - -func TestNewLogsRes(t *testing.T) { - logs := make([]state.Log, 3) - logs[0] = MakeStateLog(1) - logs[1] = MakeStateLog(2) - logs[2] = MakeStateLog(3) - _ = NewLogsRes(logs) -} +// func TestNewBlockRes(t *testing.T) { +// parentHash := common.HexToHash("0x01") +// coinbase := common.HexToAddress("0x01") +// root := common.HexToHash("0x01") +// difficulty := common.Big1 +// nonce := uint64(1) +// extra := "" +// block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, extra) + +// _ = NewBlockRes(block) +// } + +// func TestBlockRes(t *testing.T) { +// v := &BlockRes{ +// BlockNumber: big.NewInt(0), +// BlockHash: common.HexToHash("0x0"), +// ParentHash: common.HexToHash("0x0"), +// Nonce: [8]byte{0, 0, 0, 0, 0, 0, 0, 0}, +// Sha3Uncles: common.HexToHash("0x0"), +// LogsBloom: types.BytesToBloom([]byte{0}), +// TransactionRoot: common.HexToHash("0x0"), +// StateRoot: common.HexToHash("0x0"), +// Miner: common.HexToAddress("0x0"), +// Difficulty: big.NewInt(0), +// TotalDifficulty: big.NewInt(0), +// Size: big.NewInt(0), +// ExtraData: []byte{}, +// GasLimit: big.NewInt(0), +// MinGasPrice: int64(0), +// GasUsed: big.NewInt(0), +// UnixTimestamp: int64(0), +// // Transactions []*TransactionRes `json:"transactions"` +// // Uncles []common.Hash `json:"uncles"` +// } + +// _, _ = json.Marshal(v) + +// // fmt.Println(string(j)) + +// } + +// func TestTransactionRes(t *testing.T) { +// a := common.HexToAddress("0x0") +// v := &TransactionRes{ +// Hash: common.HexToHash("0x0"), +// Nonce: uint64(0), +// BlockHash: common.HexToHash("0x0"), +// BlockNumber: int64(0), +// TxIndex: int64(0), +// From: common.HexToAddress("0x0"), +// To: &a, +// Value: big.NewInt(0), +// Gas: big.NewInt(0), +// GasPrice: big.NewInt(0), +// Input: []byte{0}, +// } + +// _, _ = json.Marshal(v) +// } + +// func TestNewTransactionRes(t *testing.T) { +// to := common.HexToAddress("0x02") +// amount := big.NewInt(1) +// gasAmount := big.NewInt(1) +// gasPrice := big.NewInt(1) +// data := []byte{1, 2, 3} +// tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data) + +// _ = NewTransactionRes(tx) +// } + +// func TestLogRes(t *testing.T) { +// topics := make([]common.Hash, 3) +// topics = append(topics, common.HexToHash("0x00")) +// topics = append(topics, common.HexToHash("0x10")) +// topics = append(topics, common.HexToHash("0x20")) + +// v := &LogRes{ +// Topics: topics, +// Address: common.HexToAddress("0x0"), +// Data: []byte{1, 2, 3}, +// BlockNumber: uint64(5), +// } + +// _, _ = json.Marshal(v) +// } + +// func MakeStateLog(num int) state.Log { +// address := common.HexToAddress("0x0") +// data := []byte{1, 2, 3} +// number := uint64(num) +// topics := make([]common.Hash, 3) +// topics = append(topics, common.HexToHash("0x00")) +// topics = append(topics, common.HexToHash("0x10")) +// topics = append(topics, common.HexToHash("0x20")) +// log := state.NewLog(address, topics, data, number) +// return log +// } + +// func TestNewLogRes(t *testing.T) { +// log := MakeStateLog(0) +// _ = NewLogRes(log) +// } + +// func TestNewLogsRes(t *testing.T) { +// logs := make([]state.Log, 3) +// logs[0] = MakeStateLog(1) +// logs[1] = MakeStateLog(2) +// logs[2] = MakeStateLog(3) +// _ = NewLogsRes(logs) +// } From 40ea46620066bd7888b3f9a425fcd6201e0c7320 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Tue, 31 Mar 2015 22:40:12 +0200 Subject: [PATCH 07/12] Store and retrieve tx context metadata #608 Improving this in the future will allow for cleaning up a bit of legacy code. --- core/block_processor.go | 28 +++++++++++++++++++++++++--- rpc/api.go | 8 ++++++-- xeth/xeth.go | 23 ++++++++++++++++++++--- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/core/block_processor.go b/core/block_processor.go index e970ad06ef..ceb0ef8a7c 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -233,8 +233,9 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big sm.txpool.RemoveSet(block.Transactions()) } - for _, tx := range block.Transactions() { - putTx(sm.extraDb, tx) + // This puts transactions in a extra db for rpc + for i, tx := range block.Transactions() { + putTx(sm.extraDb, tx, block, i) } if uncle { @@ -358,11 +359,32 @@ func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err erro return state.Logs(), nil } -func putTx(db common.Database, tx *types.Transaction) { +func putTx(db common.Database, tx *types.Transaction, block *types.Block, i int) { rlpEnc, err := rlp.EncodeToBytes(tx) if err != nil { statelogger.Infoln("Failed encoding tx", err) return } db.Put(tx.Hash().Bytes(), rlpEnc) + + rlpEnc, err = rlp.EncodeToBytes(block.Hash().Bytes()) + if err != nil { + statelogger.Infoln("Failed encoding meta", err) + return + } + db.Put(append(tx.Hash().Bytes(), 0x0001), rlpEnc) + + rlpEnc, err = rlp.EncodeToBytes(block.Number().Bytes()) + if err != nil { + statelogger.Infoln("Failed encoding meta", err) + return + } + db.Put(append(tx.Hash().Bytes(), 0x0002), rlpEnc) + + rlpEnc, err = rlp.EncodeToBytes(i) + if err != nil { + statelogger.Infoln("Failed encoding meta", err) + return + } + db.Put(append(tx.Hash().Bytes(), 0x0003), rlpEnc) } diff --git a/rpc/api.go b/rpc/api.go index 3f5d33da6e..48039511e1 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -199,9 +199,13 @@ 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, bhash, bnum, txi := api.xeth().EthTransactionByHash(args.Hash) if tx != nil { - *reply = NewTransactionRes(tx) + v := NewTransactionRes(tx) + v.BlockHash = newHexData(bhash) + v.BlockNumber = newHexNum(bnum) + v.TxIndex = newHexNum(txi) + *reply = v } case "eth_getTransactionByBlockHashAndIndex": args := new(HashIndexArgs) diff --git a/xeth/xeth.go b/xeth/xeth.go index 7e1548964e..fcc03b85f2 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -185,12 +185,29 @@ func (self *XEth) EthBlockByHash(strHash string) *types.Block { return block } -func (self *XEth) EthTransactionByHash(hash string) *types.Transaction { +func (self *XEth) EthTransactionByHash(hash string) (tx *types.Transaction, blhash common.Hash, blnum *big.Int, txi uint64) { data, _ := self.backend.ExtraDb().Get(common.FromHex(hash)) if len(data) != 0 { - return types.NewTransactionFromBytes(data) + tx = types.NewTransactionFromBytes(data) } - return nil + + // blockhash + data, _ = self.backend.ExtraDb().Get(append(common.FromHex(hash), 0x0001)) + if len(data) != 0 { + blhash = common.BytesToHash(data) + } + // blocknum + data, _ = self.backend.ExtraDb().Get(append(common.FromHex(hash), 0x0002)) + if len(data) != 0 { + blnum = common.Bytes2Big(data) + } + // txindex + data, _ = self.backend.ExtraDb().Get(append(common.FromHex(hash), 0x0003)) + if len(data) != 0 { + txi = common.BytesToNumber(data) + } + + return } func (self *XEth) BlockByNumber(num int64) *Block { From 25998cfc456876a5447e45877b7f843730bab7c1 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 1 Apr 2015 09:11:23 +0200 Subject: [PATCH 08/12] Re-enabled response tests (needs improvement) --- rpc/responses_test.go | 169 +++++++++++++----------------------------- 1 file changed, 52 insertions(+), 117 deletions(-) diff --git a/rpc/responses_test.go b/rpc/responses_test.go index 18598f0713..8c1e2873fc 100644 --- a/rpc/responses_test.go +++ b/rpc/responses_test.go @@ -1,123 +1,58 @@ package rpc import ( -// "encoding/json" -// "math/big" -// "testing" + "math/big" + "testing" -// "github.com/ethereum/go-ethereum/common" -// "github.com/ethereum/go-ethereum/core/state" -// "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" ) -// func TestNewBlockRes(t *testing.T) { -// parentHash := common.HexToHash("0x01") -// coinbase := common.HexToAddress("0x01") -// root := common.HexToHash("0x01") -// difficulty := common.Big1 -// nonce := uint64(1) -// extra := "" -// block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, extra) - -// _ = NewBlockRes(block) -// } - -// func TestBlockRes(t *testing.T) { -// v := &BlockRes{ -// BlockNumber: big.NewInt(0), -// BlockHash: common.HexToHash("0x0"), -// ParentHash: common.HexToHash("0x0"), -// Nonce: [8]byte{0, 0, 0, 0, 0, 0, 0, 0}, -// Sha3Uncles: common.HexToHash("0x0"), -// LogsBloom: types.BytesToBloom([]byte{0}), -// TransactionRoot: common.HexToHash("0x0"), -// StateRoot: common.HexToHash("0x0"), -// Miner: common.HexToAddress("0x0"), -// Difficulty: big.NewInt(0), -// TotalDifficulty: big.NewInt(0), -// Size: big.NewInt(0), -// ExtraData: []byte{}, -// GasLimit: big.NewInt(0), -// MinGasPrice: int64(0), -// GasUsed: big.NewInt(0), -// UnixTimestamp: int64(0), -// // Transactions []*TransactionRes `json:"transactions"` -// // Uncles []common.Hash `json:"uncles"` -// } - -// _, _ = json.Marshal(v) - -// // fmt.Println(string(j)) - -// } - -// func TestTransactionRes(t *testing.T) { -// a := common.HexToAddress("0x0") -// v := &TransactionRes{ -// Hash: common.HexToHash("0x0"), -// Nonce: uint64(0), -// BlockHash: common.HexToHash("0x0"), -// BlockNumber: int64(0), -// TxIndex: int64(0), -// From: common.HexToAddress("0x0"), -// To: &a, -// Value: big.NewInt(0), -// Gas: big.NewInt(0), -// GasPrice: big.NewInt(0), -// Input: []byte{0}, -// } - -// _, _ = json.Marshal(v) -// } - -// func TestNewTransactionRes(t *testing.T) { -// to := common.HexToAddress("0x02") -// amount := big.NewInt(1) -// gasAmount := big.NewInt(1) -// gasPrice := big.NewInt(1) -// data := []byte{1, 2, 3} -// tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data) - -// _ = NewTransactionRes(tx) -// } - -// func TestLogRes(t *testing.T) { -// topics := make([]common.Hash, 3) -// topics = append(topics, common.HexToHash("0x00")) -// topics = append(topics, common.HexToHash("0x10")) -// topics = append(topics, common.HexToHash("0x20")) - -// v := &LogRes{ -// Topics: topics, -// Address: common.HexToAddress("0x0"), -// Data: []byte{1, 2, 3}, -// BlockNumber: uint64(5), -// } - -// _, _ = json.Marshal(v) -// } - -// func MakeStateLog(num int) state.Log { -// address := common.HexToAddress("0x0") -// data := []byte{1, 2, 3} -// number := uint64(num) -// topics := make([]common.Hash, 3) -// topics = append(topics, common.HexToHash("0x00")) -// topics = append(topics, common.HexToHash("0x10")) -// topics = append(topics, common.HexToHash("0x20")) -// log := state.NewLog(address, topics, data, number) -// return log -// } - -// func TestNewLogRes(t *testing.T) { -// log := MakeStateLog(0) -// _ = NewLogRes(log) -// } - -// func TestNewLogsRes(t *testing.T) { -// logs := make([]state.Log, 3) -// logs[0] = MakeStateLog(1) -// logs[1] = MakeStateLog(2) -// logs[2] = MakeStateLog(3) -// _ = NewLogsRes(logs) -// } +func TestNewBlockRes(t *testing.T) { + parentHash := common.HexToHash("0x01") + coinbase := common.HexToAddress("0x01") + root := common.HexToHash("0x01") + difficulty := common.Big1 + nonce := uint64(1) + extra := "" + block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, extra) + + _ = NewBlockRes(block) +} + +func TestNewTransactionRes(t *testing.T) { + to := common.HexToAddress("0x02") + amount := big.NewInt(1) + gasAmount := big.NewInt(1) + gasPrice := big.NewInt(1) + data := []byte{1, 2, 3} + tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data) + + _ = NewTransactionRes(tx) +} + +func MakeStateLog(num int) state.Log { + address := common.HexToAddress("0x0") + data := []byte{1, 2, 3} + number := uint64(num) + topics := make([]common.Hash, 3) + topics = append(topics, common.HexToHash("0x00")) + topics = append(topics, common.HexToHash("0x10")) + topics = append(topics, common.HexToHash("0x20")) + log := state.NewLog(address, topics, data, number) + return log +} + +func TestNewLogRes(t *testing.T) { + log := MakeStateLog(0) + _ = NewLogRes(log) +} + +func TestNewLogsRes(t *testing.T) { + logs := make([]state.Log, 3) + logs[0] = MakeStateLog(1) + logs[1] = MakeStateLog(2) + logs[2] = MakeStateLog(3) + _ = NewLogsRes(logs) +} From 7b7392826d7b76fd4a0bd57baa7ca1224a19a3f6 Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 1 Apr 2015 11:38:06 +0200 Subject: [PATCH 09/12] Improved response tests Actually verifies output as by regex --- rpc/messages.go | 6 +- rpc/responses_test.go | 128 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 117 insertions(+), 17 deletions(-) diff --git a/rpc/messages.go b/rpc/messages.go index 1ad41654b2..42af53c58f 100644 --- a/rpc/messages.go +++ b/rpc/messages.go @@ -50,8 +50,12 @@ func newHexData(input interface{}) *hexdata { d.data = input.([]byte) case common.Hash: d.data = input.(common.Hash).Bytes() + case *common.Hash: + d.data = input.(*common.Hash).Bytes() case common.Address: d.data = input.(common.Address).Bytes() + case *common.Address: + d.data = input.(*common.Address).Bytes() case *big.Int: d.data = input.(*big.Int).Bytes() case int64: @@ -62,7 +66,7 @@ func newHexData(input interface{}) *hexdata { d.data = big.NewInt(int64(input.(int))).Bytes() case uint: d.data = big.NewInt(int64(input.(uint))).Bytes() - case string: + case string: // hexstring d.data = common.Big(input.(string)).Bytes() default: d.data = nil diff --git a/rpc/responses_test.go b/rpc/responses_test.go index 8c1e2873fc..5c6c6a895b 100644 --- a/rpc/responses_test.go +++ b/rpc/responses_test.go @@ -1,7 +1,10 @@ package rpc import ( + "encoding/json" + "fmt" "math/big" + "regexp" "testing" "github.com/ethereum/go-ethereum/common" @@ -9,6 +12,15 @@ import ( "github.com/ethereum/go-ethereum/core/types" ) +const ( + reHash = `"0x[0-9a-f]{64}"` // 32 bytes + reHashOpt = `"(0x[0-9a-f]{64})"|null` // 32 bytes or null + reAddress = `"0x[0-9a-f]{40}"` // 20 bytes + reAddressOpt = `"0x[0-9a-f]{40}"|null` // 20 bytes or null + reNum = `"0x([1-9a-f][0-9a-f]{1,15})|0"` // must not have left-padded zeros + reData = `"0x[0-9a-f]*"` // can be "empty" +) + func TestNewBlockRes(t *testing.T) { parentHash := common.HexToHash("0x01") coinbase := common.HexToAddress("0x01") @@ -17,8 +29,35 @@ func TestNewBlockRes(t *testing.T) { nonce := uint64(1) extra := "" block := types.NewBlock(parentHash, coinbase, root, difficulty, nonce, extra) + tests := map[string]string{ + "number": reNum, + "hash": reHash, + "parentHash": reHash, + "nonce": reNum, + "sha3Uncles": reHash, + "logsBloom": reData, + "transactionRoot": reHash, + "stateRoot": reHash, + "miner": reAddress, + "difficulty": `"0x1"`, + "totalDifficulty": reNum, + "size": reNum, + "extraData": reData, + "gasLimit": reNum, + // "minGasPrice": "0x", + "gasUsed": reNum, + "timestamp": reNum, + } - _ = NewBlockRes(block) + v := NewBlockRes(block) + j, _ := json.Marshal(v) + + for k, re := range tests { + match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j)) + if !match { + t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j)) + } + } } func TestNewTransactionRes(t *testing.T) { @@ -29,10 +68,80 @@ func TestNewTransactionRes(t *testing.T) { data := []byte{1, 2, 3} tx := types.NewTransactionMessage(to, amount, gasAmount, gasPrice, data) - _ = NewTransactionRes(tx) + tests := map[string]string{ + "hash": reHash, + "nonce": reNum, + "blockHash": reHash, + "blockNum": reNum, + "transactionIndex": reNum, + "from": reAddress, + "to": reAddressOpt, + "value": reNum, + "gas": reNum, + "gasPrice": reNum, + "input": reData, + } + + v := NewTransactionRes(tx) + v.BlockHash = newHexData(common.HexToHash("0x030201")) + v.BlockNumber = newHexNum(5) + v.TxIndex = newHexNum(0) + j, _ := json.Marshal(v) + for k, re := range tests { + match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j)) + if !match { + t.Error(fmt.Sprintf("`%s` output json does not match format %s. Source %s", k, re, j)) + } + } + } -func MakeStateLog(num int) state.Log { +func TestNewLogRes(t *testing.T) { + log := makeStateLog(0) + tests := map[string]string{ + "address": reAddress, + // "topics": "[.*]" + "data": reData, + "blockNumber": reNum, + // "hash": reHash, + // "logIndex": reNum, + // "blockHash": reHash, + // "transactionHash": reHash, + "transactionIndex": reNum, + } + + v := NewLogRes(log) + j, _ := json.Marshal(v) + + for k, re := range tests { + match, _ := regexp.MatchString(fmt.Sprintf(`{.*"%s":%s.*}`, k, re), string(j)) + if !match { + t.Error(fmt.Sprintf("`%s` output json does not match format %s. Got %s", k, re, j)) + } + } + +} + +func TestNewLogsRes(t *testing.T) { + logs := make([]state.Log, 3) + logs[0] = makeStateLog(1) + logs[1] = makeStateLog(2) + logs[2] = makeStateLog(3) + tests := map[string]string{} + + v := NewLogsRes(logs) + j, _ := json.Marshal(v) + + for k, re := range tests { + match, _ := regexp.MatchString(fmt.Sprintf(`[{.*"%s":%s.*}]`, k, re), string(j)) + if !match { + t.Error(fmt.Sprintf("%s output json does not match format %s. Got %s", k, re, j)) + } + } + +} + +func makeStateLog(num int) state.Log { address := common.HexToAddress("0x0") data := []byte{1, 2, 3} number := uint64(num) @@ -43,16 +152,3 @@ func MakeStateLog(num int) state.Log { log := state.NewLog(address, topics, data, number) return log } - -func TestNewLogRes(t *testing.T) { - log := MakeStateLog(0) - _ = NewLogRes(log) -} - -func TestNewLogsRes(t *testing.T) { - logs := make([]state.Log, 3) - logs[0] = MakeStateLog(1) - logs[1] = MakeStateLog(2) - logs[2] = MakeStateLog(3) - _ = NewLogsRes(logs) -} From b860b6769329137c24024c2330529d7b2078d89d Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 1 Apr 2015 11:45:29 +0200 Subject: [PATCH 10/12] Remove extra type assetion --- rpc/messages.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/rpc/messages.go b/rpc/messages.go index 42af53c58f..f868c5f9b0 100644 --- a/rpc/messages.go +++ b/rpc/messages.go @@ -45,29 +45,29 @@ func (d *hexdata) UnmarshalJSON(b []byte) (err error) { func newHexData(input interface{}) *hexdata { d := new(hexdata) - switch input.(type) { + switch input := input.(type) { case []byte: - d.data = input.([]byte) + d.data = input case common.Hash: - d.data = input.(common.Hash).Bytes() + d.data = input.Bytes() case *common.Hash: - d.data = input.(*common.Hash).Bytes() + d.data = input.Bytes() case common.Address: - d.data = input.(common.Address).Bytes() + d.data = input.Bytes() case *common.Address: - d.data = input.(*common.Address).Bytes() + d.data = input.Bytes() case *big.Int: - d.data = input.(*big.Int).Bytes() + d.data = input.Bytes() case int64: - d.data = big.NewInt(input.(int64)).Bytes() + d.data = big.NewInt(input).Bytes() case uint64: - d.data = big.NewInt(int64(input.(uint64))).Bytes() + d.data = big.NewInt(int64(input)).Bytes() case int: - d.data = big.NewInt(int64(input.(int))).Bytes() + d.data = big.NewInt(int64(input)).Bytes() case uint: - d.data = big.NewInt(int64(input.(uint))).Bytes() + d.data = big.NewInt(int64(input)).Bytes() case string: // hexstring - d.data = common.Big(input.(string)).Bytes() + d.data = common.Big(input).Bytes() default: d.data = nil } From 86ba7432a965d9469ce1b4ccc2397ed2e08c9a3c Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 1 Apr 2015 12:14:35 +0200 Subject: [PATCH 11/12] txMeta storage as struct --- core/block_processor.go | 28 +++++++++++----------------- xeth/xeth.go | 27 ++++++++++++++------------- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/core/block_processor.go b/core/block_processor.go index ceb0ef8a7c..c463bd0836 100644 --- a/core/block_processor.go +++ b/core/block_processor.go @@ -235,7 +235,7 @@ func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big // This puts transactions in a extra db for rpc for i, tx := range block.Transactions() { - putTx(sm.extraDb, tx, block, i) + putTx(sm.extraDb, tx, block, uint64(i)) } if uncle { @@ -359,7 +359,7 @@ func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err erro return state.Logs(), nil } -func putTx(db common.Database, tx *types.Transaction, block *types.Block, i int) { +func putTx(db common.Database, tx *types.Transaction, block *types.Block, i uint64) { rlpEnc, err := rlp.EncodeToBytes(tx) if err != nil { statelogger.Infoln("Failed encoding tx", err) @@ -367,24 +367,18 @@ func putTx(db common.Database, tx *types.Transaction, block *types.Block, i int) } db.Put(tx.Hash().Bytes(), rlpEnc) - rlpEnc, err = rlp.EncodeToBytes(block.Hash().Bytes()) - if err != nil { - statelogger.Infoln("Failed encoding meta", err) - return + var txExtra struct { + BlockHash common.Hash + BlockIndex uint64 + Index uint64 } - db.Put(append(tx.Hash().Bytes(), 0x0001), rlpEnc) - - rlpEnc, err = rlp.EncodeToBytes(block.Number().Bytes()) - if err != nil { - statelogger.Infoln("Failed encoding meta", err) - return - } - db.Put(append(tx.Hash().Bytes(), 0x0002), rlpEnc) - - rlpEnc, err = rlp.EncodeToBytes(i) + txExtra.BlockHash = block.Hash() + txExtra.BlockIndex = block.NumberU64() + txExtra.Index = i + rlpMeta, err := rlp.EncodeToBytes(txExtra) if err != nil { statelogger.Infoln("Failed encoding meta", err) return } - db.Put(append(tx.Hash().Bytes(), 0x0003), rlpEnc) + db.Put(append(tx.Hash().Bytes(), 0x0001), rlpMeta) } diff --git a/xeth/xeth.go b/xeth/xeth.go index fcc03b85f2..33fda9b4be 100644 --- a/xeth/xeth.go +++ b/xeth/xeth.go @@ -19,6 +19,7 @@ import ( "github.com/ethereum/go-ethereum/event/filter" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/miner" + "github.com/ethereum/go-ethereum/rlp" ) var ( @@ -191,20 +192,20 @@ func (self *XEth) EthTransactionByHash(hash string) (tx *types.Transaction, blha tx = types.NewTransactionFromBytes(data) } - // blockhash - data, _ = self.backend.ExtraDb().Get(append(common.FromHex(hash), 0x0001)) - if len(data) != 0 { - blhash = common.BytesToHash(data) - } - // blocknum - data, _ = self.backend.ExtraDb().Get(append(common.FromHex(hash), 0x0002)) - if len(data) != 0 { - blnum = common.Bytes2Big(data) + // meta + var txExtra struct { + BlockHash common.Hash + BlockIndex int64 + Index uint64 } - // txindex - data, _ = self.backend.ExtraDb().Get(append(common.FromHex(hash), 0x0003)) - if len(data) != 0 { - txi = common.BytesToNumber(data) + + v, _ := self.backend.ExtraDb().Get(append(common.FromHex(hash), 0x0001)) + r := bytes.NewReader(v) + err := rlp.Decode(r, &txExtra) + if err == nil { + blhash = txExtra.BlockHash + blnum = big.NewInt(txExtra.BlockIndex) + txi = txExtra.Index } return From 02fb83782eab5d6ad394aca58daab77a9525d5ff Mon Sep 17 00:00:00 2001 From: Taylor Gerring Date: Wed, 1 Apr 2015 12:28:48 +0200 Subject: [PATCH 12/12] #612 rename eth_protocol method --- rpc/api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/api.go b/rpc/api.go index 7f10f16e37..c046c22fed 100644 --- a/rpc/api.go +++ b/rpc/api.go @@ -54,7 +54,7 @@ func (api *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) err case "net_peerCount": v := api.xeth().PeerCount() *reply = common.ToHex(big.NewInt(int64(v)).Bytes()) - case "eth_version": + case "eth_protocolVersion": *reply = api.xeth().EthVersion() case "eth_coinbase": // TODO handling of empty coinbase due to lack of accounts