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:
19 files changed
+210
-163
No files matched your search
@@ -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
@@ -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.
|
||||
|
||||
@@ -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...)
|
||||
}
|
||||
@@ -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...,
|
||||
)
|
||||
}
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,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,4 +1,4 @@
|
||||
//go:build !test_db_postgres && !test_db_sqlite
|
||||
//go:build !test_db_postgres && !test_db_sqlite && !test_native_sql
|
||||
|
||||
package sqldb
|
||||
|
||||
|
||||
Reference in new issue
Block a user