multi: add and use V1 constructor for models.ChannelEdgeInfo
What changed, and why it matters
This commit is a code-quality and safety refactor for LND's Lightning channel graph data structures. It introduces a single, controlled constructor for creating V1 channel records, replacing many places where fields were set by hand. The change makes it harder to accidentally create an invalid or inconsistent channel record, and adds a check that any attached proof matches the channel version. It is not an obvious security fix for an active vulnerability, but it reduces the risk of future bugs in how the network graph is built and validated.
Treat as a hardening/refactor commit. Review the new constructor's validation logic for completeness, ensure the AuthProof version check is exercised by tests, and verify that no production path can bypass the constructor to create an inconsistent ChannelEdgeInfo. No urgent patch or incident response is indicated by the supplied materials.
Security signals we found
New constructor centralizes validation of ChannelEdgeInfo creation
Added version-consistency check between AuthProof.Version and ChannelEdgeInfo.Version
Replaces scattered manual struct initialization, reducing risk of partially-initialized channel edges
No direct bug or CVE described in commit message or diff
Large refactor (+853/-575) across 18 files, mostly test updates
Evidence from the diff
The patch adds models.NewV1Channel() and a set of functional-option helpers (WithCapacity, WithChannelPoint, WithFeatures, WithChanProof, WithFundingScript) in graph/db/models/channel_edge_info.go. It then migrates production and test code from direct struct initialization of models.ChannelEdgeInfo to the constructor. The constructor enforces required fields (ChannelID, ChainHash, NodeKey1Bytes, NodeKey2Bytes) and V1-specific fields (BitcoinKey1Bytes, BitcoinKey2Bytes, ExtraOpaqueData), while making capacity, channel point, features, proof and funding script optional. A validation rule rejects an AuthProof whose version does not match the edge’s Version. The change touches the gossiper, graph stores (KV and SQL), dev RPC import, local channel manager, and many tests.
Changed components
graph/db/models/channel_edge_info.godiscovery/gossiper.gograph/db/kv_store.gograph/db/sql_store.golnrpc/devrpc/dev_server.gorouting/localchans/manager.goInspect captured patch +853 / −575
diff --git a/autopilot/prefattach_test.go b/autopilot/prefattach_test.go
index a4026d7..30ec7ff 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 2cbd4e8..b26435c 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 efb7307..b1231b0 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 f2648a0..25b2d28 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,20 +1515,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,
- Capacity: btcutil.Amount(edge.Capacity),
- Features: lnwire.EmptyFeatureVector(),
+ var node1Vertex, node2Vertex route.Vertex
+ copy(node1Vertex[:], node1Bytes)
+ copy(node2Vertex[:], 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
}
- copy(edgeInfo.NodeKey1Bytes[:], node1Bytes)
- copy(edgeInfo.NodeKey2Bytes[:], node2Bytes)
- copy(edgeInfo.BitcoinKey1Bytes[:], node1Bytes)
- copy(edgeInfo.BitcoinKey2Bytes[:], node2Bytes)
-
shortID := lnwire.NewShortChanIDFromInt(edge.ChannelID)
links[shortID] = &mockLink{
bandwidth: lnwire.MilliSatoshi(
@@ -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 04f6d03..27ff654 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 fcae25e..c9e703f 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(),
+ 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,
}
- copy(edgeInfo.NodeKey1Bytes[:], firstNode[:])
- copy(edgeInfo.NodeKey2Bytes[:], secondNode[:])
- copy(edgeInfo.BitcoinKey1Bytes[:], firstNode[:])
- copy(edgeInfo.BitcoinKey2Bytes[:], secondNode[:])
+ 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(),
+ )
+
+ 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 := graph.AddChannelEdge(ctx, &edgeInfo); err != nil {
+ 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 b137c62..14185f1 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 4c783a6..7e872c5 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 2535826..0ef5855 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
+ }
+ node2, err := route.NewVertexFromBytes(zombie.NodeKey2)
+ if err != nil {
+ return err
}
- copy(edge.NodeKey1Bytes[:], zombie.NodeKey1)
- copy(edge.NodeKey2Bytes[:], zombie.NodeKey2)
+ 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)
-
- 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,
+ 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, 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 fab5b4c..b086fc5 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 31db5fe..7dee162 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,28 +272,30 @@ 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),
+ node1, err := parsePubKey(rpcEdge.Node1Pub)
+ if err != nil {
+ return nil, err
}
- edge.NodeKey1Bytes, err = parsePubKey(rpcEdge.Node1Pub)
+ node2, err := parsePubKey(rpcEdge.Node2Pub)
if err != nil {
return nil, err
}
- edge.NodeKey2Bytes, err = parsePubKey(rpcEdge.Node2Pub)
+ channelPoint, err := parseOutPoint(rpcEdge.ChanPoint)
if err != nil {
return nil, err
}
- channelPoint, err := parseOutPoint(rpcEdge.ChanPoint)
+ 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
}
- edge.ChannelPoint = *channelPoint
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 ceab2be..ca83f8b 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 1ec7cea..5265d31 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 02d1d56..c46b90a 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 f47e34a..cc86d82 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 108fe0a..6196330 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 bbb31fd..ed291a6 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,20 +346,29 @@ 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)
+
+ 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
}
- copy(edgeInfo.NodeKey1Bytes[:], node1Bytes)
- copy(edgeInfo.NodeKey2Bytes[:], node2Bytes)
- copy(edgeInfo.BitcoinKey1Bytes[:], node1Bytes)
- copy(edgeInfo.BitcoinKey2Bytes[:], node2Bytes)
-
shortID := lnwire.NewShortChanIDFromInt(edge.ChannelID)
links[shortID] = &mockLink{
bandwidth: lnwire.MilliSatoshi(
@@ -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 bb0b2f8..6f9d2c3 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))
Why this scored 27/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.