diff --git a/autopilot/prefattach_test.go b/autopilot/prefattach_test.go index a4026d73d..30ec7ffc6 100644 --- a/autopilot/prefattach_test.go +++ b/autopilot/prefattach_test.go @@ -12,6 +12,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg/chainhash" graphdb "github.com/lightningnetwork/lnd/graph/db" "github.com/lightningnetwork/lnd/graph/db/models" "github.com/lightningnetwork/lnd/lnwire" @@ -492,16 +493,20 @@ func (d *testDBGraph) addRandChannel(node1, node2 *btcec.PublicKey, } chanID := randChanID() - edge := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID.ToUint64(), - Capacity: capacity, - Features: lnwire.EmptyFeatureVector(), + nodeKey1 := route.NewVertex(lnNode1) + nodeKey2 := route.NewVertex(lnNode2) + btcKey1 := route.NewVertex(lnNode1) + btcKey2 := route.NewVertex(lnNode2) + edge, err := models.NewV1Channel( + chanID.ToUint64(), chainhash.Hash{}, nodeKey1, nodeKey2, + &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, models.WithCapacity(capacity), + ) + if err != nil { + return nil, nil, err } - copy(edge.NodeKey1Bytes[:], lnNode1.SerializeCompressed()) - copy(edge.NodeKey2Bytes[:], lnNode2.SerializeCompressed()) - copy(edge.BitcoinKey1Bytes[:], lnNode1.SerializeCompressed()) - copy(edge.BitcoinKey2Bytes[:], lnNode2.SerializeCompressed()) if err := d.db.AddChannelEdge(ctx, edge); err != nil { return nil, nil, err diff --git a/discovery/gossiper.go b/discovery/gossiper.go index 2cbd4e873..b26435c56 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -2818,19 +2818,26 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(ctx context.Context, // With the proof validated (if necessary), we can now store it within // the database for our path finding and syncing needs. - edge := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: scid.ToUint64(), - ChainHash: ann.ChainHash, - NodeKey1Bytes: ann.NodeID1, - NodeKey2Bytes: ann.NodeID2, - BitcoinKey1Bytes: ann.BitcoinKey1, - BitcoinKey2Bytes: ann.BitcoinKey2, - AuthProof: proof, - Features: lnwire.NewFeatureVector( - ann.Features, lnwire.Features, - ), - ExtraOpaqueData: ann.ExtraOpaqueData, + edge, err := models.NewV1Channel( + scid.ToUint64(), ann.ChainHash, ann.NodeID1, ann.NodeID2, + &models.ChannelV1Fields{ + BitcoinKey1Bytes: ann.BitcoinKey1, + BitcoinKey2Bytes: ann.BitcoinKey2, + ExtraOpaqueData: ann.ExtraOpaqueData, + }, + models.WithChanProof(proof), models.WithFeatures(ann.Features), + ) + if err != nil { + key := newRejectCacheKey( + ann.GossipVersion(), + scid.ToUint64(), + sourceToPub(nMsg.source), + ) + _, _ = d.recentRejects.Put(key, &cachedReject{}) + + log.Errorf("unable to create channel edge: %v", err) + nMsg.err <- err + return nil, false } // If there were any optional message fields provided, we'll include diff --git a/discovery/gossiper_test.go b/discovery/gossiper_test.go index efb7307da..b1231b0e3 100644 --- a/discovery/gossiper_test.go +++ b/discovery/gossiper_test.go @@ -272,11 +272,15 @@ func (r *mockGraphSource) GetChannelByID(chanID lnwire.ShortChannelID) ( return nil, nil, nil, graphdb.ErrEdgeNotFound } - return &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - NodeKey1Bytes: pubKeys[0], - NodeKey2Bytes: pubKeys[1], - }, nil, nil, graphdb.ErrZombieEdge + zombieEdge, err := models.NewV1Channel( + 0, chainhash.Hash{}, pubKeys[0], pubKeys[1], + &models.ChannelV1Fields{}, + ) + if err != nil { + return nil, nil, nil, err + } + + return zombieEdge, nil, nil, graphdb.ErrZombieEdge } edges := r.edges[chanID.ToUint64()] diff --git a/graph/builder_test.go b/graph/builder_test.go index f2648a002..25b2d28b1 100644 --- a/graph/builder_test.go +++ b/graph/builder_test.go @@ -17,10 +17,10 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/chainntnfs" - "github.com/lightningnetwork/lnd/fn/v2" graphdb "github.com/lightningnetwork/lnd/graph/db" "github.com/lightningnetwork/lnd/graph/db/models" "github.com/lightningnetwork/lnd/htlcswitch" @@ -65,18 +65,17 @@ func TestAddProof(t *testing.T) { ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight) // After utxo was recreated adding the edge without the proof. - edge := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID.ToUint64(), - NodeKey1Bytes: node1.PubKeyBytes, - NodeKey2Bytes: node2.PubKeyBytes, - AuthProof: nil, - Features: lnwire.EmptyFeatureVector(), - FundingScript: fn.Some(script), - } - copy(edge.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed()) - copy(edge.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed()) + btcKey1 := route.NewVertex(bitcoinKey1) + btcKey2 := route.NewVertex(bitcoinKey2) + edge, err := models.NewV1Channel( + chanID.ToUint64(), *chaincfg.SimNetParams.GenesisHash, + node1.PubKeyBytes, node2.PubKeyBytes, &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, models.WithFundingScript(script), + ) + require.NoError(t, err) require.NoError(t, ctx.builder.AddEdge(ctxb, edge)) // Now we'll attempt to update the proof and check that it has been @@ -152,17 +151,20 @@ func TestIgnoreChannelEdgePolicyForUnknownChannel(t *testing.T) { } ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight) - edge := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID.ToUint64(), - NodeKey1Bytes: pub1, - NodeKey2Bytes: pub2, - BitcoinKey1Bytes: pub1, - BitcoinKey2Bytes: pub2, - AuthProof: nil, - Features: lnwire.EmptyFeatureVector(), - FundingScript: fn.Some(script), - } + pub1Vertex, err := route.NewVertexFromBytes(pub1[:]) + require.NoError(t, err) + pub2Vertex, err := route.NewVertexFromBytes(pub2[:]) + require.NoError(t, err) + + edge, err := models.NewV1Channel( + chanID.ToUint64(), *chaincfg.SimNetParams.GenesisHash, + pub1Vertex, pub2Vertex, &models.ChannelV1Fields{ + BitcoinKey1Bytes: pub1Vertex, + BitcoinKey2Bytes: pub2Vertex, + }, models.WithFundingScript(script), + ) + require.NoError(t, err) + edgePolicy := &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), ChannelID: edge.ChannelID, @@ -274,43 +276,42 @@ func TestWakeUpOnStaleBranch(t *testing.T) { node1 := createTestNode(t) node2 := createTestNode(t) - edge1 := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID1, - NodeKey1Bytes: node1.PubKeyBytes, - NodeKey2Bytes: node2.PubKeyBytes, - AuthProof: models.NewV1ChannelAuthProof( - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - ), - Features: lnwire.EmptyFeatureVector(), - FundingScript: fn.Some(fundingScript1), - } - copy(edge1.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed()) - copy(edge1.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed()) + btcKey1, err := route.NewVertexFromBytes( + bitcoinKey1.SerializeCompressed(), + ) + require.NoError(t, err) + btcKey2, err := route.NewVertexFromBytes( + bitcoinKey2.SerializeCompressed(), + ) + require.NoError(t, err) + + edge1, err := models.NewV1Channel( + chanID1, *chaincfg.SimNetParams.GenesisHash, + node1.PubKeyBytes, node2.PubKeyBytes, &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, models.WithChanProof(models.NewV1ChannelAuthProof( + testSig.Serialize(), testSig.Serialize(), + testSig.Serialize(), testSig.Serialize(), + )), models.WithFundingScript(fundingScript1), + ) + require.NoError(t, err) if err := ctx.builder.AddEdge(ctxb, edge1); err != nil { t.Fatalf("unable to add edge: %v", err) } - edge2 := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID2, - NodeKey1Bytes: node1.PubKeyBytes, - NodeKey2Bytes: node2.PubKeyBytes, - AuthProof: models.NewV1ChannelAuthProof( - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - ), - Features: lnwire.EmptyFeatureVector(), - FundingScript: fn.Some(fundingScript2), - } - copy(edge2.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed()) - copy(edge2.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed()) + edge2, err := models.NewV1Channel( + chanID2, *chaincfg.SimNetParams.GenesisHash, node1.PubKeyBytes, + node2.PubKeyBytes, &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, models.WithChanProof(models.NewV1ChannelAuthProof( + testSig.Serialize(), testSig.Serialize(), + testSig.Serialize(), testSig.Serialize(), + )), models.WithFundingScript(fundingScript2), + ) + require.NoError(t, err) if err := ctx.builder.AddEdge(ctxb, edge2); err != nil { t.Fatalf("unable to add edge: %v", err) @@ -486,47 +487,39 @@ func TestDisconnectedBlocks(t *testing.T) { node1 := createTestNode(t) node2 := createTestNode(t) - edge1 := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID1, - NodeKey1Bytes: node1.PubKeyBytes, - NodeKey2Bytes: node2.PubKeyBytes, - BitcoinKey1Bytes: node1.PubKeyBytes, - BitcoinKey2Bytes: node2.PubKeyBytes, - AuthProof: models.NewV1ChannelAuthProof( - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - ), - Features: lnwire.EmptyFeatureVector(), - FundingScript: fn.Some([]byte{}), - } - copy(edge1.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed()) - copy(edge1.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed()) + btcKey1 := route.NewVertex(bitcoinKey1) + btcKey2 := route.NewVertex(bitcoinKey2) + + proof := models.NewV1ChannelAuthProof( + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + ) + + edge1, err := models.NewV1Channel( + chanID1, *chaincfg.SimNetParams.GenesisHash, node1.PubKeyBytes, + node2.PubKeyBytes, &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, models.WithChanProof(proof), + models.WithFundingScript([]byte{}), + ) + require.NoError(t, err) if err := ctx.builder.AddEdge(ctxb, edge1); err != nil { t.Fatalf("unable to add edge: %v", err) } - edge2 := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID2, - NodeKey1Bytes: node1.PubKeyBytes, - NodeKey2Bytes: node2.PubKeyBytes, - BitcoinKey1Bytes: node1.PubKeyBytes, - BitcoinKey2Bytes: node2.PubKeyBytes, - AuthProof: models.NewV1ChannelAuthProof( - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - ), - Features: lnwire.EmptyFeatureVector(), - FundingScript: fn.Some([]byte{}), - } - copy(edge2.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed()) - copy(edge2.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed()) + edge2, err := models.NewV1Channel( + chanID2, *chaincfg.SimNetParams.GenesisHash, node1.PubKeyBytes, + node2.PubKeyBytes, &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, models.WithChanProof(proof), + models.WithFundingScript([]byte{}), + ) + require.NoError(t, err) if err := ctx.builder.AddEdge(ctxb, edge2); err != nil { t.Fatalf("unable to add edge: %v", err) @@ -644,24 +637,28 @@ func TestChansClosedOfflinePruneGraph(t *testing.T) { node1 := createTestNode(t) node2 := createTestNode(t) - edge1 := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID1.ToUint64(), - NodeKey1Bytes: node1.PubKeyBytes, - NodeKey2Bytes: node2.PubKeyBytes, - AuthProof: models.NewV1ChannelAuthProof( - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - ), - ChannelPoint: *chanUTXO, - Capacity: chanValue, - Features: lnwire.EmptyFeatureVector(), - FundingScript: fn.Some(script), - } - copy(edge1.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed()) - copy(edge1.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed()) + btcKey1 := route.NewVertex(bitcoinKey1) + btcKey2 := route.NewVertex(bitcoinKey2) + + proof := models.NewV1ChannelAuthProof( + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + ) + + edge1, err := models.NewV1Channel( + chanID1.ToUint64(), *chaincfg.SimNetParams.GenesisHash, + node1.PubKeyBytes, node2.PubKeyBytes, &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, models.WithChanProof(proof), + models.WithCapacity(chanValue), + models.WithChannelPoint(*chanUTXO), + models.WithFundingScript(script), + ) + require.NoError(t, err) + if err := ctx.builder.AddEdge(ctxb, edge1); err != nil { t.Fatalf("unable to add edge: %v", err) } @@ -1068,17 +1065,15 @@ func TestIsStaleNode(t *testing.T) { } ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight) - edge := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID.ToUint64(), - NodeKey1Bytes: pub1, - NodeKey2Bytes: pub2, - BitcoinKey1Bytes: pub1, - BitcoinKey2Bytes: pub2, - AuthProof: nil, - Features: lnwire.EmptyFeatureVector(), - FundingScript: fn.Some(script), - } + edge, err := models.NewV1Channel( + chanID.ToUint64(), *chaincfg.SimNetParams.GenesisHash, + pub1, pub2, &models.ChannelV1Fields{ + BitcoinKey1Bytes: pub1, + BitcoinKey2Bytes: pub2, + }, models.WithFundingScript(script), + ) + require.NoError(t, err) + if err := ctx.builder.AddEdge(ctxb, edge); err != nil { t.Fatalf("unable to add edge: %v", err) } @@ -1149,17 +1144,16 @@ func TestIsKnownEdge(t *testing.T) { } ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight) - edge := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID.ToUint64(), - NodeKey1Bytes: pub1, - NodeKey2Bytes: pub2, - BitcoinKey1Bytes: pub1, - BitcoinKey2Bytes: pub2, - AuthProof: nil, - FundingScript: fn.Some(script), - Features: lnwire.EmptyFeatureVector(), - } + edge, err := models.NewV1Channel( + chanID.ToUint64(), *chaincfg.SimNetParams.GenesisHash, pub1, + pub2, &models.ChannelV1Fields{ + BitcoinKey1Bytes: pub1, + BitcoinKey2Bytes: pub2, + }, + models.WithFundingScript(script), + ) + require.NoError(t, err) + if err := ctx.builder.AddEdge(ctxb, edge); err != nil { t.Fatalf("unable to add edge: %v", err) } @@ -1210,17 +1204,15 @@ func TestIsStaleEdgePolicy(t *testing.T) { t.Fatalf("router failed to detect fresh edge policy") } - edge := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID.ToUint64(), - NodeKey1Bytes: pub1, - NodeKey2Bytes: pub2, - BitcoinKey1Bytes: pub1, - BitcoinKey2Bytes: pub2, - AuthProof: nil, - Features: lnwire.EmptyFeatureVector(), - FundingScript: fn.Some(script), - } + edge, err := models.NewV1Channel( + chanID.ToUint64(), *chaincfg.SimNetParams.GenesisHash, pub1, + pub2, &models.ChannelV1Fields{ + BitcoinKey1Bytes: pub1, + BitcoinKey2Bytes: pub2, + }, models.WithFundingScript(script), + ) + require.NoError(t, err) + if err := ctx.builder.AddEdge(ctxb, edge); err != nil { t.Fatalf("unable to add edge: %v", err) } @@ -1523,19 +1515,27 @@ func parseTestGraph(t *testing.T, useCache bool, path string) ( // We first insert the existence of the edge between the two // nodes. - edgeInfo := models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: edge.ChannelID, - AuthProof: &testAuthProof, - ChannelPoint: fundingPoint, - Capacity: btcutil.Amount(edge.Capacity), - Features: lnwire.EmptyFeatureVector(), - } + var node1Vertex, node2Vertex route.Vertex + copy(node1Vertex[:], node1Bytes) + copy(node2Vertex[:], node2Bytes) - copy(edgeInfo.NodeKey1Bytes[:], node1Bytes) - copy(edgeInfo.NodeKey2Bytes[:], node2Bytes) - copy(edgeInfo.BitcoinKey1Bytes[:], node1Bytes) - copy(edgeInfo.BitcoinKey2Bytes[:], node2Bytes) + var btcKey1, btcKey2 route.Vertex + copy(btcKey1[:], node1Bytes) + copy(btcKey2[:], node2Bytes) + + edgeInfo, err := models.NewV1Channel( + edge.ChannelID, *chaincfg.SimNetParams.GenesisHash, + node1Vertex, node2Vertex, &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, + models.WithChanProof(&testAuthProof), + models.WithChannelPoint(fundingPoint), + models.WithCapacity(btcutil.Amount(edge.Capacity)), + ) + if err != nil { + return nil, err + } shortID := lnwire.NewShortChanIDFromInt(edge.ChannelID) links[shortID] = &mockLink{ @@ -1544,7 +1544,7 @@ func parseTestGraph(t *testing.T, useCache bool, path string) ( ), } - err = graph.AddChannelEdge(ctx, &edgeInfo) + err = graph.AddChannelEdge(ctx, edgeInfo) if err != nil && !errors.Is(err, graphdb.ErrEdgeAlreadyExist) { return nil, err } @@ -1584,12 +1584,12 @@ func parseTestGraph(t *testing.T, useCache bool, path string) ( } // We also store the channel IDs info for each of the node. - node1Vertex, err := route.NewVertexFromBytes(node1Bytes) + node1Vertex, err = route.NewVertexFromBytes(node1Bytes) if err != nil { return nil, err } - node2Vertex, err := route.NewVertexFromBytes(node2Bytes) + node2Vertex, err = route.NewVertexFromBytes(node2Bytes) if err != nil { return nil, err } @@ -1895,21 +1895,21 @@ func createTestGraphFromChannels(t *testing.T, useCache bool, // We first insert the existence of the edge between the two // nodes. - edgeInfo := models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: channelID, - AuthProof: &testAuthProof, - ChannelPoint: *fundingPoint, - Capacity: testChannel.Capacity, - - NodeKey1Bytes: node1Vertex, - BitcoinKey1Bytes: node1Vertex, - NodeKey2Bytes: node2Vertex, - BitcoinKey2Bytes: node2Vertex, - Features: lnwire.EmptyFeatureVector(), + edgeInfo, err := models.NewV1Channel( + channelID, *chaincfg.SimNetParams.GenesisHash, + node1Vertex, node2Vertex, &models.ChannelV1Fields{ + BitcoinKey1Bytes: node1Vertex, + BitcoinKey2Bytes: node2Vertex, + }, + models.WithChanProof(&testAuthProof), + models.WithChannelPoint(*fundingPoint), + models.WithCapacity(testChannel.Capacity), + ) + if err != nil { + return nil, err } - err = graph.AddChannelEdge(ctx, &edgeInfo) + err = graph.AddChannelEdge(ctx, edgeInfo) if err != nil && !errors.Is(err, graphdb.ErrEdgeAlreadyExist) { diff --git a/graph/db/channel_cache_test.go b/graph/db/channel_cache_test.go index 04f6d0331..27ff65432 100644 --- a/graph/db/channel_cache_test.go +++ b/graph/db/channel_cache_test.go @@ -4,8 +4,9 @@ import ( "reflect" "testing" + "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/lightningnetwork/lnd/graph/db/models" - "github.com/lightningnetwork/lnd/lnwire" + "github.com/lightningnetwork/lnd/routing/route" ) // TestChannelCache checks the behavior of the channelCache with respect to @@ -100,10 +101,14 @@ func assertHasChanEntries(t *testing.T, c *channelCache, start, end uint64) { // channelForInt generates a unique ChannelEdge given an integer. func channelForInt(i uint64) ChannelEdge { + info, err := models.NewV1Channel( + i, chainhash.Hash{}, route.Vertex{}, route.Vertex{}, + &models.ChannelV1Fields{}, + ) + if err != nil { + panic(err) + } return ChannelEdge{ - Info: &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: i, - }, + Info: info, } } diff --git a/graph/db/graph_test.go b/graph/db/graph_test.go index fcae25e8a..c9e703f4d 100644 --- a/graph/db/graph_test.go +++ b/graph/db/graph_test.go @@ -379,7 +379,7 @@ func TestPartialNode(t *testing.T) { // Create an edge attached to these nodes and add it to the graph. edgeInfo, _ := createEdge(140, 0, 0, 0, &node1, &node2) - require.NoError(t, graph.AddChannelEdge(ctx, &edgeInfo)) + require.NoError(t, graph.AddChannelEdge(ctx, edgeInfo)) // Both of the nodes should now be in both the graph (as partial/shell) // nodes _and_ the cache should also have an awareness of both nodes. @@ -562,31 +562,50 @@ func TestEdgeInsertionDeletion(t *testing.T) { require.NoError(t, err, "unable to generate node key") node2Pub, err := node2.PubKey() require.NoError(t, err, "unable to generate node key") - edgeInfo := models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID, - ChainHash: *chaincfg.MainNetParams.GenesisHash, - AuthProof: models.NewV1ChannelAuthProof( - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - ), - Features: lnwire.EmptyFeatureVector(), - ChannelPoint: outpoint, - Capacity: 9000, - } - copy(edgeInfo.NodeKey1Bytes[:], node1Pub.SerializeCompressed()) - copy(edgeInfo.NodeKey2Bytes[:], node2Pub.SerializeCompressed()) - copy(edgeInfo.BitcoinKey1Bytes[:], node1Pub.SerializeCompressed()) - copy(edgeInfo.BitcoinKey2Bytes[:], node2Pub.SerializeCompressed()) - require.NoError(t, graph.AddChannelEdge(ctx, &edgeInfo)) - assertEdgeWithNoPoliciesInCache(t, graph, &edgeInfo) + 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) // 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). @@ -623,7 +642,7 @@ func TestEdgeInsertionDeletion(t *testing.T) { } func createEdge(height, txIndex uint32, txPosition uint16, outPointIndex uint32, - node1, node2 *models.Node) (models.ChannelEdgeInfo, + node1, node2 *models.Node) (*models.ChannelEdgeInfo, lnwire.ShortChannelID) { shortChanID := lnwire.ShortChannelID{ @@ -638,26 +657,37 @@ func createEdge(height, txIndex uint32, txPosition uint16, outPointIndex uint32, node1Pub, _ := node1.PubKey() node2Pub, _ := node2.PubKey() - edgeInfo := models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: shortChanID.ToUint64(), - ChainHash: *chaincfg.MainNetParams.GenesisHash, - AuthProof: models.NewV1ChannelAuthProof( - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - ), - ChannelPoint: outpoint, - Capacity: 9000, - ExtraOpaqueData: make([]byte, 0), - Features: lnwire.EmptyFeatureVector(), - } - copy(edgeInfo.NodeKey1Bytes[:], node1Pub.SerializeCompressed()) - copy(edgeInfo.NodeKey2Bytes[:], node2Pub.SerializeCompressed()) - copy(edgeInfo.BitcoinKey1Bytes[:], node1Pub.SerializeCompressed()) - copy(edgeInfo.BitcoinKey2Bytes[:], node2Pub.SerializeCompressed()) + node1Vertex, _ := route.NewVertexFromBytes( + node1Pub.SerializeCompressed(), + ) + node2Vertex, _ := route.NewVertexFromBytes( + node2Pub.SerializeCompressed(), + ) + btcKey1, _ := route.NewVertexFromBytes( + node1Pub.SerializeCompressed(), + ) + btcKey2, _ := route.NewVertexFromBytes( + node2Pub.SerializeCompressed(), + ) + + proof := models.NewV1ChannelAuthProof( + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + ) + + edgeInfo, _ := models.NewV1Channel( + shortChanID.ToUint64(), *chaincfg.MainNetParams.GenesisHash, + node1Vertex, node2Vertex, &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + ExtraOpaqueData: make([]byte, 0), + }, + models.WithChanProof(proof), models.WithChannelPoint(outpoint), + models.WithCapacity(9000), + ) return edgeInfo, shortChanID } @@ -716,20 +746,20 @@ func TestDisconnectBlockAtHeight(t *testing.T) { edgeInfo3, _ := createEdge(height-1, 0, 0, 2, node1, node2) // Now add all these new edges to the database. - if err := graph.AddChannelEdge(ctx, &edgeInfo); err != nil { + if err := graph.AddChannelEdge(ctx, edgeInfo); err != nil { t.Fatalf("unable to create channel edge: %v", err) } - if err := graph.AddChannelEdge(ctx, &edgeInfo2); err != nil { + if err := graph.AddChannelEdge(ctx, edgeInfo2); err != nil { t.Fatalf("unable to create channel edge: %v", err) } - if err := graph.AddChannelEdge(ctx, &edgeInfo3); err != nil { + if err := graph.AddChannelEdge(ctx, edgeInfo3); err != nil { t.Fatalf("unable to create channel edge: %v", err) } - assertEdgeWithNoPoliciesInCache(t, graph, &edgeInfo) - assertEdgeWithNoPoliciesInCache(t, graph, &edgeInfo2) - assertEdgeWithNoPoliciesInCache(t, graph, &edgeInfo3) + assertEdgeWithNoPoliciesInCache(t, graph, edgeInfo) + assertEdgeWithNoPoliciesInCache(t, graph, edgeInfo2) + assertEdgeWithNoPoliciesInCache(t, graph, edgeInfo3) // Call DisconnectBlockAtHeight, which should prune every channel // that has a funding height of 'height' or greater. @@ -739,7 +769,7 @@ func TestDisconnectBlockAtHeight(t *testing.T) { } assertNoEdge(t, graph, edgeInfo.ChannelID) assertNoEdge(t, graph, edgeInfo2.ChannelID) - assertEdgeWithNoPoliciesInCache(t, graph, &edgeInfo3) + assertEdgeWithNoPoliciesInCache(t, graph, edgeInfo3) // The two edges should have been removed. if len(removed) != 2 { @@ -898,35 +928,50 @@ func createChannelEdge(node1, node2 *models.Node, // Add the new edge to the database, this should proceed without any // errors. - edgeInfo := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID, - ChainHash: *chaincfg.MainNetParams.GenesisHash, - ChannelPoint: outpoint, - Capacity: 1000, - ExtraOpaqueData: []byte{ - 1, 1, 1, - 2, 2, 2, 2, - 3, 3, 3, 3, 3, - }, - Features: lnwire.EmptyFeatureVector(), - } - copy(edgeInfo.NodeKey1Bytes[:], firstNode[:]) - copy(edgeInfo.NodeKey2Bytes[:], secondNode[:]) - copy(edgeInfo.BitcoinKey1Bytes[:], firstNode[:]) - copy(edgeInfo.BitcoinKey2Bytes[:], secondNode[:]) + var node1Key, node2Key route.Vertex + copy(node1Key[:], firstNode[:]) + copy(node2Key[:], secondNode[:]) + extraData := []byte{ + 1, 1, 1, + 2, 2, 2, 2, + 3, 3, 3, 3, 3, + } + + var edgeInfo *models.ChannelEdgeInfo if opts.skipProofs { + edgeInfo, _ = models.NewV1Channel( + chanID, *chaincfg.MainNetParams.GenesisHash, node1Key, + node2Key, &models.ChannelV1Fields{ + BitcoinKey1Bytes: node1Key, + BitcoinKey2Bytes: node2Key, + ExtraOpaqueData: extraData, + }, models.WithChannelPoint(outpoint), + models.WithCapacity(1000), + ) + return edgeInfo, nil, nil } - edgeInfo.AuthProof = models.NewV1ChannelAuthProof( + proof := models.NewV1ChannelAuthProof( testSig.Serialize(), testSig.Serialize(), testSig.Serialize(), testSig.Serialize(), ) + edgeInfo, _ = models.NewV1Channel( + chanID, *chaincfg.MainNetParams.GenesisHash, node1Key, node2Key, + &models.ChannelV1Fields{ + BitcoinKey1Bytes: node1Key, + BitcoinKey2Bytes: node2Key, + ExtraOpaqueData: extraData, + }, + models.WithChanProof(proof), + models.WithChannelPoint(outpoint), + models.WithCapacity(1000), + ) + edge1 := &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), ChannelID: chanID, @@ -1780,25 +1825,29 @@ func fillTestGraph(t testing.TB, graph *ChannelGraph, numNodes, Index: 0, } - edgeInfo := models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID, - ChainHash: *chaincfg.MainNetParams.GenesisHash, - AuthProof: models.NewV1ChannelAuthProof( - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - ), - Features: lnwire.EmptyFeatureVector(), - ChannelPoint: op, - Capacity: 1000, - } - copy(edgeInfo.NodeKey1Bytes[:], node1.PubKeyBytes[:]) - copy(edgeInfo.NodeKey2Bytes[:], node2.PubKeyBytes[:]) - copy(edgeInfo.BitcoinKey1Bytes[:], node1.PubKeyBytes[:]) - copy(edgeInfo.BitcoinKey2Bytes[:], node2.PubKeyBytes[:]) - err := graph.AddChannelEdge(ctx, &edgeInfo) + var node1Key, node2Key route.Vertex + copy(node1Key[:], node1.PubKeyBytes[:]) + copy(node2Key[:], node2.PubKeyBytes[:]) + + proof := models.NewV1ChannelAuthProof( + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + ) + + edgeInfo, err := models.NewV1Channel( + chanID, *chaincfg.MainNetParams.GenesisHash, + node1Key, node2Key, &models.ChannelV1Fields{ + BitcoinKey1Bytes: node1Key, + BitcoinKey2Bytes: node2Key, + }, + models.WithChanProof(proof), + models.WithChannelPoint(op), + models.WithCapacity(1000), + ) + require.NoError(t, err) + err = graph.AddChannelEdge(ctx, edgeInfo) require.NoError(t, err) // Create and add an edge with random data that points @@ -1963,28 +2012,31 @@ func TestGraphPruning(t *testing.T) { channelPoints = append(channelPoints, &op) - edgeInfo := models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID, - ChainHash: *chaincfg.MainNetParams.GenesisHash, - AuthProof: models.NewV1ChannelAuthProof( - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - ), - Features: lnwire.EmptyFeatureVector(), - ChannelPoint: op, - Capacity: 1000, - } - copy(edgeInfo.NodeKey1Bytes[:], graphNodes[i].PubKeyBytes[:]) - copy(edgeInfo.NodeKey2Bytes[:], graphNodes[i+1].PubKeyBytes[:]) - copy(edgeInfo.BitcoinKey1Bytes[:], graphNodes[i].PubKeyBytes[:]) - copy( - edgeInfo.BitcoinKey2Bytes[:], - graphNodes[i+1].PubKeyBytes[:], + var node1Key, node2Key route.Vertex + copy(node1Key[:], graphNodes[i].PubKeyBytes[:]) + copy(node2Key[:], graphNodes[i+1].PubKeyBytes[:]) + + proof := models.NewV1ChannelAuthProof( + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), ) - if err := graph.AddChannelEdge(ctx, &edgeInfo); err != nil { + + edgeInfo, err := models.NewV1Channel( + chanID, *chaincfg.MainNetParams.GenesisHash, + node1Key, node2Key, &models.ChannelV1Fields{ + BitcoinKey1Bytes: node1Key, + BitcoinKey2Bytes: node2Key, + }, + models.WithChanProof(proof), + models.WithChannelPoint(op), + models.WithCapacity(1000), + ) + if err != nil { + t.Fatalf("unable to create edge: %v", err) + } + if err := graph.AddChannelEdge(ctx, edgeInfo); err != nil { t.Fatalf("unable to add node: %v", err) } @@ -2140,10 +2192,10 @@ func TestHighestChanID(t *testing.T) { edge1, _ := createEdge(10, 0, 0, 0, node1, node2) edge2, chanID2 := createEdge(100, 0, 0, 0, node1, node2) - if err := graph.AddChannelEdge(ctx, &edge1); err != nil { + if err := graph.AddChannelEdge(ctx, edge1); err != nil { t.Fatalf("unable to create channel edge: %v", err) } - if err := graph.AddChannelEdge(ctx, &edge2); err != nil { + if err := graph.AddChannelEdge(ctx, edge2); err != nil { t.Fatalf("unable to create channel edge: %v", err) } @@ -2160,7 +2212,7 @@ func TestHighestChanID(t *testing.T) { // If we add another edge, then the current best chan ID should be // updated as well. edge3, chanID3 := createEdge(1000, 0, 0, 0, node1, node2) - if err := graph.AddChannelEdge(ctx, &edge3); err != nil { + if err := graph.AddChannelEdge(ctx, edge3); err != nil { t.Fatalf("unable to create channel edge: %v", err) } bestID, err = graph.HighestChanID(ctx) @@ -2216,7 +2268,7 @@ func TestChanUpdatesInHorizon(t *testing.T) { uint32(i*10), 0, 0, 0, node1, node2, ) - if err := graph.AddChannelEdge(ctx, &channel); err != nil { + if err := graph.AddChannelEdge(ctx, channel); err != nil { t.Fatalf("unable to create channel edge: %v", err) } @@ -2245,7 +2297,7 @@ func TestChanUpdatesInHorizon(t *testing.T) { } edges = append(edges, ChannelEdge{ - Info: &channel, + Info: channel, Policy1: edge1, Policy2: edge2, }) @@ -2683,7 +2735,7 @@ func TestChanUpdatesInHorizonBoundaryConditions(t *testing.T) { uint32(i*10), 0, 0, 0, node1, node2, ) require.NoError( - t, graph.AddChannelEdge(ctx, &channel), + t, graph.AddChannelEdge(ctx, channel), ) edge1 := newEdgePolicy( @@ -2851,7 +2903,7 @@ func TestFilterKnownChanIDs(t *testing.T) { uint32(i*10), 0, 0, 0, node1, node2, ) - if err := graph.AddChannelEdge(ctx, &channel); err != nil { + if err := graph.AddChannelEdge(ctx, channel); err != nil { t.Fatalf("unable to create channel edge: %v", err) } @@ -2866,7 +2918,7 @@ func TestFilterKnownChanIDs(t *testing.T) { channel, chanID := createEdge( uint32(i*10+1), 0, 0, 0, node1, node2, ) - if err := graph.AddChannelEdge(ctx, &channel); err != nil { + if err := graph.AddChannelEdge(ctx, channel); err != nil { t.Fatalf("unable to create channel edge: %v", err) } err := graph.DeleteChannelEdges(false, true, channel.ChannelID) @@ -3027,7 +3079,7 @@ func TestStressTestChannelGraphAPI(t *testing.T) { ) newChan := &chanInfo{ - info: channel, + info: *channel, id: chanID, } chans = append(chans, newChan) @@ -3339,12 +3391,12 @@ func TestFilterChannelRange(t *testing.T) { channel1, chanID1 := createEdge( chanHeight, uint32(i+1), 0, 0, node1, node2, ) - require.NoError(t, graph.AddChannelEdge(ctx, &channel1)) + require.NoError(t, graph.AddChannelEdge(ctx, channel1)) channel2, chanID2 := createEdge( chanHeight, uint32(i+2), 0, 0, node1, node2, ) - require.NoError(t, graph.AddChannelEdge(ctx, &channel2)) + require.NoError(t, graph.AddChannelEdge(ctx, channel2)) chanInfo1 := NewChannelUpdateInfo( chanID1, time.Time{}, time.Time{}, @@ -3520,7 +3572,7 @@ func TestFetchChanInfos(t *testing.T) { uint32(i*10), 0, 0, 0, node1, node2, ) - if err := graph.AddChannelEdge(ctx, &channel); err != nil { + if err := graph.AddChannelEdge(ctx, channel); err != nil { t.Fatalf("unable to create channel edge: %v", err) } @@ -3544,7 +3596,7 @@ func TestFetchChanInfos(t *testing.T) { } edges = append(edges, ChannelEdge{ - Info: &channel, + Info: channel, Policy1: edge1, Policy2: edge2, }) @@ -3561,7 +3613,7 @@ func TestFetchChanInfos(t *testing.T) { zombieChan, zombieChanID := createEdge( 666, 0, 0, 0, node1, node2, ) - if err := graph.AddChannelEdge(ctx, &zombieChan); err != nil { + if err := graph.AddChannelEdge(ctx, zombieChan); err != nil { t.Fatalf("unable to create channel edge: %v", err) } err := graph.DeleteChannelEdges(false, true, zombieChan.ChannelID) @@ -3614,7 +3666,7 @@ func TestIncompleteChannelPolicies(t *testing.T) { uint32(0), 0, 0, 0, node1, node2, ) - if err := graph.AddChannelEdge(ctx, &channel); err != nil { + if err := graph.AddChannelEdge(ctx, channel); err != nil { t.Fatalf("unable to create channel edge: %v", err) } @@ -3718,7 +3770,7 @@ func TestChannelEdgePruningUpdateIndexDeletion(t *testing.T) { // With the two nodes created, we'll now create a random channel, as // well as two edges in the database with distinct update times. edgeInfo, chanID := createEdge(100, 0, 0, 0, node1, node2) - if err := graph.AddChannelEdge(ctx, &edgeInfo); err != nil { + if err := graph.AddChannelEdge(ctx, edgeInfo); err != nil { t.Fatalf("unable to add edge: %v", err) } @@ -3867,7 +3919,7 @@ func TestPruneGraphNodes(t *testing.T) { // We'll now add a new edge to the graph, but only actually advertise // the edge of *one* of the nodes. edgeInfo, chanID := createEdge(100, 0, 0, 0, node1, node2) - if err := graph.AddChannelEdge(ctx, &edgeInfo); err != nil { + if err := graph.AddChannelEdge(ctx, edgeInfo); err != nil { t.Fatalf("unable to add edge: %v", err) } @@ -3916,7 +3968,7 @@ func TestAddChannelEdgeShellNodes(t *testing.T) { // We'll now create an edge between the two nodes, as a result, node2 // should be inserted into the database as a shell node. edgeInfo, _ := createEdge(100, 0, 0, 0, node1, node2) - require.NoError(t, graph.AddChannelEdge(ctx, &edgeInfo)) + require.NoError(t, graph.AddChannelEdge(ctx, edgeInfo)) // Ensure that node1 was inserted as a full node, while node2 only has // a shell node present. @@ -3930,7 +3982,7 @@ func TestAddChannelEdgeShellNodes(t *testing.T) { // Show that attempting to add the channel again will result in an // error. - err = graph.AddChannelEdge(ctx, &edgeInfo) + err = graph.AddChannelEdge(ctx, edgeInfo) require.ErrorIs(t, err, ErrEdgeAlreadyExist) // Show that updating the shell node to a full node record works. @@ -4049,7 +4101,7 @@ func TestNodeIsPublic(t *testing.T) { // After creating all of our nodes and edges, we'll add them to each // participant's graph. nodes := []*models.Node{aliceNode, bobNode, carolNode} - edges := []*models.ChannelEdgeInfo{&aliceBobEdge, &bobCarolEdge} + edges := []*models.ChannelEdgeInfo{aliceBobEdge, bobCarolEdge} graphs := []*ChannelGraph{aliceGraph, bobGraph, carolGraph} for _, graph := range graphs { for _, node := range nodes { @@ -4131,7 +4183,7 @@ func TestNodeIsPublic(t *testing.T) { } bobCarolEdge.AuthProof = nil - if err := graph.AddChannelEdge(ctx, &bobCarolEdge); err != nil { + if err := graph.AddChannelEdge(ctx, bobCarolEdge); err != nil { t.Fatalf("unable to add edge: %v", err) } } @@ -4634,7 +4686,7 @@ func TestBatchedAddChannelEdge(t *testing.T) { // Create a third edge, this with a block height of 155. edgeInfo3, _ := createEdge(height-1, 0, 0, 2, node1, node2) - edges := []models.ChannelEdgeInfo{edgeInfo, edgeInfo2, edgeInfo3} + edges := []models.ChannelEdgeInfo{*edgeInfo, *edgeInfo2, *edgeInfo3} errChan := make(chan error, len(edges)) errTimeout := errors.New("timeout adding batched channel") diff --git a/graph/db/kv_store.go b/graph/db/kv_store.go index b137c6240..14185f11a 100644 --- a/graph/db/kv_store.go +++ b/graph/db/kv_store.go @@ -3950,11 +3950,14 @@ func (c *KVStore) FetchChannelEdgesByID(chanID uint64) ( // populate the edge info with the public keys of each // party as this is the only information we have about // it and return an error signaling so. - edgeInfo = &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - NodeKey1Bytes: pubKey1, - NodeKey2Bytes: pubKey2, + zombieEdge, err := models.NewV1Channel( + 0, chainhash.Hash{}, pubKey1, pubKey2, + &models.ChannelV1Fields{}, + ) + if err != nil { + return err } + edgeInfo = zombieEdge return ErrZombieEdge } diff --git a/graph/db/models/channel_edge_info.go b/graph/db/models/channel_edge_info.go index 4c783a6a9..7e872c5cd 100644 --- a/graph/db/models/channel_edge_info.go +++ b/graph/db/models/channel_edge_info.go @@ -76,6 +76,99 @@ type ChannelEdgeInfo struct { ExtraOpaqueData []byte } +// EdgeModifier is a functional option that modifies a ChannelEdgeInfo. +type EdgeModifier func(*ChannelEdgeInfo) + +// WithChannelPoint sets the channel point (funding outpoint) on the edge. +func WithChannelPoint(cp wire.OutPoint) EdgeModifier { + return func(e *ChannelEdgeInfo) { + e.ChannelPoint = cp + } +} + +// WithFeatures sets the feature vector on the edge. +func WithFeatures(f *lnwire.RawFeatureVector) EdgeModifier { + return func(e *ChannelEdgeInfo) { + e.Features = lnwire.NewFeatureVector(f, lnwire.Features) + } +} + +// WithCapacity sets the capacity on the edge. +func WithCapacity(c btcutil.Amount) EdgeModifier { + return func(e *ChannelEdgeInfo) { + e.Capacity = c + } +} + +// WithChanProof sets the authentication proof on the edge. +func WithChanProof(proof *ChannelAuthProof) EdgeModifier { + return func(e *ChannelEdgeInfo) { + e.AuthProof = proof + } +} + +// WithFundingScript sets the funding script on the edge. +func WithFundingScript(script []byte) EdgeModifier { + return func(e *ChannelEdgeInfo) { + e.FundingScript = fn.Some(script) + } +} + +// ChannelV1Fields contains the fields that are specific to v1 channel +// announcements. +type ChannelV1Fields struct { + // BitcoinKey1Bytes is the raw public key of the first node. + BitcoinKey1Bytes route.Vertex + + // BitcoinKey2Bytes is the raw public key of the second node. + BitcoinKey2Bytes route.Vertex + + // ExtraOpaqueData is the set of data that was appended to this + // message, some of which we may not actually know how to iterate or + // parse. By holding onto this data, we ensure that we're able to + // properly validate the set of signatures that cover these new fields, + // and ensure we're able to make upgrades to the network in a forwards + // compatible manner. + ExtraOpaqueData []byte +} + +// NewV1Channel creates a new ChannelEdgeInfo for a v1 channel announcement. +// It takes the required fields for all channels (chanID, chainHash, node keys) +// and v1-specific fields, along with optional modifiers for setting additional +// fields like capacity, channel point, features, and auth proof. +// +// The constructor validates that if an AuthProof is provided via modifiers, its +// version matches the channel version (v1). +func NewV1Channel(chanID uint64, chainHash chainhash.Hash, node1, + node2 route.Vertex, v1Fields *ChannelV1Fields, + opts ...EdgeModifier) (*ChannelEdgeInfo, error) { + + edge := &ChannelEdgeInfo{ + Version: lnwire.GossipVersion1, + NodeKey1Bytes: node1, + NodeKey2Bytes: node2, + BitcoinKey1Bytes: v1Fields.BitcoinKey1Bytes, + BitcoinKey2Bytes: v1Fields.BitcoinKey2Bytes, + ChannelID: chanID, + ChainHash: chainHash, + Features: lnwire.EmptyFeatureVector(), + ExtraOpaqueData: v1Fields.ExtraOpaqueData, + } + + for _, opt := range opts { + opt(edge) + } + + // Validate some fields after the options have been applied. + if edge.AuthProof != nil && edge.AuthProof.Version != edge.Version { + return nil, fmt.Errorf("channel auth proof version %d does "+ + "not match channel version %d", edge.AuthProof.Version, + edge.Version) + } + + return edge, nil +} + // NodeKey1 is the identity public key of the "first" node that was involved in // the creation of this channel. A node is considered "first" if the // lexicographical ordering the its serialized public key is "smaller" than diff --git a/graph/db/sql_store.go b/graph/db/sql_store.go index 253582669..0ef5855bf 100644 --- a/graph/db/sql_store.go +++ b/graph/db/sql_store.go @@ -2038,11 +2038,22 @@ func (s *SQLStore) FetchChannelEdgesByID(chanID uint64) ( // populate the edge info with the public keys of each // party as this is the only information we have about // it. - edge = &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, + node1, err := route.NewVertexFromBytes(zombie.NodeKey1) + if err != nil { + return err } - copy(edge.NodeKey1Bytes[:], zombie.NodeKey1) - copy(edge.NodeKey2Bytes[:], zombie.NodeKey2) + node2, err := route.NewVertexFromBytes(zombie.NodeKey2) + if err != nil { + return err + } + zombieEdge, err := models.NewV1Channel( + 0, chainhash.Hash{}, node1, node2, + &models.ChannelV1Fields{}, + ) + if err != nil { + return err + } + edge = zombieEdge return ErrZombieEdge } else if err != nil { @@ -4467,22 +4478,28 @@ func buildEdgeInfoWithBatchData(chain chainhash.Hash, recs = make([]byte, 0) } - var btcKey1, btcKey2 route.Vertex - copy(btcKey1[:], dbChan.BitcoinKey1) - copy(btcKey2[:], dbChan.BitcoinKey2) + btcKey1, err := route.NewVertexFromBytes(dbChan.BitcoinKey1) + if err != nil { + return nil, err + } + btcKey2, err := route.NewVertexFromBytes(dbChan.BitcoinKey2) + if err != nil { + return nil, err + } - channel := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChainHash: chain, - ChannelID: byteOrder.Uint64(dbChan.Scid), - NodeKey1Bytes: node1, - NodeKey2Bytes: node2, - BitcoinKey1Bytes: btcKey1, - BitcoinKey2Bytes: btcKey2, - ChannelPoint: *op, - Capacity: btcutil.Amount(dbChan.Capacity.Int64), - Features: fv, - ExtraOpaqueData: recs, + channel, err := models.NewV1Channel( + byteOrder.Uint64(dbChan.Scid), chain, node1, node2, + &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + ExtraOpaqueData: recs, + }, + models.WithChannelPoint(*op), + models.WithCapacity(btcutil.Amount(dbChan.Capacity.Int64)), + models.WithFeatures(fv.RawFeatureVector), + ) + if err != nil { + return nil, err } // We always set all the signatures at the same time, so we can diff --git a/graph/notifications_test.go b/graph/notifications_test.go index fab5b4ce6..b086fc562 100644 --- a/graph/notifications_test.go +++ b/graph/notifications_test.go @@ -14,6 +14,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/ecdsa" "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/chainntnfs" @@ -447,24 +448,27 @@ func TestEdgeUpdateNotification(t *testing.T) { // Finally, to conclude our test set up, we'll create a channel // update to announce the created channel between the two nodes. - edge := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID.ToUint64(), - NodeKey1Bytes: node1.PubKeyBytes, - NodeKey2Bytes: node2.PubKeyBytes, - AuthProof: models.NewV1ChannelAuthProof( - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - ), - Features: lnwire.EmptyFeatureVector(), - ChannelPoint: *chanPoint, - Capacity: chanValue, - FundingScript: fn.Some(script), - } - copy(edge.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed()) - copy(edge.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed()) + btcKey1 := route.NewVertex(bitcoinKey1) + btcKey2 := route.NewVertex(bitcoinKey2) + + proof := models.NewV1ChannelAuthProof( + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + ) + + edge, err := models.NewV1Channel( + chanID.ToUint64(), *chaincfg.SimNetParams.GenesisHash, + node1.PubKeyBytes, node2.PubKeyBytes, &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, models.WithChanProof(proof), + models.WithChannelPoint(*chanPoint), + models.WithCapacity(chanValue), + models.WithFundingScript(script), + ) + require.NoError(t, err) if err := ctx.builder.AddEdge(ctxb, edge); err != nil { t.Fatalf("unable to add edge: %v", err) @@ -642,22 +646,25 @@ func TestNodeUpdateNotification(t *testing.T) { testFeaturesBuf := new(bytes.Buffer) require.NoError(t, testFeatures.Encode(testFeaturesBuf)) - edge := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID.ToUint64(), - NodeKey1Bytes: node1.PubKeyBytes, - NodeKey2Bytes: node2.PubKeyBytes, - Features: lnwire.EmptyFeatureVector(), - AuthProof: models.NewV1ChannelAuthProof( - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - ), - FundingScript: fn.Some(script), - } - copy(edge.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed()) - copy(edge.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed()) + btcKey1 := route.NewVertex(bitcoinKey1) + btcKey2 := route.NewVertex(bitcoinKey2) + + proof := models.NewV1ChannelAuthProof( + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + ) + + edge, err := models.NewV1Channel( + chanID.ToUint64(), *chaincfg.SimNetParams.GenesisHash, + node1.PubKeyBytes, node2.PubKeyBytes, &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, models.WithChanProof(proof), + models.WithFundingScript(script), + ) + require.NoError(t, err) // Adding the edge will add the nodes to the graph, but with no info // except the pubkey known. @@ -829,24 +836,28 @@ func TestNotificationCancellation(t *testing.T) { // to the client. ntfnClient.Cancel() - edge := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID.ToUint64(), - NodeKey1Bytes: node1.PubKeyBytes, - NodeKey2Bytes: node2.PubKeyBytes, - AuthProof: models.NewV1ChannelAuthProof( - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - ), - Features: lnwire.EmptyFeatureVector(), - ChannelPoint: *chanPoint, - Capacity: chanValue, - FundingScript: fn.Some(script), - } - copy(edge.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed()) - copy(edge.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed()) + btcKey1 := route.NewVertex(bitcoinKey1) + btcKey2 := route.NewVertex(bitcoinKey2) + + proof := models.NewV1ChannelAuthProof( + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + ) + + edge, err := models.NewV1Channel( + chanID.ToUint64(), *chaincfg.SimNetParams.GenesisHash, + node1.PubKeyBytes, node2.PubKeyBytes, &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, models.WithChanProof(proof), + models.WithChannelPoint(*chanPoint), + models.WithCapacity(chanValue), + models.WithFundingScript(script), + ) + require.NoError(t, err) + if err := ctx.builder.AddEdge(ctxb, edge); err != nil { t.Fatalf("unable to add edge: %v", err) } @@ -906,24 +917,28 @@ func TestChannelCloseNotification(t *testing.T) { // Finally, to conclude our test set up, we'll create a channel // announcement to announce the created channel between the two nodes. - edge := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID.ToUint64(), - NodeKey1Bytes: node1.PubKeyBytes, - NodeKey2Bytes: node2.PubKeyBytes, - AuthProof: models.NewV1ChannelAuthProof( - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - testSig.Serialize(), - ), - Features: lnwire.EmptyFeatureVector(), - ChannelPoint: *chanUtxo, - Capacity: chanValue, - FundingScript: fn.Some(script), - } - copy(edge.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed()) - copy(edge.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed()) + btcKey1 := route.NewVertex(bitcoinKey1) + btcKey2 := route.NewVertex(bitcoinKey2) + + proof := models.NewV1ChannelAuthProof( + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + testSig.Serialize(), + ) + + edge, err := models.NewV1Channel( + chanID.ToUint64(), *chaincfg.SimNetParams.GenesisHash, + node1.PubKeyBytes, node2.PubKeyBytes, &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, models.WithChanProof(proof), + models.WithChannelPoint(*chanUtxo), + models.WithCapacity(chanValue), + models.WithFundingScript(script), + ) + require.NoError(t, err) + if err := ctx.builder.AddEdge(ctxb, edge); err != nil { t.Fatalf("unable to add edge: %v", err) } diff --git a/lnrpc/devrpc/dev_server.go b/lnrpc/devrpc/dev_server.go index 31db5fe0a..7dee1627a 100644 --- a/lnrpc/devrpc/dev_server.go +++ b/lnrpc/devrpc/dev_server.go @@ -224,7 +224,6 @@ func (s *Server) ImportGraph(ctx context.Context, // Obtain the pointer to the global singleton channel graph. graphDB := s.cfg.GraphDB - var err error for _, rpcNode := range graph.Nodes { pubKeyBytes, err := parsePubKey(rpcNode.PubKey) if err != nil { @@ -273,19 +272,12 @@ func (s *Server) ImportGraph(ctx context.Context, for _, rpcEdge := range graph.Edges { rpcEdge := rpcEdge - edge := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: rpcEdge.ChannelId, - ChainHash: *s.cfg.ActiveNetParams.GenesisHash, - Capacity: btcutil.Amount(rpcEdge.Capacity), - } - - edge.NodeKey1Bytes, err = parsePubKey(rpcEdge.Node1Pub) + node1, err := parsePubKey(rpcEdge.Node1Pub) if err != nil { return nil, err } - edge.NodeKey2Bytes, err = parsePubKey(rpcEdge.Node2Pub) + node2, err := parsePubKey(rpcEdge.Node2Pub) if err != nil { return nil, err } @@ -294,7 +286,16 @@ func (s *Server) ImportGraph(ctx context.Context, if err != nil { return nil, err } - edge.ChannelPoint = *channelPoint + + edge, err := models.NewV1Channel( + rpcEdge.ChannelId, *s.cfg.ActiveNetParams.GenesisHash, + node1, node2, &models.ChannelV1Fields{}, + models.WithCapacity(btcutil.Amount(rpcEdge.Capacity)), + models.WithChannelPoint(*channelPoint), + ) + if err != nil { + return nil, err + } if err := graphDB.AddChannelEdge(ctx, edge); err != nil { return nil, fmt.Errorf("unable to add edge %v: %w", diff --git a/lnrpc/invoicesrpc/addinvoice_test.go b/lnrpc/invoicesrpc/addinvoice_test.go index ceab2bec4..ca83f8bab 100644 --- a/lnrpc/invoicesrpc/addinvoice_test.go +++ b/lnrpc/invoicesrpc/addinvoice_test.go @@ -6,10 +6,12 @@ import ( "testing" "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/graph/db/models" "github.com/lightningnetwork/lnd/lnwire" + "github.com/lightningnetwork/lnd/routing/route" "github.com/lightningnetwork/lnd/zpay32" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -305,10 +307,16 @@ var shouldIncludeChannelTestCases = []struct { h.Mock.On( "FetchChannelEdgesByID", mock.Anything, ).Once().Return( - &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - NodeKey1Bytes: selectedPolicy, - }, + func() *models.ChannelEdgeInfo { + edge, err := models.NewV1Channel( + 0, chainhash.Hash{}, selectedPolicy, + route.Vertex{}, + &models.ChannelV1Fields{}, + ) + require.NoError(h.t, err) + + return edge + }(), &models.ChannelEdgePolicy{ FeeBaseMSat: 1000, FeeProportionalMillionths: 20, diff --git a/netann/chan_status_manager_test.go b/netann/chan_status_manager_test.go index 1ec7cea23..5265d317f 100644 --- a/netann/chan_status_manager_test.go +++ b/netann/chan_status_manager_test.go @@ -12,6 +12,7 @@ import ( "time" "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/channeldb" graphdb "github.com/lightningnetwork/lnd/graph/db" @@ -19,6 +20,7 @@ import ( "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/netann" + "github.com/lightningnetwork/lnd/routing/route" "github.com/stretchr/testify/require" ) @@ -100,12 +102,19 @@ func createEdgePolicies(t *testing.T, channel *channeldb.OpenChannel, // bit. dir2 |= lnwire.ChanUpdateDirection - return &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelPoint: channel.FundingOutpoint, - NodeKey1Bytes: pubkey1, - NodeKey2Bytes: pubkey2, - }, + pubkey1Vertex, err := route.NewVertexFromBytes(pubkey1[:]) + require.NoError(t, err) + pubkey2Vertex, err := route.NewVertexFromBytes(pubkey2[:]) + require.NoError(t, err) + + edgeInfo, err := models.NewV1Channel( + channel.ShortChanID().ToUint64(), chainhash.Hash{}, + pubkey1Vertex, pubkey2Vertex, &models.ChannelV1Fields{}, + models.WithChannelPoint(channel.FundingOutpoint), + ) + require.NoError(t, err) + + return edgeInfo, &models.ChannelEdgePolicy{ ChannelID: channel.ShortChanID().ToUint64(), ChannelFlags: dir1, diff --git a/netann/channel_announcement_test.go b/netann/channel_announcement_test.go index 02d1d5617..c46b90a9d 100644 --- a/netann/channel_announcement_test.go +++ b/netann/channel_announcement_test.go @@ -46,21 +46,19 @@ func TestCreateChanAnnouncement(t *testing.T) { expChanAnn.BitcoinSig1.ToSignatureBytes(), expChanAnn.BitcoinSig2.ToSignatureBytes(), ) - chanInfo := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChainHash: expChanAnn.ChainHash, - ChannelID: expChanAnn.ShortChannelID.ToUint64(), - ChannelPoint: wire.OutPoint{Index: 1}, - Capacity: btcutil.SatoshiPerBitcoin, - NodeKey1Bytes: key, - NodeKey2Bytes: key, - BitcoinKey1Bytes: key, - BitcoinKey2Bytes: key, - Features: lnwire.NewFeatureVector( - features, lnwire.Features, - ), - ExtraOpaqueData: expChanAnn.ExtraOpaqueData, - } + chanInfo, err := models.NewV1Channel( + expChanAnn.ShortChannelID.ToUint64(), expChanAnn.ChainHash, + key, key, &models.ChannelV1Fields{ + BitcoinKey1Bytes: key, + BitcoinKey2Bytes: key, + ExtraOpaqueData: expChanAnn.ExtraOpaqueData, + }, + models.WithChanProof(chanProof), + models.WithChannelPoint(wire.OutPoint{Index: 1}), + models.WithCapacity(btcutil.SatoshiPerBitcoin), + models.WithFeatures(features), + ) + require.NoError(t, err) chanAnn, _, _, err := CreateChanAnnouncement( chanProof, chanInfo, nil, nil, ) diff --git a/routing/localchans/manager.go b/routing/localchans/manager.go index f47e34a16..cc86d82cc 100644 --- a/routing/localchans/manager.go +++ b/routing/localchans/manager.go @@ -18,6 +18,7 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing" + "github.com/lightningnetwork/lnd/routing/route" ) // Manager manages the node's local channels. The only operation that is @@ -328,20 +329,36 @@ func (r *Manager) createEdge(channel *channeldb.OpenChannel, "script: %v", err) } - info := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: shortChanID.ToUint64(), - ChainHash: channel.ChainHash, - Features: lnwire.EmptyFeatureVector(), - Capacity: channel.Capacity, - ChannelPoint: channel.FundingOutpoint, - FundingScript: fn.Some(fundingScript), + nodeKey1, err := route.NewVertexFromBytes(nodeKey1Bytes) + if err != nil { + return nil, nil, err + } + nodeKey2, err := route.NewVertexFromBytes(nodeKey2Bytes) + if err != nil { + return nil, nil, err + } + bitcoinKey1, err := route.NewVertexFromBytes(bitcoinKey1Bytes) + if err != nil { + return nil, nil, err + } + bitcoinKey2, err := route.NewVertexFromBytes(bitcoinKey2Bytes) + if err != nil { + return nil, nil, err } - copy(info.NodeKey1Bytes[:], nodeKey1Bytes) - copy(info.NodeKey2Bytes[:], nodeKey2Bytes) - copy(info.BitcoinKey1Bytes[:], bitcoinKey1Bytes) - copy(info.BitcoinKey2Bytes[:], bitcoinKey2Bytes) + info, err := models.NewV1Channel( + shortChanID.ToUint64(), channel.ChainHash, nodeKey1, nodeKey2, + &models.ChannelV1Fields{ + BitcoinKey1Bytes: bitcoinKey1, + BitcoinKey2Bytes: bitcoinKey2, + }, + models.WithCapacity(channel.Capacity), + models.WithChannelPoint(channel.FundingOutpoint), + models.WithFundingScript(fundingScript), + ) + if err != nil { + return nil, nil, err + } // Construct a dummy channel edge policy with default values that will // be updated with the new values in the call to processChan below. diff --git a/routing/localchans/manager_test.go b/routing/localchans/manager_test.go index 108fe0a7a..6196330bd 100644 --- a/routing/localchans/manager_test.go +++ b/routing/localchans/manager_test.go @@ -13,13 +13,13 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/discovery" - "github.com/lightningnetwork/lnd/fn/v2" "github.com/lightningnetwork/lnd/funding" "github.com/lightningnetwork/lnd/graph/db/models" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing" + "github.com/lightningnetwork/lnd/routing/route" "github.com/stretchr/testify/require" ) @@ -211,11 +211,21 @@ func TestManager(t *testing.T) { newPolicy: newPolicy, channelSet: []channel{ { - edgeInfo: &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - Capacity: chanCap, - ChannelPoint: chanPointValid, - }, + //nolint:ll + edgeInfo: func() *models.ChannelEdgeInfo { + info, err := models.NewV1Channel( + 0, + chainhash.Hash{}, + route.Vertex{}, + route.Vertex{}, + &models.ChannelV1Fields{}, + models.WithCapacity(chanCap), + models.WithChannelPoint(chanPointValid), + ) + require.NoError(t, err) + + return info + }(), }, }, specifiedChanPoints: []wire.OutPoint{chanPointValid}, @@ -230,11 +240,21 @@ func TestManager(t *testing.T) { newPolicy: newPolicy, channelSet: []channel{ { - edgeInfo: &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - Capacity: chanCap, - ChannelPoint: chanPointValid, - }, + //nolint:ll + edgeInfo: func() *models.ChannelEdgeInfo { + info, err := models.NewV1Channel( + 0, + chainhash.Hash{}, + route.Vertex{}, + route.Vertex{}, + &models.ChannelV1Fields{}, + models.WithCapacity(chanCap), + models.WithChannelPoint(chanPointValid), + ) + require.NoError(t, err) + + return info + }(), }, }, specifiedChanPoints: []wire.OutPoint{}, @@ -249,11 +269,22 @@ func TestManager(t *testing.T) { newPolicy: newPolicy, channelSet: []channel{ { - edgeInfo: &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - Capacity: chanCap, - ChannelPoint: chanPointValid, - }, + //nolint:ll + edgeInfo: func() *models.ChannelEdgeInfo { + info, err := models.NewV1Channel( + 0, + chainhash.Hash{}, + route.Vertex{}, + route.Vertex{}, + &models.ChannelV1Fields{}, + models.WithCapacity(chanCap), + models.WithChannelPoint(chanPointValid), + ) + + require.NoError(t, err) + + return info + }(), }, }, specifiedChanPoints: []wire.OutPoint{chanPointMissing}, @@ -272,11 +303,22 @@ func TestManager(t *testing.T) { newPolicy: noMaxHtlcPolicy, channelSet: []channel{ { - edgeInfo: &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - Capacity: chanCap, - ChannelPoint: chanPointValid, - }, + //nolint:ll + edgeInfo: func() *models.ChannelEdgeInfo { + info, err := models.NewV1Channel( + 0, + chainhash.Hash{}, + route.Vertex{}, + route.Vertex{}, + &models.ChannelV1Fields{}, + models.WithCapacity(chanCap), + models.WithChannelPoint(chanPointValid), + ) + + require.NoError(t, err) + + return info + }(), }, }, specifiedChanPoints: []wire.OutPoint{chanPointValid}, @@ -395,23 +437,19 @@ func TestCreateEdgeLower(t *testing.T) { fundingScript, err := funding.MakeFundingScript(channel) require.NoError(t, err) - expectedInfo := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: 8, - ChainHash: channel.ChainHash, - Features: lnwire.EmptyFeatureVector(), - Capacity: 9, - ChannelPoint: channel.FundingOutpoint, - NodeKey1Bytes: sp, - NodeKey2Bytes: rp, - BitcoinKey1Bytes: [33]byte( - localMultisigKey.SerializeCompressed()), - BitcoinKey2Bytes: [33]byte( - remoteMultisigKey.SerializeCompressed()), - AuthProof: nil, - ExtraOpaqueData: nil, - FundingScript: fn.Some(fundingScript), - } + btcKey1 := route.NewVertex(localMultisigKey) + btcKey2 := route.NewVertex(remoteMultisigKey) + expectedInfo, err := models.NewV1Channel( + 8, channel.ChainHash, sp, rp, &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, + models.WithCapacity(9), + models.WithChannelPoint(channel.FundingOutpoint), + models.WithFundingScript(fundingScript), + ) + require.NoError(t, err) + expectedEdge := &models.ChannelEdgePolicy{ ChannelID: 8, LastUpdate: timestamp, @@ -489,23 +527,20 @@ func TestCreateEdgeHigher(t *testing.T) { fundingScript, err := funding.MakeFundingScript(channel) require.NoError(t, err) - expectedInfo := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: 8, - ChainHash: channel.ChainHash, - Features: lnwire.EmptyFeatureVector(), - Capacity: 9, - ChannelPoint: channel.FundingOutpoint, - NodeKey1Bytes: rp, - NodeKey2Bytes: sp, - BitcoinKey1Bytes: [33]byte( - remoteMultisigKey.SerializeCompressed()), - BitcoinKey2Bytes: [33]byte( - localMultisigKey.SerializeCompressed()), - AuthProof: nil, - ExtraOpaqueData: nil, - FundingScript: fn.Some(fundingScript), - } + btcKey1 := route.NewVertex(remoteMultisigKey) + btcKey2 := route.NewVertex(localMultisigKey) + expectedInfo, err := models.NewV1Channel( + 8, channel.ChainHash, rp, sp, + &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, + models.WithCapacity(9), + models.WithChannelPoint(channel.FundingOutpoint), + models.WithFundingScript(fundingScript), + ) + require.NoError(t, err) + expectedEdge := &models.ChannelEdgePolicy{ ChannelID: 8, LastUpdate: timestamp, diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index bbb31fdaf..ed291a6aa 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -19,6 +19,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/ecdsa" "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" sphinx "github.com/lightningnetwork/lightning-onion" @@ -345,19 +346,28 @@ func parseTestGraph(t *testing.T, useCache bool, path string) ( // We first insert the existence of the edge between the two // nodes. - edgeInfo := models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: edge.ChannelID, - AuthProof: &testAuthProof, - ChannelPoint: fundingPoint, - Features: lnwire.EmptyFeatureVector(), - Capacity: btcutil.Amount(edge.Capacity), - } + var node1Vertex, node2Vertex route.Vertex + copy(node1Vertex[:], node1Bytes) + copy(node2Vertex[:], node2Bytes) - copy(edgeInfo.NodeKey1Bytes[:], node1Bytes) - copy(edgeInfo.NodeKey2Bytes[:], node2Bytes) - copy(edgeInfo.BitcoinKey1Bytes[:], node1Bytes) - copy(edgeInfo.BitcoinKey2Bytes[:], node2Bytes) + var btcKey1, btcKey2 route.Vertex + copy(btcKey1[:], node1Bytes) + copy(btcKey2[:], node2Bytes) + + edgeInfo, err := models.NewV1Channel( + edge.ChannelID, *chaincfg.SimNetParams.GenesisHash, + node1Vertex, node2Vertex, + &models.ChannelV1Fields{ + BitcoinKey1Bytes: btcKey1, + BitcoinKey2Bytes: btcKey2, + }, + models.WithChanProof(&testAuthProof), + models.WithChannelPoint(fundingPoint), + models.WithCapacity(btcutil.Amount(edge.Capacity)), + ) + if err != nil { + return nil, err + } shortID := lnwire.NewShortChanIDFromInt(edge.ChannelID) links[shortID] = &mockLink{ @@ -366,7 +376,7 @@ func parseTestGraph(t *testing.T, useCache bool, path string) ( ), } - err = graph.AddChannelEdge(ctx, &edgeInfo) + err = graph.AddChannelEdge(ctx, edgeInfo) if err != nil && !errors.Is(err, graphdb.ErrEdgeAlreadyExist) { return nil, err } @@ -396,12 +406,12 @@ func parseTestGraph(t *testing.T, useCache bool, path string) ( } // We also store the channel IDs info for each of the node. - node1Vertex, err := route.NewVertexFromBytes(node1Bytes) + node1Vertex, err = route.NewVertexFromBytes(node1Bytes) if err != nil { return nil, err } - node2Vertex, err := route.NewVertexFromBytes(node2Bytes) + node2Vertex, err = route.NewVertexFromBytes(node2Bytes) if err != nil { return nil, err } @@ -678,21 +688,21 @@ func createTestGraphFromChannels(t *testing.T, useCache bool, // We first insert the existence of the edge between the two // nodes. - edgeInfo := models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: channelID, - AuthProof: &testAuthProof, - ChannelPoint: *fundingPoint, - Capacity: testChannel.Capacity, - Features: lnwire.EmptyFeatureVector(), - - NodeKey1Bytes: node1Vertex, - BitcoinKey1Bytes: node1Vertex, - NodeKey2Bytes: node2Vertex, - BitcoinKey2Bytes: node2Vertex, + edgeInfo, err := models.NewV1Channel( + channelID, *chaincfg.SimNetParams.GenesisHash, + node1Vertex, node2Vertex, &models.ChannelV1Fields{ + BitcoinKey1Bytes: node1Vertex, + BitcoinKey2Bytes: node2Vertex, + }, + models.WithChanProof(&testAuthProof), + models.WithChannelPoint(*fundingPoint), + models.WithCapacity(testChannel.Capacity), + ) + if err != nil { + return nil, err } - err = graph.AddChannelEdge(ctx, &edgeInfo) + err = graph.AddChannelEdge(ctx, edgeInfo) if err != nil && !errors.Is(err, graphdb.ErrEdgeAlreadyExist) { return nil, err } diff --git a/routing/router_test.go b/routing/router_test.go index bb0b2f85c..6f9d2c3f3 100644 --- a/routing/router_test.go +++ b/routing/router_test.go @@ -2738,16 +2738,14 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { ) require.NoError(t, err, "unable to create channel edge") - edge := &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID.ToUint64(), - NodeKey1Bytes: pub1, - NodeKey2Bytes: pub2, - BitcoinKey1Bytes: pub1, - BitcoinKey2Bytes: pub2, - Features: lnwire.EmptyFeatureVector(), - AuthProof: nil, - } + edge, err := models.NewV1Channel( + chanID.ToUint64(), chainhash.Hash{}, pub1, pub2, + &models.ChannelV1Fields{ + BitcoinKey1Bytes: pub1, + BitcoinKey2Bytes: pub2, + }, + ) + require.NoError(t, err) require.NoError(t, ctx.graph.AddChannelEdge(ctxb, edge)) // We must add the edge policy to be able to use the edge for route @@ -2819,16 +2817,17 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { 10000, 510) require.NoError(t, err, "unable to create channel edge") - edge = &models.ChannelEdgeInfo{ - Version: lnwire.GossipVersion1, - ChannelID: chanID.ToUint64(), - Features: lnwire.EmptyFeatureVector(), - AuthProof: nil, - } - copy(edge.NodeKey1Bytes[:], node1Bytes) - edge.NodeKey2Bytes = node2Bytes - copy(edge.BitcoinKey1Bytes[:], node1Bytes) - edge.BitcoinKey2Bytes = node2Bytes + node1Vertex, err := route.NewVertexFromBytes(node1Bytes) + require.NoError(t, err) + + edge, err = models.NewV1Channel( + chanID.ToUint64(), chainhash.Hash{}, node1Vertex, node2Bytes, + &models.ChannelV1Fields{ + BitcoinKey1Bytes: node1Vertex, + BitcoinKey2Bytes: node2Bytes, + }, + ) + require.NoError(t, err) require.NoError(t, ctx.graph.AddChannelEdge(ctxb, edge))