From db278f4d7d8e86926a3e2dae89d743436c8b3cf2 Mon Sep 17 00:00:00 2001 From: piersy Date: Fri, 27 Sep 2024 16:19:45 +0100 Subject: [PATCH] Fix receipt decoding for calls to eth_getLogs (#242) * Fix receipt decoding for calls to eth_getLogs We added a special receipt type for celo dynamic fee transactions that stores the base fee in the fee currency in the receipt, this makes it possible to calculate the gasPrice without needing state access, but we missed the flow for eth_getLogs because they use a different type to decode the receipts to avoid makeing the bloom filter. So this adds support for decoding our added receipts in that flow. --- core/rawdb/accessors_chain.go | 18 +++++++++++++++++- core/types/receipt.go | 8 ++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index 4914d961ec..b6fe2540c4 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -694,8 +694,24 @@ type receiptLogs struct { // DecodeRLP implements rlp.Decoder. func (r *receiptLogs) DecodeRLP(s *rlp.Stream) error { + // Retrieve the entire receipt blob as we need to try multiple decoders + blob, err := s.Raw() + if err != nil { + return err + } + // Check to see if this is a celo dynamic fee receipt. + if types.IsCeloDynamicFeeReceipt(blob) { + var stored types.CeloDynamicFeeStoredReceiptRLP + err := rlp.DecodeBytes(blob, &stored) + if err != nil { + return err + } + r.Logs = stored.Logs + return nil + } + var stored storedReceiptRLP - if err := s.Decode(&stored); err != nil { + if err := rlp.DecodeBytes(blob, &stored); err != nil { return err } r.Logs = stored.Logs diff --git a/core/types/receipt.go b/core/types/receipt.go index 19593bd32f..9d2aad03e8 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -168,7 +168,7 @@ type storedReceiptRLP struct { DepositReceiptVersion *uint64 `rlp:"optional"` } -type celoDynamicFeeStoredReceiptRLP struct { +type CeloDynamicFeeStoredReceiptRLP struct { CeloDynamicReceiptMarker []interface{} // Marker to distinguish this from storedReceiptRLP PostStateOrStatus []byte CumulativeGasUsed uint64 @@ -465,7 +465,7 @@ func (r *ReceiptForStorage) EncodeRLP(_w io.Writer) error { // Detect CeloDynamicFee receipts by looking at the first list element // To distinguish these receipts from the very similar normal receipts, an // empty list is added as the first element of the RLP-serialized struct. -func isCeloDynamicFeeReceipt(blob []byte) bool { +func IsCeloDynamicFeeReceipt(blob []byte) bool { listHeaderSize := 1 // Length of the list header representing the struct in bytes if blob[0] > 0xf7 { listHeaderSize += int(blob[0]) - 0xf7 @@ -483,7 +483,7 @@ func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { return err } // First try to decode the latest receipt database format, try the pre-bedrock Optimism legacy format otherwise. - if isCeloDynamicFeeReceipt(blob) { + if IsCeloDynamicFeeReceipt(blob) { return decodeStoredCeloDynamicFeeReceiptRLP(r, blob) } if err := decodeStoredReceiptRLP(r, blob); err == nil { @@ -523,7 +523,7 @@ func decodeLegacyOptimismReceiptRLP(r *ReceiptForStorage, blob []byte) error { } func decodeStoredCeloDynamicFeeReceiptRLP(r *ReceiptForStorage, blob []byte) error { - var stored celoDynamicFeeStoredReceiptRLP + var stored CeloDynamicFeeStoredReceiptRLP if err := rlp.DecodeBytes(blob, &stored); err != nil { return err }