From ca37730c9ddf8b3b7e59abc95f462de54ac9457e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 8 Sep 2016 17:17:55 +0300 Subject: [PATCH 1/2] ethclient: fix new block->header subscription endpoint --- ethclient/ethclient.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 50346f6ae..ffa8228cc 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -227,7 +227,7 @@ func (ec *Client) SyncProgress(ctx context.Context) (*ethereum.SyncProgress, err // SubscribeNewHead subscribes to notifications about the current blockchain head // on the given channel. func (ec *Client) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) { - return ec.c.EthSubscribe(ctx, ch, "newBlocks", map[string]struct{}{}) + return ec.c.EthSubscribe(ctx, ch, "newHeads", map[string]struct{}{}) } // State Access From b6b5ec8f75502df65a44cea4f4c07cc28231027c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 8 Sep 2016 18:16:53 +0300 Subject: [PATCH 2/2] core/types: add core type marshal methods too --- core/types/json.go | 21 +++++++++++ core/types/json_test.go | 77 +++++++++++++++++++++++++++++++++++++++ core/types/receipt.go | 15 ++++++++ core/types/transaction.go | 18 +++++++++ 4 files changed, 131 insertions(+) diff --git a/core/types/json.go b/core/types/json.go index 403e79899..d2718a96d 100644 --- a/core/types/json.go +++ b/core/types/json.go @@ -26,6 +26,13 @@ import ( type hexBytes []byte +func (b *hexBytes) MarshalJSON() ([]byte, error) { + if b != nil { + return []byte(fmt.Sprintf(`"0x%x"`, []byte(*b))), nil + } + return nil, nil +} + func (b *hexBytes) UnmarshalJSON(input []byte) error { if len(input) < 2 || input[0] != '"' || input[len(input)-1] != '"' { return fmt.Errorf("cannot unmarshal non-string into hexBytes") @@ -44,6 +51,13 @@ func (b *hexBytes) UnmarshalJSON(input []byte) error { type hexBig big.Int +func (b *hexBig) MarshalJSON() ([]byte, error) { + if b != nil { + return []byte(fmt.Sprintf(`"0x%x"`, (*big.Int)(b))), nil + } + return nil, nil +} + func (b *hexBig) UnmarshalJSON(input []byte) error { raw, err := checkHexNumber(input) if err != nil { @@ -59,6 +73,13 @@ func (b *hexBig) UnmarshalJSON(input []byte) error { type hexUint64 uint64 +func (b *hexUint64) MarshalJSON() ([]byte, error) { + if b != nil { + return []byte(fmt.Sprintf(`"0x%x"`, *(*uint64)(b))), nil + } + return nil, nil +} + func (b *hexUint64) UnmarshalJSON(input []byte) error { raw, err := checkHexNumber(input) if err != nil { diff --git a/core/types/json_test.go b/core/types/json_test.go index 5f422b873..605c2b564 100644 --- a/core/types/json_test.go +++ b/core/types/json_test.go @@ -2,6 +2,7 @@ package types import ( "encoding/json" + "reflect" "testing" "github.com/ethereum/go-ethereum/common" @@ -44,6 +45,31 @@ func TestUnmarshalHeader(t *testing.T) { } } +func TestMarshalHeader(t *testing.T) { + for name, test := range unmarshalHeaderTests { + if test.wantError != nil { + continue + } + var original *Header + json.Unmarshal([]byte(test.input), &original) + + blob, err := json.Marshal(original) + if err != nil { + t.Errorf("test %q: failed to marshal header: %v", name, err) + continue + } + var proced *Header + if err := json.Unmarshal(blob, &proced); err != nil { + t.Errorf("Test %q: failed to unmarshal marhsalled header: %v", name, err) + continue + } + if !reflect.DeepEqual(original, proced) { + t.Errorf("test %q: header mismatch: have %+v, want %+v", name, proced, original) + continue + } + } +} + var unmarshalTransactionTests = map[string]struct { input string wantHash common.Hash @@ -94,6 +120,32 @@ func TestUnmarshalTransaction(t *testing.T) { } } +func TestMarshalTransaction(t *testing.T) { + for name, test := range unmarshalTransactionTests { + if test.wantError != nil { + continue + } + var original *Transaction + json.Unmarshal([]byte(test.input), &original) + + blob, err := json.Marshal(original) + if err != nil { + t.Errorf("test %q: failed to marshal transaction: %v", name, err) + continue + } + var proced *Transaction + if err := json.Unmarshal(blob, &proced); err != nil { + t.Errorf("Test %q: failed to unmarshal marhsalled transaction: %v", name, err) + continue + } + proced.Hash() // hack private fields to pass deep equal + if !reflect.DeepEqual(original, proced) { + t.Errorf("test %q: transaction mismatch: have %+v, want %+v", name, proced, original) + continue + } + } +} + var unmarshalReceiptTests = map[string]struct { input string wantError error @@ -119,6 +171,31 @@ func TestUnmarshalReceipt(t *testing.T) { } } +func TestMarshalReceipt(t *testing.T) { + for name, test := range unmarshalReceiptTests { + if test.wantError != nil { + continue + } + var original *Receipt + json.Unmarshal([]byte(test.input), &original) + + blob, err := json.Marshal(original) + if err != nil { + t.Errorf("test %q: failed to marshal receipt: %v", name, err) + continue + } + var proced *Receipt + if err := json.Unmarshal(blob, &proced); err != nil { + t.Errorf("Test %q: failed to unmarshal marhsalled receipt: %v", name, err) + continue + } + if !reflect.DeepEqual(original, proced) { + t.Errorf("test %q: receipt mismatch: have %+v, want %+v", name, proced, original) + continue + } + } +} + func checkError(t *testing.T, testname string, got, want error) bool { if got == nil { if want != nil { diff --git a/core/types/receipt.go b/core/types/receipt.go index 9f820eb18..b00fdabff 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -84,6 +84,21 @@ func (r *Receipt) DecodeRLP(s *rlp.Stream) error { return nil } +// MarshalJSON encodes receipts into the web3 RPC response block format. +func (r *Receipt) MarshalJSON() ([]byte, error) { + root := common.BytesToHash(r.PostState) + + return json.Marshal(&jsonReceipt{ + PostState: &root, + CumulativeGasUsed: (*hexBig)(r.CumulativeGasUsed), + Bloom: &r.Bloom, + Logs: &r.Logs, + TxHash: &r.TxHash, + ContractAddress: &r.ContractAddress, + GasUsed: (*hexBig)(r.GasUsed), + }) +} + // UnmarshalJSON decodes the web3 RPC receipt format. func (r *Receipt) UnmarshalJSON(input []byte) error { var dec jsonReceipt diff --git a/core/types/transaction.go b/core/types/transaction.go index 5bb599479..f0512ae7e 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -128,6 +128,24 @@ func (tx *Transaction) DecodeRLP(s *rlp.Stream) error { return err } +// MarshalJSON encodes transactions into the web3 RPC response block format. +func (tx *Transaction) MarshalJSON() ([]byte, error) { + hash, v := tx.Hash(), uint64(tx.data.V) + + return json.Marshal(&jsonTransaction{ + Hash: &hash, + AccountNonce: (*hexUint64)(&tx.data.AccountNonce), + Price: (*hexBig)(tx.data.Price), + GasLimit: (*hexBig)(tx.data.GasLimit), + Recipient: tx.data.Recipient, + Amount: (*hexBig)(tx.data.Amount), + Payload: (*hexBytes)(&tx.data.Payload), + V: (*hexUint64)(&v), + R: (*hexBig)(tx.data.R), + S: (*hexBig)(tx.data.S), + }) +} + // UnmarshalJSON decodes the web3 RPC transaction format. func (tx *Transaction) UnmarshalJSON(input []byte) error { var dec jsonTransaction