Skip to content

Commit

Permalink
bugfix: Fixed the receipt encoding and decoding issue
Browse files Browse the repository at this point in the history
  • Loading branch information
gameofpointers committed Aug 23, 2023
1 parent 1f81f6f commit 0346768
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 96 deletions.
7 changes: 7 additions & 0 deletions core/types/gen_receipt_json.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 14 additions & 69 deletions core/types/receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -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()
Expand Down Expand Up @@ -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)
}

Expand All @@ -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 {
Expand All @@ -265,56 +244,22 @@ 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
r.Logs = make([]*Log, len(stored.Logs))
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

Expand All @@ -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)
}
Expand Down
30 changes: 3 additions & 27 deletions core/types/receipt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
1 change: 1 addition & 0 deletions internal/quaiapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
}
Expand Down

0 comments on commit 0346768

Please sign in to comment.