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()
receipt1 := &types.Receipt{
Failed: true,
Status: types.ReceiptStatusFailed,
CumulativeGasUsed: big.NewInt(1),
Logs: []*types.Log{
{Address: common.BytesToAddress([]byte{0x11})},

@ -14,7 +14,7 @@ import (
func (r Receipt) MarshalJSON() ([]byte, error) {
type Receipt struct {
PostState hexutil.Bytes `json:"root"`
Failed bool `json:"failed"`
Status hexutil.Uint `json:"status"`
CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"`
Bloom Bloom `json:"logsBloom" gencodec:"required"`
Logs []*Log `json:"logs" gencodec:"required"`
@ -24,7 +24,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) {
}
var enc Receipt
enc.PostState = r.PostState
enc.Failed = r.Failed
enc.Status = hexutil.Uint(r.Status)
enc.CumulativeGasUsed = (*hexutil.Big)(r.CumulativeGasUsed)
enc.Bloom = r.Bloom
enc.Logs = r.Logs
@ -37,7 +37,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) {
func (r *Receipt) UnmarshalJSON(input []byte) error {
type Receipt struct {
PostState hexutil.Bytes `json:"root"`
Failed *bool `json:"failed"`
Status *hexutil.Uint `json:"status"`
CumulativeGasUsed *hexutil.Big `json:"cumulativeGasUsed" gencodec:"required"`
Bloom *Bloom `json:"logsBloom" gencodec:"required"`
Logs []*Log `json:"logs" gencodec:"required"`
@ -52,8 +52,8 @@ func (r *Receipt) UnmarshalJSON(input []byte) error {
if dec.PostState != nil {
r.PostState = dec.PostState
}
if dec.Failed != nil {
r.Failed = *dec.Failed
if dec.Status != nil {
r.Status = uint(*dec.Status)
}
if dec.CumulativeGasUsed == nil {
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
var (
receiptStatusFailed = []byte{}
receiptStatusSuccessful = []byte{0x01}
receiptStatusFailedRLP = []byte{}
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.
type Receipt struct {
// Consensus fields
PostState []byte `json:"root"`
Failed bool `json:"failed"`
Status uint `json:"status"`
CumulativeGasUsed *big.Int `json:"cumulativeGasUsed" gencodec:"required"`
Bloom Bloom `json:"logsBloom" gencodec:"required"`
Logs []*Log `json:"logs" gencodec:"required"`
@ -51,6 +59,7 @@ type Receipt struct {
type receiptMarshaling struct {
PostState hexutil.Bytes
Status hexutil.Uint
CumulativeGasUsed *hexutil.Big
GasUsed *hexutil.Big
}
@ -75,7 +84,13 @@ type receiptStorageRLP struct {
// NewReceipt creates a barebone transaction receipt, copying the init fields.
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
@ -100,10 +115,10 @@ func (r *Receipt) DecodeRLP(s *rlp.Stream) error {
func (r *Receipt) setStatus(postStateOrStatus []byte) error {
switch {
case bytes.Equal(postStateOrStatus, receiptStatusSuccessful):
r.Failed = false
case bytes.Equal(postStateOrStatus, receiptStatusFailed):
r.Failed = true
case bytes.Equal(postStateOrStatus, receiptStatusSuccessfulRLP):
r.Status = ReceiptStatusSuccessful
case bytes.Equal(postStateOrStatus, receiptStatusFailedRLP):
r.Status = ReceiptStatusFailed
case len(postStateOrStatus) == len(common.Hash{}):
r.PostState = postStateOrStatus
default:
@ -114,19 +129,18 @@ func (r *Receipt) setStatus(postStateOrStatus []byte) error {
func (r *Receipt) statusEncoding() []byte {
if len(r.PostState) == 0 {
if r.Failed {
return receiptStatusFailed
} else {
return receiptStatusSuccessful
if r.Status == ReceiptStatusFailed {
return receiptStatusFailedRLP
}
return receiptStatusSuccessfulRLP
}
return r.PostState
}
// String implements the Stringer interface.
func (r *Receipt) String() string {
if r.PostState == nil {
return fmt.Sprintf("receipt{failed=%t cgas=%v bloom=%x logs=%v}", r.Failed, r.CumulativeGasUsed, r.Bloom, r.Logs)
if len(r.PostState) == 0 {
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)
}

@ -991,7 +991,6 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(hash common.Hash) (map[
from, _ := types.Sender(signer, tx)
fields := map[string]interface{}{
"root": hexutil.Bytes(receipt.PostState),
"blockHash": blockHash,
"blockNumber": hexutil.Uint64(blockNumber),
"transactionHash": hash,
@ -1004,6 +1003,13 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(hash common.Hash) (map[
"logs": receipt.Logs,
"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 {
fields["logs"] = [][]*types.Log{}
}