Fixed the rare case where a tx receipt is nil

I think this cannot happen in the wild while syncing block, otherwise it would mean the transaction would have no receipt which is impossible.

However in testing conditions or when doing "speculative exeuction", it's possible to get that condition.

This is just to better deal with a potential `nil pointer exception`.
This commit is contained in:
Matthieu Vachon 2024-05-01 13:27:39 -04:00
parent f0dcb13f6b
commit dccb2f36cd

View file

@ -281,6 +281,8 @@ func (f *Firehose) resetBlock() {
// resetTransaction resets the transaction state and the call state in one shot // resetTransaction resets the transaction state and the call state in one shot
func (f *Firehose) resetTransaction() { func (f *Firehose) resetTransaction() {
firehoseDebug("resetting transaction state")
f.transaction = nil f.transaction = nil
f.evm = nil f.evm = nil
f.transactionLogIndex = 0 f.transactionLogIndex = 0
@ -683,8 +685,6 @@ func (f *Firehose) assignOrdinalAndIndexToReceiptLogs() {
trx := f.transaction trx := f.transaction
receiptsLogs := trx.Receipt.Logs
callLogs := []*pbeth.Log{} callLogs := []*pbeth.Log{}
for _, call := range trx.Calls { for _, call := range trx.Calls {
firehoseTrace("checking call (reverted=%t logs=%d)", call.StateReverted, len(call.Logs)) firehoseTrace("checking call (reverted=%t logs=%d)", call.StateReverted, len(call.Logs))
@ -699,6 +699,24 @@ func (f *Firehose) assignOrdinalAndIndexToReceiptLogs() {
return cmp.Compare(i.Ordinal, j.Ordinal) return cmp.Compare(i.Ordinal, j.Ordinal)
}) })
// When a transaction failed the receipt can be nil, so we need to deal with this
var receiptsLogs []*pbeth.Log
if trx.Receipt == nil {
if len(callLogs) == 0 {
// No logs in the transaction (nor in calls), nothing to do
return
}
panic(fmt.Errorf(
"mismatch between Firehose call logs and Ethereum transaction %s receipt logs at block #%d, the transaction has no receipt (failed) so there is no logs but it exists %d Firehose call logs",
hex.EncodeToString(trx.Hash),
f.block.Number,
len(callLogs),
))
} else {
receiptsLogs = trx.Receipt.Logs
}
if len(callLogs) != len(receiptsLogs) { if len(callLogs) != len(receiptsLogs) {
panic(fmt.Errorf( panic(fmt.Errorf(
"mismatch between Firehose call logs and Ethereum transaction %s receipt logs at block #%d, transaction receipt has %d logs but there is %d Firehose call logs", "mismatch between Firehose call logs and Ethereum transaction %s receipt logs at block #%d, transaction receipt has %d logs but there is %d Firehose call logs",