Skip to content

Commit 2a6e668

Browse files
committed
graph/db+sqldb: implement DeleteChannelEdges
This lets us run TestGraphZombieIndex against the SQL backends.
1 parent 00b6e02 commit 2a6e668

File tree

6 files changed

+326
-1
lines changed

6 files changed

+326
-1
lines changed

docs/release-notes/release-notes-0.20.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ circuit. The indices are only available for forwarding events saved after v0.20.
8686
* [4](https://github.com/lightningnetwork/lnd/pull/9931)
8787
* [5](https://github.com/lightningnetwork/lnd/pull/9935)
8888
* [6](https://github.com/lightningnetwork/lnd/pull/9936)
89+
* [7](https://github.com/lightningnetwork/lnd/pull/9937)
8990

9091
## RPC Updates
9192

graph/db/graph_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3811,7 +3811,7 @@ func TestGraphZombieIndex(t *testing.T) {
38113811
ctx := context.Background()
38123812

38133813
// We'll start by creating our test graph along with a test edge.
3814-
graph := MakeTestGraph(t)
3814+
graph := MakeTestGraphNew(t)
38153815

38163816
node1 := createTestVertex(t)
38173817
node2 := createTestVertex(t)

graph/db/sql_store.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,15 @@ type SQLQueries interface {
8888
*/
8989
CreateChannel(ctx context.Context, arg sqlc.CreateChannelParams) (int64, error)
9090
GetChannelBySCID(ctx context.Context, arg sqlc.GetChannelBySCIDParams) (sqlc.Channel, error)
91+
GetChannelBySCIDWithPolicies(ctx context.Context, arg sqlc.GetChannelBySCIDWithPoliciesParams) (sqlc.GetChannelBySCIDWithPoliciesRow, error)
9192
GetChannelAndNodesBySCID(ctx context.Context, arg sqlc.GetChannelAndNodesBySCIDParams) (sqlc.GetChannelAndNodesBySCIDRow, error)
9293
GetChannelFeaturesAndExtras(ctx context.Context, channelID int64) ([]sqlc.GetChannelFeaturesAndExtrasRow, error)
9394
HighestSCID(ctx context.Context, version int16) ([]byte, error)
9495
ListChannelsByNodeID(ctx context.Context, arg sqlc.ListChannelsByNodeIDParams) ([]sqlc.ListChannelsByNodeIDRow, error)
9596
ListChannelsWithPoliciesPaginated(ctx context.Context, arg sqlc.ListChannelsWithPoliciesPaginatedParams) ([]sqlc.ListChannelsWithPoliciesPaginatedRow, error)
9697
GetChannelsByPolicyLastUpdateRange(ctx context.Context, arg sqlc.GetChannelsByPolicyLastUpdateRangeParams) ([]sqlc.GetChannelsByPolicyLastUpdateRangeRow, error)
9798
GetPublicV1ChannelsBySCID(ctx context.Context, arg sqlc.GetPublicV1ChannelsBySCIDParams) ([]sqlc.Channel, error)
99+
DeleteChannel(ctx context.Context, id int64) error
98100

99101
CreateChannelExtraType(ctx context.Context, arg sqlc.CreateChannelExtraTypeParams) error
100102
InsertChannelFeature(ctx context.Context, arg sqlc.InsertChannelFeatureParams) error
@@ -1552,6 +1554,123 @@ func (s *SQLStore) NumZombies() (uint64, error) {
15521554
return numZombies, nil
15531555
}
15541556

1557+
// DeleteChannelEdges removes edges with the given channel IDs from the
1558+
// database and marks them as zombies. This ensures that we're unable to re-add
1559+
// it to our database once again. If an edge does not exist within the
1560+
// database, then ErrEdgeNotFound will be returned. If strictZombiePruning is
1561+
// true, then when we mark these edges as zombies, we'll set up the keys such
1562+
// that we require the node that failed to send the fresh update to be the one
1563+
// that resurrects the channel from its zombie state. The markZombie bool
1564+
// denotes whether to mark the channel as a zombie.
1565+
//
1566+
// NOTE: part of the V1Store interface.
1567+
func (s *SQLStore) DeleteChannelEdges(strictZombiePruning, markZombie bool,
1568+
chanIDs ...uint64) ([]*models.ChannelEdgeInfo, error) {
1569+
1570+
s.cacheMu.Lock()
1571+
defer s.cacheMu.Unlock()
1572+
1573+
var (
1574+
ctx = context.TODO()
1575+
deleted []*models.ChannelEdgeInfo
1576+
)
1577+
err := s.db.ExecTx(ctx, sqldb.WriteTxOpt(), func(db SQLQueries) error {
1578+
for _, chanID := range chanIDs {
1579+
chanIDB := channelIDToBytes(chanID)
1580+
1581+
row, err := db.GetChannelBySCIDWithPolicies(
1582+
ctx, sqlc.GetChannelBySCIDWithPoliciesParams{
1583+
Scid: chanIDB[:],
1584+
Version: int16(ProtocolV1),
1585+
},
1586+
)
1587+
if errors.Is(err, sql.ErrNoRows) {
1588+
return ErrEdgeNotFound
1589+
} else if err != nil {
1590+
return fmt.Errorf("unable to fetch channel: %w",
1591+
err)
1592+
}
1593+
1594+
node1, node2, err := buildNodeVertices(
1595+
row.Node.PubKey, row.Node_2.PubKey,
1596+
)
1597+
if err != nil {
1598+
return err
1599+
}
1600+
1601+
info, err := getAndBuildEdgeInfo(
1602+
ctx, db, s.cfg.ChainHash, row.Channel.ID,
1603+
row.Channel, node1, node2,
1604+
)
1605+
if err != nil {
1606+
return err
1607+
}
1608+
1609+
err = db.DeleteChannel(ctx, row.Channel.ID)
1610+
if err != nil {
1611+
return fmt.Errorf("unable to delete "+
1612+
"channel: %w", err)
1613+
}
1614+
1615+
deleted = append(deleted, info)
1616+
1617+
if !markZombie {
1618+
continue
1619+
}
1620+
1621+
nodeKey1, nodeKey2 := info.NodeKey1Bytes,
1622+
info.NodeKey2Bytes
1623+
if strictZombiePruning {
1624+
var e1UpdateTime, e2UpdateTime *time.Time
1625+
if row.Policy1LastUpdate.Valid {
1626+
e1Time := time.Unix(
1627+
row.Policy1LastUpdate.Int64, 0,
1628+
)
1629+
e1UpdateTime = &e1Time
1630+
}
1631+
if row.Policy2LastUpdate.Valid {
1632+
e2Time := time.Unix(
1633+
row.Policy2LastUpdate.Int64, 0,
1634+
)
1635+
e2UpdateTime = &e2Time
1636+
}
1637+
1638+
nodeKey1, nodeKey2 = makeZombiePubkeys(
1639+
info, e1UpdateTime, e2UpdateTime,
1640+
)
1641+
}
1642+
1643+
err = db.UpsertZombieChannel(
1644+
ctx, sqlc.UpsertZombieChannelParams{
1645+
Version: int16(ProtocolV1),
1646+
Scid: chanIDB[:],
1647+
NodeKey1: nodeKey1[:],
1648+
NodeKey2: nodeKey2[:],
1649+
},
1650+
)
1651+
if err != nil {
1652+
return fmt.Errorf("unable to mark channel as "+
1653+
"zombie: %w", err)
1654+
}
1655+
}
1656+
1657+
return nil
1658+
}, func() {
1659+
deleted = nil
1660+
})
1661+
if err != nil {
1662+
return nil, fmt.Errorf("unable to delete channel edges: %w",
1663+
err)
1664+
}
1665+
1666+
for _, chanID := range chanIDs {
1667+
s.rejectCache.remove(chanID)
1668+
s.chanCache.remove(chanID)
1669+
}
1670+
1671+
return deleted, nil
1672+
}
1673+
15551674
// forEachNodeDirectedChannel iterates through all channels of a given
15561675
// node, executing the passed callback on the directed edge representing the
15571676
// channel and its incoming policy. If the node is not found, no error is

sqldb/sqlc/graph.sql.go

Lines changed: 154 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sqldb/sqlc/querier.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)