graph/db: add version parameter to IsPublicNode
Make IsPublicNode version-aware by routing to the appropriate SQL query based on gossip version. V1 and v2 have different criteria for determining node publicity (v1 requires four signatures, v2 requires one). Convert TestNodeIsPublic to versioned test for both protocols.
This commit is contained in:
6 files changed
+46
-24
No files matched your search
+1
-1
@@ -1330,7 +1330,7 @@ func (b *Builder) IsStaleNode(ctx context.Context, node route.Vertex,
|
|||||||
//
|
//
|
||||||
// NOTE: This method is part of the ChannelGraphSource interface.
|
// NOTE: This method is part of the ChannelGraphSource interface.
|
||||||
func (b *Builder) IsPublicNode(node route.Vertex) (bool, error) {
|
func (b *Builder) IsPublicNode(node route.Vertex) (bool, error) {
|
||||||
return b.cfg.Graph.IsPublicNode(node)
|
return b.v1Graph.IsPublicNode(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsKnownEdge returns true if the graph source already knows of the passed
|
// IsKnownEdge returns true if the graph source already knows of the passed
|
||||||
|
|||||||
+6
-1
@@ -637,7 +637,7 @@ func (c *ChannelGraph) HasV1Node(ctx context.Context,
|
|||||||
|
|
||||||
// IsPublicNode determines whether the node is seen as public in the graph.
|
// IsPublicNode determines whether the node is seen as public in the graph.
|
||||||
func (c *ChannelGraph) IsPublicNode(pubKey [33]byte) (bool, error) {
|
func (c *ChannelGraph) IsPublicNode(pubKey [33]byte) (bool, error) {
|
||||||
return c.db.IsPublicNode(pubKey)
|
return c.db.IsPublicNode(lnwire.GossipVersion1, pubKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachChannel iterates through all channel edges stored within the graph.
|
// ForEachChannel iterates through all channel edges stored within the graph.
|
||||||
@@ -861,6 +861,11 @@ func (c *VersionedGraph) DeleteChannelEdges(strictZombiePruning,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsPublicNode determines whether the node is seen as public in the graph.
|
||||||
|
func (c *VersionedGraph) IsPublicNode(pubKey [33]byte) (bool, error) {
|
||||||
|
return c.db.IsPublicNode(c.v, pubKey)
|
||||||
|
}
|
||||||
|
|
||||||
// MakeTestGraph creates a new instance of the ChannelGraph for testing
|
// MakeTestGraph creates a new instance of the ChannelGraph for testing
|
||||||
// purposes. The backing Store implementation depends on the version of
|
// purposes. The backing Store implementation depends on the version of
|
||||||
// NewTestDB included in the current build.
|
// NewTestDB included in the current build.
|
||||||
|
|||||||
+18
-18
@@ -146,6 +146,10 @@ var versionedTests = []versionedTest{
|
|||||||
name: "partial node",
|
name: "partial node",
|
||||||
test: testPartialNode,
|
test: testPartialNode,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "node is public",
|
||||||
|
test: testNodeIsPublic,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestVersionedDBs runs various tests against both v1 and v2 versioned
|
// TestVersionedDBs runs various tests against both v1 and v2 versioned
|
||||||
@@ -4125,9 +4129,9 @@ func nextBlockHeight() uint32 {
|
|||||||
return updateBlock
|
return updateBlock
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestNodeIsPublic ensures that we properly detect nodes that are seen as
|
// testNodeIsPublic ensures that we properly detect nodes that are seen as
|
||||||
// public within the network graph.
|
// public within the network graph.
|
||||||
func TestNodeIsPublic(t *testing.T) {
|
func testNodeIsPublic(t *testing.T, v lnwire.GossipVersion) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
ctx := t.Context()
|
ctx := t.Context()
|
||||||
|
|
||||||
@@ -4139,33 +4143,29 @@ func TestNodeIsPublic(t *testing.T) {
|
|||||||
// We'll need to create a separate database and channel graph for each
|
// We'll need to create a separate database and channel graph for each
|
||||||
// participant to replicate real-world scenarios (private edges being in
|
// participant to replicate real-world scenarios (private edges being in
|
||||||
// some graphs but not others, etc.).
|
// some graphs but not others, etc.).
|
||||||
aliceGraph := MakeTestGraph(t)
|
aliceGraph := NewVersionedGraph(MakeTestGraph(t), v)
|
||||||
aliceNode := createTestVertex(t, lnwire.GossipVersion1)
|
aliceNode := createTestVertex(t, v)
|
||||||
err := aliceGraph.SetSourceNode(ctx, aliceNode)
|
err := aliceGraph.SetSourceNode(ctx, aliceNode)
|
||||||
require.NoError(t, err, "unable to set source node")
|
require.NoError(t, err, "unable to set source node")
|
||||||
|
|
||||||
bobGraph := MakeTestGraph(t)
|
bobGraph := NewVersionedGraph(MakeTestGraph(t), v)
|
||||||
bobNode := createTestVertex(t, lnwire.GossipVersion1)
|
bobNode := createTestVertex(t, v)
|
||||||
err = bobGraph.SetSourceNode(ctx, bobNode)
|
err = bobGraph.SetSourceNode(ctx, bobNode)
|
||||||
require.NoError(t, err, "unable to set source node")
|
require.NoError(t, err, "unable to set source node")
|
||||||
|
|
||||||
carolGraph := MakeTestGraph(t)
|
carolGraph := NewVersionedGraph(MakeTestGraph(t), v)
|
||||||
carolNode := createTestVertex(t, lnwire.GossipVersion1)
|
carolNode := createTestVertex(t, v)
|
||||||
err = carolGraph.SetSourceNode(ctx, carolNode)
|
err = carolGraph.SetSourceNode(ctx, carolNode)
|
||||||
require.NoError(t, err, "unable to set source node")
|
require.NoError(t, err, "unable to set source node")
|
||||||
|
|
||||||
aliceBobEdge, _ := createEdge(
|
aliceBobEdge, _ := createEdge(v, 10, 0, 0, 0, aliceNode, bobNode)
|
||||||
lnwire.GossipVersion1, 10, 0, 0, 0, aliceNode, bobNode,
|
bobCarolEdge, _ := createEdge(v, 10, 1, 0, 1, bobNode, carolNode)
|
||||||
)
|
|
||||||
bobCarolEdge, _ := createEdge(
|
|
||||||
lnwire.GossipVersion1, 10, 1, 0, 1, bobNode, carolNode,
|
|
||||||
)
|
|
||||||
|
|
||||||
// After creating all of our nodes and edges, we'll add them to each
|
// After creating all of our nodes and edges, we'll add them to each
|
||||||
// participant's graph.
|
// participant's graph.
|
||||||
nodes := []*models.Node{aliceNode, bobNode, carolNode}
|
nodes := []*models.Node{aliceNode, bobNode, carolNode}
|
||||||
edges := []*models.ChannelEdgeInfo{aliceBobEdge, bobCarolEdge}
|
edges := []*models.ChannelEdgeInfo{aliceBobEdge, bobCarolEdge}
|
||||||
graphs := []*ChannelGraph{aliceGraph, bobGraph, carolGraph}
|
graphs := []*VersionedGraph{aliceGraph, bobGraph, carolGraph}
|
||||||
for _, graph := range graphs {
|
for _, graph := range graphs {
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
node.LastUpdate = nextUpdateTime()
|
node.LastUpdate = nextUpdateTime()
|
||||||
@@ -4181,7 +4181,7 @@ func TestNodeIsPublic(t *testing.T) {
|
|||||||
// checkNodes is a helper closure that will be used to assert that the
|
// checkNodes is a helper closure that will be used to assert that the
|
||||||
// given nodes are seen as public/private within the given graphs.
|
// given nodes are seen as public/private within the given graphs.
|
||||||
checkNodes := func(nodes []*models.Node,
|
checkNodes := func(nodes []*models.Node,
|
||||||
graphs []*ChannelGraph, public bool) {
|
graphs []*VersionedGraph, public bool) {
|
||||||
|
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
@@ -4212,7 +4212,7 @@ func TestNodeIsPublic(t *testing.T) {
|
|||||||
}
|
}
|
||||||
checkNodes(
|
checkNodes(
|
||||||
[]*models.Node{aliceNode},
|
[]*models.Node{aliceNode},
|
||||||
[]*ChannelGraph{bobGraph, carolGraph},
|
[]*VersionedGraph{bobGraph, carolGraph},
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -4240,7 +4240,7 @@ func TestNodeIsPublic(t *testing.T) {
|
|||||||
// node from both Alice's and Carol's perspective.
|
// node from both Alice's and Carol's perspective.
|
||||||
checkNodes(
|
checkNodes(
|
||||||
[]*models.Node{bobNode},
|
[]*models.Node{bobNode},
|
||||||
[]*ChannelGraph{aliceGraph, carolGraph},
|
[]*VersionedGraph{aliceGraph, carolGraph},
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ type Store interface { //nolint:interfacebloat
|
|||||||
// IsPublicNode is a helper method that determines whether the node with
|
// IsPublicNode is a helper method that determines whether the node with
|
||||||
// the given public key is seen as a public node in the graph from the
|
// the given public key is seen as a public node in the graph from the
|
||||||
// graph's source node's point of view.
|
// graph's source node's point of view.
|
||||||
IsPublicNode(pubKey [33]byte) (bool, error)
|
IsPublicNode(v lnwire.GossipVersion, pubKey [33]byte) (bool, error)
|
||||||
|
|
||||||
// GraphSession will provide the call-back with access to a
|
// GraphSession will provide the call-back with access to a
|
||||||
// NodeTraverser instance which can be used to perform queries against
|
// NodeTraverser instance which can be used to perform queries against
|
||||||
|
|||||||
@@ -4005,7 +4005,13 @@ func (c *KVStore) FetchChannelEdgesByID(chanID uint64) (
|
|||||||
// IsPublicNode is a helper method that determines whether the node with the
|
// IsPublicNode is a helper method that determines whether the node with the
|
||||||
// given public key is seen as a public node in the graph from the graph's
|
// given public key is seen as a public node in the graph from the graph's
|
||||||
// source node's point of view.
|
// source node's point of view.
|
||||||
func (c *KVStore) IsPublicNode(pubKey [33]byte) (bool, error) {
|
func (c *KVStore) IsPublicNode(v lnwire.GossipVersion, pubKey [33]byte) (bool,
|
||||||
|
error) {
|
||||||
|
|
||||||
|
if v != lnwire.GossipVersion1 {
|
||||||
|
return false, ErrVersionNotSupportedForKVDB
|
||||||
|
}
|
||||||
|
|
||||||
var nodeIsPublic bool
|
var nodeIsPublic bool
|
||||||
err := kvdb.View(c.db, func(tx kvdb.RTx) error {
|
err := kvdb.View(c.db, func(tx kvdb.RTx) error {
|
||||||
nodes := tx.ReadBucket(nodeBucket)
|
nodes := tx.ReadBucket(nodeBucket)
|
||||||
|
|||||||
+13
-2
@@ -50,6 +50,7 @@ type SQLQueries interface {
|
|||||||
ListNodesPaginated(ctx context.Context, arg sqlc.ListNodesPaginatedParams) ([]sqlc.GraphNode, error)
|
ListNodesPaginated(ctx context.Context, arg sqlc.ListNodesPaginatedParams) ([]sqlc.GraphNode, error)
|
||||||
ListNodeIDsAndPubKeys(ctx context.Context, arg sqlc.ListNodeIDsAndPubKeysParams) ([]sqlc.ListNodeIDsAndPubKeysRow, error)
|
ListNodeIDsAndPubKeys(ctx context.Context, arg sqlc.ListNodeIDsAndPubKeysParams) ([]sqlc.ListNodeIDsAndPubKeysRow, error)
|
||||||
IsPublicV1Node(ctx context.Context, pubKey []byte) (bool, error)
|
IsPublicV1Node(ctx context.Context, pubKey []byte) (bool, error)
|
||||||
|
IsPublicV2Node(ctx context.Context, pubKey []byte) (bool, error)
|
||||||
DeleteUnconnectedNodes(ctx context.Context) ([][]byte, error)
|
DeleteUnconnectedNodes(ctx context.Context) ([][]byte, error)
|
||||||
DeleteNodeByPubKey(ctx context.Context, arg sqlc.DeleteNodeByPubKeyParams) (sql.Result, error)
|
DeleteNodeByPubKey(ctx context.Context, arg sqlc.DeleteNodeByPubKeyParams) (sql.Result, error)
|
||||||
DeleteNode(ctx context.Context, id int64) error
|
DeleteNode(ctx context.Context, id int64) error
|
||||||
@@ -2338,13 +2339,23 @@ func (s *SQLStore) ChannelID(chanPoint *wire.OutPoint) (uint64, error) {
|
|||||||
// source node's point of view.
|
// source node's point of view.
|
||||||
//
|
//
|
||||||
// NOTE: part of the Store interface.
|
// NOTE: part of the Store interface.
|
||||||
func (s *SQLStore) IsPublicNode(pubKey [33]byte) (bool, error) {
|
func (s *SQLStore) IsPublicNode(v lnwire.GossipVersion, pubKey [33]byte) (bool,
|
||||||
|
error) {
|
||||||
|
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
if !isKnownGossipVersion(v) {
|
||||||
|
return false, fmt.Errorf("unsupported gossip version: %d", v)
|
||||||
|
}
|
||||||
|
|
||||||
var isPublic bool
|
var isPublic bool
|
||||||
err := s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
err := s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
||||||
var err error
|
var err error
|
||||||
isPublic, err = db.IsPublicV1Node(ctx, pubKey[:])
|
switch v {
|
||||||
|
case lnwire.GossipVersion1:
|
||||||
|
isPublic, err = db.IsPublicV1Node(ctx, pubKey[:])
|
||||||
|
case lnwire.GossipVersion2:
|
||||||
|
isPublic, err = db.IsPublicV2Node(ctx, pubKey[:])
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}, sqldb.NoOpReset)
|
}, sqldb.NoOpReset)
|
||||||
|
|||||||
Reference in new issue
Block a user