Skip to content

Commit

Permalink
blockchain: don't rely on BlockHeightByHash for prune height
Browse files Browse the repository at this point in the history
calculations

Since BlockHeightByHash only returns the heights for blocks that are in
the main chain, when a block that is stale gets pruned, this will cause
an error in the block height lookup and cause an error in block
processing.

Look up the node directly from the index and if the node isn't found,
just skip that node. For utxoCache.lastFlushHash, if that isn't found,
just force a flush.
  • Loading branch information
kcalvinalvin committed Feb 16, 2024
1 parent a0c9e3b commit 42f313c
Showing 1 changed file with 16 additions and 9 deletions.
25 changes: 16 additions & 9 deletions blockchain/utxocache.go
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,7 @@ func (b *BlockChain) InitConsistentState(tip *blockNode, interrupt <-chan struct

// Set the last flush hash as it's the default value of 0s.
s.lastFlushHash = tip.hash
s.lastFlushTime = time.Now()

return err
}
Expand Down Expand Up @@ -725,22 +726,28 @@ func (b *BlockChain) InitConsistentState(tip *blockNode, interrupt <-chan struct
// Example: if the last flush hash was at height 100 and one of the deleted blocks was at
// height 98, this function will return true.
func (b *BlockChain) flushNeededAfterPrune(deletedBlockHashes []chainhash.Hash) (bool, error) {
lastFlushHeight, err := b.BlockHeightByHash(&b.utxoCache.lastFlushHash)
if err != nil {
return false, err
node := b.index.LookupNode(&b.utxoCache.lastFlushHash)
if node == nil {
// If we couldn't find the node where we last flushed at, have the utxo cache
// flush to be safe and that will set the last flush hash again.
return true, nil
}
lastFlushHeight := node.Height()

// Loop through all the block hashes and find out what the highest block height
// among the deleted hashes is.
highestDeletedHeight := int32(-1)
for _, deletedBlockHash := range deletedBlockHashes {
height, err := b.BlockHeightByHash(&deletedBlockHash)
if err != nil {
return false, err
node := b.index.LookupNode(&deletedBlockHash)
if node == nil {
// If we couldn't find this node, just skip it and try the next
// deleted hash. This might be a corruption in the database
// but there's nothing we can do here to address it except for
// moving onto the next block.
continue
}

if height > highestDeletedHeight {
highestDeletedHeight = height
if node.height > highestDeletedHeight {
highestDeletedHeight = node.height
}
}

Expand Down

0 comments on commit 42f313c

Please sign in to comment.