Merge pull request #9972 from ellemouton/graphSQL17-complete-unit-tests

[17] multi: run all graph unit tests against SQL backends & run itest suite against SQL graph backend
This commit is contained in:
Oliver Gugger authored and GitHub committed 2025-06-26 12:40:42 +02:00
commit 5f961e4349
19 files changed
+210 -163

No files matched your search

+4
View File
@@ -368,10 +368,14 @@ jobs:
args: backend=bitcoind dbbackend=sqlite
- name: bitcoind-sqlite-nativesql
args: backend=bitcoind dbbackend=sqlite nativesql=true
- name: bitcoind-sqlite=nativesql-experiment
args: backend=bitcoind dbbackend=sqlite nativesql=true tags=test_native_sql
- name: bitcoind-postgres
args: backend=bitcoind dbbackend=postgres
- name: bitcoind-postgres-nativesql
args: backend=bitcoind dbbackend=postgres nativesql=true
- name: bitcoind-postgres-nativesql-experiment
args: backend=bitcoind dbbackend=postgres nativesql=true tags=test_native_sql
steps:
- name: git checkout
uses: actions/checkout@v4
+33 -19
View File
@@ -1046,23 +1046,6 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
)
}
graphStore, err := graphdb.NewKVStore(
databaseBackends.GraphDB, graphDBOptions...,
)
if err != nil {
return nil, nil, err
}
dbs.GraphDB, err = graphdb.NewChannelGraph(graphStore, chanGraphOpts...)
if err != nil {
cleanUp()
err = fmt.Errorf("unable to open graph DB: %w", err)
d.logger.Error(err)
return nil, nil, err
}
dbOptions := []channeldb.OptionModifier{
channeldb.OptionDryRunMigration(cfg.DryRunMigration),
channeldb.OptionKeepFailedPaymentAttempts(
@@ -1098,6 +1081,10 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
return nil, nil, err
}
// The graph store implementation we will use depends on whether
// native SQL is enabled or not.
var graphStore graphdb.V1Store
// Instantiate a native SQL store if the flag is set.
if d.cfg.DB.UseNativeSQL {
migrations := sqldb.GetMigrations()
@@ -1156,17 +1143,27 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
// the base DB and transaction executor for the native SQL
// invoice store.
baseDB := dbs.NativeSQLStore.GetBaseDB()
executor := sqldb.NewTransactionExecutor(
invoiceExecutor := sqldb.NewTransactionExecutor(
baseDB, func(tx *sql.Tx) invoices.SQLInvoiceQueries {
return baseDB.WithTx(tx)
},
)
sqlInvoiceDB := invoices.NewSQLStore(
executor, clock.NewDefaultClock(),
invoiceExecutor, clock.NewDefaultClock(),
)
dbs.InvoiceDB = sqlInvoiceDB
graphStore, err = d.getGraphStore(
baseDB, databaseBackends.GraphDB, graphDBOptions...,
)
if err != nil {
err = fmt.Errorf("unable to get graph store: %w", err)
d.logger.Error(err)
return nil, nil, err
}
} else {
// Check if the invoice bucket tombstone is set. If it is, we
// need to return and ask the user switch back to using the
@@ -1188,6 +1185,23 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
}
dbs.InvoiceDB = dbs.ChanStateDB
graphStore, err = graphdb.NewKVStore(
databaseBackends.GraphDB, graphDBOptions...,
)
if err != nil {
return nil, nil, err
}
}
dbs.GraphDB, err = graphdb.NewChannelGraph(graphStore, chanGraphOpts...)
if err != nil {
cleanUp()
err = fmt.Errorf("unable to open channel graph DB: %w", err)
d.logger.Error(err)
return nil, nil, err
}
// Wrap the watchtower client DB and make sure we clean up.
+18
View File
@@ -0,0 +1,18 @@
//go:build !test_native_sql
package lnd
import (
graphdb "github.com/lightningnetwork/lnd/graph/db"
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/sqldb"
)
// getGraphStore returns a graphdb.V1Store backed by a graphdb.KVStore
// implementation.
func (d *DefaultDatabaseBuilder) getGraphStore(_ *sqldb.BaseDB,
kvBackend kvdb.Backend,
opts ...graphdb.StoreOptionModifier) (graphdb.V1Store, error) {
return graphdb.NewKVStore(kvBackend, opts...)
}
+31
View File
@@ -0,0 +1,31 @@
//go:build test_native_sql
package lnd
import (
"database/sql"
graphdb "github.com/lightningnetwork/lnd/graph/db"
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/sqldb"
)
// getGraphStore returns a graphdb.V1Store backed by a graphdb.SQLStore
// implementation.
func (d *DefaultDatabaseBuilder) getGraphStore(baseDB *sqldb.BaseDB,
_ kvdb.Backend, opts ...graphdb.StoreOptionModifier) (graphdb.V1Store,
error) {
graphExecutor := sqldb.NewTransactionExecutor(
baseDB, func(tx *sql.Tx) graphdb.SQLQueries {
return baseDB.WithTx(tx)
},
)
return graphdb.NewSQLStore(
&graphdb.SQLStoreConfig{
ChainHash: *d.cfg.ActiveNetParams.GenesisHash,
},
graphExecutor, opts...,
)
}
+1 -1
View File
@@ -236,7 +236,7 @@ func (c *ChannelGraphBootstrapper) SampleNodeAddrs(_ context.Context,
return errFound
})
if err != nil && err != errFound {
if err != nil && !errors.Is(err, errFound) {
return nil, err
}
@@ -91,6 +91,7 @@ circuit. The indices are only available for forwarding events saved after v0.20.
* [8](https://github.com/lightningnetwork/lnd/pull/9938)
* [9](https://github.com/lightningnetwork/lnd/pull/9939)
* [10](https://github.com/lightningnetwork/lnd/pull/9971)
* [11](https://github.com/lightningnetwork/lnd/pull/9972)
## RPC Updates
+44 -28
View File
@@ -892,15 +892,27 @@ func TestPruneChannelGraphDoubleDisabled(t *testing.T) {
}
func testPruneChannelGraphDoubleDisabled(t *testing.T, assumeValid bool) {
timestamp := time.Now()
// nextTimeStamp is a helper closure that will return a new
// timestamp each time it's called, this helps us create channel updates
// with new timestamps so that we don't run into our SQL DB constraint
// which only allows an update to a channel edge if the last update
// timestamp is greater than the previous one.
nextTimeStamp := func() time.Time {
timestamp = timestamp.Add(time.Second)
return timestamp
}
// We'll create the following test graph so that only the last channel
// is pruned. We'll use a fresh timestamp to ensure they're not pruned
// according to that heuristic.
timestamp := time.Now()
testChannels := []*testChannel{
// Channel from self shouldn't be pruned.
symmetricTestChannel(
"self", "a", 100000, &testChannelPolicy{
LastUpdate: timestamp,
LastUpdate: nextTimeStamp(),
Disabled: true,
}, 99,
),
@@ -918,7 +930,7 @@ func testPruneChannelGraphDoubleDisabled(t *testing.T, assumeValid bool) {
Node1: &testChannelEnd{
Alias: "a",
testChannelPolicy: &testChannelPolicy{
LastUpdate: timestamp,
LastUpdate: nextTimeStamp(),
Disabled: true,
},
},
@@ -932,7 +944,7 @@ func testPruneChannelGraphDoubleDisabled(t *testing.T, assumeValid bool) {
Node1: &testChannelEnd{
Alias: "a",
testChannelPolicy: &testChannelPolicy{
LastUpdate: timestamp,
LastUpdate: nextTimeStamp(),
Disabled: false,
},
},
@@ -946,14 +958,14 @@ func testPruneChannelGraphDoubleDisabled(t *testing.T, assumeValid bool) {
Node1: &testChannelEnd{
Alias: "a",
testChannelPolicy: &testChannelPolicy{
LastUpdate: timestamp,
LastUpdate: nextTimeStamp(),
Disabled: true,
},
},
Node2: &testChannelEnd{
Alias: "b",
testChannelPolicy: &testChannelPolicy{
LastUpdate: timestamp,
LastUpdate: nextTimeStamp(),
Disabled: false,
},
},
@@ -963,13 +975,13 @@ func testPruneChannelGraphDoubleDisabled(t *testing.T, assumeValid bool) {
// Both edges enabled.
symmetricTestChannel("c", "d", 100000, &testChannelPolicy{
LastUpdate: timestamp,
LastUpdate: nextTimeStamp(),
Disabled: false,
}, 2),
// Both edges disabled, only one pruned.
symmetricTestChannel("e", "f", 100000, &testChannelPolicy{
LastUpdate: timestamp,
LastUpdate: nextTimeStamp(),
Disabled: true,
}, 3),
}
@@ -1363,7 +1375,9 @@ func parseTestGraph(t *testing.T, useCache bool, path string) (
testAddrs = append(testAddrs, testAddr)
// Next, create a temporary graph database for usage within the test.
graph := graphdb.MakeTestGraph(t, graphdb.WithUseGraphCache(useCache))
graph := graphdb.MakeTestGraph(
t, graphdb.WithUseGraphCache(useCache),
)
aliasMap := make(map[string]route.Vertex)
privKeyMap := make(map[string]*btcec.PrivateKey)
@@ -1441,6 +1455,13 @@ func parseTestGraph(t *testing.T, useCache bool, path string) (
}
source = dbNode
// Set the selected source node.
if err := graph.SetSourceNode(ctx, source); err != nil {
return nil, err
}
continue
}
// With the node fully parsed, add it as a vertex within the
@@ -1450,13 +1471,6 @@ func parseTestGraph(t *testing.T, useCache bool, path string) (
}
}
if source != nil {
// Set the selected source node
if err := graph.SetSourceNode(ctx, source); err != nil {
return nil, err
}
}
// With all the vertexes inserted, we can now insert the edges into the
// test graph.
for _, edge := range g.Edges {
@@ -1739,14 +1753,16 @@ func createTestGraphFromChannels(t *testing.T, useCache bool,
testAddrs = append(testAddrs, testAddr)
// Next, create a temporary graph database for usage within the test.
graph := graphdb.MakeTestGraph(t, graphdb.WithUseGraphCache(useCache))
graph := graphdb.MakeTestGraph(
t, graphdb.WithUseGraphCache(useCache),
)
aliasMap := make(map[string]route.Vertex)
privKeyMap := make(map[string]*btcec.PrivateKey)
nodeIndex := byte(0)
addNodeWithAlias := func(alias string, features *lnwire.FeatureVector) (
*models.LightningNode, error) {
addNodeWithAlias := func(alias string,
features *lnwire.FeatureVector) error {
keyBytes := []byte{
0, 0, 0, 0, 0, 0, 0, 0,
@@ -1776,26 +1792,26 @@ func createTestGraphFromChannels(t *testing.T, useCache bool,
// With the node fully parsed, add it as a vertex within the
// graph.
if err := graph.AddLightningNode(ctx, dbNode); err != nil {
return nil, err
if alias == source {
err = graph.SetSourceNode(ctx, dbNode)
require.NoError(t, err)
} else {
err := graph.AddLightningNode(ctx, dbNode)
require.NoError(t, err)
}
aliasMap[alias] = dbNode.PubKeyBytes
nodeIndex++
return dbNode, nil
return nil
}
// Add the source node.
dbNode, err := addNodeWithAlias(source, lnwire.EmptyFeatureVector())
err = addNodeWithAlias(source, lnwire.EmptyFeatureVector())
if err != nil {
return nil, err
}
if err = graph.SetSourceNode(ctx, dbNode); err != nil {
return nil, err
}
// Initialize variable that keeps track of the next channel id to assign
// if none is specified.
nextUnassignedChannelID := uint64(100000)
@@ -1813,7 +1829,7 @@ func createTestGraphFromChannels(t *testing.T, useCache bool,
features =
node.testChannelPolicy.Features
}
_, err := addNodeWithAlias(
err := addNodeWithAlias(
node.Alias, features,
)
if err != nil {
+5
View File
@@ -66,6 +66,11 @@ var (
// ErrUnknownAddressType is returned when a node's addressType is not
// an expected value.
ErrUnknownAddressType = fmt.Errorf("address type cannot be resolved")
// ErrCantCheckIfZombieEdgeStr is an error returned when we
// attempt to check if an edge is a zombie but encounter an error.
ErrCantCheckIfZombieEdgeStr = fmt.Errorf("unable to check if edge " +
"is a zombie")
)
// ErrTooManyExtraOpaqueBytes creates an error which should be returned if the
+2 -2
View File
@@ -594,7 +594,7 @@ func (c *ChannelGraph) UpdateEdgePolicy(ctx context.Context,
return nil
}
// MakeTestGraphNew creates a new instance of the ChannelGraph for testing
// MakeTestGraph creates a new instance of the ChannelGraph for testing
// purposes. The backing V1Store implementation depends on the version of
// NewTestDB included in the current build.
//
@@ -603,7 +603,7 @@ func (c *ChannelGraph) UpdateEdgePolicy(ctx context.Context,
// implemented, unit tests will be switched to use this function instead of
// the existing MakeTestGraph helper. Once only this function is used, the
// existing MakeTestGraph function will be removed and this one will be renamed.
func MakeTestGraphNew(t testing.TB,
func MakeTestGraph(t testing.TB,
opts ...ChanGraphOption) *ChannelGraph {
t.Helper()
+50 -43
View File
@@ -101,7 +101,7 @@ func TestNodeInsertionAndDeletion(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// We'd like to test basic insertion/deletion for vertexes from the
// graph, so we'll create a test vertex to start with.
@@ -264,7 +264,7 @@ func TestPartialNode(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// To insert a partial node, we need to add a channel edge that has
// node keys for nodes we are not yet aware
@@ -332,7 +332,7 @@ func TestAliasLookup(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// We'd like to test the alias index within the database, so first
// create a new test node.
@@ -363,7 +363,7 @@ func TestSourceNode(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// We'd like to test the setting/getting of the source node, so we
// first create a fake node to use within the test.
@@ -390,7 +390,7 @@ func TestEdgeInsertionDeletion(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// We'd like to test the insertion/deletion of edges, so we create two
// vertexes to connect.
@@ -453,7 +453,8 @@ func TestEdgeInsertionDeletion(t *testing.T) {
require.ErrorIs(t, err, ErrEdgeNotFound)
_, _, _, err = graph.FetchChannelEdgesByID(chanID)
require.ErrorIs(t, err, ErrZombieEdge)
isZombie, _, _ := graph.IsZombieEdge(chanID)
isZombie, _, _, err := graph.IsZombieEdge(chanID)
require.NoError(t, err)
require.True(t, isZombie)
// Finally, attempt to delete a (now) non-existent edge within the
@@ -513,7 +514,7 @@ func TestDisconnectBlockAtHeight(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
sourceNode := createTestVertex(t)
if err := graph.SetSourceNode(ctx, sourceNode); err != nil {
@@ -810,7 +811,7 @@ func TestEdgeInfoUpdates(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// We'd like to test the update of edges inserted into the database, so
// we create two vertexes to connect.
@@ -1128,7 +1129,7 @@ func TestAddEdgeProof(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// Add an edge with no proof.
node1 := createTestVertex(t)
@@ -1187,7 +1188,7 @@ func TestForEachSourceNodeChannel(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// Create a source node (A) and set it as such in the DB.
nodeA := createTestVertex(t)
@@ -1275,7 +1276,7 @@ func TestForEachSourceNodeChannel(t *testing.T) {
func TestGraphTraversal(t *testing.T) {
t.Parallel()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// We'd like to test some of the graph traversal capabilities within
// the DB, so we'll create a series of fake nodes to insert into the
@@ -1370,7 +1371,7 @@ func TestGraphTraversal(t *testing.T) {
func TestGraphTraversalCacheable(t *testing.T) {
t.Parallel()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// We'd like to test some of the graph traversal capabilities within
// the DB, so we'll create a series of fake nodes to insert into the
@@ -1440,7 +1441,7 @@ func TestGraphTraversalCacheable(t *testing.T) {
func TestGraphCacheTraversal(t *testing.T) {
t.Parallel()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// We'd like to test some of the graph traversal capabilities within
// the DB, so we'll create a series of fake nodes to insert into the
@@ -1685,7 +1686,7 @@ func TestGraphPruning(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
sourceNode := createTestVertex(t)
if err := graph.SetSourceNode(ctx, sourceNode); err != nil {
@@ -1875,7 +1876,7 @@ func TestHighestChanID(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// If we don't yet have any channels in the database, then we should
// get a channel ID of zero if we ask for the highest channel ID.
@@ -1935,7 +1936,7 @@ func TestChanUpdatesInHorizon(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// If we issue an arbitrary query before any channel updates are
// inserted in the database, we should get zero results.
@@ -2093,7 +2094,7 @@ func TestNodeUpdatesInHorizon(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
startTime := time.Unix(1234, 0)
endTime := startTime
@@ -2196,7 +2197,7 @@ func TestNodeUpdatesInHorizon(t *testing.T) {
func TestFilterKnownChanIDsZombieRevival(t *testing.T) {
t.Parallel()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
var (
scid1 = lnwire.ShortChannelID{BlockHeight: 1}
@@ -2205,7 +2206,9 @@ func TestFilterKnownChanIDsZombieRevival(t *testing.T) {
)
isZombie := func(scid lnwire.ShortChannelID) bool {
zombie, _, _ := graph.IsZombieEdge(scid.ToUint64())
zombie, _, _, err := graph.IsZombieEdge(scid.ToUint64())
require.NoError(t, err)
return zombie
}
@@ -2262,7 +2265,7 @@ func TestFilterKnownChanIDs(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
isZombieUpdate := func(updateTime1 time.Time,
updateTime2 time.Time) bool {
@@ -2440,7 +2443,7 @@ func TestStressTestChannelGraphAPI(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
node1 := createTestVertex(t)
require.NoError(t, graph.AddLightningNode(ctx, node1))
@@ -2729,7 +2732,7 @@ func TestFilterChannelRange(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// We'll first populate our graph with two nodes. All channels created
// below will be made between these two nodes.
@@ -2948,7 +2951,7 @@ func TestFetchChanInfos(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// We'll first populate our graph with two nodes. All channels created
// below will be made between these two nodes.
@@ -3051,7 +3054,7 @@ func TestIncompleteChannelPolicies(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// Create two nodes.
node1 := createTestVertex(t)
@@ -3295,7 +3298,7 @@ func TestPruneGraphNodes(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// We'll start off by inserting our source node, to ensure that it's
// the only node left after we prune the graph.
@@ -3361,7 +3364,7 @@ func TestAddChannelEdgeShellNodes(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// To start, we'll create two nodes, and only add one of them to the
// channel graph.
@@ -3400,7 +3403,7 @@ func TestNodePruningUpdateIndexDeletion(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// We'll first populate our graph with a single node that will be
// removed shortly.
@@ -3469,19 +3472,19 @@ func TestNodeIsPublic(t *testing.T) {
// We'll need to create a separate database and channel graph for each
// participant to replicate real-world scenarios (private edges being in
// some graphs but not others, etc.).
aliceGraph := MakeTestGraphNew(t)
aliceGraph := MakeTestGraph(t)
aliceNode := createTestVertex(t)
if err := aliceGraph.SetSourceNode(ctx, aliceNode); err != nil {
t.Fatalf("unable to set source node: %v", err)
}
bobGraph := MakeTestGraphNew(t)
bobGraph := MakeTestGraph(t)
bobNode := createTestVertex(t)
if err := bobGraph.SetSourceNode(ctx, bobNode); err != nil {
t.Fatalf("unable to set source node: %v", err)
}
carolGraph := MakeTestGraphNew(t)
carolGraph := MakeTestGraph(t)
carolNode := createTestVertex(t)
if err := carolGraph.SetSourceNode(ctx, carolNode); err != nil {
t.Fatalf("unable to set source node: %v", err)
@@ -3596,7 +3599,7 @@ func TestDisabledChannelIDs(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// Create first node and add it to the graph.
node1 := createTestVertex(t)
@@ -3828,7 +3831,7 @@ func TestGraphZombieIndex(t *testing.T) {
ctx := context.Background()
// We'll start by creating our test graph along with a test edge.
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
node1 := createTestVertex(t)
node2 := createTestVertex(t)
@@ -3844,15 +3847,17 @@ func TestGraphZombieIndex(t *testing.T) {
// Since the edge is known the graph and it isn't a zombie, IsZombieEdge
// should not report the channel as a zombie.
isZombie, _, _ := graph.IsZombieEdge(edge.ChannelID)
isZombie, _, _, err := graph.IsZombieEdge(edge.ChannelID)
require.NoError(t, err)
require.False(t, isZombie)
assertNumZombies(t, graph, 0)
// If we delete the edge and mark it as a zombie, then we should expect
// to see it within the index.
err := graph.DeleteChannelEdges(false, true, edge.ChannelID)
err = graph.DeleteChannelEdges(false, true, edge.ChannelID)
require.NoError(t, err, "unable to mark edge as zombie")
isZombie, pubKey1, pubKey2 := graph.IsZombieEdge(edge.ChannelID)
isZombie, pubKey1, pubKey2, err := graph.IsZombieEdge(edge.ChannelID)
require.NoError(t, err)
require.True(t, isZombie)
require.Equal(t, node1.PubKeyBytes, pubKey1)
require.Equal(t, node2.PubKeyBytes, pubKey2)
@@ -3868,7 +3873,8 @@ func TestGraphZombieIndex(t *testing.T) {
t, graph.MarkEdgeLive(edge.ChannelID), ErrZombieEdgeNotFound,
)
isZombie, _, _ = graph.IsZombieEdge(edge.ChannelID)
isZombie, _, _, err = graph.IsZombieEdge(edge.ChannelID)
require.NoError(t, err)
require.False(t, isZombie)
assertNumZombies(t, graph, 0)
@@ -3880,7 +3886,8 @@ func TestGraphZombieIndex(t *testing.T) {
)
require.NoError(t, err, "unable to mark edge as zombie")
isZombie, _, _ = graph.IsZombieEdge(edge.ChannelID)
isZombie, _, _, err = graph.IsZombieEdge(edge.ChannelID)
require.NoError(t, err)
require.True(t, isZombie)
assertNumZombies(t, graph, 1)
}
@@ -4010,7 +4017,7 @@ func TestBatchedAddChannelEdge(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
sourceNode := createTestVertex(t)
require.Nil(t, graph.SetSourceNode(ctx, sourceNode))
@@ -4087,7 +4094,7 @@ func TestBatchedUpdateEdgePolicy(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// We'd like to test the update of edges inserted into the database, so
// we create two vertexes to connect.
@@ -4137,7 +4144,7 @@ func TestBatchedUpdateEdgePolicy(t *testing.T) {
// BenchmarkForEachChannel is a benchmark test that measures the number of
// allocations and the total memory consumed by the full graph traversal.
func BenchmarkForEachChannel(b *testing.B) {
graph := MakeTestGraphNew(b)
graph := MakeTestGraph(b)
const numNodes = 100
const numChannels = 4
@@ -4190,7 +4197,7 @@ func TestGraphCacheForEachNodeChannel(t *testing.T) {
t.Parallel()
ctx := context.Background()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
// Unset the channel graph cache to simulate the user running with the
// option turned off.
@@ -4325,7 +4332,7 @@ func TestGraphLoading(t *testing.T) {
func TestClosedScid(t *testing.T) {
t.Parallel()
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
scid := lnwire.ShortChannelID{}
@@ -4362,7 +4369,7 @@ func TestLightningNodePersistence(t *testing.T) {
ctx := context.Background()
// Create a new test graph instance.
graph := MakeTestGraphNew(t)
graph := MakeTestGraph(t)
nodeAnnBytes, err := hex.DecodeString(testNodeAnn)
require.NoError(t, err)
+1 -1
View File
@@ -308,7 +308,7 @@ type V1Store interface { //nolint:interfacebloat
// IsZombieEdge returns whether the edge is considered zombie. If it is
// a zombie, then the two node public keys corresponding to this edge
// are also returned.
IsZombieEdge(chanID uint64) (bool, [33]byte, [33]byte)
IsZombieEdge(chanID uint64) (bool, [33]byte, [33]byte, error)
// NumZombies returns the current number of zombie channels in the
// graph.
+6 -34
View File
@@ -12,7 +12,6 @@ import (
"net"
"sort"
"sync"
"testing"
"time"
"github.com/btcsuite/btcd/btcec/v2"
@@ -28,7 +27,6 @@ import (
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/stretchr/testify/require"
)
var (
@@ -3794,7 +3792,9 @@ func (c *KVStore) markEdgeLiveUnsafe(tx kvdb.RwTx, chanID uint64) error {
// IsZombieEdge returns whether the edge is considered zombie. If it is a
// zombie, then the two node public keys corresponding to this edge are also
// returned.
func (c *KVStore) IsZombieEdge(chanID uint64) (bool, [33]byte, [33]byte) {
func (c *KVStore) IsZombieEdge(chanID uint64) (bool, [33]byte, [33]byte,
error) {
var (
isZombie bool
pubKey1, pubKey2 [33]byte
@@ -3819,10 +3819,11 @@ func (c *KVStore) IsZombieEdge(chanID uint64) (bool, [33]byte, [33]byte) {
pubKey2 = [33]byte{}
})
if err != nil {
return false, [33]byte{}, [33]byte{}
return false, [33]byte{}, [33]byte{}, fmt.Errorf("%w: %w "+
"(chanID=%d)", ErrCantCheckIfZombieEdgeStr, err, chanID)
}
return isZombie, pubKey1, pubKey2
return isZombie, pubKey1, pubKey2, nil
}
// isZombieEdge returns whether an entry exists for the given channel in the
@@ -4869,32 +4870,3 @@ func (c *chanGraphNodeTx) ForEachChannel(f func(*models.ChannelEdgeInfo,
},
)
}
// MakeTestGraph creates a new instance of the ChannelGraph for testing
// purposes.
//
// NOTE: this helper currently creates a ChannelGraph that is only ever backed
// by the `KVStore` of the `V1Store` interface.
func MakeTestGraph(t testing.TB, opts ...ChanGraphOption) *ChannelGraph {
t.Helper()
// Next, create KVStore for the first time.
backend, backendCleanup, err := kvdb.GetTestBackend(t.TempDir(), "cgr")
t.Cleanup(backendCleanup)
require.NoError(t, err)
t.Cleanup(func() {
require.NoError(t, backend.Close())
})
graphStore, err := NewKVStore(backend)
require.NoError(t, err)
graph, err := NewChannelGraph(graphStore, opts...)
require.NoError(t, err)
require.NoError(t, graph.Start())
t.Cleanup(func() {
require.NoError(t, graph.Stop())
})
return graph
}
+8 -11
View File
@@ -175,10 +175,6 @@ type SQLStore struct {
srcNodes map[ProtocolVersion]*srcNodeInfo
srcNodeMu sync.Mutex
// Temporary fall-back to the KVStore so that we can implement the
// interface incrementally.
*KVStore
}
// A compile-time assertion to ensure that SQLStore implements the V1Store
@@ -194,7 +190,7 @@ type SQLStoreConfig struct {
// NewSQLStore creates a new SQLStore instance given an open BatchedSQLQueries
// storage backend.
func NewSQLStore(cfg *SQLStoreConfig, db BatchedSQLQueries, kvStore *KVStore,
func NewSQLStore(cfg *SQLStoreConfig, db BatchedSQLQueries,
options ...StoreOptionModifier) (*SQLStore, error) {
opts := DefaultOptions()
@@ -210,7 +206,6 @@ func NewSQLStore(cfg *SQLStoreConfig, db BatchedSQLQueries, kvStore *KVStore,
s := &SQLStore{
cfg: cfg,
db: db,
KVStore: kvStore,
rejectCache: newRejectCache(opts.RejectCacheSize),
chanCache: newChannelCache(opts.ChannelCacheSize),
srcNodes: make(map[ProtocolVersion]*srcNodeInfo),
@@ -1641,7 +1636,9 @@ func (s *SQLStore) MarkEdgeLive(chanID uint64) error {
// returned.
//
// NOTE: part of the V1Store interface.
func (s *SQLStore) IsZombieEdge(chanID uint64) (bool, [33]byte, [33]byte) {
func (s *SQLStore) IsZombieEdge(chanID uint64) (bool, [33]byte, [33]byte,
error) {
var (
ctx = context.TODO()
isZombie bool
@@ -1671,12 +1668,12 @@ func (s *SQLStore) IsZombieEdge(chanID uint64) (bool, [33]byte, [33]byte) {
return nil
}, sqldb.NoOpReset)
if err != nil {
// TODO(elle): update the IsZombieEdge method to return an
// error.
return false, route.Vertex{}, route.Vertex{}
return false, route.Vertex{}, route.Vertex{},
fmt.Errorf("%w: %w (chanID=%d)",
ErrCantCheckIfZombieEdgeStr, err, chanID)
}
return isZombie, pubKey1, pubKey2
return isZombie, pubKey1, pubKey2, nil
}
// NumZombies returns the current number of zombie channels in the graph.
+1 -10
View File
@@ -7,7 +7,6 @@ import (
"testing"
"github.com/btcsuite/btcd/chaincfg"
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/sqldb"
"github.com/stretchr/testify/require"
)
@@ -16,14 +15,6 @@ import (
// database for testing. At the moment, it embeds a KVStore but once the
// SQLStore fully implements the V1Store interface, the KVStore will be removed.
func NewTestDB(t testing.TB) V1Store {
backend, backendCleanup, err := kvdb.GetTestBackend(t.TempDir(), "cgr")
require.NoError(t, err)
t.Cleanup(backendCleanup)
graphStore, err := NewKVStore(backend)
require.NoError(t, err)
pgFixture := sqldb.NewTestPgFixture(
t, sqldb.DefaultPostgresFixtureLifetime,
)
@@ -42,7 +33,7 @@ func NewTestDB(t testing.TB) V1Store {
store, err := NewSQLStore(
&SQLStoreConfig{
ChainHash: *chaincfg.MainNetParams.GenesisHash,
}, executor, graphStore,
}, executor,
)
require.NoError(t, err)
+1 -10
View File
@@ -7,7 +7,6 @@ import (
"testing"
"github.com/btcsuite/btcd/chaincfg"
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/sqldb"
"github.com/stretchr/testify/require"
)
@@ -16,14 +15,6 @@ import (
// database for testing. At the moment, it embeds a KVStore but once the
// SQLStore fully implements the V1Store interface, the KVStore will be removed.
func NewTestDB(t testing.TB) V1Store {
backend, backendCleanup, err := kvdb.GetTestBackend(t.TempDir(), "cgr")
require.NoError(t, err)
t.Cleanup(backendCleanup)
graphStore, err := NewKVStore(backend)
require.NoError(t, err)
db := sqldb.NewTestSqliteDB(t).BaseDB
executor := sqldb.NewTransactionExecutor(
@@ -35,7 +26,7 @@ func NewTestDB(t testing.TB) V1Store {
store, err := NewSQLStore(
&SQLStoreConfig{
ChainHash: *chaincfg.MainNetParams.GenesisHash,
}, executor, graphStore,
}, executor,
)
require.NoError(t, err)
+1 -1
View File
@@ -763,7 +763,7 @@ func TestNodeUpdateNotification(t *testing.T) {
// then it should trigger a new notification.
// TODO(roasbeef): assume monotonic time.
nodeUpdateAnn := *node1
nodeUpdateAnn.LastUpdate = node1.LastUpdate.Add(300 * time.Millisecond)
nodeUpdateAnn.LastUpdate = node1.LastUpdate.Add(time.Second)
// Add new node topology update to the channel router.
if err := ctx.builder.AddNode(ctxb, &nodeUpdateAnn); err != nil {
+1 -1
View File
@@ -160,7 +160,7 @@ func makeTestGraph(t *testing.T, useCache bool) (*graphdb.ChannelGraph,
kvdb.Backend, error) {
// Create channelgraph for the first time.
graph := graphdb.MakeTestGraphNew(
graph := graphdb.MakeTestGraph(
t, graphdb.WithUseGraphCache(useCache),
)
require.NoError(t, graph.Start())
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build test_db_postgres || test_db_sqlite
//go:build test_db_postgres || test_db_sqlite || test_native_sql
package sqldb
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build !test_db_postgres && !test_db_sqlite
//go:build !test_db_postgres && !test_db_sqlite && !test_native_sql
package sqldb