@@ -88,13 +88,15 @@ type SQLQueries interface {
88
88
*/
89
89
CreateChannel (ctx context.Context , arg sqlc.CreateChannelParams ) (int64 , error )
90
90
GetChannelBySCID (ctx context.Context , arg sqlc.GetChannelBySCIDParams ) (sqlc.Channel , error )
91
+ GetChannelBySCIDWithPolicies (ctx context.Context , arg sqlc.GetChannelBySCIDWithPoliciesParams ) (sqlc.GetChannelBySCIDWithPoliciesRow , error )
91
92
GetChannelAndNodesBySCID (ctx context.Context , arg sqlc.GetChannelAndNodesBySCIDParams ) (sqlc.GetChannelAndNodesBySCIDRow , error )
92
93
GetChannelFeaturesAndExtras (ctx context.Context , channelID int64 ) ([]sqlc.GetChannelFeaturesAndExtrasRow , error )
93
94
HighestSCID (ctx context.Context , version int16 ) ([]byte , error )
94
95
ListChannelsByNodeID (ctx context.Context , arg sqlc.ListChannelsByNodeIDParams ) ([]sqlc.ListChannelsByNodeIDRow , error )
95
96
ListChannelsWithPoliciesPaginated (ctx context.Context , arg sqlc.ListChannelsWithPoliciesPaginatedParams ) ([]sqlc.ListChannelsWithPoliciesPaginatedRow , error )
96
97
GetChannelsByPolicyLastUpdateRange (ctx context.Context , arg sqlc.GetChannelsByPolicyLastUpdateRangeParams ) ([]sqlc.GetChannelsByPolicyLastUpdateRangeRow , error )
97
98
GetPublicV1ChannelsBySCID (ctx context.Context , arg sqlc.GetPublicV1ChannelsBySCIDParams ) ([]sqlc.Channel , error )
99
+ DeleteChannel (ctx context.Context , id int64 ) error
98
100
99
101
CreateChannelExtraType (ctx context.Context , arg sqlc.CreateChannelExtraTypeParams ) error
100
102
InsertChannelFeature (ctx context.Context , arg sqlc.InsertChannelFeatureParams ) error
@@ -1552,6 +1554,123 @@ func (s *SQLStore) NumZombies() (uint64, error) {
1552
1554
return numZombies , nil
1553
1555
}
1554
1556
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
+
1555
1674
// forEachNodeDirectedChannel iterates through all channels of a given
1556
1675
// node, executing the passed callback on the directed edge representing the
1557
1676
// channel and its incoming policy. If the node is not found, no error is
0 commit comments