Merge pull request #15042 from rjl493456442/receipt_rpc

internal/ethapi: add status code to receipt rpc return
This commit is contained in:
Péter Szilágyi 2017-10-02 14:41:10 +03:00 committed by GitHub
commit f86c4177d5
4 changed files with 41 additions and 21 deletions

@ -336,7 +336,7 @@ func TestBlockReceiptStorage(t *testing.T) {
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
receipt1 := &types.Receipt{ receipt1 := &types.Receipt{
Failed: true, Status: types.ReceiptStatusFailed,
CumulativeGasUsed: big.NewInt(1), CumulativeGasUsed: big.NewInt(1),
Logs: []*types.Log{ Logs: []*types.Log{
{Address: common.BytesToAddress([]byte{0x11})}, {Address: common.BytesToAddress([]byte{0x11})},

@ -14,7 +14,7 @@ import (
func (r Receipt) MarshalJSON() ([]byte, error) { func (r Receipt) MarshalJSON() ([]byte, error) {
type Receipt struct { type Receipt struct {
PostState hexutil.Bytes `json:"root"` PostState hexutil.Bytes `json:"root"`
Failed bool `json:"failed"` Status hexutil.Uint `json:"status"`
CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"` CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"`
Bloom Bloom `json:"logsBloom" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"`
Logs []*Log `json:"logs" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"`
@ -24,7 +24,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) {
} }
var enc Receipt var enc Receipt
enc.PostState = r.PostState enc.PostState = r.PostState
enc.Failed = r.Failed enc.Status = hexutil.Uint(r.Status)
enc.CumulativeGasUsed = (*hexutil.Big)(r.CumulativeGasUsed) enc.CumulativeGasUsed = (*hexutil.Big)(r.CumulativeGasUsed)
enc.Bloom = r.Bloom enc.Bloom = r.Bloom
enc.Logs = r.Logs enc.Logs = r.Logs
@ -37,7 +37,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) {
func (r *Receipt) UnmarshalJSON(input []byte) error { func (r *Receipt) UnmarshalJSON(input []byte) error {
type Receipt struct { type Receipt struct {
PostState hexutil.Bytes `json:"root"` PostState hexutil.Bytes `json:"root"`
Failed *bool `json:"failed"` Status *hexutil.Uint `json:"status"`
CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"` CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"`
Bloom *Bloom `json:"logsBloom" gencodec:"required"` Bloom *Bloom `json:"logsBloom" gencodec:"required"`
Logs []*Log `json:"logs" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"`
@ -52,8 +52,8 @@ func (r *Receipt) UnmarshalJSON(input []byte) error {
if dec.PostState != nil { if dec.PostState != nil {
r.PostState = dec.PostState r.PostState = dec.PostState
} }
if dec.Failed != nil { if dec.Status != nil {
r.Failed = *dec.Failed r.Status = uint(*dec.Status)
} }
if dec.CumulativeGasUsed == nil { if dec.CumulativeGasUsed == nil {
return errors.New("missing required field 'cumulativeGasUsed' for Receipt") return errors.New("missing required field 'cumulativeGasUsed' for Receipt")

@ -30,15 +30,23 @@ import (
//go:generate gencodec -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go //go:generate gencodec -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go
var ( var (
receiptStatusFailed = []byte{} receiptStatusFailedRLP = []byte{}
receiptStatusSuccessful = []byte{0x01} receiptStatusSuccessfulRLP = []byte{0x01}
)
const (
// ReceiptStatusFailed is the status code of a transaction if execution failed.
ReceiptStatusFailed = uint(0)
// ReceiptStatusSuccessful is the status code of a transaction if execution succeeded.
ReceiptStatusSuccessful = uint(1)
) )
// Receipt represents the results of a transaction. // Receipt represents the results of a transaction.
type Receipt struct { type Receipt struct {
// Consensus fields // Consensus fields
PostState []byte `json:"root"` PostState []byte `json:"root"`
Failed bool `json:"failed"` Status uint `json:"status"`
CumulativeGasUsed *big.Int `json:"cumulativeGasUsed" gencodec:"required"` CumulativeGasUsed *big.Int `json:"cumulativeGasUsed" gencodec:"required"`
Bloom Bloom `json:"logsBloom" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"`
Logs []*Log `json:"logs" gencodec:"required"` Logs []*Log `json:"logs" gencodec:"required"`
@ -51,6 +59,7 @@ type Receipt struct {
type receiptMarshaling struct { type receiptMarshaling struct {
PostState hexutil.Bytes PostState hexutil.Bytes
Status hexutil.Uint
CumulativeGasUsed *hexutil.Big CumulativeGasUsed *hexutil.Big
GasUsed *hexutil.Big GasUsed *hexutil.Big
} }
@ -75,7 +84,13 @@ type receiptStorageRLP struct {
// NewReceipt creates a barebone transaction receipt, copying the init fields. // NewReceipt creates a barebone transaction receipt, copying the init fields.
func NewReceipt(root []byte, failed bool, cumulativeGasUsed *big.Int) *Receipt { func NewReceipt(root []byte, failed bool, cumulativeGasUsed *big.Int) *Receipt {
return &Receipt{PostState: common.CopyBytes(root), Failed: failed, CumulativeGasUsed: new(big.Int).Set(cumulativeGasUsed)} r := &Receipt{PostState: common.CopyBytes(root), CumulativeGasUsed: new(big.Int).Set(cumulativeGasUsed)}
if failed {
r.Status = ReceiptStatusFailed
} else {
r.Status = ReceiptStatusSuccessful
}
return r
} }
// EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt // EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt
@ -100,10 +115,10 @@ func (r *Receipt) DecodeRLP(s *rlp.Stream) error {
func (r *Receipt) setStatus(postStateOrStatus []byte) error { func (r *Receipt) setStatus(postStateOrStatus []byte) error {
switch { switch {
case bytes.Equal(postStateOrStatus, receiptStatusSuccessful): case bytes.Equal(postStateOrStatus, receiptStatusSuccessfulRLP):
r.Failed = false r.Status = ReceiptStatusSuccessful
case bytes.Equal(postStateOrStatus, receiptStatusFailed): case bytes.Equal(postStateOrStatus, receiptStatusFailedRLP):
r.Failed = true r.Status = ReceiptStatusFailed
case len(postStateOrStatus) == len(common.Hash{}): case len(postStateOrStatus) == len(common.Hash{}):
r.PostState = postStateOrStatus r.PostState = postStateOrStatus
default: default:
@ -114,19 +129,18 @@ func (r *Receipt) setStatus(postStateOrStatus []byte) error {
func (r *Receipt) statusEncoding() []byte { func (r *Receipt) statusEncoding() []byte {
if len(r.PostState) == 0 { if len(r.PostState) == 0 {
if r.Failed { if r.Status == ReceiptStatusFailed {
return receiptStatusFailed return receiptStatusFailedRLP
} else {
return receiptStatusSuccessful
} }
return receiptStatusSuccessfulRLP
} }
return r.PostState return r.PostState
} }
// String implements the Stringer interface. // String implements the Stringer interface.
func (r *Receipt) String() string { func (r *Receipt) String() string {
if r.PostState == nil { if len(r.PostState) == 0 {
return fmt.Sprintf("receipt{failed=%t cgas=%v bloom=%x logs=%v}", r.Failed, r.CumulativeGasUsed, r.Bloom, r.Logs) return fmt.Sprintf("receipt{status=%d cgas=%v bloom=%x logs=%v}", r.Status, r.CumulativeGasUsed, r.Bloom, r.Logs)
} }
return fmt.Sprintf("receipt{med=%x cgas=%v bloom=%x logs=%v}", r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs) return fmt.Sprintf("receipt{med=%x cgas=%v bloom=%x logs=%v}", r.PostState, r.CumulativeGasUsed, r.Bloom, r.Logs)
} }

@ -991,7 +991,6 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(hash common.Hash) (map[
from, _ := types.Sender(signer, tx) from, _ := types.Sender(signer, tx)
fields := map[string]interface{}{ fields := map[string]interface{}{
"root": hexutil.Bytes(receipt.PostState),
"blockHash": blockHash, "blockHash": blockHash,
"blockNumber": hexutil.Uint64(blockNumber), "blockNumber": hexutil.Uint64(blockNumber),
"transactionHash": hash, "transactionHash": hash,
@ -1004,6 +1003,13 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(hash common.Hash) (map[
"logs": receipt.Logs, "logs": receipt.Logs,
"logsBloom": receipt.Bloom, "logsBloom": receipt.Bloom,
} }
// Assign receipt status or post state.
if len(receipt.PostState) > 0 {
fields["root"] = hexutil.Bytes(receipt.PostState)
} else {
fields["status"] = hexutil.Uint(receipt.Status)
}
if receipt.Logs == nil { if receipt.Logs == nil {
fields["logs"] = [][]*types.Log{} fields["logs"] = [][]*types.Log{}
} }