graph/db: add version parameter to DeleteChannelEdges

Thread the gossip version through DeleteChannelEdges to enable
version-aware channel deletion. The KVStore rejects non-v1 versions
while SQLStore properly passes the version to the underlying queries.
This prepares for v2 channel zombie handling (strict zombie pruning
for v2 is marked as TODO).
This commit is contained in:
Elle Mouton committed 2026-02-13 07:21:22 +02:00
1 parent 6bb3bdc83d
commit a73189ccec
5 files changed
+43 -18

No files matched your search

+2 -1
View File
@@ -371,7 +371,8 @@ func (c *ChannelGraph) DeleteChannelEdges(strictZombiePruning, markZombie bool,
chanIDs ...uint64) error { chanIDs ...uint64) error {
infos, err := c.db.DeleteChannelEdges( infos, err := c.db.DeleteChannelEdges(
strictZombiePruning, markZombie, chanIDs..., lnwire.GossipVersion1, strictZombiePruning, markZombie,
chanIDs...,
) )
if err != nil { if err != nil {
return err return err
+15 -5
View File
@@ -713,7 +713,9 @@ func createEdge(version lnwire.GossipVersion, height, txIndex uint32,
// Create a test funding script. // Create a test funding script.
fundingScript := []byte{0x00, 0x20} fundingScript := []byte{0x00, 0x20}
fundingScript = append(fundingScript, bytes.Repeat([]byte{0xbb}, 32)...) fundingScript = append(
fundingScript, bytes.Repeat([]byte{0xbb}, 32)...,
)
proof := models.NewV2ChannelAuthProof(testSig.Serialize()) proof := models.NewV2ChannelAuthProof(testSig.Serialize())
@@ -777,7 +779,9 @@ func TestDisconnectBlockAtHeight(t *testing.T) {
// Create an edge which has its block height at 156. // Create an edge which has its block height at 156.
height := uint32(156) height := uint32(156)
edgeInfo, _ := createEdge(lnwire.GossipVersion1, height, 0, 0, 0, node1, node2) edgeInfo, _ := createEdge(
lnwire.GossipVersion1, height, 0, 0, 0, node1, node2,
)
// Create an edge with block height 157. We give it // Create an edge with block height 157. We give it
// maximum values for tx index and position, to make // maximum values for tx index and position, to make
@@ -2238,8 +2242,12 @@ func TestHighestChanID(t *testing.T) {
// The first channel with be at height 10, while the other will be at // The first channel with be at height 10, while the other will be at
// height 100. // height 100.
edge1, _ := createEdge(lnwire.GossipVersion1, 10, 0, 0, 0, node1, node2) edge1, _ := createEdge(
edge2, chanID2 := createEdge(lnwire.GossipVersion1, 100, 0, 0, 0, node1, node2) lnwire.GossipVersion1, 10, 0, 0, 0, node1, node2,
)
edge2, chanID2 := createEdge(
lnwire.GossipVersion1, 100, 0, 0, 0, node1, node2,
)
if err := graph.AddChannelEdge(ctx, edge1); err != nil { if err := graph.AddChannelEdge(ctx, edge1); err != nil {
t.Fatalf("unable to create channel edge: %v", err) t.Fatalf("unable to create channel edge: %v", err)
@@ -4723,7 +4731,9 @@ func TestBatchedAddChannelEdge(t *testing.T) {
// Create an edge which has its block height at 156. // Create an edge which has its block height at 156.
height := uint32(156) height := uint32(156)
edgeInfo, _ := createEdge(lnwire.GossipVersion1, height, 0, 0, 0, node1, node2) edgeInfo, _ := createEdge(
lnwire.GossipVersion1, height, 0, 0, 0, node1, node2,
)
// Create an edge with block height 157. We give it // Create an edge with block height 157. We give it
// maximum values for tx index and position, to make // maximum values for tx index and position, to make
+3 -2
View File
@@ -215,8 +215,9 @@ type Store interface { //nolint:interfacebloat
// failed to send the fresh update to be the one that resurrects the // failed to send the fresh update to be the one that resurrects the
// channel from its zombie state. The markZombie bool denotes whether // channel from its zombie state. The markZombie bool denotes whether
// to mark the channel as a zombie. // to mark the channel as a zombie.
DeleteChannelEdges(strictZombiePruning, markZombie bool, DeleteChannelEdges(v lnwire.GossipVersion, strictZombiePruning,
chanIDs ...uint64) ([]*models.ChannelEdgeInfo, error) markZombie bool, chanIDs ...uint64) (
[]*models.ChannelEdgeInfo, error)
// AddEdgeProof sets the proof of an existing edge in the graph // AddEdgeProof sets the proof of an existing edge in the graph
// database. // database.
+7 -2
View File
@@ -1889,8 +1889,13 @@ func (c *KVStore) PruneTip() (*chainhash.Hash, uint32, error) {
// that we require the node that failed to send the fresh update to be the one // that we require the node that failed to send the fresh update to be the one
// that resurrects the channel from its zombie state. The markZombie bool // that resurrects the channel from its zombie state. The markZombie bool
// denotes whether or not to mark the channel as a zombie. // denotes whether or not to mark the channel as a zombie.
func (c *KVStore) DeleteChannelEdges(strictZombiePruning, markZombie bool, func (c *KVStore) DeleteChannelEdges(v lnwire.GossipVersion,
chanIDs ...uint64) ([]*models.ChannelEdgeInfo, error) { strictZombiePruning, markZombie bool, chanIDs ...uint64) (
[]*models.ChannelEdgeInfo, error) {
if v != lnwire.GossipVersion1 {
return nil, ErrVersionNotSupportedForKVDB
}
// TODO(roasbeef): possibly delete from node bucket if node has no more // TODO(roasbeef): possibly delete from node bucket if node has no more
// channels // channels
+16 -8
View File
@@ -1900,8 +1900,9 @@ func (s *SQLStore) NumZombies() (uint64, error) {
// denotes whether to mark the channel as a zombie. // denotes whether to mark the channel as a zombie.
// //
// NOTE: part of the Store interface. // NOTE: part of the Store interface.
func (s *SQLStore) DeleteChannelEdges(strictZombiePruning, markZombie bool, func (s *SQLStore) DeleteChannelEdges(v lnwire.GossipVersion,
chanIDs ...uint64) ([]*models.ChannelEdgeInfo, error) { strictZombiePruning, markZombie bool, chanIDs ...uint64) (
[]*models.ChannelEdgeInfo, error) {
s.cacheMu.Lock() s.cacheMu.Lock()
defer s.cacheMu.Unlock() defer s.cacheMu.Unlock()
@@ -1934,7 +1935,7 @@ func (s *SQLStore) DeleteChannelEdges(strictZombiePruning, markZombie bool,
} }
err := s.forEachChanWithPoliciesInSCIDList( err := s.forEachChanWithPoliciesInSCIDList(
ctx, db, chanCallBack, chanIDs, ctx, db, v, chanCallBack, chanIDs,
) )
if err != nil { if err != nil {
return err return err
@@ -1962,7 +1963,7 @@ func (s *SQLStore) DeleteChannelEdges(strictZombiePruning, markZombie bool,
scid := byteOrder.Uint64(row.GraphChannel.Scid) scid := byteOrder.Uint64(row.GraphChannel.Scid)
err := handleZombieMarking( err := handleZombieMarking(
ctx, db, row, edges[i], ctx, db, v, row, edges[i],
strictZombiePruning, scid, strictZombiePruning, scid,
) )
if err != nil { if err != nil {
@@ -2377,7 +2378,7 @@ func (s *SQLStore) FetchChanInfos(chanIDs []uint64) ([]ChannelEdge, error) {
} }
err := s.forEachChanWithPoliciesInSCIDList( err := s.forEachChanWithPoliciesInSCIDList(
ctx, db, chanCallBack, chanIDs, ctx, db, lnwire.GossipVersion1, chanCallBack, chanIDs,
) )
if err != nil { if err != nil {
return err return err
@@ -2425,7 +2426,7 @@ func (s *SQLStore) FetchChanInfos(chanIDs []uint64) ([]ChannelEdge, error) {
// GetChannelsBySCIDWithPolicies query that allows us to iterate through // GetChannelsBySCIDWithPolicies query that allows us to iterate through
// channels in a paginated manner. // channels in a paginated manner.
func (s *SQLStore) forEachChanWithPoliciesInSCIDList(ctx context.Context, func (s *SQLStore) forEachChanWithPoliciesInSCIDList(ctx context.Context,
db SQLQueries, cb func(ctx context.Context, db SQLQueries, v lnwire.GossipVersion, cb func(ctx context.Context,
row sqlc.GetChannelsBySCIDWithPoliciesRow) error, row sqlc.GetChannelsBySCIDWithPoliciesRow) error,
chanIDs []uint64) error { chanIDs []uint64) error {
@@ -2435,7 +2436,7 @@ func (s *SQLStore) forEachChanWithPoliciesInSCIDList(ctx context.Context,
return db.GetChannelsBySCIDWithPolicies( return db.GetChannelsBySCIDWithPolicies(
ctx, sqlc.GetChannelsBySCIDWithPoliciesParams{ ctx, sqlc.GetChannelsBySCIDWithPoliciesParams{
Version: int16(lnwire.GossipVersion1), Version: int16(v),
Scids: scids, Scids: scids,
}, },
) )
@@ -6027,12 +6028,19 @@ func batchBuildChannelInfo[T sqlc.ChannelAndNodeIDs](ctx context.Context,
// we are in strict zombie pruning mode, and adjusts the node public keys // we are in strict zombie pruning mode, and adjusts the node public keys
// accordingly based on the last update timestamps of the channel policies. // accordingly based on the last update timestamps of the channel policies.
func handleZombieMarking(ctx context.Context, db SQLQueries, func handleZombieMarking(ctx context.Context, db SQLQueries,
v lnwire.GossipVersion,
row sqlc.GetChannelsBySCIDWithPoliciesRow, info *models.ChannelEdgeInfo, row sqlc.GetChannelsBySCIDWithPoliciesRow, info *models.ChannelEdgeInfo,
strictZombiePruning bool, scid uint64) error { strictZombiePruning bool, scid uint64) error {
nodeKey1, nodeKey2 := info.NodeKey1Bytes, info.NodeKey2Bytes nodeKey1, nodeKey2 := info.NodeKey1Bytes, info.NodeKey2Bytes
if strictZombiePruning { if strictZombiePruning {
// TODO(elle): update for V2 last update times.
if v != lnwire.GossipVersion1 {
return fmt.Errorf("strict zombie pruning only "+
"supported for gossip v1, got %v", v)
}
var e1UpdateTime, e2UpdateTime *time.Time var e1UpdateTime, e2UpdateTime *time.Time
if row.Policy1LastUpdate.Valid { if row.Policy1LastUpdate.Valid {
e1Time := time.Unix(row.Policy1LastUpdate.Int64, 0) e1Time := time.Unix(row.Policy1LastUpdate.Int64, 0)
@@ -6051,7 +6059,7 @@ func handleZombieMarking(ctx context.Context, db SQLQueries,
return db.UpsertZombieChannel( return db.UpsertZombieChannel(
ctx, sqlc.UpsertZombieChannelParams{ ctx, sqlc.UpsertZombieChannelParams{
Version: int16(lnwire.GossipVersion1), Version: int16(v),
Scid: channelIDToBytes(scid), Scid: channelIDToBytes(scid),
NodeKey1: nodeKey1[:], NodeKey1: nodeKey1[:],
NodeKey2: nodeKey2[:], NodeKey2: nodeKey2[:],