@@ -19,6 +19,7 @@ import (
1919 "github.com/btcsuite/btcd/btcutil"
2020 "github.com/btcsuite/btcd/chaincfg/chainhash"
2121 "github.com/btcsuite/btcd/wire"
22+ "github.com/lightningnetwork/lnd/aliasmgr"
2223 "github.com/lightningnetwork/lnd/batch"
2324 "github.com/lightningnetwork/lnd/fn/v2"
2425 "github.com/lightningnetwork/lnd/graph/db/models"
@@ -92,6 +93,7 @@ type SQLQueries interface {
9293 CreateChannel (ctx context.Context , arg sqlc.CreateChannelParams ) (int64 , error )
9394 GetChannelBySCID (ctx context.Context , arg sqlc.GetChannelBySCIDParams ) (sqlc.Channel , error )
9495 GetChannelByOutpoint (ctx context.Context , outpoint string ) (sqlc.GetChannelByOutpointRow , error )
96+ GetChannelsBySCIDRange (ctx context.Context , arg sqlc.GetChannelsBySCIDRangeParams ) ([]sqlc.GetChannelsBySCIDRangeRow , error )
9597 GetChannelBySCIDWithPolicies (ctx context.Context , arg sqlc.GetChannelBySCIDWithPoliciesParams ) (sqlc.GetChannelBySCIDWithPoliciesRow , error )
9698 GetChannelAndNodesBySCID (ctx context.Context , arg sqlc.GetChannelAndNodesBySCIDParams ) (sqlc.GetChannelAndNodesBySCIDRow , error )
9799 GetChannelFeaturesAndExtras (ctx context.Context , channelID int64 ) ([]sqlc.GetChannelFeaturesAndExtrasRow , error )
@@ -133,6 +135,7 @@ type SQLQueries interface {
133135 */
134136 GetPruneTip (ctx context.Context ) (sqlc.PruneLog , error )
135137 UpsertPruneLogEntry (ctx context.Context , arg sqlc.UpsertPruneLogEntryParams ) error
138+ DeletePruneLogEntriesInRange (ctx context.Context , arg sqlc.DeletePruneLogEntriesInRangeParams ) error
136139}
137140
138141// BatchedSQLQueries is a version of SQLQueries that's capable of batched
@@ -2481,6 +2484,97 @@ func (s *SQLStore) pruneGraphNodes(ctx context.Context,
24812484 return prunedNodes , nil
24822485}
24832486
2487+ // DisconnectBlockAtHeight is used to indicate that the block specified
2488+ // by the passed height has been disconnected from the main chain. This
2489+ // will "rewind" the graph back to the height below, deleting channels
2490+ // that are no longer confirmed from the graph. The prune log will be
2491+ // set to the last prune height valid for the remaining chain.
2492+ // Channels that were removed from the graph resulting from the
2493+ // disconnected block are returned.
2494+ //
2495+ // NOTE: part of the V1Store interface.
2496+ func (s * SQLStore ) DisconnectBlockAtHeight (height uint32 ) (
2497+ []* models.ChannelEdgeInfo , error ) {
2498+
2499+ ctx := context .TODO ()
2500+
2501+ var (
2502+ // Every channel having a ShortChannelID starting at 'height'
2503+ // will no longer be confirmed.
2504+ startShortChanID = lnwire.ShortChannelID {
2505+ BlockHeight : height ,
2506+ }
2507+
2508+ // Delete everything after this height from the db up until the
2509+ // SCID alias range.
2510+ endShortChanID = aliasmgr .StartingAlias
2511+
2512+ removedChans []* models.ChannelEdgeInfo
2513+ )
2514+
2515+ var chanIDStart [8 ]byte
2516+ byteOrder .PutUint64 (chanIDStart [:], startShortChanID .ToUint64 ())
2517+ var chanIDEnd [8 ]byte
2518+ byteOrder .PutUint64 (chanIDEnd [:], endShortChanID .ToUint64 ())
2519+
2520+ err := s .db .ExecTx (ctx , sqldb .WriteTxOpt (), func (db SQLQueries ) error {
2521+ rows , err := db .GetChannelsBySCIDRange (
2522+ ctx , sqlc.GetChannelsBySCIDRangeParams {
2523+ StartScid : chanIDStart [:],
2524+ EndScid : chanIDEnd [:],
2525+ },
2526+ )
2527+ if err != nil {
2528+ return fmt .Errorf ("unable to fetch channels: %w" , err )
2529+ }
2530+
2531+ for _ , row := range rows {
2532+ node1 , node2 , err := buildNodeVertices (
2533+ row .Node1PubKey , row .Node2PubKey ,
2534+ )
2535+ if err != nil {
2536+ return err
2537+ }
2538+
2539+ channel , err := getAndBuildEdgeInfo (
2540+ ctx , db , s .cfg .ChainHash , row .Channel .ID ,
2541+ row .Channel , node1 , node2 ,
2542+ )
2543+ if err != nil {
2544+ return err
2545+ }
2546+
2547+ err = db .DeleteChannel (ctx , row .Channel .ID )
2548+ if err != nil {
2549+ return fmt .Errorf ("unable to delete " +
2550+ "channel: %w" , err )
2551+ }
2552+
2553+ removedChans = append (removedChans , channel )
2554+ }
2555+
2556+ return db .DeletePruneLogEntriesInRange (
2557+ ctx , sqlc.DeletePruneLogEntriesInRangeParams {
2558+ StartHeight : int64 (height ),
2559+ EndHeight : int64 (endShortChanID .BlockHeight ),
2560+ },
2561+ )
2562+ }, func () {
2563+ removedChans = nil
2564+ })
2565+ if err != nil {
2566+ return nil , fmt .Errorf ("unable to disconnect block at " +
2567+ "height: %w" , err )
2568+ }
2569+
2570+ for _ , channel := range removedChans {
2571+ s .rejectCache .remove (channel .ChannelID )
2572+ s .chanCache .remove (channel .ChannelID )
2573+ }
2574+
2575+ return removedChans , nil
2576+ }
2577+
24842578// forEachNodeDirectedChannel iterates through all channels of a given
24852579// node, executing the passed callback on the directed edge representing the
24862580// channel and its incoming policy. If the node is not found, no error is
0 commit comments