|
|
|
@ -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) |
|
|
|
|
} |
|
|
|
|