Skip to content

Commit 5efc000

Browse files
committed
graph/db+sqldb: implement DeleteChannelEdges
This lets us run TestGraphZombieIndex against the SQL backends.
1 parent 4668171 commit 5efc000

File tree

6 files changed

+327
-1
lines changed

6 files changed

+327
-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: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,15 @@ type SQLQueries interface {
8787
*/
8888
CreateChannel(ctx context.Context, arg sqlc.CreateChannelParams) (int64, error)
8989
GetChannelBySCID(ctx context.Context, arg sqlc.GetChannelBySCIDParams) (sqlc.Channel, error)
90+
GetChannelBySCIDWithPolicies(ctx context.Context, arg sqlc.GetChannelBySCIDWithPoliciesParams) (sqlc.GetChannelBySCIDWithPoliciesRow, error)
9091
GetChannelAndNodesBySCID(ctx context.Context, arg sqlc.GetChannelAndNodesBySCIDParams) (sqlc.GetChannelAndNodesBySCIDRow, error)
9192
GetChannelFeaturesAndExtras(ctx context.Context, channelID int64) ([]sqlc.GetChannelFeaturesAndExtrasRow, error)
9293
HighestSCID(ctx context.Context, version int16) ([]byte, error)
9394
ListChannelsByNodeID(ctx context.Context, arg sqlc.ListChannelsByNodeIDParams) ([]sqlc.ListChannelsByNodeIDRow, error)
9495
ListChannelsPaginated(ctx context.Context, arg sqlc.ListChannelsPaginatedParams) ([]sqlc.ListChannelsPaginatedRow, error)
9596
GetChannelsByPolicyLastUpdateRange(ctx context.Context, arg sqlc.GetChannelsByPolicyLastUpdateRangeParams) ([]sqlc.GetChannelsByPolicyLastUpdateRangeRow, error)
9697
GetPublicV1ChannelsBySCID(ctx context.Context, arg sqlc.GetPublicV1ChannelsBySCIDParams) ([]sqlc.Channel, error)
98+
DeleteChannel(ctx context.Context, id int64) error
9799

98100
CreateChannelExtraType(ctx context.Context, arg sqlc.CreateChannelExtraTypeParams) error
99101
InsertChannelFeature(ctx context.Context, arg sqlc.InsertChannelFeatureParams) error
@@ -1549,6 +1551,124 @@ func (s *SQLStore) NumZombies() (uint64, error) {
15491551
return numZombies, nil
15501552
}
15511553

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