graph/db: move cache writes for Prune methods

This commit moves the cache writes for PruneGraphNodes and PruneGraph
from the KVStore to the ChannelGraph.
This commit is contained in:
Elle Mouton committed 2025-03-24 15:05:47 +02:00
1 parent 941e7bf6b3
commit cc4fcbf838
3 files changed
+87 -39

No files matched your search

@@ -325,6 +325,7 @@ The underlying functionality between those two options remain the same.
- [1](https://github.com/lightningnetwork/lnd/pull/9533) - [1](https://github.com/lightningnetwork/lnd/pull/9533)
- [2](https://github.com/lightningnetwork/lnd/pull/9545) - [2](https://github.com/lightningnetwork/lnd/pull/9545)
- [3](https://github.com/lightningnetwork/lnd/pull/9550) - [3](https://github.com/lightningnetwork/lnd/pull/9550)
- [4](https://github.com/lightningnetwork/lnd/pull/9551)
* [Golang was updated to * [Golang was updated to
`v1.22.11`](https://github.com/lightningnetwork/lnd/pull/9462). `v1.22.11`](https://github.com/lightningnetwork/lnd/pull/9462).
+64
View File
@@ -4,6 +4,8 @@ import (
"sync" "sync"
"time" "time"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/batch" "github.com/lightningnetwork/lnd/batch"
"github.com/lightningnetwork/lnd/graph/db/models" "github.com/lightningnetwork/lnd/graph/db/models"
"github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/kvdb"
@@ -322,3 +324,65 @@ func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) (
return edges, nil return edges, nil
} }
// PruneGraph prunes newly closed channels from the channel graph in response
// to a new block being solved on the network. Any transactions which spend the
// funding output of any known channels within he graph will be deleted.
// Additionally, the "prune tip", or the last block which has been used to
// prune the graph is stored so callers can ensure the graph is fully in sync
// with the current UTXO state. A slice of channels that have been closed by
// the target block are returned if the function succeeds without error.
func (c *ChannelGraph) PruneGraph(spentOutputs []*wire.OutPoint,
blockHash *chainhash.Hash, blockHeight uint32) (
[]*models.ChannelEdgeInfo, error) {
c.cacheMu.Lock()
defer c.cacheMu.Unlock()
edges, nodes, err := c.KVStore.PruneGraph(
spentOutputs, blockHash, blockHeight,
)
if err != nil {
return nil, err
}
if c.graphCache != nil {
for _, edge := range edges {
c.graphCache.RemoveChannel(
edge.NodeKey1Bytes, edge.NodeKey2Bytes,
edge.ChannelID,
)
}
for _, node := range nodes {
c.graphCache.RemoveNode(node)
}
log.Debugf("Pruned graph, cache now has %s",
c.graphCache.Stats())
}
return edges, nil
}
// PruneGraphNodes is a garbage collection method which attempts to prune out
// any nodes from the channel graph that are currently unconnected. This ensure
// that we only maintain a graph of reachable nodes. In the event that a pruned
// node gains more channels, it will be re-added back to the graph.
func (c *ChannelGraph) PruneGraphNodes() error {
c.cacheMu.Lock()
defer c.cacheMu.Unlock()
nodes, err := c.KVStore.PruneGraphNodes()
if err != nil {
return err
}
if c.graphCache != nil {
for _, node := range nodes {
c.graphCache.RemoveNode(node)
}
}
return nil
}
+22 -39
View File
@@ -1316,15 +1316,19 @@ const (
// Additionally, the "prune tip", or the last block which has been used to // Additionally, the "prune tip", or the last block which has been used to
// prune the graph is stored so callers can ensure the graph is fully in sync // prune the graph is stored so callers can ensure the graph is fully in sync
// with the current UTXO state. A slice of channels that have been closed by // with the current UTXO state. A slice of channels that have been closed by
// the target block are returned if the function succeeds without error. // the target block along with any pruned nodes are returned if the function
// succeeds without error.
func (c *KVStore) PruneGraph(spentOutputs []*wire.OutPoint, func (c *KVStore) PruneGraph(spentOutputs []*wire.OutPoint,
blockHash *chainhash.Hash, blockHeight uint32) ( blockHash *chainhash.Hash, blockHeight uint32) (
[]*models.ChannelEdgeInfo, error) { []*models.ChannelEdgeInfo, []route.Vertex, error) {
c.cacheMu.Lock() c.cacheMu.Lock()
defer c.cacheMu.Unlock() defer c.cacheMu.Unlock()
var chansClosed []*models.ChannelEdgeInfo var (
chansClosed []*models.ChannelEdgeInfo
prunedNodes []route.Vertex
)
err := kvdb.Update(c.db, func(tx kvdb.RwTx) error { err := kvdb.Update(c.db, func(tx kvdb.RwTx) error {
// First grab the edges bucket which houses the information // First grab the edges bucket which houses the information
@@ -1387,14 +1391,6 @@ func (c *KVStore) PruneGraph(spentOutputs []*wire.OutPoint,
return err return err
} }
if c.graphCache != nil {
c.graphCache.RemoveChannel(
edgeInfo.NodeKey1Bytes,
edgeInfo.NodeKey2Bytes,
edgeInfo.ChannelID,
)
}
chansClosed = append(chansClosed, edgeInfo) chansClosed = append(chansClosed, edgeInfo)
} }
@@ -1427,23 +1423,15 @@ func (c *KVStore) PruneGraph(spentOutputs []*wire.OutPoint,
// Now that the graph has been pruned, we'll also attempt to // Now that the graph has been pruned, we'll also attempt to
// prune any nodes that have had a channel closed within the // prune any nodes that have had a channel closed within the
// latest block. // latest block.
prunedNodes, err := c.pruneGraphNodes(nodes, edgeIndex) prunedNodes, err = c.pruneGraphNodes(nodes, edgeIndex)
if err != nil {
return err
}
if c.graphCache != nil { return err
for _, nodePubKey := range prunedNodes {
c.graphCache.RemoveNode(nodePubKey)
}
}
return nil
}, func() { }, func() {
chansClosed = nil chansClosed = nil
prunedNodes = nil
}) })
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
for _, channel := range chansClosed { for _, channel := range chansClosed {
@@ -1451,20 +1439,16 @@ func (c *KVStore) PruneGraph(spentOutputs []*wire.OutPoint,
c.chanCache.remove(channel.ChannelID) c.chanCache.remove(channel.ChannelID)
} }
if c.graphCache != nil { return chansClosed, prunedNodes, nil
log.Debugf("Pruned graph, cache now has %s",
c.graphCache.Stats())
}
return chansClosed, nil
} }
// PruneGraphNodes is a garbage collection method which attempts to prune out // PruneGraphNodes is a garbage collection method which attempts to prune out
// any nodes from the channel graph that are currently unconnected. This ensure // any nodes from the channel graph that are currently unconnected. This ensure
// that we only maintain a graph of reachable nodes. In the event that a pruned // that we only maintain a graph of reachable nodes. In the event that a pruned
// node gains more channels, it will be re-added back to the graph. // node gains more channels, it will be re-added back to the graph.
func (c *KVStore) PruneGraphNodes() error { func (c *KVStore) PruneGraphNodes() ([]route.Vertex, error) {
return kvdb.Update(c.db, func(tx kvdb.RwTx) error { var prunedNodes []route.Vertex
err := kvdb.Update(c.db, func(tx kvdb.RwTx) error {
nodes := tx.ReadWriteBucket(nodeBucket) nodes := tx.ReadWriteBucket(nodeBucket)
if nodes == nil { if nodes == nil {
return ErrGraphNodesNotFound return ErrGraphNodesNotFound
@@ -1478,19 +1462,18 @@ func (c *KVStore) PruneGraphNodes() error {
return ErrGraphNoEdgesFound return ErrGraphNoEdgesFound
} }
prunedNodes, err := c.pruneGraphNodes(nodes, edgeIndex) var err error
prunedNodes, err = c.pruneGraphNodes(nodes, edgeIndex)
if err != nil { if err != nil {
return err return err
} }
if c.graphCache != nil {
for _, nodePubKey := range prunedNodes {
c.graphCache.RemoveNode(nodePubKey)
}
}
return nil return nil
}, func() {}) }, func() {
prunedNodes = nil
})
return prunedNodes, err
} }
// pruneGraphNodes attempts to remove any nodes from the graph who have had a // pruneGraphNodes attempts to remove any nodes from the graph who have had a