graph/db: add version parameter to IsZombieEdge
Make IsZombieEdge version-aware and add corresponding method to VersionedGraph. Convert TestEdgeInsertionDeletion to versioned test using the createEdge helper for both v1 and v2 channel testing.
This commit is contained in:
5 files changed
+103
-65
No files matched your search
+8
-1
@@ -735,7 +735,7 @@ func (c *ChannelGraph) ChannelView() ([]EdgePoint, error) {
|
||||
func (c *ChannelGraph) IsZombieEdge(chanID uint64) (bool, [33]byte, [33]byte,
|
||||
error) {
|
||||
|
||||
return c.db.IsZombieEdge(chanID)
|
||||
return c.db.IsZombieEdge(lnwire.GossipVersion1, chanID)
|
||||
}
|
||||
|
||||
// NumZombies returns the current number of zombie channels in the graph.
|
||||
@@ -806,6 +806,13 @@ func (c *VersionedGraph) FetchChannelEdgesByOutpoint(op *wire.OutPoint) (
|
||||
return c.db.FetchChannelEdgesByOutpoint(c.v, op)
|
||||
}
|
||||
|
||||
// IsZombieEdge returns whether the edge is considered zombie for this version.
|
||||
func (c *VersionedGraph) IsZombieEdge(chanID uint64) (bool, [33]byte,
|
||||
[33]byte, error) {
|
||||
|
||||
return c.db.IsZombieEdge(c.v, chanID)
|
||||
}
|
||||
|
||||
// AddrsForNode returns all known addresses for the target node public key.
|
||||
func (c *VersionedGraph) AddrsForNode(ctx context.Context,
|
||||
nodePub *btcec.PublicKey) (bool, []net.Addr, error) {
|
||||
|
||||
+78
-58
@@ -142,6 +142,10 @@ var versionedTests = []versionedTest{
|
||||
name: "add edge proof",
|
||||
test: testAddEdgeProof,
|
||||
},
|
||||
{
|
||||
name: "edge insertion deletion",
|
||||
test: testEdgeInsertionDeletion,
|
||||
},
|
||||
{
|
||||
name: "partial node",
|
||||
test: testPartialNode,
|
||||
@@ -549,88 +553,104 @@ func TestSetSourceNodeSameTimestamp(t *testing.T) {
|
||||
require.Equal(t, testNode.LastUpdate, updatedNode.LastUpdate)
|
||||
}
|
||||
|
||||
// TestEdgeInsertionDeletion tests the basic CRUD operations for channel edges.
|
||||
func TestEdgeInsertionDeletion(t *testing.T) {
|
||||
// testEdgeInsertionDeletion tests the basic CRUD operations for channel edges.
|
||||
func testEdgeInsertionDeletion(t *testing.T, v lnwire.GossipVersion) {
|
||||
t.Parallel()
|
||||
ctx := t.Context()
|
||||
|
||||
graph := MakeTestGraph(t)
|
||||
graph := NewVersionedGraph(MakeTestGraph(t), v)
|
||||
|
||||
// We'd like to test the insertion/deletion of edges, so we create two
|
||||
// vertexes to connect.
|
||||
node1 := createTestVertex(t, lnwire.GossipVersion1)
|
||||
node2 := createTestVertex(t, lnwire.GossipVersion1)
|
||||
node1 := createTestVertex(t, v)
|
||||
node2 := createTestVertex(t, v)
|
||||
|
||||
// In addition to the fake vertexes we create some fake channel
|
||||
// identifiers.
|
||||
chanID := uint64(prand.Int63())
|
||||
// Create a fake channel and add it to the graph.
|
||||
const (
|
||||
blockHeight = 1234
|
||||
txIndex = 1
|
||||
txPosition = 0
|
||||
outPointIndex = 9
|
||||
)
|
||||
|
||||
edgeInfo, shortChanID := createEdge(
|
||||
v, blockHeight, txIndex, txPosition, outPointIndex, node1,
|
||||
node2,
|
||||
)
|
||||
chanID := shortChanID.ToUint64()
|
||||
outpoint := wire.OutPoint{
|
||||
Hash: rev,
|
||||
Index: 9,
|
||||
Index: outPointIndex,
|
||||
}
|
||||
|
||||
// Add the new edge to the database, this should proceed without any
|
||||
// errors.
|
||||
node1Pub, err := node1.PubKey()
|
||||
require.NoError(t, err, "unable to generate node key")
|
||||
node2Pub, err := node2.PubKey()
|
||||
require.NoError(t, err, "unable to generate node key")
|
||||
|
||||
node1Vertex, err := route.NewVertexFromBytes(
|
||||
node1Pub.SerializeCompressed(),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
node2Vertex, err := route.NewVertexFromBytes(
|
||||
node2Pub.SerializeCompressed(),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
btcKey1, err := route.NewVertexFromBytes(
|
||||
node1Pub.SerializeCompressed(),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
btcKey2, err := route.NewVertexFromBytes(
|
||||
node2Pub.SerializeCompressed(),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
proof := models.NewV1ChannelAuthProof(
|
||||
testSig.Serialize(),
|
||||
testSig.Serialize(),
|
||||
testSig.Serialize(),
|
||||
testSig.Serialize(),
|
||||
)
|
||||
|
||||
edgeInfo, err := models.NewV1Channel(
|
||||
chanID, *chaincfg.MainNetParams.GenesisHash, node1Vertex,
|
||||
node2Vertex, &models.ChannelV1Fields{
|
||||
BitcoinKey1Bytes: btcKey1,
|
||||
BitcoinKey2Bytes: btcKey2,
|
||||
},
|
||||
models.WithChanProof(proof),
|
||||
models.WithChannelPoint(outpoint),
|
||||
models.WithCapacity(9000),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, graph.AddChannelEdge(ctx, edgeInfo))
|
||||
assertEdgeWithNoPoliciesInCache(t, graph, edgeInfo)
|
||||
assertEdgeWithNoPoliciesInCache(t, graph.ChannelGraph, edgeInfo)
|
||||
|
||||
// Show that trying to insert the same channel again will return the
|
||||
// expected error.
|
||||
err = graph.AddChannelEdge(ctx, edgeInfo)
|
||||
err := graph.AddChannelEdge(ctx, edgeInfo)
|
||||
require.ErrorIs(t, err, ErrEdgeAlreadyExist)
|
||||
|
||||
// Ensure that both policies are returned as unknown (nil).
|
||||
_, e1, e2, err := graph.FetchChannelEdgesByID(chanID)
|
||||
// Ensure that both policies are returned as unknown (nil) and that
|
||||
// the edge info round-trips correctly.
|
||||
dbEdge, e1, e2, err := graph.FetchChannelEdgesByID(chanID)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, e1)
|
||||
require.Nil(t, e2)
|
||||
|
||||
// Verify core fields match.
|
||||
require.Equal(t, edgeInfo.ChannelID, dbEdge.ChannelID)
|
||||
require.Equal(t, edgeInfo.Version, dbEdge.Version)
|
||||
require.Equal(t, edgeInfo.NodeKey1Bytes, dbEdge.NodeKey1Bytes)
|
||||
require.Equal(t, edgeInfo.NodeKey2Bytes, dbEdge.NodeKey2Bytes)
|
||||
require.Equal(t, edgeInfo.ChainHash, dbEdge.ChainHash)
|
||||
require.Equal(t, edgeInfo.ChannelPoint, dbEdge.ChannelPoint)
|
||||
require.Equal(t, edgeInfo.Capacity, dbEdge.Capacity)
|
||||
|
||||
// Verify auth proof round-trips.
|
||||
require.NotNil(t, dbEdge.AuthProof)
|
||||
require.Equal(t, edgeInfo.AuthProof.Version, dbEdge.AuthProof.Version)
|
||||
|
||||
// Verify version-specific fields.
|
||||
switch v {
|
||||
case lnwire.GossipVersion1:
|
||||
require.Equal(t,
|
||||
edgeInfo.BitcoinKey1Bytes, dbEdge.BitcoinKey1Bytes,
|
||||
)
|
||||
require.Equal(t,
|
||||
edgeInfo.BitcoinKey2Bytes, dbEdge.BitcoinKey2Bytes,
|
||||
)
|
||||
require.Equal(t,
|
||||
edgeInfo.ExtraOpaqueData, dbEdge.ExtraOpaqueData,
|
||||
)
|
||||
|
||||
case lnwire.GossipVersion2:
|
||||
require.Equal(t,
|
||||
edgeInfo.BitcoinKey1Bytes, dbEdge.BitcoinKey1Bytes,
|
||||
)
|
||||
require.Equal(t,
|
||||
edgeInfo.BitcoinKey2Bytes, dbEdge.BitcoinKey2Bytes,
|
||||
)
|
||||
require.Equal(t,
|
||||
edgeInfo.MerkleRootHash, dbEdge.MerkleRootHash,
|
||||
)
|
||||
require.Equal(t,
|
||||
edgeInfo.FundingScript, dbEdge.FundingScript,
|
||||
)
|
||||
require.Equal(t,
|
||||
edgeInfo.ExtraSignedFields, dbEdge.ExtraSignedFields,
|
||||
)
|
||||
}
|
||||
|
||||
// Also verify fetching by outpoint returns the same data.
|
||||
dbEdge2, _, _, err := graph.FetchChannelEdgesByOutpoint(&outpoint)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, dbEdge.ChannelID, dbEdge2.ChannelID)
|
||||
|
||||
// Next, attempt to delete the edge from the database, again this
|
||||
// should proceed without any issues.
|
||||
require.NoError(t, graph.DeleteChannelEdges(false, true, chanID))
|
||||
assertNoEdge(t, graph, chanID)
|
||||
assertNoEdge(t, graph.ChannelGraph, chanID)
|
||||
|
||||
// Ensure that any query attempts to lookup the delete channel edge are
|
||||
// properly deleted.
|
||||
|
||||
@@ -314,7 +314,8 @@ type Store 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, error)
|
||||
IsZombieEdge(v lnwire.GossipVersion, chanID uint64) (bool, [33]byte,
|
||||
[33]byte, error)
|
||||
|
||||
// NumZombies returns the current number of zombie channels in the
|
||||
// graph.
|
||||
|
||||
@@ -4257,14 +4257,19 @@ 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,
|
||||
error) {
|
||||
func (c *KVStore) IsZombieEdge(v lnwire.GossipVersion,
|
||||
chanID uint64) (bool, [33]byte, [33]byte, error) {
|
||||
|
||||
var (
|
||||
isZombie bool
|
||||
pubKey1, pubKey2 [33]byte
|
||||
)
|
||||
|
||||
if v != lnwire.GossipVersion1 {
|
||||
return false, [33]byte{}, [33]byte{},
|
||||
ErrVersionNotSupportedForKVDB
|
||||
}
|
||||
|
||||
err := kvdb.View(c.db, func(tx kvdb.RTx) error {
|
||||
edges := tx.ReadBucket(edgeBucket)
|
||||
if edges == nil {
|
||||
|
||||
@@ -1824,8 +1824,8 @@ func (s *SQLStore) MarkEdgeLive(chanID uint64) error {
|
||||
// returned.
|
||||
//
|
||||
// NOTE: part of the Store interface.
|
||||
func (s *SQLStore) IsZombieEdge(chanID uint64) (bool, [33]byte, [33]byte,
|
||||
error) {
|
||||
func (s *SQLStore) IsZombieEdge(v lnwire.GossipVersion,
|
||||
chanID uint64) (bool, [33]byte, [33]byte, error) {
|
||||
|
||||
var (
|
||||
ctx = context.TODO()
|
||||
@@ -1834,11 +1834,16 @@ func (s *SQLStore) IsZombieEdge(chanID uint64) (bool, [33]byte, [33]byte,
|
||||
chanIDB = channelIDToBytes(chanID)
|
||||
)
|
||||
|
||||
if !isKnownGossipVersion(v) {
|
||||
return false, [33]byte{}, [33]byte{},
|
||||
fmt.Errorf("unsupported gossip version: %d", v)
|
||||
}
|
||||
|
||||
err := s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
||||
zombie, err := db.GetZombieChannel(
|
||||
ctx, sqlc.GetZombieChannelParams{
|
||||
Scid: chanIDB,
|
||||
Version: int16(lnwire.GossipVersion1),
|
||||
Version: int16(v),
|
||||
},
|
||||
)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
|
||||
Reference in new issue
Block a user