From e3b87dd4dc4bcea85753e5b5266d231b7aa3ad3f Mon Sep 17 00:00:00 2001 From: Somnath Date: Wed, 17 Apr 2024 16:58:28 +0400 Subject: [PATCH] Fix missing prune log index (#9968) Existing prune had some confusing logic (thanks to me). In PR, change the logic to: if receipt, or any individual log in the receipt contains an address in `noPruneContracts` the entire log must be stored and indexed. Also fixes a regression that logs were not getting indexed - this was due to ``` if l.BlockNumber < pruneBlock && cfg.noPruneContracts != nil && !cfg.noPruneContracts[l.Address] { ``` Since the individual log object didn't have the block number - something that shouldn't matter. In PR, change the logic to: Use `blockNum` from outer loop --- eth/stagedsync/stage_execute.go | 17 ++++++++--- eth/stagedsync/stage_log_index.go | 51 +++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/eth/stagedsync/stage_execute.go b/eth/stagedsync/stage_execute.go index c363def9b46..b58e605ebae 100644 --- a/eth/stagedsync/stage_execute.go +++ b/eth/stagedsync/stage_execute.go @@ -208,12 +208,21 @@ func executeBlock( func gatherNoPruneReceipts(receipts *types.Receipts, chainCfg *chain.Config) bool { cr := types.Receipts{} for _, r := range *receipts { - for _, l := range r.Logs { - if chainCfg.NoPruneContracts[l.Address] { - cr = append(cr, r) - break + toStore := false + if chainCfg.NoPruneContracts != nil && chainCfg.NoPruneContracts[r.ContractAddress] { + toStore = true + } else { + for _, l := range r.Logs { + if chainCfg.NoPruneContracts != nil && chainCfg.NoPruneContracts[l.Address] { + toStore = true + break + } } } + + if toStore { + cr = append(cr, r) + } } receipts = &cr if receipts.Len() > 0 { diff --git a/eth/stagedsync/stage_log_index.go b/eth/stagedsync/stage_log_index.go index 6919ffbfc0f..d0c19faa1c9 100644 --- a/eth/stagedsync/stage_log_index.go +++ b/eth/stagedsync/stage_log_index.go @@ -130,7 +130,7 @@ func promoteLogIndex(logPrefix string, tx kv.RwTx, start uint64, endBlock uint64 reader := bytes.NewReader(nil) if endBlock != 0 && endBlock-start > 100 { - logger.Info(fmt.Sprintf("[%s] processing", logPrefix), "from", start, "to", endBlock) + logger.Info(fmt.Sprintf("[%s] processing", logPrefix), "from", start, "to", endBlock, "pruneTo", pruneBlock) } for k, v, err := logs.Seek(dbutils.LogKey(start, 0)); k != nil; k, v, err = logs.Next() { @@ -178,10 +178,26 @@ func promoteLogIndex(logPrefix string, tx kv.RwTx, start uint64, endBlock uint64 return fmt.Errorf("receipt unmarshal failed: %w, blocl=%d", err, blockNum) } - for _, l := range ll { - if l.BlockNumber < pruneBlock && cfg.noPruneContracts != nil && !cfg.noPruneContracts[l.Address] { + toStore := true + // if pruning is enabled, and noPruneContracts isn't configured for the chain, don't index + if blockNum < pruneBlock { + toStore = false + if cfg.noPruneContracts == nil { continue } + for _, l := range ll { + // if any of the log address is in noPrune, store and index all logs for this txId + if cfg.noPruneContracts[l.Address] { + toStore = true + break + } + } + } + + if !toStore { + continue + } + for _, l := range ll { for _, topic := range l.Topics { topicStr := string(topic.Bytes()) m, ok := topics[topicStr] @@ -477,27 +493,30 @@ func pruneLogIndex(logPrefix string, tx kv.RwTx, tmpDir string, pruneFrom, prune return fmt.Errorf("receipt unmarshal failed: %w, block=%d", err, binary.BigEndian.Uint64(k)) } - notToPrune := false // To identify whether this log key has addr in noPruneContracts + toPrune := true for _, l := range logs { - // If any of the logs have an address in noPruneContracts, then the whole tx is related to it, and must not be pruned, including addr and topic indexes - if noPruneContracts != nil && noPruneContracts[l.Address] || notToPrune { - notToPrune = true - continue + // No logs (or sublogs) for this txId should be pruned + // if one of the logs belongs to noPruneContracts lis + if noPruneContracts != nil && noPruneContracts[l.Address] { + toPrune = false + break } - for _, topic := range l.Topics { - if err := topics.Collect(topic.Bytes(), nil); err != nil { + } + if toPrune { + for _, l := range logs { + for _, topic := range l.Topics { + if err := topics.Collect(topic.Bytes(), nil); err != nil { + return err + } + } + if err := addrs.Collect(l.Address.Bytes(), nil); err != nil { return err } } - if err := addrs.Collect(l.Address.Bytes(), nil); err != nil { + if err := pruneLogKeyCollector.Collect(k, nil); err != nil { return err } } - // No logs (or sublogs) for this txId should be pruned - // if one of the logs belongs to noPruneContracts list - if !notToPrune { - pruneLogKeyCollector.Collect(k, nil) - } } }