routing: move call to PruneGraph outside of the collating loop

This commit moves the call to PruneGraph outside of the loop
that collates all of the spentOutputs. With this change, if
a node has been offline for a long period of time, resyncing
with the chain no longer takes up as much memory (1MB vs 200MB
in some cases) or time. Previously, PruneGraph was called
for every block and allocated a very large map further down
in the pruneGraphNodes function. Now, pruneGraphNodes is only
called once.
This commit is contained in:
nsa 2019-06-27 13:34:55 -04:00
parent 5f4922cd57
commit 678fb674eb

View File

@ -680,7 +680,7 @@ func (r *ChannelRouter) syncGraphWithChain() error {
// If we're not yet caught up, then we'll walk forward in the chain // If we're not yet caught up, then we'll walk forward in the chain
// pruning the channel graph with each new block that hasn't yet been // pruning the channel graph with each new block that hasn't yet been
// consumed by the channel graph. // consumed by the channel graph.
var numChansClosed uint32 var spentOutputs []*wire.OutPoint
for nextHeight := pruneHeight + 1; nextHeight <= uint32(bestHeight); nextHeight++ { for nextHeight := pruneHeight + 1; nextHeight <= uint32(bestHeight); nextHeight++ {
// Break out of the rescan early if a shutdown has been // Break out of the rescan early if a shutdown has been
// requested, otherwise long rescans will block the daemon from // requested, otherwise long rescans will block the daemon from
@ -705,33 +705,25 @@ func (r *ChannelRouter) syncGraphWithChain() error {
// We're only interested in all prior outputs that have been // We're only interested in all prior outputs that have been
// spent in the block, so collate all the referenced previous // spent in the block, so collate all the referenced previous
// outpoints within each tx and input. // outpoints within each tx and input.
var spentOutputs []*wire.OutPoint
for _, tx := range filterBlock.Transactions { for _, tx := range filterBlock.Transactions {
for _, txIn := range tx.TxIn { for _, txIn := range tx.TxIn {
spentOutputs = append(spentOutputs, spentOutputs = append(spentOutputs,
&txIn.PreviousOutPoint) &txIn.PreviousOutPoint)
} }
} }
}
// With the spent outputs gathered, attempt to prune the // With the spent outputs gathered, attempt to prune the channel graph,
// channel graph, also passing in the hash+height of the block // also passing in the best hash+height so the prune tip can be updated.
// being pruned so the prune tip can be updated. closedChans, err := r.cfg.Graph.PruneGraph(
closedChans, err := r.cfg.Graph.PruneGraph(spentOutputs, spentOutputs, bestHash, uint32(bestHeight),
nextHash, )
nextHeight) if err != nil {
if err != nil { return err
return err
}
numClosed := uint32(len(closedChans))
log.Infof("Block %v (height=%v) closed %v channels",
nextHash, nextHeight, numClosed)
numChansClosed += numClosed
} }
log.Infof("Graph pruning complete: %v channels were closed since "+ log.Infof("Graph pruning complete: %v channels were closed since "+
"height %v", numChansClosed, pruneHeight) "height %v", len(closedChans), pruneHeight)
return nil return nil
} }