internal/ethapi: add missing output fields
- returned headers didn't include mixHash - returned transactions didn't include signature fields - empty transaction input was returned as "", but should be "0x" - returned receipts didn't include the bloom filter - "root" in receipts was missing 0x prefix
This commit is contained in:
parent
704fde01e8
commit
b0d9f7372a
@ -588,24 +588,26 @@ func FormatLogs(structLogs []vm.StructLog) []StructLogRes {
|
|||||||
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
|
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
|
||||||
// transaction hashes.
|
// transaction hashes.
|
||||||
func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
|
func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
|
||||||
|
head := b.Header() // copies the header once
|
||||||
fields := map[string]interface{}{
|
fields := map[string]interface{}{
|
||||||
"number": rpc.NewHexNumber(b.Number()),
|
"number": rpc.NewHexNumber(head.Number),
|
||||||
"hash": b.Hash(),
|
"hash": b.Hash(),
|
||||||
"parentHash": b.ParentHash(),
|
"parentHash": head.ParentHash,
|
||||||
"nonce": b.Header().Nonce,
|
"nonce": head.Nonce,
|
||||||
"sha3Uncles": b.UncleHash(),
|
"mixHash": head.MixDigest,
|
||||||
"logsBloom": b.Bloom(),
|
"sha3Uncles": head.UncleHash,
|
||||||
"stateRoot": b.Root(),
|
"logsBloom": head.Bloom,
|
||||||
"miner": b.Coinbase(),
|
"stateRoot": head.Root,
|
||||||
"difficulty": rpc.NewHexNumber(b.Difficulty()),
|
"miner": head.Coinbase,
|
||||||
|
"difficulty": rpc.NewHexNumber(head.Difficulty),
|
||||||
"totalDifficulty": rpc.NewHexNumber(s.b.GetTd(b.Hash())),
|
"totalDifficulty": rpc.NewHexNumber(s.b.GetTd(b.Hash())),
|
||||||
"extraData": fmt.Sprintf("0x%x", b.Extra()),
|
"extraData": rpc.HexBytes(head.Extra),
|
||||||
"size": rpc.NewHexNumber(b.Size().Int64()),
|
"size": rpc.NewHexNumber(b.Size().Int64()),
|
||||||
"gasLimit": rpc.NewHexNumber(b.GasLimit()),
|
"gasLimit": rpc.NewHexNumber(head.GasLimit),
|
||||||
"gasUsed": rpc.NewHexNumber(b.GasUsed()),
|
"gasUsed": rpc.NewHexNumber(head.GasUsed),
|
||||||
"timestamp": rpc.NewHexNumber(b.Time()),
|
"timestamp": rpc.NewHexNumber(head.Time),
|
||||||
"transactionsRoot": b.TxHash(),
|
"transactionsRoot": head.TxHash,
|
||||||
"receiptRoot": b.ReceiptHash(),
|
"receiptRoot": head.ReceiptHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
if inclTx {
|
if inclTx {
|
||||||
@ -648,26 +650,32 @@ type RPCTransaction struct {
|
|||||||
Gas *rpc.HexNumber `json:"gas"`
|
Gas *rpc.HexNumber `json:"gas"`
|
||||||
GasPrice *rpc.HexNumber `json:"gasPrice"`
|
GasPrice *rpc.HexNumber `json:"gasPrice"`
|
||||||
Hash common.Hash `json:"hash"`
|
Hash common.Hash `json:"hash"`
|
||||||
Input string `json:"input"`
|
Input rpc.HexBytes `json:"input"`
|
||||||
Nonce *rpc.HexNumber `json:"nonce"`
|
Nonce *rpc.HexNumber `json:"nonce"`
|
||||||
To *common.Address `json:"to"`
|
To *common.Address `json:"to"`
|
||||||
TransactionIndex *rpc.HexNumber `json:"transactionIndex"`
|
TransactionIndex *rpc.HexNumber `json:"transactionIndex"`
|
||||||
Value *rpc.HexNumber `json:"value"`
|
Value *rpc.HexNumber `json:"value"`
|
||||||
|
V *rpc.HexNumber `json:"v"`
|
||||||
|
R *rpc.HexNumber `json:"r"`
|
||||||
|
S *rpc.HexNumber `json:"s"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation
|
// newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation
|
||||||
func newRPCPendingTransaction(tx *types.Transaction) *RPCTransaction {
|
func newRPCPendingTransaction(tx *types.Transaction) *RPCTransaction {
|
||||||
from, _ := tx.FromFrontier()
|
from, _ := tx.FromFrontier()
|
||||||
|
v, r, s := tx.SignatureValues()
|
||||||
return &RPCTransaction{
|
return &RPCTransaction{
|
||||||
From: from,
|
From: from,
|
||||||
Gas: rpc.NewHexNumber(tx.Gas()),
|
Gas: rpc.NewHexNumber(tx.Gas()),
|
||||||
GasPrice: rpc.NewHexNumber(tx.GasPrice()),
|
GasPrice: rpc.NewHexNumber(tx.GasPrice()),
|
||||||
Hash: tx.Hash(),
|
Hash: tx.Hash(),
|
||||||
Input: fmt.Sprintf("0x%x", tx.Data()),
|
Input: rpc.HexBytes(tx.Data()),
|
||||||
Nonce: rpc.NewHexNumber(tx.Nonce()),
|
Nonce: rpc.NewHexNumber(tx.Nonce()),
|
||||||
To: tx.To(),
|
To: tx.To(),
|
||||||
Value: rpc.NewHexNumber(tx.Value()),
|
Value: rpc.NewHexNumber(tx.Value()),
|
||||||
|
V: rpc.NewHexNumber(v),
|
||||||
|
R: rpc.NewHexNumber(r),
|
||||||
|
S: rpc.NewHexNumber(s),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -679,7 +687,7 @@ func newRPCTransactionFromBlockIndex(b *types.Block, txIndex int) (*RPCTransacti
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
v, r, s := tx.SignatureValues()
|
||||||
return &RPCTransaction{
|
return &RPCTransaction{
|
||||||
BlockHash: b.Hash(),
|
BlockHash: b.Hash(),
|
||||||
BlockNumber: rpc.NewHexNumber(b.Number()),
|
BlockNumber: rpc.NewHexNumber(b.Number()),
|
||||||
@ -687,11 +695,14 @@ func newRPCTransactionFromBlockIndex(b *types.Block, txIndex int) (*RPCTransacti
|
|||||||
Gas: rpc.NewHexNumber(tx.Gas()),
|
Gas: rpc.NewHexNumber(tx.Gas()),
|
||||||
GasPrice: rpc.NewHexNumber(tx.GasPrice()),
|
GasPrice: rpc.NewHexNumber(tx.GasPrice()),
|
||||||
Hash: tx.Hash(),
|
Hash: tx.Hash(),
|
||||||
Input: fmt.Sprintf("0x%x", tx.Data()),
|
Input: rpc.HexBytes(tx.Data()),
|
||||||
Nonce: rpc.NewHexNumber(tx.Nonce()),
|
Nonce: rpc.NewHexNumber(tx.Nonce()),
|
||||||
To: tx.To(),
|
To: tx.To(),
|
||||||
TransactionIndex: rpc.NewHexNumber(txIndex),
|
TransactionIndex: rpc.NewHexNumber(txIndex),
|
||||||
Value: rpc.NewHexNumber(tx.Value()),
|
Value: rpc.NewHexNumber(tx.Value()),
|
||||||
|
V: rpc.NewHexNumber(v),
|
||||||
|
R: rpc.NewHexNumber(r),
|
||||||
|
S: rpc.NewHexNumber(s),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,7 +872,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(txHash common.Hash) (ma
|
|||||||
}
|
}
|
||||||
|
|
||||||
fields := map[string]interface{}{
|
fields := map[string]interface{}{
|
||||||
"root": common.Bytes2Hex(receipt.PostState),
|
"root": rpc.HexBytes(receipt.PostState),
|
||||||
"blockHash": txBlock,
|
"blockHash": txBlock,
|
||||||
"blockNumber": rpc.NewHexNumber(blockIndex),
|
"blockNumber": rpc.NewHexNumber(blockIndex),
|
||||||
"transactionHash": txHash,
|
"transactionHash": txHash,
|
||||||
@ -872,17 +883,15 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(txHash common.Hash) (ma
|
|||||||
"cumulativeGasUsed": rpc.NewHexNumber(receipt.CumulativeGasUsed),
|
"cumulativeGasUsed": rpc.NewHexNumber(receipt.CumulativeGasUsed),
|
||||||
"contractAddress": nil,
|
"contractAddress": nil,
|
||||||
"logs": receipt.Logs,
|
"logs": receipt.Logs,
|
||||||
|
"logsBloom": receipt.Bloom,
|
||||||
}
|
}
|
||||||
|
|
||||||
if receipt.Logs == nil {
|
if receipt.Logs == nil {
|
||||||
fields["logs"] = []vm.Logs{}
|
fields["logs"] = []vm.Logs{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation
|
// If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation
|
||||||
if bytes.Compare(receipt.ContractAddress.Bytes(), bytes.Repeat([]byte{0}, 20)) != 0 {
|
if receipt.ContractAddress != (common.Address{}) {
|
||||||
fields["contractAddress"] = receipt.ContractAddress
|
fields["contractAddress"] = receipt.ContractAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
return fields, nil
|
return fields, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
30
rpc/types.go
30
rpc/types.go
@ -17,6 +17,8 @@
|
|||||||
package rpc
|
package rpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
@ -272,3 +274,31 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error {
|
|||||||
func (bn BlockNumber) Int64() int64 {
|
func (bn BlockNumber) Int64() int64 {
|
||||||
return (int64)(bn)
|
return (int64)(bn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HexBytes JSON-encodes as hex with 0x prefix.
|
||||||
|
type HexBytes []byte
|
||||||
|
|
||||||
|
func (b HexBytes) MarshalJSON() ([]byte, error) {
|
||||||
|
result := make([]byte, len(b)*2+4)
|
||||||
|
copy(result, `"0x`)
|
||||||
|
hex.Encode(result[3:], b)
|
||||||
|
result[len(result)-1] = '"'
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *HexBytes) UnmarshalJSON(input []byte) error {
|
||||||
|
if len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' {
|
||||||
|
input = input[1 : len(input)-1]
|
||||||
|
}
|
||||||
|
if !bytes.HasPrefix(input, []byte("0x")) {
|
||||||
|
return fmt.Errorf("missing 0x prefix for hex byte array")
|
||||||
|
}
|
||||||
|
input = input[2:]
|
||||||
|
if len(input) == 0 {
|
||||||
|
*b = nil
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
*b = make([]byte, len(input)/2)
|
||||||
|
_, err := hex.Decode(*b, input)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
@ -71,3 +71,25 @@ func TestHexNumberMarshalJSON(t *testing.T) {
|
|||||||
t.Fatalf("Invalid json.Marshal, expected '%s', got '%s'", exp, got)
|
t.Fatalf("Invalid json.Marshal, expected '%s', got '%s'", exp, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hexBytesTests = []struct{ in, out []byte }{
|
||||||
|
{in: []byte(`"0x"`), out: []byte{}},
|
||||||
|
{in: []byte(`"0x00"`), out: []byte{0}},
|
||||||
|
{in: []byte(`"0x01ff"`), out: []byte{0x01, 0xFF}},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHexBytes(t *testing.T) {
|
||||||
|
for i, test := range hexBytesTests {
|
||||||
|
var dec HexBytes
|
||||||
|
if err := json.Unmarshal(test.in, &dec); err != nil {
|
||||||
|
t.Fatalf("test %d: can't decode: %v", i, err)
|
||||||
|
}
|
||||||
|
enc, _ := json.Marshal(HexBytes(test.out))
|
||||||
|
if !bytes.Equal(dec, test.out) {
|
||||||
|
t.Errorf("test %d: wrong decoded value 0x%x", i, dec)
|
||||||
|
}
|
||||||
|
if !bytes.Equal(enc, test.in) {
|
||||||
|
t.Errorf("test %d: wrong encoded value %#q", i, enc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user