Skip to content

Commit e875183

Browse files
committed
sqldb+graph/db: impl DisconnectBlockAtHeight
Which lets us run `TestDisconnectBlockAtHeight` and `TestStressTestChannelGraphAPI` against our SQL backends.
1 parent 9dd0361 commit e875183

File tree

6 files changed

+195
-2
lines changed

6 files changed

+195
-2
lines changed

docs/release-notes/release-notes-0.20.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ circuit. The indices are only available for forwarding events saved after v0.20.
8888
* [6](https://github.com/lightningnetwork/lnd/pull/9936)
8989
* [7](https://github.com/lightningnetwork/lnd/pull/9937)
9090
* [8](https://github.com/lightningnetwork/lnd/pull/9938)
91+
* [9](https://github.com/lightningnetwork/lnd/pull/9939)
9192

9293
## RPC Updates
9394

graph/db/graph_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ func TestDisconnectBlockAtHeight(t *testing.T) {
513513
t.Parallel()
514514
ctx := context.Background()
515515

516-
graph := MakeTestGraph(t)
516+
graph := MakeTestGraphNew(t)
517517

518518
sourceNode := createTestVertex(t)
519519
if err := graph.SetSourceNode(ctx, sourceNode); err != nil {
@@ -2440,14 +2440,18 @@ func TestStressTestChannelGraphAPI(t *testing.T) {
24402440
t.Parallel()
24412441
ctx := context.Background()
24422442

2443-
graph := MakeTestGraph(t)
2443+
graph := MakeTestGraphNew(t)
24442444

24452445
node1 := createTestVertex(t)
24462446
require.NoError(t, graph.AddLightningNode(ctx, node1))
24472447

24482448
node2 := createTestVertex(t)
24492449
require.NoError(t, graph.AddLightningNode(ctx, node2))
24502450

2451+
// We need to update the node's timestamp since this call to
2452+
// SetSourceNode will trigger an upsert which will only be allowed if
2453+
// the newest LastUpdate time is greater than the current one.
2454+
node1.LastUpdate = node1.LastUpdate.Add(time.Second)
24512455
require.NoError(t, graph.SetSourceNode(ctx, node1))
24522456

24532457
type chanInfo struct {

graph/db/sql_store.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

sqldb/sqlc/graph.sql.go

Lines changed: 77 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sqldb/sqlc/querier.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sqldb/sqlc/queries/graph.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,16 @@ INSERT INTO channels (
208208
)
209209
RETURNING id;
210210

211+
-- name: GetChannelsBySCIDRange :many
212+
SELECT sqlc.embed(c),
213+
n1.pub_key AS node1_pub_key,
214+
n2.pub_key AS node2_pub_key
215+
FROM channels c
216+
JOIN nodes n1 ON c.node_id_1 = n1.id
217+
JOIN nodes n2 ON c.node_id_2 = n2.id
218+
WHERE scid >= @start_scid
219+
AND scid < @end_scid;
220+
211221
-- name: GetChannelBySCID :one
212222
SELECT * FROM channels
213223
WHERE scid = $1 AND version = $2;
@@ -685,3 +695,8 @@ SELECT block_height, block_hash
685695
FROM prune_log
686696
ORDER BY block_height DESC
687697
LIMIT 1;
698+
699+
-- name: DeletePruneLogEntriesInRange :exec
700+
DELETE FROM prune_log
701+
WHERE block_height >= @start_height
702+
AND block_height <= @end_height;

0 commit comments

Comments
 (0)