diff --git a/core/types/gen_receipt_json.go b/core/types/gen_receipt_json.go index b1fd85aeee..9d6dac371f 100644 --- a/core/types/gen_receipt_json.go +++ b/core/types/gen_receipt_json.go @@ -28,6 +28,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) { BlockHash common.Hash `json:"blockHash,omitempty"` BlockNumber *hexutil.Big `json:"blockNumber,omitempty"` TransactionIndex hexutil.Uint `json:"transactionIndex"` + Etxs []*Transaction `json:"etxs"` } var enc Receipt enc.Type = hexutil.Uint64(r.Type) @@ -36,6 +37,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) { enc.CumulativeGasUsed = hexutil.Uint64(r.CumulativeGasUsed) enc.Bloom = r.Bloom enc.Logs = r.Logs + enc.Etxs = r.Etxs enc.TxHash = r.TxHash enc.ContractAddress = r.ContractAddress enc.GasUsed = hexutil.Uint64(r.GasUsed) @@ -60,6 +62,7 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { BlockHash *common.Hash `json:"blockHash,omitempty"` BlockNumber *hexutil.Big `json:"blockNumber,omitempty"` TransactionIndex *hexutil.Uint `json:"transactionIndex"` + Etxs []*Transaction `json:"etxs"` } var dec Receipt if err := json.Unmarshal(input, &dec); err != nil { @@ -106,5 +109,9 @@ func (r *Receipt) UnmarshalJSON(input []byte) error { if dec.TransactionIndex != nil { r.TransactionIndex = uint(*dec.TransactionIndex) } + if dec.Etxs == nil { + return errors.New("missing required field 'etxs' for Receipt") + } + r.Etxs = dec.Etxs return nil } diff --git a/core/types/receipt.go b/core/types/receipt.go index bf1a1767da..ad1e42193e 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -89,33 +89,17 @@ type receiptRLP struct { CumulativeGasUsed uint64 Bloom Bloom Logs []*Log + Etxs []*Transaction } -// storedReceiptRLP is the storage encoding of a receipt. +// storedReceiptRLP is the storage encoding of a receipt used in database version 4. type storedReceiptRLP struct { PostStateOrStatus []byte CumulativeGasUsed uint64 - Logs []*LogForStorage -} - -// v4StoredReceiptRLP is the storage encoding of a receipt used in database version 4. -type v4StoredReceiptRLP struct { - PostStateOrStatus []byte - CumulativeGasUsed uint64 - TxHash common.Hash - ContractAddress common.Address - Logs []*LogForStorage - GasUsed uint64 -} - -// v3StoredReceiptRLP is the original storage encoding of a receipt including some unnecessary fields. -type v3StoredReceiptRLP struct { - PostStateOrStatus []byte - CumulativeGasUsed uint64 - Bloom Bloom TxHash common.Hash ContractAddress common.Address Logs []*LogForStorage + Etxs []*Transaction GasUsed uint64 } @@ -138,7 +122,7 @@ func NewReceipt(root []byte, failed bool, cumulativeGasUsed uint64) *Receipt { // EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt // into an RLP stream. func (r *Receipt) EncodeRLP(w io.Writer) error { - data := &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs} + data := &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs, r.Etxs} buf := encodeBufferPool.Get().(*bytes.Buffer) defer encodeBufferPool.Put(buf) buf.Reset() @@ -229,10 +213,14 @@ func (r *ReceiptForStorage) EncodeRLP(w io.Writer) error { PostStateOrStatus: (*Receipt)(r).statusEncoding(), CumulativeGasUsed: r.CumulativeGasUsed, Logs: make([]*LogForStorage, len(r.Logs)), + Etxs: make([]*Transaction, len(r.Etxs)), } for i, log := range r.Logs { enc.Logs[i] = (*LogForStorage)(log) } + for i, etx := range r.Etxs { + enc.Etxs[i] = (*Transaction)(etx) + } return rlp.Encode(w, enc) } @@ -244,16 +232,7 @@ func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { if err != nil { return err } - // Try decoding from the newest format for future proofness, then the older one - // for old nodes that just upgraded. V4 was an intermediate unreleased format so - // we do need to decode it, but it's not common (try last). - if err := decodeStoredReceiptRLP(r, blob); err == nil { - return nil - } - if err := decodeV3StoredReceiptRLP(r, blob); err == nil { - return nil - } - return decodeV4StoredReceiptRLP(r, blob) + return decodeStoredReceiptRLP(r, blob) } func decodeStoredReceiptRLP(r *ReceiptForStorage, blob []byte) error { @@ -265,24 +244,6 @@ func decodeStoredReceiptRLP(r *ReceiptForStorage, blob []byte) error { return err } r.CumulativeGasUsed = stored.CumulativeGasUsed - r.Logs = make([]*Log, len(stored.Logs)) - for i, log := range stored.Logs { - r.Logs[i] = (*Log)(log) - } - r.Bloom = CreateBloom(Receipts{(*Receipt)(r)}) - - return nil -} - -func decodeV4StoredReceiptRLP(r *ReceiptForStorage, blob []byte) error { - var stored v4StoredReceiptRLP - if err := rlp.DecodeBytes(blob, &stored); err != nil { - return err - } - if err := (*Receipt)(r).setStatus(stored.PostStateOrStatus); err != nil { - return err - } - r.CumulativeGasUsed = stored.CumulativeGasUsed r.TxHash = stored.TxHash r.ContractAddress = stored.ContractAddress r.GasUsed = stored.GasUsed @@ -290,31 +251,15 @@ func decodeV4StoredReceiptRLP(r *ReceiptForStorage, blob []byte) error { for i, log := range stored.Logs { r.Logs[i] = (*Log)(log) } + r.Etxs = make([]*Transaction, len(stored.Etxs)) + for i, etx := range stored.Etxs { + r.Etxs[i] = (*Transaction)(etx) + } r.Bloom = CreateBloom(Receipts{(*Receipt)(r)}) return nil } -func decodeV3StoredReceiptRLP(r *ReceiptForStorage, blob []byte) error { - var stored v3StoredReceiptRLP - if err := rlp.DecodeBytes(blob, &stored); err != nil { - return err - } - if err := (*Receipt)(r).setStatus(stored.PostStateOrStatus); err != nil { - return err - } - r.CumulativeGasUsed = stored.CumulativeGasUsed - r.Bloom = stored.Bloom - r.TxHash = stored.TxHash - r.ContractAddress = stored.ContractAddress - r.GasUsed = stored.GasUsed - r.Logs = make([]*Log, len(stored.Logs)) - for i, log := range stored.Logs { - r.Logs[i] = (*Log)(log) - } - return nil -} - // Receipts implements DerivableList for receipts. type Receipts []*Receipt @@ -329,7 +274,7 @@ func (r Receipt) Supported() bool { // EncodeIndex encodes the i'th receipt to w. func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) { if r := rs[i]; r.Supported() { - data := &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs} + data := &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs, r.Etxs} w.WriteByte(r.Type) rlp.Encode(w, data) } diff --git a/core/types/receipt_test.go b/core/types/receipt_test.go index deb504fb7c..b3fe87f4ac 100644 --- a/core/types/receipt_test.go +++ b/core/types/receipt_test.go @@ -119,43 +119,19 @@ func TestLegacyReceiptDecoding(t *testing.T) { func encodeAsStoredReceiptRLP(want *Receipt) ([]byte, error) { stored := &storedReceiptRLP{ - PostStateOrStatus: want.statusEncoding(), - CumulativeGasUsed: want.CumulativeGasUsed, - Logs: make([]*LogForStorage, len(want.Logs)), - } - for i, log := range want.Logs { - stored.Logs[i] = (*LogForStorage)(log) - } - return rlp.EncodeToBytes(stored) -} - -func encodeAsV4StoredReceiptRLP(want *Receipt) ([]byte, error) { - stored := &v4StoredReceiptRLP{ PostStateOrStatus: want.statusEncoding(), CumulativeGasUsed: want.CumulativeGasUsed, TxHash: want.TxHash, ContractAddress: want.ContractAddress, Logs: make([]*LogForStorage, len(want.Logs)), GasUsed: want.GasUsed, + Etxs: make([]*Transaction, len(want.Etxs)), } for i, log := range want.Logs { stored.Logs[i] = (*LogForStorage)(log) } - return rlp.EncodeToBytes(stored) -} - -func encodeAsV3StoredReceiptRLP(want *Receipt) ([]byte, error) { - stored := &v3StoredReceiptRLP{ - PostStateOrStatus: want.statusEncoding(), - CumulativeGasUsed: want.CumulativeGasUsed, - Bloom: want.Bloom, - TxHash: want.TxHash, - ContractAddress: want.ContractAddress, - Logs: make([]*LogForStorage, len(want.Logs)), - GasUsed: want.GasUsed, - } - for i, log := range want.Logs { - stored.Logs[i] = (*LogForStorage)(log) + for i, etx := range want.Etxs { + stored.Etxs[i] = (*Transaction)(etx) } return rlp.EncodeToBytes(stored) } diff --git a/internal/quaiapi/api.go b/internal/quaiapi/api.go index 439a854edb..ef8258f3b3 100644 --- a/internal/quaiapi/api.go +++ b/internal/quaiapi/api.go @@ -1374,6 +1374,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, ha "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed), "contractAddress": nil, "logs": receipt.Logs, + "etxs": receipt.Etxs, "logsBloom": receipt.Bloom, "type": hexutil.Uint(tx.Type()), }