From a31835c8b4086582879a4e7a48e4bdb5e4dccc3d Mon Sep 17 00:00:00 2001 From: rjl493456442 Date: Sat, 26 Aug 2017 15:30:56 +0800 Subject: [PATCH 1/2] internal/ethapi: add status code to receipt rpc return --- internal/ethapi/api.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 8d1a6f7462..a7cb08466a 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -44,8 +44,10 @@ import ( ) const ( - defaultGas = 90000 - defaultGasPrice = 50 * params.Shannon + defaultGas = 90000 + defaultGasPrice = 50 * params.Shannon + receiptStatusSuccessful = 1 + receiptStatusFailed = 0 ) // PublicEthereumAPI provides an API to access Ethereum related information. @@ -991,7 +993,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 +1005,16 @@ 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(receiptStatusSuccessful) + if receipt.Failed { + fields["status"] = hexutil.Uint(receiptStatusFailed) + } + } if receipt.Logs == nil { fields["logs"] = [][]*types.Log{} } From 7e9e3a134b9607209def42279db081973b5e0ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 2 Oct 2017 11:42:08 +0300 Subject: [PATCH 2/2] core/types, internal: swap Receipt.Failed to Status --- core/database_util_test.go | 2 +- core/types/gen_receipt_json.go | 10 ++++---- core/types/receipt.go | 42 ++++++++++++++++++++++------------ internal/ethapi/api.go | 11 +++------ 4 files changed, 37 insertions(+), 28 deletions(-) diff --git a/core/database_util_test.go b/core/database_util_test.go index 940221a299..36f43cf50a 100644 --- a/core/database_util_test.go +++ b/core/database_util_test.go @@ -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})}, diff --git a/core/types/gen_receipt_json.go b/core/types/gen_receipt_json.go index 1e6880c223..b95d99c951 100644 --- a/core/types/gen_receipt_json.go +++ b/core/types/gen_receipt_json.go @@ -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") diff --git a/core/types/receipt.go b/core/types/receipt.go index e179fe0cfd..bc3c996b4f 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -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) } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index a7cb08466a..ab8478929f 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -44,10 +44,8 @@ import ( ) const ( - defaultGas = 90000 - defaultGasPrice = 50 * params.Shannon - receiptStatusSuccessful = 1 - receiptStatusFailed = 0 + defaultGas = 90000 + defaultGasPrice = 50 * params.Shannon ) // PublicEthereumAPI provides an API to access Ethereum related information. @@ -1010,10 +1008,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(hash common.Hash) (map[ if len(receipt.PostState) > 0 { fields["root"] = hexutil.Bytes(receipt.PostState) } else { - fields["status"] = hexutil.Uint(receiptStatusSuccessful) - if receipt.Failed { - fields["status"] = hexutil.Uint(receiptStatusFailed) - } + fields["status"] = hexutil.Uint(receipt.Status) } if receipt.Logs == nil { fields["logs"] = [][]*types.Log{}