@@ -19,6 +19,7 @@ import (
19
19
"github.com/btcsuite/btcd/btcutil"
20
20
"github.com/btcsuite/btcd/chaincfg/chainhash"
21
21
"github.com/btcsuite/btcd/wire"
22
+ "github.com/lightningnetwork/lnd/aliasmgr"
22
23
"github.com/lightningnetwork/lnd/batch"
23
24
"github.com/lightningnetwork/lnd/fn/v2"
24
25
"github.com/lightningnetwork/lnd/graph/db/models"
@@ -92,6 +93,7 @@ type SQLQueries interface {
92
93
CreateChannel (ctx context.Context , arg sqlc.CreateChannelParams ) (int64 , error )
93
94
GetChannelBySCID (ctx context.Context , arg sqlc.GetChannelBySCIDParams ) (sqlc.Channel , error )
94
95
GetChannelByOutpoint (ctx context.Context , outpoint string ) (sqlc.GetChannelByOutpointRow , error )
96
+ GetChannelsBySCIDRange (ctx context.Context , arg sqlc.GetChannelsBySCIDRangeParams ) ([]sqlc.GetChannelsBySCIDRangeRow , error )
95
97
GetChannelBySCIDWithPolicies (ctx context.Context , arg sqlc.GetChannelBySCIDWithPoliciesParams ) (sqlc.GetChannelBySCIDWithPoliciesRow , error )
96
98
GetChannelAndNodesBySCID (ctx context.Context , arg sqlc.GetChannelAndNodesBySCIDParams ) (sqlc.GetChannelAndNodesBySCIDRow , error )
97
99
GetChannelFeaturesAndExtras (ctx context.Context , channelID int64 ) ([]sqlc.GetChannelFeaturesAndExtrasRow , error )
@@ -133,6 +135,7 @@ type SQLQueries interface {
133
135
*/
134
136
GetPruneTip (ctx context.Context ) (sqlc.PruneLog , error )
135
137
UpsertPruneLogEntry (ctx context.Context , arg sqlc.UpsertPruneLogEntryParams ) error
138
+ DeletePruneLogEntriesInRange (ctx context.Context , arg sqlc.DeletePruneLogEntriesInRangeParams ) error
136
139
}
137
140
138
141
// BatchedSQLQueries is a version of SQLQueries that's capable of batched
@@ -2481,6 +2484,97 @@ func (s *SQLStore) pruneGraphNodes(ctx context.Context,
2481
2484
return prunedNodes , nil
2482
2485
}
2483
2486
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
+
2484
2578
// forEachNodeDirectedChannel iterates through all channels of a given
2485
2579
// node, executing the passed callback on the directed edge representing the
2486
2580
// channel and its incoming policy. If the node is not found, no error is
0 commit comments