core/types: reset Log.Removed in Receipt.DeriveFields

DeriveFields rewrites every canonical inclusion field on each log
(BlockNumber, BlockHash, BlockTimestamp, TxHash, TxIndex, Index) but left
the transient Removed flag untouched. A canonically-included log is by
definition not removed, so derivation should drive Removed back to false
just like the other derived fields.

This is a defensive consistency fix rather than a fix for a presently
reachable bug. The only place Removed is set to true is
collectReceiptsAndLogs, which operates on fresh receipts read via
ReadRawReceipts (Removed is rlp:"-", so always decoded as false), derives
fields before flagging removal, and discards those objects after emitting
the reorg event. They are never cached or re-derived, and the cached
receipts are separate instances, so no Removed==true log currently reaches
DeriveFields. Resetting the flag here hardens the function against a
reused/stale log object regardless of the calling path.
This commit is contained in:
cuiweixie 2026-06-11 20:00:00 +08:00
parent eea6242742
commit 4668a93150

View file

@ -308,6 +308,10 @@ func (r *Receipt) DeriveFields(signer Signer, context DeriveReceiptContext) {
r.Logs[j].TxHash = r.TxHash r.Logs[j].TxHash = r.TxHash
r.Logs[j].TxIndex = context.TxIndex r.Logs[j].TxIndex = context.TxIndex
r.Logs[j].Index = logIndex r.Logs[j].Index = logIndex
// A canonically-included log is by definition not removed; reset the
// transient Removed flag so a reused log object can't carry a stale
// reorg marking into a canonical receipt.
r.Logs[j].Removed = false
logIndex++ logIndex++
} }
// Also derive the Bloom if not derived yet // Also derive the Bloom if not derived yet