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