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 2025-02-17 12:58:51 -03:00
parent 39964ce6e1
commit b3f75fb4e0
No known key found for this signature in database
GPG Key ID: D7D916376026F177
3 changed files with 87 additions and 39 deletions

View File

@ -266,6 +266,7 @@ The underlying functionality between those two options remain the same.
- [1](https://github.com/lightningnetwork/lnd/pull/9533)
- [2](https://github.com/lightningnetwork/lnd/pull/9545)
- [3](https://github.com/lightningnetwork/lnd/pull/9550)
- [4](https://github.com/lightningnetwork/lnd/pull/9551)
* [Golang was updated to
`v1.22.11`](https://github.com/lightningnetwork/lnd/pull/9462).

View File

@ -4,6 +4,8 @@ import (
"sync"
"time"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/batch"
"github.com/lightningnetwork/lnd/graph/db/models"
"github.com/lightningnetwork/lnd/kvdb"
@ -322,3 +324,65 @@ func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) (
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
}

View File

@ -1316,15 +1316,19 @@ const (
// 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.
// the target block along with any pruned nodes are returned if the function
// succeeds without error.
func (c *KVStore) PruneGraph(spentOutputs []*wire.OutPoint,
blockHash *chainhash.Hash, blockHeight uint32) (
[]*models.ChannelEdgeInfo, error) {
[]*models.ChannelEdgeInfo, []route.Vertex, error) {
c.cacheMu.Lock()
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 {
// First grab the edges bucket which houses the information
@ -1387,14 +1391,6 @@ func (c *KVStore) PruneGraph(spentOutputs []*wire.OutPoint,
return err
}
if c.graphCache != nil {
c.graphCache.RemoveChannel(
edgeInfo.NodeKey1Bytes,
edgeInfo.NodeKey2Bytes,
edgeInfo.ChannelID,
)
}
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
// prune any nodes that have had a channel closed within the
// latest block.
prunedNodes, err := c.pruneGraphNodes(nodes, edgeIndex)
if err != nil {
return err
}
prunedNodes, err = c.pruneGraphNodes(nodes, edgeIndex)
if c.graphCache != nil {
for _, nodePubKey := range prunedNodes {
c.graphCache.RemoveNode(nodePubKey)
}
}
return nil
return err
}, func() {
chansClosed = nil
prunedNodes = nil
})
if err != nil {
return nil, err
return nil, nil, err
}
for _, channel := range chansClosed {
@ -1451,20 +1439,16 @@ func (c *KVStore) PruneGraph(spentOutputs []*wire.OutPoint,
c.chanCache.remove(channel.ChannelID)
}
if c.graphCache != nil {
log.Debugf("Pruned graph, cache now has %s",
c.graphCache.Stats())
}
return chansClosed, nil
return chansClosed, prunedNodes, 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 *KVStore) PruneGraphNodes() error {
return kvdb.Update(c.db, func(tx kvdb.RwTx) error {
func (c *KVStore) PruneGraphNodes() ([]route.Vertex, error) {
var prunedNodes []route.Vertex
err := kvdb.Update(c.db, func(tx kvdb.RwTx) error {
nodes := tx.ReadWriteBucket(nodeBucket)
if nodes == nil {
return ErrGraphNodesNotFound
@ -1478,19 +1462,18 @@ func (c *KVStore) PruneGraphNodes() error {
return ErrGraphNoEdgesFound
}
prunedNodes, err := c.pruneGraphNodes(nodes, edgeIndex)
var err error
prunedNodes, err = c.pruneGraphNodes(nodes, edgeIndex)
if err != nil {
return err
}
if c.graphCache != nil {
for _, nodePubKey := range prunedNodes {
c.graphCache.RemoveNode(nodePubKey)
}
}
return nil
}, func() {})
}, func() {
prunedNodes = nil
})
return prunedNodes, err
}
// pruneGraphNodes attempts to remove any nodes from the graph who have had a