@@ -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
0 commit comments