From fa7c1e250bde76e8342dbf80817fe2af44599b31 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Mon, 23 Oct 2023 13:44:40 +0200 Subject: [PATCH 01/12] multi: let ForEachChannel be a method on ChannelGraph Having a `ForEachChannel` method on the `LightningNode` struct itself results in a `kvdb.Backend` object needing to be stored within the LightningNode struct. In this commit, this method is replaced with a `ForEachNodeChannel` method on the `ChannelGraph` struct will perform the same function without needing the db pointer to be stored within the LightningNode. This change, the LightningNode struct more closely represents the schema on disk. The existing `ForEachNodeChannel` method on `ChannelGraph` is renamed to `ForEachNodeDirectedChannel`. It performs a slightly different function since it's call-back operates on Cached policies. --- autopilot/graph.go | 54 ++++++++++++-------- channeldb/graph.go | 109 +++++++++++++++++++++------------------- channeldb/graph_test.go | 96 +++++++++++++++++++---------------- routing/graph.go | 2 +- routing/router.go | 19 ++++--- rpcserver.go | 96 +++++++++++++++++++---------------- server.go | 2 +- 7 files changed, 207 insertions(+), 171 deletions(-) diff --git a/autopilot/graph.go b/autopilot/graph.go index 0b062a535..89e03cbdd 100644 --- a/autopilot/graph.go +++ b/autopilot/graph.go @@ -53,6 +53,8 @@ func ChannelGraphFromDatabase(db *channeldb.ChannelGraph) ChannelGraph { // channeldb.LightningNode. The wrapper method implement the autopilot.Node // interface. type dbNode struct { + db *channeldb.ChannelGraph + tx kvdb.RTx node *channeldb.LightningNode @@ -86,31 +88,36 @@ func (d dbNode) Addrs() []net.Addr { // // NOTE: Part of the autopilot.Node interface. func (d dbNode) ForEachChannel(cb func(ChannelEdge) error) error { - return d.node.ForEachChannel(d.tx, func(tx kvdb.RTx, - ei *channeldb.ChannelEdgeInfo, ep, _ *channeldb.ChannelEdgePolicy) error { + return d.db.ForEachNodeChannel(d.tx, d.node.PubKeyBytes, + func(tx kvdb.RTx, ei *channeldb.ChannelEdgeInfo, ep, + _ *channeldb.ChannelEdgePolicy) error { - // Skip channels for which no outgoing edge policy is available. - // - // TODO(joostjager): Ideally the case where channels have a nil - // policy should be supported, as autopilot is not looking at - // the policies. For now, it is not easily possible to get a - // reference to the other end LightningNode object without - // retrieving the policy. - if ep == nil { - return nil - } + // Skip channels for which no outgoing edge policy is + // available. + // + // TODO(joostjager): Ideally the case where channels + // have a nil policy should be supported, as autopilot + // is not looking at the policies. For now, it is not + // easily possible to get a reference to the other end + // LightningNode object without retrieving the policy. + if ep == nil { + return nil + } - edge := ChannelEdge{ - ChanID: lnwire.NewShortChanIDFromInt(ep.ChannelID), - Capacity: ei.Capacity, - Peer: dbNode{ - tx: tx, - node: ep.Node, - }, - } + edge := ChannelEdge{ + ChanID: lnwire.NewShortChanIDFromInt( + ep.ChannelID, + ), + Capacity: ei.Capacity, + Peer: dbNode{ + tx: tx, + db: d.db, + node: ep.Node, + }, + } - return cb(edge) - }) + return cb(edge) + }) } // ForEachNode is a higher-order function that should be called once for each @@ -128,6 +135,7 @@ func (d *databaseChannelGraph) ForEachNode(cb func(Node) error) error { } node := dbNode{ + db: d.db, tx: tx, node: n, } @@ -266,6 +274,7 @@ func (d *databaseChannelGraph) addRandChannel(node1, node2 *btcec.PublicKey, ChanID: chanID, Capacity: capacity, Peer: dbNode{ + db: d.db, node: vertex1, }, }, @@ -273,6 +282,7 @@ func (d *databaseChannelGraph) addRandChannel(node1, node2 *btcec.PublicKey, ChanID: chanID, Capacity: capacity, Peer: dbNode{ + db: d.db, node: vertex2, }, }, diff --git a/channeldb/graph.go b/channeldb/graph.go index 8367aaf68..00be88d18 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -459,16 +459,14 @@ func (c *ChannelGraph) ForEachChannel(cb func(*ChannelEdgeInfo, }, func() {}) } -// ForEachNodeChannel iterates through all channels of a given node, executing the -// passed callback with an edge info structure and the policies of each end -// of the channel. The first edge policy is the outgoing edge *to* the -// connecting node, while the second is the incoming edge *from* the -// connecting node. If the callback returns an error, then the iteration is -// halted with the error propagated back up to the caller. +// ForEachNodeDirectedChannel iterates through all channels of a given node, +// executing the passed callback on the directed edge representing the channel +// and its incoming policy. If the callback returns an error, then the iteration +// is halted with the error propagated back up to the caller. // // Unknown policies are passed into the callback as nil values. -func (c *ChannelGraph) ForEachNodeChannel(tx kvdb.RTx, node route.Vertex, - cb func(channel *DirectedChannel) error) error { +func (c *ChannelGraph) ForEachNodeDirectedChannel(tx kvdb.RTx, + node route.Vertex, cb func(channel *DirectedChannel) error) error { if c.graphCache != nil { return c.graphCache.ForEachChannel(node, cb) @@ -557,44 +555,49 @@ func (c *ChannelGraph) ForEachNodeCached(cb func(node route.Vertex, return c.ForEachNode(func(tx kvdb.RTx, node *LightningNode) error { channels := make(map[uint64]*DirectedChannel) - err := node.ForEachChannel(tx, func(tx kvdb.RTx, - e *ChannelEdgeInfo, p1 *ChannelEdgePolicy, - p2 *ChannelEdgePolicy) error { + err := c.ForEachNodeChannel(tx, node.PubKeyBytes, + func(tx kvdb.RTx, e *ChannelEdgeInfo, + p1 *ChannelEdgePolicy, + p2 *ChannelEdgePolicy) error { - toNodeCallback := func() route.Vertex { - return node.PubKeyBytes - } - toNodeFeatures, err := c.FetchNodeFeatures( - node.PubKeyBytes, - ) - if err != nil { - return err - } + toNodeCallback := func() route.Vertex { + return node.PubKeyBytes + } + toNodeFeatures, err := c.FetchNodeFeatures( + node.PubKeyBytes, + ) + if err != nil { + return err + } - var cachedInPolicy *CachedEdgePolicy - if p2 != nil { - cachedInPolicy := NewCachedPolicy(p2) - cachedInPolicy.ToNodePubKey = toNodeCallback - cachedInPolicy.ToNodeFeatures = toNodeFeatures - } + var cachedInPolicy *CachedEdgePolicy + if p2 != nil { + cachedInPolicy := NewCachedPolicy(p2) + cachedInPolicy.ToNodePubKey = + toNodeCallback + cachedInPolicy.ToNodeFeatures = + toNodeFeatures + } - directedChannel := &DirectedChannel{ - ChannelID: e.ChannelID, - IsNode1: node.PubKeyBytes == e.NodeKey1Bytes, - OtherNode: e.NodeKey2Bytes, - Capacity: e.Capacity, - OutPolicySet: p1 != nil, - InPolicy: cachedInPolicy, - } + directedChannel := &DirectedChannel{ + ChannelID: e.ChannelID, + IsNode1: node.PubKeyBytes == + e.NodeKey1Bytes, + OtherNode: e.NodeKey2Bytes, + Capacity: e.Capacity, + OutPolicySet: p1 != nil, + InPolicy: cachedInPolicy, + } - if node.PubKeyBytes == e.NodeKey2Bytes { - directedChannel.OtherNode = e.NodeKey1Bytes - } + if node.PubKeyBytes == e.NodeKey2Bytes { + directedChannel.OtherNode = + e.NodeKey1Bytes + } - channels[e.ChannelID] = directedChannel + channels[e.ChannelID] = directedChannel - return nil - }) + return nil + }) if err != nil { return err } @@ -2740,15 +2743,18 @@ func (l *LightningNode) NodeAnnouncement(signed bool) (*lnwire.NodeAnnouncement, // isPublic determines whether the node is seen as public within the graph from // the source node's point of view. An existing database transaction can also be // specified. -func (l *LightningNode) isPublic(tx kvdb.RTx, sourcePubKey []byte) (bool, error) { +func (c *ChannelGraph) isPublic(tx kvdb.RTx, nodePub route.Vertex, + sourcePubKey []byte) (bool, error) { + // In order to determine whether this node is publicly advertised within // the graph, we'll need to look at all of its edges and check whether // they extend to any other node than the source node. errDone will be // used to terminate the check early. nodeIsPublic := false errDone := errors.New("done") - err := l.ForEachChannel(tx, func(_ kvdb.RTx, info *ChannelEdgeInfo, - _, _ *ChannelEdgePolicy) error { + err := c.ForEachNodeChannel(tx, nodePub, func(tx kvdb.RTx, + info *ChannelEdgeInfo, _ *ChannelEdgePolicy, + _ *ChannelEdgePolicy) error { // If this edge doesn't extend to the source node, we'll // terminate our search as we can now conclude that the node is @@ -3003,10 +3009,10 @@ func nodeTraversal(tx kvdb.RTx, nodePub []byte, db kvdb.Backend, return traversal(tx) } -// ForEachChannel iterates through all channels of this node, executing the -// passed callback with an edge info structure and the policies of each end -// of the channel. The first edge policy is the outgoing edge *to* the -// connecting node, while the second is the incoming edge *from* the +// ForEachNodeChannel iterates through all channels of the given node, +// executing the passed callback with an edge info structure and the policies +// of each end of the channel. The first edge policy is the outgoing edge *to* +// the connecting node, while the second is the incoming edge *from* the // connecting node. If the callback returns an error, then the iteration is // halted with the error propagated back up to the caller. // @@ -3016,14 +3022,11 @@ func nodeTraversal(tx kvdb.RTx, nodePub []byte, db kvdb.Backend, // should be passed as the first argument. Otherwise the first argument should // be nil and a fresh transaction will be created to execute the graph // traversal. -func (l *LightningNode) ForEachChannel(tx kvdb.RTx, +func (c *ChannelGraph) ForEachNodeChannel(tx kvdb.RTx, nodePub route.Vertex, cb func(kvdb.RTx, *ChannelEdgeInfo, *ChannelEdgePolicy, *ChannelEdgePolicy) error) error { - nodePub := l.PubKeyBytes[:] - db := l.db - - return nodeTraversal(tx, nodePub, db, cb) + return nodeTraversal(tx, nodePub[:], c.db, cb) } // ChannelEdgeInfo represents a fully authenticated channel along with all its @@ -3718,7 +3721,7 @@ func (c *ChannelGraph) IsPublicNode(pubKey [33]byte) (bool, error) { return err } - nodeIsPublic, err = node.isPublic(tx, ourPubKey) + nodeIsPublic, err = c.isPublic(tx, node.PubKeyBytes, ourPubKey) return err }, func() { nodeIsPublic = false diff --git a/channeldb/graph_test.go b/channeldb/graph_test.go index 0afc9ea19..1455763a7 100644 --- a/channeldb/graph_test.go +++ b/channeldb/graph_test.go @@ -1056,30 +1056,39 @@ func TestGraphTraversal(t *testing.T) { // outgoing channels for a particular node. numNodeChans := 0 firstNode, secondNode := nodeList[0], nodeList[1] - err = firstNode.ForEachChannel(nil, func(_ kvdb.RTx, _ *ChannelEdgeInfo, - outEdge, inEdge *ChannelEdgePolicy) error { + err = graph.ForEachNodeChannel(nil, firstNode.PubKeyBytes, + func(_ kvdb.RTx, _ *ChannelEdgeInfo, outEdge, + inEdge *ChannelEdgePolicy) error { - // All channels between first and second node should have fully - // (both sides) specified policies. - if inEdge == nil || outEdge == nil { - return fmt.Errorf("channel policy not present") - } + // All channels between first and second node should + // have fully (both sides) specified policies. + if inEdge == nil || outEdge == nil { + return fmt.Errorf("channel policy not present") + } - // Each should indicate that it's outgoing (pointed - // towards the second node). - if !bytes.Equal(outEdge.Node.PubKeyBytes[:], secondNode.PubKeyBytes[:]) { - return fmt.Errorf("wrong outgoing edge") - } + // Each should indicate that it's outgoing (pointed + // towards the second node). + if !bytes.Equal( + outEdge.Node.PubKeyBytes[:], + secondNode.PubKeyBytes[:], + ) { - // The incoming edge should also indicate that it's pointing to - // the origin node. - if !bytes.Equal(inEdge.Node.PubKeyBytes[:], firstNode.PubKeyBytes[:]) { - return fmt.Errorf("wrong outgoing edge") - } + return fmt.Errorf("wrong outgoing edge") + } - numNodeChans++ - return nil - }) + // The incoming edge should also indicate that it's + // pointing to the origin node. + if !bytes.Equal( + inEdge.Node.PubKeyBytes[:], + firstNode.PubKeyBytes[:], + ) { + + return fmt.Errorf("wrong outgoing edge") + } + + numNodeChans++ + return nil + }) require.NoError(t, err) require.Equal(t, numChannels, numNodeChans) } @@ -2280,29 +2289,30 @@ func TestIncompleteChannelPolicies(t *testing.T) { // Ensure that channel is reported with unknown policies. checkPolicies := func(node *LightningNode, expectedIn, expectedOut bool) { calls := 0 - err := node.ForEachChannel(nil, func(_ kvdb.RTx, _ *ChannelEdgeInfo, - outEdge, inEdge *ChannelEdgePolicy) error { + err := graph.ForEachNodeChannel(nil, node.PubKeyBytes, + func(_ kvdb.RTx, _ *ChannelEdgeInfo, outEdge, + inEdge *ChannelEdgePolicy) error { - if !expectedOut && outEdge != nil { - t.Fatalf("Expected no outgoing policy") - } + if !expectedOut && outEdge != nil { + t.Fatalf("Expected no outgoing policy") + } - if expectedOut && outEdge == nil { - t.Fatalf("Expected an outgoing policy") - } + if expectedOut && outEdge == nil { + t.Fatalf("Expected an outgoing policy") + } - if !expectedIn && inEdge != nil { - t.Fatalf("Expected no incoming policy") - } + if !expectedIn && inEdge != nil { + t.Fatalf("Expected no incoming policy") + } - if expectedIn && inEdge == nil { - t.Fatalf("Expected an incoming policy") - } + if expectedIn && inEdge == nil { + t.Fatalf("Expected an incoming policy") + } - calls++ + calls++ - return nil - }) + return nil + }) if err != nil { t.Fatalf("unable to scan channels: %v", err) } @@ -3470,8 +3480,8 @@ func BenchmarkForEachChannel(b *testing.B) { } } -// TestGraphCacheForEachNodeChannel tests that the ForEachNodeChannel method -// works as expected, and is able to handle nil self edges. +// TestGraphCacheForEachNodeChannel tests that the ForEachNodeDirectedChannel +// method works as expected, and is able to handle nil self edges. func TestGraphCacheForEachNodeChannel(t *testing.T) { graph, err := MakeTestGraph(t) require.NoError(t, err) @@ -3498,11 +3508,13 @@ func TestGraphCacheForEachNodeChannel(t *testing.T) { // We should be able to accumulate the single channel added, even // though we have a nil edge policy here. var numChans int - err = graph.ForEachNodeChannel(nil, node1.PubKeyBytes, - func(channel *DirectedChannel) error { + err = graph.ForEachNodeDirectedChannel(nil, node1.PubKeyBytes, + func(_ *DirectedChannel) error { numChans++ + return nil - }) + }, + ) require.NoError(t, err) require.Equal(t, numChans, 1) diff --git a/routing/graph.go b/routing/graph.go index 23bdd41e2..7f344f54a 100644 --- a/routing/graph.go +++ b/routing/graph.go @@ -75,7 +75,7 @@ func (g *CachedGraph) Close() error { func (g *CachedGraph) forEachNodeChannel(nodePub route.Vertex, cb func(channel *channeldb.DirectedChannel) error) error { - return g.graph.ForEachNodeChannel(g.tx, nodePub, cb) + return g.graph.ForEachNodeDirectedChannel(g.tx, nodePub, cb) } // sourceNode returns the source node of the graph. diff --git a/routing/router.go b/routing/router.go index 827e21864..1eca002dd 100644 --- a/routing/router.go +++ b/routing/router.go @@ -2824,16 +2824,19 @@ func (r *ChannelRouter) ForEachNode( func (r *ChannelRouter) ForAllOutgoingChannels(cb func(kvdb.RTx, *channeldb.ChannelEdgeInfo, *channeldb.ChannelEdgePolicy) error) error { - return r.selfNode.ForEachChannel(nil, func(tx kvdb.RTx, - c *channeldb.ChannelEdgeInfo, - e, _ *channeldb.ChannelEdgePolicy) error { + return r.cfg.Graph.ForEachNodeChannel(nil, r.selfNode.PubKeyBytes, + func(tx kvdb.RTx, c *channeldb.ChannelEdgeInfo, + e *channeldb.ChannelEdgePolicy, + _ *channeldb.ChannelEdgePolicy) error { - if e == nil { - return fmt.Errorf("channel from self node has no policy") - } + if e == nil { + return fmt.Errorf("channel from self node " + + "has no policy") + } - return cb(tx, c, e) - }) + return cb(tx, c, e) + }, + ) } // AddProof updates the channel edge info with proof which is needed to diff --git a/rpcserver.go b/rpcserver.go index 85a156cf9..67337e08d 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -6151,30 +6151,33 @@ func (r *rpcServer) GetNodeInfo(ctx context.Context, channels []*lnrpc.ChannelEdge ) - if err := node.ForEachChannel(nil, func(_ kvdb.RTx, - edge *channeldb.ChannelEdgeInfo, - c1, c2 *channeldb.ChannelEdgePolicy) error { + err = graph.ForEachNodeChannel(nil, node.PubKeyBytes, + func(_ kvdb.RTx, edge *channeldb.ChannelEdgeInfo, + c1, c2 *channeldb.ChannelEdgePolicy) error { - numChannels++ - totalCapacity += edge.Capacity + numChannels++ + totalCapacity += edge.Capacity - // Only populate the node's channels if the user requested them. - if in.IncludeChannels { - // Do not include unannounced channels - private - // channels or public channels whose authentication - // proof were not confirmed yet. - if edge.AuthProof == nil { - return nil + // Only populate the node's channels if the user + // requested them. + if in.IncludeChannels { + // Do not include unannounced channels - private + // channels or public channels whose + // authentication proof were not confirmed yet. + if edge.AuthProof == nil { + return nil + } + + // Convert the database's edge format into the + // network/RPC edge format. + channelEdge := marshalDbEdge(edge, c1, c2) + channels = append(channels, channelEdge) } - // Convert the database's edge format into the - // network/RPC edge format. - channelEdge := marshalDbEdge(edge, c1, c2) - channels = append(channels, channelEdge) - } - - return nil - }); err != nil { + return nil + }, + ) + if err != nil { return nil, err } @@ -6763,34 +6766,39 @@ func (r *rpcServer) FeeReport(ctx context.Context, } var feeReports []*lnrpc.ChannelFeeReport - err = selfNode.ForEachChannel(nil, func(_ kvdb.RTx, chanInfo *channeldb.ChannelEdgeInfo, - edgePolicy, _ *channeldb.ChannelEdgePolicy) error { + err = channelGraph.ForEachNodeChannel(nil, selfNode.PubKeyBytes, + func(_ kvdb.RTx, chanInfo *channeldb.ChannelEdgeInfo, + edgePolicy, _ *channeldb.ChannelEdgePolicy) error { - // Self node should always have policies for its channels. - if edgePolicy == nil { - return fmt.Errorf("no policy for outgoing channel %v ", - chanInfo.ChannelID) - } + // Self node should always have policies for its + // channels. + if edgePolicy == nil { + return fmt.Errorf("no policy for outgoing "+ + "channel %v ", chanInfo.ChannelID) + } - // We'll compute the effective fee rate by converting from a - // fixed point fee rate to a floating point fee rate. The fee - // rate field in the database the amount of mSAT charged per - // 1mil mSAT sent, so will divide by this to get the proper fee - // rate. - feeRateFixedPoint := edgePolicy.FeeProportionalMillionths - feeRate := float64(feeRateFixedPoint) / feeBase + // We'll compute the effective fee rate by converting + // from a fixed point fee rate to a floating point fee + // rate. The fee rate field in the database the amount + // of mSAT charged per 1mil mSAT sent, so will divide by + // this to get the proper fee rate. + feeRateFixedPoint := + edgePolicy.FeeProportionalMillionths + feeRate := float64(feeRateFixedPoint) / feeBase - // TODO(roasbeef): also add stats for revenue for each channel - feeReports = append(feeReports, &lnrpc.ChannelFeeReport{ - ChanId: chanInfo.ChannelID, - ChannelPoint: chanInfo.ChannelPoint.String(), - BaseFeeMsat: int64(edgePolicy.FeeBaseMSat), - FeePerMil: int64(feeRateFixedPoint), - FeeRate: feeRate, - }) + // TODO(roasbeef): also add stats for revenue for each + // channel + feeReports = append(feeReports, &lnrpc.ChannelFeeReport{ + ChanId: chanInfo.ChannelID, + ChannelPoint: chanInfo.ChannelPoint.String(), + BaseFeeMsat: int64(edgePolicy.FeeBaseMSat), + FeePerMil: int64(feeRateFixedPoint), + FeeRate: feeRate, + }) - return nil - }) + return nil + }, + ) if err != nil { return nil, err } diff --git a/server.go b/server.go index f3419a446..5d3eea6b0 100644 --- a/server.go +++ b/server.go @@ -3092,7 +3092,7 @@ func (s *server) establishPersistentConnections() error { // TODO(roasbeef): instead iterate over link nodes and query graph for // each of the nodes. selfPub := s.identityECDH.PubKey().SerializeCompressed() - err = sourceNode.ForEachChannel(nil, func( + err = s.graphDB.ForEachNodeChannel(nil, sourceNode.PubKeyBytes, func( tx kvdb.RTx, chanInfo *channeldb.ChannelEdgeInfo, policy, _ *channeldb.ChannelEdgePolicy) error { From d37f5d7e1a13800474618447ee358fb17215aec2 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Wed, 8 Nov 2023 14:50:21 +0200 Subject: [PATCH 02/12] autopilot: use pointer receivers for dbNode methods --- autopilot/graph.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autopilot/graph.go b/autopilot/graph.go index 89e03cbdd..2dbcfb781 100644 --- a/autopilot/graph.go +++ b/autopilot/graph.go @@ -69,7 +69,7 @@ var _ Node = (*dbNode)(nil) // will be returned in serialized compressed format. // // NOTE: Part of the autopilot.Node interface. -func (d dbNode) PubKey() [33]byte { +func (d *dbNode) PubKey() [33]byte { return d.node.PubKeyBytes } @@ -77,7 +77,7 @@ func (d dbNode) PubKey() [33]byte { // peer is known to be listening on. // // NOTE: Part of the autopilot.Node interface. -func (d dbNode) Addrs() []net.Addr { +func (d *dbNode) Addrs() []net.Addr { return d.node.Addresses } @@ -87,7 +87,7 @@ func (d dbNode) Addrs() []net.Addr { // describes the active channel. // // NOTE: Part of the autopilot.Node interface. -func (d dbNode) ForEachChannel(cb func(ChannelEdge) error) error { +func (d *dbNode) ForEachChannel(cb func(ChannelEdge) error) error { return d.db.ForEachNodeChannel(d.tx, d.node.PubKeyBytes, func(tx kvdb.RTx, ei *channeldb.ChannelEdgeInfo, ep, _ *channeldb.ChannelEdgePolicy) error { @@ -109,7 +109,7 @@ func (d dbNode) ForEachChannel(cb func(ChannelEdge) error) error { ep.ChannelID, ), Capacity: ei.Capacity, - Peer: dbNode{ + Peer: &dbNode{ tx: tx, db: d.db, node: ep.Node, @@ -134,7 +134,7 @@ func (d *databaseChannelGraph) ForEachNode(cb func(Node) error) error { return nil } - node := dbNode{ + node := &dbNode{ db: d.db, tx: tx, node: n, @@ -273,7 +273,7 @@ func (d *databaseChannelGraph) addRandChannel(node1, node2 *btcec.PublicKey, return &ChannelEdge{ ChanID: chanID, Capacity: capacity, - Peer: dbNode{ + Peer: &dbNode{ db: d.db, node: vertex1, }, @@ -281,7 +281,7 @@ func (d *databaseChannelGraph) addRandChannel(node1, node2 *btcec.PublicKey, &ChannelEdge{ ChanID: chanID, Capacity: capacity, - Peer: dbNode{ + Peer: &dbNode{ db: d.db, node: vertex2, }, From 6d878c65fcd0857b82e68c615fcf100533ac2c5b Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Mon, 23 Oct 2023 13:51:18 +0200 Subject: [PATCH 03/12] channeldb: remove kvdb.Backend from LightningNode Now that the kvdb.Backend is no longer required, it is removed from the LightningNode struct. --- channeldb/graph.go | 9 --------- channeldb/graph_test.go | 8 -------- 2 files changed, 17 deletions(-) diff --git a/channeldb/graph.go b/channeldb/graph.go index 00be88d18..ac40830e6 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -682,7 +682,6 @@ func (c *ChannelGraph) ForEachNode( if err != nil { return err } - node.db = c.db // Execute the callback, the transaction will abort if // this returns an error. @@ -780,7 +779,6 @@ func (c *ChannelGraph) sourceNode(nodes kvdb.RBucket) (*LightningNode, error) { if err != nil { return nil, err } - node.db = c.db return &node, nil } @@ -2038,7 +2036,6 @@ func (c *ChannelGraph) NodeUpdatesInHorizon(startTime, if err != nil { return err } - node.db = c.db nodesInHorizon = append(nodesInHorizon, node) } @@ -2660,8 +2657,6 @@ type LightningNode struct { // compatible manner. ExtraOpaqueData []byte - db kvdb.Backend - // TODO(roasbeef): discovery will need storage to keep it's last IP // address and re-announce if interface changes? @@ -2813,7 +2808,6 @@ func (c *ChannelGraph) FetchLightningNode(nodePub route.Vertex) ( if err != nil { return err } - n.db = c.db node = &n @@ -3239,7 +3233,6 @@ func (c *ChannelEdgeInfo) FetchOtherNode(tx kvdb.RTx, if err != nil { return err } - node.db = c.db targetNode = &node @@ -4642,7 +4635,6 @@ func fetchChanEdgePolicies(edgeIndex kvdb.RBucket, edges kvdb.RBucket, // only fill in the database pointers if the edge is found. if edge1 != nil { edge1.db = db - edge1.Node.db = db } // Similarly, the second node is contained within the latter @@ -4655,7 +4647,6 @@ func fetchChanEdgePolicies(edgeIndex kvdb.RBucket, edges kvdb.RBucket, if edge2 != nil { edge2.db = db - edge2.Node.db = db } return edge1, edge2, nil diff --git a/channeldb/graph_test.go b/channeldb/graph_test.go index 1455763a7..0e13e915d 100644 --- a/channeldb/graph_test.go +++ b/channeldb/graph_test.go @@ -95,7 +95,6 @@ func createLightningNode(db kvdb.Backend, priv *btcec.PrivateKey) (*LightningNod Alias: "kek" + string(pub[:]), Features: testFeatures, Addresses: testAddrs, - db: db, } copy(n.PubKeyBytes[:], priv.PubKey().SerializeCompressed()) @@ -129,7 +128,6 @@ func TestNodeInsertionAndDeletion(t *testing.T) { Addresses: testAddrs, ExtraOpaqueData: []byte("extra new data"), PubKeyBytes: testPub, - db: graph.db, } // First, insert the node into the graph DB. This should succeed @@ -207,7 +205,6 @@ func TestPartialNode(t *testing.T) { HaveNodeAnnouncement: false, LastUpdate: time.Unix(0, 0), PubKeyBytes: testPub, - db: graph.db, } if err := compareNodes(node, dbNode); err != nil { @@ -2713,7 +2710,6 @@ func TestNodeIsPublic(t *testing.T) { graphs := []*ChannelGraph{aliceGraph, bobGraph, carolGraph} for i, graph := range graphs { for _, node := range nodes { - node.db = dbs[i] if err := graph.AddLightningNode(node); err != nil { t.Fatalf("unable to add node: %v", err) } @@ -3150,10 +3146,6 @@ func compareNodes(a, b *LightningNode) error { return fmt.Errorf("Alias doesn't match: expected %#v, \n "+ "got %#v", a.Alias, b.Alias) } - if !reflect.DeepEqual(a.db, b.db) { - return fmt.Errorf("db doesn't match: expected %#v, \n "+ - "got %#v", a.db, b.db) - } if !reflect.DeepEqual(a.HaveNodeAnnouncement, b.HaveNodeAnnouncement) { return fmt.Errorf("HaveNodeAnnouncement doesn't match: expected %#v, \n "+ "got %#v", a.HaveNodeAnnouncement, b.HaveNodeAnnouncement) From 9dc1a1dfece5f3a3deaca69163c047258c8a77af Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Mon, 23 Oct 2023 13:58:18 +0200 Subject: [PATCH 04/12] channeldb: convert FetchOtherNode to ChannelGraph method To prepare for the `kvdb.Backend` member of `ChannelEdgeInfo` being removed, the `FetchOtherNode` method is moved from the `ChannelEdgeInfo` to the `ChannelGraph` struct. --- channeldb/graph.go | 10 +++++----- server.go | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/channeldb/graph.go b/channeldb/graph.go index ac40830e6..0b7746b6a 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -3206,16 +3206,16 @@ func (c *ChannelEdgeInfo) OtherNodeKeyBytes(thisNodeKey []byte) ( // the target node in the channel. This is useful when one knows the pubkey of // one of the nodes, and wishes to obtain the full LightningNode for the other // end of the channel. -func (c *ChannelEdgeInfo) FetchOtherNode(tx kvdb.RTx, +func (c *ChannelGraph) FetchOtherNode(tx kvdb.RTx, channel *ChannelEdgeInfo, thisNodeKey []byte) (*LightningNode, error) { // Ensure that the node passed in is actually a member of the channel. var targetNodeBytes [33]byte switch { - case bytes.Equal(c.NodeKey1Bytes[:], thisNodeKey): - targetNodeBytes = c.NodeKey2Bytes - case bytes.Equal(c.NodeKey2Bytes[:], thisNodeKey): - targetNodeBytes = c.NodeKey1Bytes + case bytes.Equal(channel.NodeKey1Bytes[:], thisNodeKey): + targetNodeBytes = channel.NodeKey2Bytes + case bytes.Equal(channel.NodeKey2Bytes[:], thisNodeKey): + targetNodeBytes = channel.NodeKey1Bytes default: return nil, fmt.Errorf("node not participating in this channel") } diff --git a/server.go b/server.go index 5d3eea6b0..85cb7616a 100644 --- a/server.go +++ b/server.go @@ -3107,7 +3107,9 @@ func (s *server) establishPersistentConnections() error { // We'll now fetch the peer opposite from us within this // channel so we can queue up a direct connection to them. - channelPeer, err := chanInfo.FetchOtherNode(tx, selfPub) + channelPeer, err := s.graphDB.FetchOtherNode( + tx, chanInfo, selfPub, + ) if err != nil { return fmt.Errorf("unable to fetch channel peer for "+ "ChannelPoint(%v): %v", chanInfo.ChannelPoint, From f06f08f5960328fefe17de975542e0bc669edfc2 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Mon, 23 Oct 2023 14:00:03 +0200 Subject: [PATCH 05/12] channeldb: remove kvdb.Backend from ChannelEdgeInfo --- channeldb/graph.go | 7 ------- channeldb/graph_test.go | 7 ++----- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/channeldb/graph.go b/channeldb/graph.go index 0b7746b6a..f34fe0b27 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -1939,7 +1939,6 @@ func (c *ChannelGraph) ChanUpdatesInHorizon(startTime, return fmt.Errorf("unable to fetch info for "+ "edge with chan_id=%v: %v", chanID, err) } - edgeInfo.db = c.db // With the static information obtained, we'll now // fetch the dynamic policy info. @@ -2270,7 +2269,6 @@ func (c *ChannelGraph) FetchChanInfos(chanIDs []uint64) ([]ChannelEdge, error) { case err != nil: return err } - edgeInfo.db = c.db // With the static information obtained, we'll now // fetch the dynamic policy info. @@ -2961,7 +2959,6 @@ func nodeTraversal(tx kvdb.RTx, nodePub []byte, db kvdb.Backend, if err != nil { return err } - edgeInfo.db = db outgoingPolicy, err := fetchChanEdgePolicy( edges, chanID, nodePub, nodes, @@ -3082,8 +3079,6 @@ type ChannelEdgeInfo struct { // and ensure we're able to make upgrades to the network in a forwards // compatible manner. ExtraOpaqueData []byte - - db kvdb.Backend } // AddNodeKeys is a setter-like method that can be used to replace the set of @@ -3560,7 +3555,6 @@ func (c *ChannelGraph) FetchChannelEdgesByOutpoint(op *wire.OutPoint, return err } edgeInfo = &edge - edgeInfo.db = c.db // Once we have the information about the channels' parameters, // we'll fetch the routing policies for each for the directed @@ -3666,7 +3660,6 @@ func (c *ChannelGraph) FetchChannelEdgesByID(chanID uint64, } edgeInfo = &edge - edgeInfo.db = c.db // Then we'll attempt to fetch the accompanying policies of this // edge. diff --git a/channeldb/graph_test.go b/channeldb/graph_test.go index 0e13e915d..a1e6fa223 100644 --- a/channeldb/graph_test.go +++ b/channeldb/graph_test.go @@ -2706,16 +2706,14 @@ func TestNodeIsPublic(t *testing.T) { // participant's graph. nodes := []*LightningNode{aliceNode, bobNode, carolNode} edges := []*ChannelEdgeInfo{&aliceBobEdge, &bobCarolEdge} - dbs := []kvdb.Backend{aliceGraph.db, bobGraph.db, carolGraph.db} graphs := []*ChannelGraph{aliceGraph, bobGraph, carolGraph} - for i, graph := range graphs { + for _, graph := range graphs { for _, node := range nodes { if err := graph.AddLightningNode(node); err != nil { t.Fatalf("unable to add node: %v", err) } } for _, edge := range edges { - edge.db = dbs[i] if err := graph.AddChannelEdge(edge); err != nil { t.Fatalf("unable to add edge: %v", err) } @@ -2775,7 +2773,7 @@ func TestNodeIsPublic(t *testing.T) { // that allows it to be advertised. Within Alice's graph, we'll // completely remove the edge as it is not possible for her to know of // it without it being advertised. - for i, graph := range graphs { + for _, graph := range graphs { err := graph.DeleteChannelEdges( false, true, bobCarolEdge.ChannelID, ) @@ -2788,7 +2786,6 @@ func TestNodeIsPublic(t *testing.T) { } bobCarolEdge.AuthProof = nil - bobCarolEdge.db = dbs[i] if err := graph.AddChannelEdge(&bobCarolEdge); err != nil { t.Fatalf("unable to add edge: %v", err) } From 9a62a46aa34355e8f2e585a94c5082b0a562403a Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Mon, 23 Oct 2023 14:02:14 +0200 Subject: [PATCH 06/12] channeldb: remove kvdb.Backend from ChannelEdgePolicy --- channeldb/graph.go | 17 ----------------- channeldb/graph_test.go | 7 ------- 2 files changed, 24 deletions(-) diff --git a/channeldb/graph.go b/channeldb/graph.go index f34fe0b27..b97d7a746 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -3438,8 +3438,6 @@ type ChannelEdgePolicy struct { // and ensure we're able to make upgrades to the network in a forwards // compatible manner. ExtraOpaqueData []byte - - db kvdb.Backend } // Signature is a channel announcement signature, which is needed for proper @@ -3823,11 +3821,6 @@ func (c *ChannelGraph) ChannelView() ([]EdgePoint, error) { return edgePoints, nil } -// NewChannelEdgePolicy returns a new blank ChannelEdgePolicy. -func (c *ChannelGraph) NewChannelEdgePolicy() *ChannelEdgePolicy { - return &ChannelEdgePolicy{db: c.db} -} - // MarkEdgeZombie attempts to mark a channel identified by its channel ID as a // zombie. This method is used on an ad-hoc basis, when channels need to be // marked as zombies outside the normal pruning cycle. @@ -4624,12 +4617,6 @@ func fetchChanEdgePolicies(edgeIndex kvdb.RBucket, edges kvdb.RBucket, return nil, nil, err } - // As we may have a single direction of the edge but not the other, - // only fill in the database pointers if the edge is found. - if edge1 != nil { - edge1.db = db - } - // Similarly, the second node is contained within the latter // half of the edge information. node2Pub := edgeInfo[33:66] @@ -4638,10 +4625,6 @@ func fetchChanEdgePolicies(edgeIndex kvdb.RBucket, edges kvdb.RBucket, return nil, nil, err } - if edge2 != nil { - edge2.db = db - } - return edge1, edge2, nil } diff --git a/channeldb/graph_test.go b/channeldb/graph_test.go index a1e6fa223..fa409441b 100644 --- a/channeldb/graph_test.go +++ b/channeldb/graph_test.go @@ -671,7 +671,6 @@ func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) (*ChannelEd FeeProportionalMillionths: 3452352, Node: secondNode, ExtraOpaqueData: []byte("new unknown feature2"), - db: db, } edge2 := &ChannelEdgePolicy{ SigBytes: testSig.Serialize(), @@ -686,7 +685,6 @@ func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) (*ChannelEd FeeProportionalMillionths: 90392423, Node: firstNode, ExtraOpaqueData: []byte("new unknown feature1"), - db: db, } return edgeInfo, edge1, edge2 @@ -992,7 +990,6 @@ func newEdgePolicy(chanID uint64, db kvdb.Backend, MaxHTLC: lnwire.MilliSatoshi(prand.Int63()), FeeBaseMSat: lnwire.MilliSatoshi(prand.Int63()), FeeProportionalMillionths: lnwire.MilliSatoshi(prand.Int63()), - db: db, } } @@ -3202,10 +3199,6 @@ func compareEdgePolicies(a, b *ChannelEdgePolicy) error { if err := compareNodes(a.Node, b.Node); err != nil { return err } - if !reflect.DeepEqual(a.db, b.db) { - return fmt.Errorf("db doesn't match: expected %#v, \n "+ - "got %#v", a.db, b.db) - } return nil } From 6c76d31e894f1d457f7f478b5c1ebdc7778ad596 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Mon, 23 Oct 2023 14:21:24 +0200 Subject: [PATCH 07/12] multi: let FetchLightningNode take an optional tx In preparation for the next commit which will remove the `*LightningNode` from the `ChannelEdgePolicy` struct, `FetchLightningNode` is modified to take in an optional transaction so that it can be utilised in places where a transaction exists. --- autopilot/graph.go | 2 +- channeldb/db.go | 2 +- channeldb/graph.go | 28 +++++++++++++++++++++------- channeldb/graph_test.go | 14 +++++++------- routing/pathfind_test.go | 4 ++-- routing/router.go | 2 +- routing/router_test.go | 4 ++-- rpcserver.go | 4 ++-- server.go | 2 +- 9 files changed, 38 insertions(+), 24 deletions(-) diff --git a/autopilot/graph.go b/autopilot/graph.go index 2dbcfb781..633a7b986 100644 --- a/autopilot/graph.go +++ b/autopilot/graph.go @@ -158,7 +158,7 @@ func (d *databaseChannelGraph) addRandChannel(node1, node2 *btcec.PublicKey, return nil, err } - dbNode, err := d.db.FetchLightningNode(vertex) + dbNode, err := d.db.FetchLightningNode(nil, vertex) switch { case err == channeldb.ErrGraphNodeNotFound: fallthrough diff --git a/channeldb/db.go b/channeldb/db.go index bf170e2ba..d1b9f684e 100644 --- a/channeldb/db.go +++ b/channeldb/db.go @@ -1351,7 +1351,7 @@ func (d *DB) AddrsForNode(nodePub *btcec.PublicKey) ([]net.Addr, if err != nil { return nil, err } - graphNode, err := d.graph.FetchLightningNode(pubKey) + graphNode, err := d.graph.FetchLightningNode(nil, pubKey) if err != nil && err != ErrGraphNodeNotFound { return nil, err } else if err == ErrGraphNodeNotFound { diff --git a/channeldb/graph.go b/channeldb/graph.go index b97d7a746..b9d99ed8c 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -519,7 +519,7 @@ func (c *ChannelGraph) FetchNodeFeatures( } // Fallback that uses the database. - targetNode, err := c.FetchLightningNode(node) + targetNode, err := c.FetchLightningNode(nil, node) switch err { // If the node exists and has features, return them directly. case nil: @@ -2779,12 +2779,13 @@ func (c *ChannelGraph) isPublic(tx kvdb.RTx, nodePub route.Vertex, // FetchLightningNode attempts to look up a target node by its identity public // key. If the node isn't found in the database, then ErrGraphNodeNotFound is -// returned. -func (c *ChannelGraph) FetchLightningNode(nodePub route.Vertex) ( +// returned. An optional transaction may be provided. If none is provided, then +// a new one will be created. +func (c *ChannelGraph) FetchLightningNode(tx kvdb.RTx, nodePub route.Vertex) ( *LightningNode, error) { var node *LightningNode - err := kvdb.View(c.db, func(tx kvdb.RTx) error { + fetch := func(tx kvdb.RTx) error { // First grab the nodes bucket which stores the mapping from // pubKey to node information. nodes := tx.ReadBucket(nodeBucket) @@ -2810,9 +2811,22 @@ func (c *ChannelGraph) FetchLightningNode(nodePub route.Vertex) ( node = &n return nil - }, func() { - node = nil - }) + } + + if tx == nil { + err := kvdb.View( + c.db, fetch, func() { + node = nil + }, + ) + if err != nil { + return nil, err + } + + return node, nil + } + + err := fetch(tx) if err != nil { return nil, err } diff --git a/channeldb/graph_test.go b/channeldb/graph_test.go index fa409441b..242fed4a7 100644 --- a/channeldb/graph_test.go +++ b/channeldb/graph_test.go @@ -139,7 +139,7 @@ func TestNodeInsertionAndDeletion(t *testing.T) { // Next, fetch the node from the database to ensure everything was // serialized properly. - dbNode, err := graph.FetchLightningNode(testPub) + dbNode, err := graph.FetchLightningNode(nil, testPub) require.NoError(t, err, "unable to locate node") if _, exists, err := graph.HasLightningNode(dbNode.PubKeyBytes); err != nil { @@ -162,7 +162,7 @@ func TestNodeInsertionAndDeletion(t *testing.T) { // Finally, attempt to fetch the node again. This should fail as the // node should have been deleted from the database. - _, err = graph.FetchLightningNode(testPub) + _, err = graph.FetchLightningNode(nil, testPub) if err != ErrGraphNodeNotFound { t.Fatalf("fetch after delete should fail!") } @@ -190,7 +190,7 @@ func TestPartialNode(t *testing.T) { // Next, fetch the node from the database to ensure everything was // serialized properly. - dbNode, err := graph.FetchLightningNode(testPub) + dbNode, err := graph.FetchLightningNode(nil, testPub) require.NoError(t, err, "unable to locate node") if _, exists, err := graph.HasLightningNode(dbNode.PubKeyBytes); err != nil { @@ -220,7 +220,7 @@ func TestPartialNode(t *testing.T) { // Finally, attempt to fetch the node again. This should fail as the // node should have been deleted from the database. - _, err = graph.FetchLightningNode(testPub) + _, err = graph.FetchLightningNode(nil, testPub) if err != ErrGraphNodeNotFound { t.Fatalf("fetch after delete should fail!") } @@ -2560,7 +2560,7 @@ func TestPruneGraphNodes(t *testing.T) { // Finally, we'll ensure that node3, the only fully unconnected node as // properly deleted from the graph and not another node in its place. - _, err = graph.FetchLightningNode(node3.PubKeyBytes) + _, err = graph.FetchLightningNode(nil, node3.PubKeyBytes) if err == nil { t.Fatalf("node 3 should have been deleted!") } @@ -2594,13 +2594,13 @@ func TestAddChannelEdgeShellNodes(t *testing.T) { // Ensure that node1 was inserted as a full node, while node2 only has // a shell node present. - node1, err = graph.FetchLightningNode(node1.PubKeyBytes) + node1, err = graph.FetchLightningNode(nil, node1.PubKeyBytes) require.NoError(t, err, "unable to fetch node1") if !node1.HaveNodeAnnouncement { t.Fatalf("have shell announcement for node1, shouldn't") } - node2, err = graph.FetchLightningNode(node2.PubKeyBytes) + node2, err = graph.FetchLightningNode(nil, node2.PubKeyBytes) require.NoError(t, err, "unable to fetch node2") if node2.HaveNodeAnnouncement { t.Fatalf("should have shell announcement for node2, but is full") diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index c016451bd..b615d8969 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -2283,7 +2283,7 @@ func TestPathFindSpecExample(t *testing.T) { // Carol, so we set "B" as the source node so path finding starts from // Bob. bob := ctx.aliases["B"] - bobNode, err := ctx.graph.FetchLightningNode(bob) + bobNode, err := ctx.graph.FetchLightningNode(nil, bob) require.NoError(t, err, "unable to find bob") if err := ctx.graph.SetSourceNode(bobNode); err != nil { t.Fatalf("unable to set source node: %v", err) @@ -2332,7 +2332,7 @@ func TestPathFindSpecExample(t *testing.T) { // Next, we'll set A as the source node so we can assert that we create // the proper route for any queries starting with Alice. alice := ctx.aliases["A"] - aliceNode, err := ctx.graph.FetchLightningNode(alice) + aliceNode, err := ctx.graph.FetchLightningNode(nil, alice) require.NoError(t, err, "unable to find alice") if err := ctx.graph.SetSourceNode(aliceNode); err != nil { t.Fatalf("unable to set source node: %v", err) diff --git a/routing/router.go b/routing/router.go index 1eca002dd..50aa6b43e 100644 --- a/routing/router.go +++ b/routing/router.go @@ -2802,7 +2802,7 @@ func (r *ChannelRouter) GetChannelByID(chanID lnwire.ShortChannelID) ( func (r *ChannelRouter) FetchLightningNode( node route.Vertex) (*channeldb.LightningNode, error) { - return r.cfg.Graph.FetchLightningNode(node) + return r.cfg.Graph.FetchLightningNode(nil, node) } // ForEachNode is used to iterate over every node in router topology. diff --git a/routing/router_test.go b/routing/router_test.go index ea1fec287..ce05be561 100644 --- a/routing/router_test.go +++ b/routing/router_test.go @@ -1613,14 +1613,14 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { _, _, err = ctx.router.FindRoute(req) require.NoError(t, err, "unable to find any routes") - copy1, err := ctx.graph.FetchLightningNode(pub1) + copy1, err := ctx.graph.FetchLightningNode(nil, pub1) require.NoError(t, err, "unable to fetch node") if copy1.Alias != n1.Alias { t.Fatalf("fetched node not equal to original") } - copy2, err := ctx.graph.FetchLightningNode(pub2) + copy2, err := ctx.graph.FetchLightningNode(nil, pub2) require.NoError(t, err, "unable to fetch node") if copy2.Alias != n2.Alias { diff --git a/rpcserver.go b/rpcserver.go index 67337e08d..a9bd480cf 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -6135,7 +6135,7 @@ func (r *rpcServer) GetNodeInfo(ctx context.Context, // With the public key decoded, attempt to fetch the node corresponding // to this public key. If the node cannot be found, then an error will // be returned. - node, err := graph.FetchLightningNode(pubKey) + node, err := graph.FetchLightningNode(nil, pubKey) switch { case err == channeldb.ErrGraphNodeNotFound: return nil, status.Error(codes.NotFound, err.Error()) @@ -7107,7 +7107,7 @@ func (r *rpcServer) ForwardingHistory(ctx context.Context, return "", err } - peer, err := r.server.graphDB.FetchLightningNode(vertex) + peer, err := r.server.graphDB.FetchLightningNode(nil, vertex) if err != nil { return "", err } diff --git a/server.go b/server.go index 85cb7616a..e9da0dc35 100644 --- a/server.go +++ b/server.go @@ -4596,7 +4596,7 @@ func (s *server) fetchNodeAdvertisedAddrs(pub *btcec.PublicKey) ([]net.Addr, err return nil, err } - node, err := s.graphDB.FetchLightningNode(vertex) + node, err := s.graphDB.FetchLightningNode(nil, vertex) if err != nil { return nil, err } From 3a17479ff414ce2d2deaace3eb57044ea2dfa316 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Mon, 23 Oct 2023 14:39:15 +0200 Subject: [PATCH 08/12] multi: remove LightningNode from ChannelEdgePolicy Finally, The LightningNode object is removed from ChannelEdgePolicy. This is a step towards letting ChannelEdgePolicy reflect exactly the schema that is on disk. This is also nice because the `Node` object is not necessarily always required when the ChannelEdgePolicy is loaded from the DB, so now it only get's loaded when needed. --- autopilot/graph.go | 7 +++- channeldb/graph.go | 78 ++++++++++++++++++++++------------- channeldb/graph_cache.go | 4 +- channeldb/graph_cache_test.go | 15 ++----- channeldb/graph_test.go | 69 ++++++++++++++++--------------- discovery/chan_series.go | 16 ++++--- routing/notifications_test.go | 2 +- routing/pathfind_test.go | 37 ++--------------- routing/router_test.go | 16 ++----- 9 files changed, 114 insertions(+), 130 deletions(-) diff --git a/autopilot/graph.go b/autopilot/graph.go index 633a7b986..7e362bc2e 100644 --- a/autopilot/graph.go +++ b/autopilot/graph.go @@ -104,6 +104,11 @@ func (d *dbNode) ForEachChannel(cb func(ChannelEdge) error) error { return nil } + node, err := d.db.FetchLightningNode(tx, ep.ToNode) + if err != nil { + return err + } + edge := ChannelEdge{ ChanID: lnwire.NewShortChanIDFromInt( ep.ChannelID, @@ -112,7 +117,7 @@ func (d *dbNode) ForEachChannel(cb func(ChannelEdge) error) error { Peer: &dbNode{ tx: tx, db: d.db, - node: ep.Node, + node: node, }, } diff --git a/channeldb/graph.go b/channeldb/graph.go index b9d99ed8c..e762f0be7 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -1858,6 +1858,14 @@ type ChannelEdge struct { // Policy2 points to the "second" edge policy of the channel containing // the dynamic information required to properly route through the edge. Policy2 *ChannelEdgePolicy + + // Node1 is "node 1" in the channel. This is the node that would have + // produced Policy1 if it exists. + Node1 *LightningNode + + // Node2 is "node 2" in the channel. This is the node that would have + // produced Policy2 if it exists. + Node2 *LightningNode } // ChanUpdatesInHorizon returns all the known channel edges which have at least @@ -1952,6 +1960,20 @@ func (c *ChannelGraph) ChanUpdatesInHorizon(startTime, err) } + node1, err := fetchLightningNode( + nodes, edgeInfo.NodeKey1Bytes[:], + ) + if err != nil { + return err + } + + node2, err := fetchLightningNode( + nodes, edgeInfo.NodeKey2Bytes[:], + ) + if err != nil { + return err + } + // Finally, we'll collate this edge with the rest of // edges to be returned. edgesSeen[chanIDInt] = struct{}{} @@ -1959,6 +1981,8 @@ func (c *ChannelGraph) ChanUpdatesInHorizon(startTime, Info: &edgeInfo, Policy1: edge1, Policy2: edge2, + Node1: &node1, + Node2: &node2, } edgesInHorizon = append(edgesInHorizon, channel) edgesToCache[chanIDInt] = channel @@ -2279,10 +2303,26 @@ func (c *ChannelGraph) FetchChanInfos(chanIDs []uint64) ([]ChannelEdge, error) { return err } + node1, err := fetchLightningNode( + nodes, edgeInfo.NodeKey1Bytes[:], + ) + if err != nil { + return err + } + + node2, err := fetchLightningNode( + nodes, edgeInfo.NodeKey2Bytes[:], + ) + if err != nil { + return err + } + chanEdges = append(chanEdges, ChannelEdge{ Info: &edgeInfo, Policy1: edge1, Policy2: edge2, + Node1: &node1, + Node2: &node2, }) } return nil @@ -2558,10 +2598,6 @@ func updateEdgePolicy(tx kvdb.RwTx, edge *ChannelEdgePolicy, if edgeIndex == nil { return false, ErrEdgeNotFound } - nodes, err := tx.CreateTopLevelBucket(nodeBucket) - if err != nil { - return false, err - } // Create the channelID key be converting the channel ID // integer into a byte slice. @@ -2591,7 +2627,7 @@ func updateEdgePolicy(tx kvdb.RwTx, edge *ChannelEdgePolicy, // Finally, with the direction of the edge being updated // identified, we update the on-disk edge representation. - err = putChanEdgePolicy(edges, nodes, edge, fromNode, toNode) + err := putChanEdgePolicy(edges, edge, fromNode, toNode) if err != nil { return false, err } @@ -3441,9 +3477,9 @@ type ChannelEdgePolicy struct { // HTLCs for each millionth of a satoshi forwarded. FeeProportionalMillionths lnwire.MilliSatoshi - // Node is the LightningNode that this directed edge leads to. Using - // this pointer the channel graph can further be traversed. - Node *LightningNode + // ToNode is the public key of the node that this directed edge leads + // to. Using this pub key, the channel graph can further be traversed. + ToNode [33]byte // ExtraOpaqueData is the set of data that was appended to this // message, some of which we may not actually know how to iterate or @@ -4460,8 +4496,8 @@ func deserializeChanEdgeInfo(r io.Reader) (ChannelEdgeInfo, error) { return edgeInfo, nil } -func putChanEdgePolicy(edges, nodes kvdb.RwBucket, edge *ChannelEdgePolicy, - from, to []byte) error { +func putChanEdgePolicy(edges kvdb.RwBucket, edge *ChannelEdgePolicy, from, + to []byte) error { var edgeKey [33 + 8]byte copy(edgeKey[:], from) @@ -4501,7 +4537,7 @@ func putChanEdgePolicy(edges, nodes kvdb.RwBucket, edge *ChannelEdgePolicy, // TODO(halseth): get rid of these invalid policies in a // migration. oldEdgePolicy, err := deserializeChanEdgePolicy( - bytes.NewReader(edgeBytes), nodes, + bytes.NewReader(edgeBytes), ) if err != nil && err != ErrEdgePolicyOptionalFieldNotFound { return err @@ -4599,7 +4635,7 @@ func fetchChanEdgePolicy(edges kvdb.RBucket, chanID []byte, edgeReader := bytes.NewReader(edgeBytes) - ep, err := deserializeChanEdgePolicy(edgeReader, nodes) + ep, err := deserializeChanEdgePolicy(edgeReader) switch { // If the db policy was missing an expected optional field, we return // nil as if the policy was unknown. @@ -4709,9 +4745,7 @@ func serializeChanEdgePolicy(w io.Writer, edge *ChannelEdgePolicy, return nil } -func deserializeChanEdgePolicy(r io.Reader, - nodes kvdb.RBucket) (*ChannelEdgePolicy, error) { - +func deserializeChanEdgePolicy(r io.Reader) (*ChannelEdgePolicy, error) { // Deserialize the policy. Note that in case an optional field is not // found, both an error and a populated policy object are returned. edge, deserializeErr := deserializeChanEdgePolicyRaw(r) @@ -4721,14 +4755,6 @@ func deserializeChanEdgePolicy(r io.Reader, return nil, deserializeErr } - // Populate full LightningNode struct. - pub := edge.Node.PubKeyBytes[:] - node, err := fetchLightningNode(nodes, pub) - if err != nil { - return nil, fmt.Errorf("unable to fetch node: %x, %v", pub, err) - } - edge.Node = &node - return edge, deserializeErr } @@ -4778,13 +4804,9 @@ func deserializeChanEdgePolicyRaw(r io.Reader) (*ChannelEdgePolicy, error) { } edge.FeeProportionalMillionths = lnwire.MilliSatoshi(n) - var pub [33]byte - if _, err := r.Read(pub[:]); err != nil { + if _, err := r.Read(edge.ToNode[:]); err != nil { return nil, err } - edge.Node = &LightningNode{ - PubKeyBytes: pub, - } // We'll try and see if there are any opaque bytes left, if not, then // we'll ignore the EOF error and return the edge as is. diff --git a/channeldb/graph_cache.go b/channeldb/graph_cache.go index 1aae21d06..84e340b56 100644 --- a/channeldb/graph_cache.go +++ b/channeldb/graph_cache.go @@ -271,7 +271,7 @@ func (c *GraphCache) AddChannel(info *ChannelEdgeInfo, // of node 2 then we have the policy 1 as seen from node 1. if policy1 != nil { fromNode, toNode := info.NodeKey1Bytes, info.NodeKey2Bytes - if policy1.Node.PubKeyBytes != info.NodeKey2Bytes { + if policy1.ToNode != info.NodeKey2Bytes { fromNode, toNode = toNode, fromNode } isEdge1 := policy1.ChannelFlags&lnwire.ChanUpdateDirection == 0 @@ -279,7 +279,7 @@ func (c *GraphCache) AddChannel(info *ChannelEdgeInfo, } if policy2 != nil { fromNode, toNode := info.NodeKey2Bytes, info.NodeKey1Bytes - if policy2.Node.PubKeyBytes != info.NodeKey1Bytes { + if policy2.ToNode != info.NodeKey1Bytes { fromNode, toNode = toNode, fromNode } isEdge1 := policy2.ChannelFlags&lnwire.ChanUpdateDirection == 0 diff --git a/channeldb/graph_cache_test.go b/channeldb/graph_cache_test.go index b408ec36d..4a6711191 100644 --- a/channeldb/graph_cache_test.go +++ b/channeldb/graph_cache_test.go @@ -73,18 +73,12 @@ func TestGraphCacheAddNode(t *testing.T) { outPolicy1 := &ChannelEdgePolicy{ ChannelID: 1000, ChannelFlags: lnwire.ChanUpdateChanFlags(channelFlagA), - Node: &LightningNode{ - PubKeyBytes: nodeB, - Features: lnwire.EmptyFeatureVector(), - }, + ToNode: nodeB, } inPolicy1 := &ChannelEdgePolicy{ ChannelID: 1000, ChannelFlags: lnwire.ChanUpdateChanFlags(channelFlagB), - Node: &LightningNode{ - PubKeyBytes: nodeA, - Features: lnwire.EmptyFeatureVector(), - }, + ToNode: nodeA, } node := &node{ pubKey: nodeA, @@ -159,9 +153,6 @@ func assertCachedPolicyEqual(t *testing.T, original *ChannelEdgePolicy, cached.FeeProportionalMillionths, ) require.Equal( - t, - route.Vertex(original.Node.PubKeyBytes), - cached.ToNodePubKey(), + t, route.Vertex(original.ToNode), cached.ToNodePubKey(), ) - require.Equal(t, original.Node.Features, cached.ToNodeFeatures) } diff --git a/channeldb/graph_test.go b/channeldb/graph_test.go index 242fed4a7..f88c46726 100644 --- a/channeldb/graph_test.go +++ b/channeldb/graph_test.go @@ -619,15 +619,15 @@ func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) (*ChannelEd *ChannelEdgePolicy, *ChannelEdgePolicy) { var ( - firstNode *LightningNode - secondNode *LightningNode + firstNode [33]byte + secondNode [33]byte ) if bytes.Compare(node1.PubKeyBytes[:], node2.PubKeyBytes[:]) == -1 { - firstNode = node1 - secondNode = node2 + firstNode = node1.PubKeyBytes + secondNode = node2.PubKeyBytes } else { - firstNode = node2 - secondNode = node1 + firstNode = node2.PubKeyBytes + secondNode = node1.PubKeyBytes } // In addition to the fake vertexes we create some fake channel @@ -653,10 +653,10 @@ func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) (*ChannelEd Capacity: 1000, ExtraOpaqueData: []byte("new unknown feature"), } - copy(edgeInfo.NodeKey1Bytes[:], firstNode.PubKeyBytes[:]) - copy(edgeInfo.NodeKey2Bytes[:], secondNode.PubKeyBytes[:]) - copy(edgeInfo.BitcoinKey1Bytes[:], firstNode.PubKeyBytes[:]) - copy(edgeInfo.BitcoinKey2Bytes[:], secondNode.PubKeyBytes[:]) + copy(edgeInfo.NodeKey1Bytes[:], firstNode[:]) + copy(edgeInfo.NodeKey2Bytes[:], secondNode[:]) + copy(edgeInfo.BitcoinKey1Bytes[:], firstNode[:]) + copy(edgeInfo.BitcoinKey2Bytes[:], secondNode[:]) edge1 := &ChannelEdgePolicy{ SigBytes: testSig.Serialize(), @@ -669,7 +669,7 @@ func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) (*ChannelEd MaxHTLC: 13928598, FeeBaseMSat: 4352345, FeeProportionalMillionths: 3452352, - Node: secondNode, + ToNode: secondNode, ExtraOpaqueData: []byte("new unknown feature2"), } edge2 := &ChannelEdgePolicy{ @@ -683,7 +683,7 @@ func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) (*ChannelEd MaxHTLC: 13928598, FeeBaseMSat: 4352345, FeeProportionalMillionths: 90392423, - Node: firstNode, + ToNode: firstNode, ExtraOpaqueData: []byte("new unknown feature1"), } @@ -1063,8 +1063,7 @@ func TestGraphTraversal(t *testing.T) { // Each should indicate that it's outgoing (pointed // towards the second node). if !bytes.Equal( - outEdge.Node.PubKeyBytes[:], - secondNode.PubKeyBytes[:], + outEdge.ToNode[:], secondNode.PubKeyBytes[:], ) { return fmt.Errorf("wrong outgoing edge") @@ -1073,14 +1072,14 @@ func TestGraphTraversal(t *testing.T) { // The incoming edge should also indicate that it's // pointing to the origin node. if !bytes.Equal( - inEdge.Node.PubKeyBytes[:], - firstNode.PubKeyBytes[:], + inEdge.ToNode[:], firstNode.PubKeyBytes[:], ) { return fmt.Errorf("wrong outgoing edge") } numNodeChans++ + return nil }) require.NoError(t, err) @@ -1275,7 +1274,7 @@ func fillTestGraph(t require.TestingT, graph *ChannelGraph, numNodes, // from node1 -> node2. edge := randEdgePolicy(chanID, graph.db) edge.ChannelFlags = 0 - edge.Node = node2 + edge.ToNode = node2.PubKeyBytes edge.SigBytes = testSig.Serialize() require.NoError(t, graph.UpdateEdgePolicy(edge)) @@ -1283,7 +1282,7 @@ func fillTestGraph(t require.TestingT, graph *ChannelGraph, numNodes, // node2 -> node1 this time. edge = randEdgePolicy(chanID, graph.db) edge.ChannelFlags = 1 - edge.Node = node1 + edge.ToNode = node1.PubKeyBytes edge.SigBytes = testSig.Serialize() require.NoError(t, graph.UpdateEdgePolicy(edge)) @@ -1468,7 +1467,7 @@ func TestGraphPruning(t *testing.T) { // node_i -> node_i+1 edge := randEdgePolicy(chanID, graph.db) edge.ChannelFlags = 0 - edge.Node = graphNodes[i] + edge.ToNode = graphNodes[i].PubKeyBytes edge.SigBytes = testSig.Serialize() if err := graph.UpdateEdgePolicy(edge); err != nil { t.Fatalf("unable to update edge: %v", err) @@ -1478,7 +1477,7 @@ func TestGraphPruning(t *testing.T) { // node_i this time. edge = randEdgePolicy(chanID, graph.db) edge.ChannelFlags = 1 - edge.Node = graphNodes[i] + edge.ToNode = graphNodes[i].PubKeyBytes edge.SigBytes = testSig.Serialize() if err := graph.UpdateEdgePolicy(edge); err != nil { t.Fatalf("unable to update edge: %v", err) @@ -1693,7 +1692,7 @@ func TestChanUpdatesInHorizon(t *testing.T) { chanID.ToUint64(), graph.db, edge1UpdateTime.Unix(), ) edge1.ChannelFlags = 0 - edge1.Node = node2 + edge1.ToNode = node2.PubKeyBytes edge1.SigBytes = testSig.Serialize() if err := graph.UpdateEdgePolicy(edge1); err != nil { t.Fatalf("unable to update edge: %v", err) @@ -1703,7 +1702,7 @@ func TestChanUpdatesInHorizon(t *testing.T) { chanID.ToUint64(), graph.db, edge2UpdateTime.Unix(), ) edge2.ChannelFlags = 1 - edge2.Node = node1 + edge2.ToNode = node1.PubKeyBytes edge2.SigBytes = testSig.Serialize() if err := graph.UpdateEdgePolicy(edge2); err != nil { t.Fatalf("unable to update edge: %v", err) @@ -2187,7 +2186,7 @@ func TestFetchChanInfos(t *testing.T) { chanID.ToUint64(), graph.db, updateTime.Unix(), ) edge1.ChannelFlags = 0 - edge1.Node = node2 + edge1.ToNode = node2.PubKeyBytes edge1.SigBytes = testSig.Serialize() if err := graph.UpdateEdgePolicy(edge1); err != nil { t.Fatalf("unable to update edge: %v", err) @@ -2197,7 +2196,7 @@ func TestFetchChanInfos(t *testing.T) { chanID.ToUint64(), graph.db, updateTime.Unix(), ) edge2.ChannelFlags = 1 - edge2.Node = node1 + edge2.ToNode = node1.PubKeyBytes edge2.SigBytes = testSig.Serialize() if err := graph.UpdateEdgePolicy(edge2); err != nil { t.Fatalf("unable to update edge: %v", err) @@ -2326,7 +2325,7 @@ func TestIncompleteChannelPolicies(t *testing.T) { chanID.ToUint64(), graph.db, updateTime.Unix(), ) edgePolicy.ChannelFlags = 0 - edgePolicy.Node = node2 + edgePolicy.ToNode = node2.PubKeyBytes edgePolicy.SigBytes = testSig.Serialize() if err := graph.UpdateEdgePolicy(edgePolicy); err != nil { t.Fatalf("unable to update edge: %v", err) @@ -2341,7 +2340,7 @@ func TestIncompleteChannelPolicies(t *testing.T) { chanID.ToUint64(), graph.db, updateTime.Unix(), ) edgePolicy.ChannelFlags = 1 - edgePolicy.Node = node1 + edgePolicy.ToNode = node1.PubKeyBytes edgePolicy.SigBytes = testSig.Serialize() if err := graph.UpdateEdgePolicy(edgePolicy); err != nil { t.Fatalf("unable to update edge: %v", err) @@ -2388,7 +2387,7 @@ func TestChannelEdgePruningUpdateIndexDeletion(t *testing.T) { edge1 := randEdgePolicy(chanID.ToUint64(), graph.db) edge1.ChannelFlags = 0 - edge1.Node = node1 + edge1.ToNode = node1.PubKeyBytes edge1.SigBytes = testSig.Serialize() if err := graph.UpdateEdgePolicy(edge1); err != nil { t.Fatalf("unable to update edge: %v", err) @@ -2396,7 +2395,7 @@ func TestChannelEdgePruningUpdateIndexDeletion(t *testing.T) { edge2 := randEdgePolicy(chanID.ToUint64(), graph.db) edge2.ChannelFlags = 1 - edge2.Node = node2 + edge2.ToNode = node2.PubKeyBytes edge2.SigBytes = testSig.Serialize() if err := graph.UpdateEdgePolicy(edge2); err != nil { t.Fatalf("unable to update edge: %v", err) @@ -2541,7 +2540,7 @@ func TestPruneGraphNodes(t *testing.T) { // points from the first to the second node. edge1 := randEdgePolicy(chanID.ToUint64(), graph.db) edge1.ChannelFlags = 0 - edge1.Node = node1 + edge1.ToNode = node1.PubKeyBytes edge1.SigBytes = testSig.Serialize() if err := graph.UpdateEdgePolicy(edge1); err != nil { t.Fatalf("unable to update edge: %v", err) @@ -2908,8 +2907,8 @@ func TestEdgePolicyMissingMaxHtcl(t *testing.T) { } chanID := edgeInfo.ChannelID - from := edge2.Node.PubKeyBytes[:] - to := edge1.Node.PubKeyBytes[:] + from := edge2.ToNode[:] + to := edge1.ToNode[:] // We'll remove the no max_htlc field from the first edge policy, and // all other opaque data, and serialize it. @@ -2945,7 +2944,7 @@ func TestEdgePolicyMissingMaxHtcl(t *testing.T) { return ErrGraphNotFound } - _, err = deserializeChanEdgePolicy(r, nodes) + _, err = deserializeChanEdgePolicy(r) if err != ErrEdgePolicyOptionalFieldNotFound { t.Fatalf("expected "+ "ErrEdgePolicyOptionalFieldNotFound, got %v", @@ -3196,9 +3195,11 @@ func compareEdgePolicies(a, b *ChannelEdgePolicy) error { return fmt.Errorf("extra data doesn't match: %v vs %v", a.ExtraOpaqueData, b.ExtraOpaqueData) } - if err := compareNodes(a.Node, b.Node); err != nil { - return err + if !bytes.Equal(a.ToNode[:], b.ToNode[:]) { + return fmt.Errorf("ToNode doesn't match: expected %x, got %x", + a.ToNode, b.ToNode) } + return nil } diff --git a/discovery/chan_series.go b/discovery/chan_series.go index 18f806316..c811017ab 100644 --- a/discovery/chan_series.go +++ b/discovery/chan_series.go @@ -280,10 +280,12 @@ func (c *ChanSeries) FetchChanAnns(chain chainhash.Hash, // If this edge has a validated node announcement, that // we haven't yet sent, then we'll send that as well. - nodePub := channel.Policy1.Node.PubKeyBytes - hasNodeAnn := channel.Policy1.Node.HaveNodeAnnouncement + nodePub := channel.Node2.PubKeyBytes + hasNodeAnn := channel.Node2.HaveNodeAnnouncement if _, ok := nodePubsSent[nodePub]; !ok && hasNodeAnn { - nodeAnn, err := channel.Policy1.Node.NodeAnnouncement(true) + nodeAnn, err := channel.Node2.NodeAnnouncement( + true, + ) if err != nil { return nil, err } @@ -297,10 +299,12 @@ func (c *ChanSeries) FetchChanAnns(chain chainhash.Hash, // If this edge has a validated node announcement, that // we haven't yet sent, then we'll send that as well. - nodePub := channel.Policy2.Node.PubKeyBytes - hasNodeAnn := channel.Policy2.Node.HaveNodeAnnouncement + nodePub := channel.Node1.PubKeyBytes + hasNodeAnn := channel.Node1.HaveNodeAnnouncement if _, ok := nodePubsSent[nodePub]; !ok && hasNodeAnn { - nodeAnn, err := channel.Policy2.Node.NodeAnnouncement(true) + nodeAnn, err := channel.Node1.NodeAnnouncement( + true, + ) if err != nil { return nil, err } diff --git a/routing/notifications_test.go b/routing/notifications_test.go index 00bc29f6b..50788fc67 100644 --- a/routing/notifications_test.go +++ b/routing/notifications_test.go @@ -85,7 +85,7 @@ func randEdgePolicy(chanID *lnwire.ShortChannelID, MaxHTLC: lnwire.MilliSatoshi(prand.Int31()), FeeBaseMSat: lnwire.MilliSatoshi(prand.Int31()), FeeProportionalMillionths: lnwire.MilliSatoshi(prand.Int31()), - Node: node, + ToNode: node.PubKeyBytes, } } diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index b615d8969..ddb847722 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -303,16 +303,6 @@ func parseTestGraph(t *testing.T, useCache bool, path string) ( } } - aliasForNode := func(node route.Vertex) string { - for alias, pubKey := range aliasMap { - if pubKey == node { - return alias - } - } - - return "" - } - // With all the vertexes inserted, we can now insert the edges into the // test graph. for _, edge := range g.Edges { @@ -387,10 +377,7 @@ func parseTestGraph(t *testing.T, useCache bool, path string) ( MaxHTLC: lnwire.MilliSatoshi(edge.MaxHTLC), FeeBaseMSat: lnwire.MilliSatoshi(edge.FeeBaseMsat), FeeProportionalMillionths: lnwire.MilliSatoshi(edge.FeeRate), - Node: &channeldb.LightningNode{ - Alias: aliasForNode(targetNode), - PubKeyBytes: targetNode, - }, + ToNode: targetNode, } if err := graph.UpdateEdgePolicy(edgePolicy); err != nil { return nil, err @@ -684,11 +671,6 @@ func createTestGraphFromChannels(t *testing.T, useCache bool, channelFlags |= lnwire.ChanUpdateDisabled } - node2Features := lnwire.EmptyFeatureVector() - if node2.testChannelPolicy != nil { - node2Features = node2.Features - } - edgePolicy := &channeldb.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), MessageFlags: msgFlags, @@ -700,11 +682,7 @@ func createTestGraphFromChannels(t *testing.T, useCache bool, MaxHTLC: node1.MaxHTLC, FeeBaseMSat: node1.FeeBaseMsat, FeeProportionalMillionths: node1.FeeRate, - Node: &channeldb.LightningNode{ - Alias: node2.Alias, - PubKeyBytes: node2Vertex, - Features: node2Features, - }, + ToNode: node2Vertex, } if err := graph.UpdateEdgePolicy(edgePolicy); err != nil { return nil, err @@ -722,11 +700,6 @@ func createTestGraphFromChannels(t *testing.T, useCache bool, } channelFlags |= lnwire.ChanUpdateDirection - node1Features := lnwire.EmptyFeatureVector() - if node1.testChannelPolicy != nil { - node1Features = node1.Features - } - edgePolicy := &channeldb.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), MessageFlags: msgFlags, @@ -738,11 +711,7 @@ func createTestGraphFromChannels(t *testing.T, useCache bool, MaxHTLC: node2.MaxHTLC, FeeBaseMSat: node2.FeeBaseMsat, FeeProportionalMillionths: node2.FeeRate, - Node: &channeldb.LightningNode{ - Alias: node1.Alias, - PubKeyBytes: node1Vertex, - Features: node1Features, - }, + ToNode: node1Vertex, } if err := graph.UpdateEdgePolicy(edgePolicy); err != nil { return nil, err diff --git a/routing/router_test.go b/routing/router_test.go index ce05be561..7ff5f2acf 100644 --- a/routing/router_test.go +++ b/routing/router_test.go @@ -1431,9 +1431,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { MinHTLC: 1, FeeBaseMSat: 10, FeeProportionalMillionths: 10000, - Node: &channeldb.LightningNode{ - PubKeyBytes: edge.NodeKey2Bytes, - }, + ToNode: edge.NodeKey2Bytes, } edgePolicy.ChannelFlags = 0 @@ -1450,9 +1448,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { MinHTLC: 1, FeeBaseMSat: 10, FeeProportionalMillionths: 10000, - Node: &channeldb.LightningNode{ - PubKeyBytes: edge.NodeKey1Bytes, - }, + ToNode: edge.NodeKey1Bytes, } edgePolicy.ChannelFlags = 1 @@ -1528,9 +1524,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { MinHTLC: 1, FeeBaseMSat: 10, FeeProportionalMillionths: 10000, - Node: &channeldb.LightningNode{ - PubKeyBytes: edge.NodeKey2Bytes, - }, + ToNode: edge.NodeKey2Bytes, } edgePolicy.ChannelFlags = 0 @@ -1546,9 +1540,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { MinHTLC: 1, FeeBaseMSat: 10, FeeProportionalMillionths: 10000, - Node: &channeldb.LightningNode{ - PubKeyBytes: edge.NodeKey1Bytes, - }, + ToNode: edge.NodeKey1Bytes, } edgePolicy.ChannelFlags = 1 From 78ff28fea172e99beb4df2361e928a6a8234a98f Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Wed, 8 Nov 2023 10:59:54 +0200 Subject: [PATCH 09/12] channeldb: remove unused func arguments --- channeldb/graph.go | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/channeldb/graph.go b/channeldb/graph.go index e762f0be7..4c08dbd96 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -1187,8 +1187,9 @@ func (c *ChannelGraph) HasChannelEdge( return ErrGraphNodeNotFound } - e1, e2, err := fetchChanEdgePolicies(edgeIndex, edges, nodes, - channelID[:], c.db) + e1, e2, err := fetchChanEdgePolicies( + edgeIndex, edges, channelID[:], + ) if err != nil { return err } @@ -1951,7 +1952,7 @@ func (c *ChannelGraph) ChanUpdatesInHorizon(startTime, // With the static information obtained, we'll now // fetch the dynamic policy info. edge1, edge2, err := fetchChanEdgePolicies( - edgeIndex, edges, nodes, chanID, c.db, + edgeIndex, edges, chanID, ) if err != nil { chanID := byteOrder.Uint64(chanID) @@ -2297,7 +2298,7 @@ func (c *ChannelGraph) FetchChanInfos(chanIDs []uint64) ([]ChannelEdge, error) { // With the static information obtained, we'll now // fetch the dynamic policy info. edge1, edge2, err := fetchChanEdgePolicies( - edgeIndex, edges, nodes, cidBytes[:], c.db, + edgeIndex, edges, cidBytes[:], ) if err != nil { return err @@ -2393,9 +2394,7 @@ func (c *ChannelGraph) delChannelEdge(edges, edgeIndex, chanIndex, zombieIndex, // we delete the edges themselves so we can access their last update // times. cid := byteOrder.Uint64(chanID) - edge1, edge2, err := fetchChanEdgePolicies( - edgeIndex, edges, nodes, chanID, nil, - ) + edge1, edge2, err := fetchChanEdgePolicies(edgeIndex, edges, chanID) if err != nil { return err } @@ -2970,10 +2969,6 @@ func nodeTraversal(tx kvdb.RTx, nodePub []byte, db kvdb.Backend, cb func(kvdb.RTx, *ChannelEdgeInfo, *ChannelEdgePolicy, *ChannelEdgePolicy) error) error { traversal := func(tx kvdb.RTx) error { - nodes := tx.ReadBucket(nodeBucket) - if nodes == nil { - return ErrGraphNotFound - } edges := tx.ReadBucket(edgeBucket) if edges == nil { return ErrGraphNotFound @@ -3011,7 +3006,7 @@ func nodeTraversal(tx kvdb.RTx, nodePub []byte, db kvdb.Backend, } outgoingPolicy, err := fetchChanEdgePolicy( - edges, chanID, nodePub, nodes, + edges, chanID, nodePub, ) if err != nil { return err @@ -3023,7 +3018,7 @@ func nodeTraversal(tx kvdb.RTx, nodePub []byte, db kvdb.Backend, } incomingPolicy, err := fetchChanEdgePolicy( - edges, chanID, otherNode[:], nodes, + edges, chanID, otherNode[:], ) if err != nil { return err @@ -3607,9 +3602,7 @@ func (c *ChannelGraph) FetchChannelEdgesByOutpoint(op *wire.OutPoint, // Once we have the information about the channels' parameters, // we'll fetch the routing policies for each for the directed // edges. - e1, e2, err := fetchChanEdgePolicies( - edgeIndex, edges, nodes, chanID, c.db, - ) + e1, e2, err := fetchChanEdgePolicies(edgeIndex, edges, chanID) if err != nil { return err } @@ -3712,7 +3705,7 @@ func (c *ChannelGraph) FetchChannelEdgesByID(chanID uint64, // Then we'll attempt to fetch the accompanying policies of this // edge. e1, e2, err := fetchChanEdgePolicies( - edgeIndex, edges, nodes, channelID[:], c.db, + edgeIndex, edges, channelID[:], ) if err != nil { return err @@ -4617,7 +4610,7 @@ func putChanEdgePolicyUnknown(edges kvdb.RwBucket, channelID uint64, } func fetchChanEdgePolicy(edges kvdb.RBucket, chanID []byte, - nodePub []byte, nodes kvdb.RBucket) (*ChannelEdgePolicy, error) { + nodePub []byte) (*ChannelEdgePolicy, error) { var edgeKey [33 + 8]byte copy(edgeKey[:], nodePub) @@ -4650,8 +4643,7 @@ func fetchChanEdgePolicy(edges kvdb.RBucket, chanID []byte, } func fetchChanEdgePolicies(edgeIndex kvdb.RBucket, edges kvdb.RBucket, - nodes kvdb.RBucket, chanID []byte, - db kvdb.Backend) (*ChannelEdgePolicy, *ChannelEdgePolicy, error) { + chanID []byte) (*ChannelEdgePolicy, *ChannelEdgePolicy, error) { edgeInfo := edgeIndex.Get(chanID) if edgeInfo == nil { @@ -4662,7 +4654,7 @@ func fetchChanEdgePolicies(edgeIndex kvdb.RBucket, edges kvdb.RBucket, // information. We only propagate the error here and below if it's // something other than edge non-existence. node1Pub := edgeInfo[:33] - edge1, err := fetchChanEdgePolicy(edges, chanID, node1Pub, nodes) + edge1, err := fetchChanEdgePolicy(edges, chanID, node1Pub) if err != nil { return nil, nil, err } @@ -4670,7 +4662,7 @@ func fetchChanEdgePolicies(edgeIndex kvdb.RBucket, edges kvdb.RBucket, // Similarly, the second node is contained within the latter // half of the edge information. node2Pub := edgeInfo[33:66] - edge2, err := fetchChanEdgePolicy(edges, chanID, node2Pub, nodes) + edge2, err := fetchChanEdgePolicy(edges, chanID, node2Pub) if err != nil { return nil, nil, err } From be23986eda3ef84b705cbd7efacc2eba307daa56 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Mon, 23 Oct 2023 15:19:06 +0200 Subject: [PATCH 10/12] docs: update release notes --- docs/release-notes/release-notes-0.18.0.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/release-notes/release-notes-0.18.0.md b/docs/release-notes/release-notes-0.18.0.md index cdb79ed13..70095e724 100644 --- a/docs/release-notes/release-notes-0.18.0.md +++ b/docs/release-notes/release-notes-0.18.0.md @@ -104,6 +104,10 @@ eliminate the use of `ScanInvoices`. ## Code Health + +* [Remove database pointers](https://github.com/lightningnetwork/lnd/pull/8117) + from channeldb schema structs. + ## Tooling and Documentation # Contributors (Alphabetical Order) From 84cdcd684766a8e2d85ff1e5c0508649d9a4335e Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Wed, 8 Nov 2023 11:18:45 +0200 Subject: [PATCH 11/12] multi: move DB schemas to channeldb/models This commit moves the ChannelEdgePolicy, ChannelEdgeInfo, ChanelAuthProof and CachedEdgePolicy structs to the `channeldb/models` package. --- autopilot/graph.go | 11 +- channeldb/channel_cache_test.go | 4 +- channeldb/graph.go | 584 ++++-------------------- channeldb/graph_cache.go | 109 +---- channeldb/graph_cache_test.go | 25 +- channeldb/graph_test.go | 87 ++-- channeldb/models/cached_edge_policy.go | 97 ++++ channeldb/models/channel_auth_proof.go | 131 ++++++ channeldb/models/channel_edge_info.go | 187 ++++++++ channeldb/models/channel_edge_policy.go | 131 ++++++ discovery/gossiper.go | 39 +- discovery/gossiper_test.go | 49 +- funding/manager.go | 6 +- funding/manager_test.go | 2 +- lnrpc/devrpc/dev_server.go | 7 +- lnrpc/invoicesrpc/addinvoice.go | 11 +- lnrpc/invoicesrpc/addinvoice_test.go | 89 ++-- lnrpc/routerrpc/router_backend.go | 3 +- netann/chan_status_manager_test.go | 33 +- netann/channel_announcement.go | 8 +- netann/channel_announcement_test.go | 6 +- netann/channel_update.go | 16 +- netann/interface.go | 5 +- peer/brontide.go | 2 +- routing/blinding.go | 10 +- routing/heap.go | 4 +- routing/localchans/manager.go | 10 +- routing/localchans/manager_test.go | 18 +- routing/mock_graph_test.go | 3 +- routing/mock_test.go | 11 +- routing/notifications.go | 7 +- routing/notifications_test.go | 23 +- routing/pathfind.go | 13 +- routing/pathfind_test.go | 61 +-- routing/payment_lifecycle.go | 3 +- routing/payment_session.go | 11 +- routing/payment_session_source.go | 7 +- routing/payment_session_test.go | 5 +- routing/router.go | 53 +-- routing/router_test.go | 59 +-- routing/unified_edges.go | 7 +- routing/unified_edges_test.go | 8 +- routing/validation_barrier.go | 13 +- rpcserver.go | 19 +- server.go | 9 +- 45 files changed, 1028 insertions(+), 968 deletions(-) create mode 100644 channeldb/models/cached_edge_policy.go create mode 100644 channeldb/models/channel_auth_proof.go create mode 100644 channeldb/models/channel_edge_info.go create mode 100644 channeldb/models/channel_edge_policy.go diff --git a/autopilot/graph.go b/autopilot/graph.go index 7e362bc2e..74b04c503 100644 --- a/autopilot/graph.go +++ b/autopilot/graph.go @@ -12,6 +12,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2/ecdsa" "github.com/btcsuite/btcd/btcutil" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" @@ -89,8 +90,8 @@ func (d *dbNode) Addrs() []net.Addr { // NOTE: Part of the autopilot.Node interface. func (d *dbNode) ForEachChannel(cb func(ChannelEdge) error) error { return d.db.ForEachNodeChannel(d.tx, d.node.PubKeyBytes, - func(tx kvdb.RTx, ei *channeldb.ChannelEdgeInfo, ep, - _ *channeldb.ChannelEdgePolicy) error { + func(tx kvdb.RTx, ei *models.ChannelEdgeInfo, ep, + _ *models.ChannelEdgePolicy) error { // Skip channels for which no outgoing edge policy is // available. @@ -235,7 +236,7 @@ func (d *databaseChannelGraph) addRandChannel(node1, node2 *btcec.PublicKey, } chanID := randChanID() - edge := &channeldb.ChannelEdgeInfo{ + edge := &models.ChannelEdgeInfo{ ChannelID: chanID.ToUint64(), Capacity: capacity, } @@ -243,7 +244,7 @@ func (d *databaseChannelGraph) addRandChannel(node1, node2 *btcec.PublicKey, if err := d.db.AddChannelEdge(edge); err != nil { return nil, nil, err } - edgePolicy := &channeldb.ChannelEdgePolicy{ + edgePolicy := &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), ChannelID: chanID.ToUint64(), LastUpdate: time.Now(), @@ -259,7 +260,7 @@ func (d *databaseChannelGraph) addRandChannel(node1, node2 *btcec.PublicKey, if err := d.db.UpdateEdgePolicy(edgePolicy); err != nil { return nil, nil, err } - edgePolicy = &channeldb.ChannelEdgePolicy{ + edgePolicy = &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), ChannelID: chanID.ToUint64(), LastUpdate: time.Now(), diff --git a/channeldb/channel_cache_test.go b/channeldb/channel_cache_test.go index d776c1318..7cb857293 100644 --- a/channeldb/channel_cache_test.go +++ b/channeldb/channel_cache_test.go @@ -3,6 +3,8 @@ package channeldb import ( "reflect" "testing" + + "github.com/lightningnetwork/lnd/channeldb/models" ) // TestChannelCache checks the behavior of the channelCache with respect to @@ -98,7 +100,7 @@ func assertHasChanEntries(t *testing.T, c *channelCache, start, end uint64) { // channelForInt generates a unique ChannelEdge given an integer. func channelForInt(i uint64) ChannelEdge { return ChannelEdge{ - Info: &ChannelEdgeInfo{ + Info: &models.ChannelEdgeInfo{ ChannelID: i, }, } diff --git a/channeldb/graph.go b/channeldb/graph.go index 4c08dbd96..5647326dc 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -16,12 +16,12 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/ecdsa" - "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/aliasmgr" "github.com/lightningnetwork/lnd/batch" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lnwire" @@ -161,9 +161,6 @@ const ( // would be possible for a node to create a ton of updates and slowly // fill our disk, and also waste bandwidth due to relaying. MaxAllowedExtraOpaqueBytes = 10000 - - // feeRateParts is the total number of parts used to express fee rates. - feeRateParts = 1e6 ) // ChannelGraph is a persistent, on-disk graph representation of the Lightning @@ -231,8 +228,8 @@ func NewChannelGraph(db kvdb.Backend, rejectCacheSize, chanCacheSize int, return nil, err } - err = g.ForEachChannel(func(info *ChannelEdgeInfo, - policy1, policy2 *ChannelEdgePolicy) error { + err = g.ForEachChannel(func(info *models.ChannelEdgeInfo, + policy1, policy2 *models.ChannelEdgePolicy) error { g.graphCache.AddChannel(info, policy1, policy2) @@ -258,10 +255,10 @@ type channelMapKey struct { // getChannelMap loads all channel edge policies from the database and stores // them in a map. func (c *ChannelGraph) getChannelMap(edges kvdb.RBucket) ( - map[channelMapKey]*ChannelEdgePolicy, error) { + map[channelMapKey]*models.ChannelEdgePolicy, error) { // Create a map to store all channel edge policies. - channelMap := make(map[channelMapKey]*ChannelEdgePolicy) + channelMap := make(map[channelMapKey]*models.ChannelEdgePolicy) err := kvdb.ForAll(edges, func(k, edgeBytes []byte) error { // Skip embedded buckets. @@ -411,8 +408,8 @@ func (c *ChannelGraph) NewPathFindTx() (kvdb.RTx, error) { // NOTE: If an edge can't be found, or wasn't advertised, then a nil pointer // for that particular channel edge routing policy will be passed into the // callback. -func (c *ChannelGraph) ForEachChannel(cb func(*ChannelEdgeInfo, - *ChannelEdgePolicy, *ChannelEdgePolicy) error) error { +func (c *ChannelGraph) ForEachChannel(cb func(*models.ChannelEdgeInfo, + *models.ChannelEdgePolicy, *models.ChannelEdgePolicy) error) error { return c.db.View(func(tx kvdb.RTx) error { edges := tx.ReadBucket(edgeBucket) @@ -481,12 +478,12 @@ func (c *ChannelGraph) ForEachNodeDirectedChannel(tx kvdb.RTx, return err } - dbCallback := func(tx kvdb.RTx, e *ChannelEdgeInfo, p1, - p2 *ChannelEdgePolicy) error { + dbCallback := func(tx kvdb.RTx, e *models.ChannelEdgeInfo, p1, + p2 *models.ChannelEdgePolicy) error { - var cachedInPolicy *CachedEdgePolicy + var cachedInPolicy *models.CachedEdgePolicy if p2 != nil { - cachedInPolicy = NewCachedPolicy(p2) + cachedInPolicy = models.NewCachedPolicy(p2) cachedInPolicy.ToNodePubKey = toNodeCallback cachedInPolicy.ToNodeFeatures = toNodeFeatures } @@ -556,9 +553,9 @@ func (c *ChannelGraph) ForEachNodeCached(cb func(node route.Vertex, channels := make(map[uint64]*DirectedChannel) err := c.ForEachNodeChannel(tx, node.PubKeyBytes, - func(tx kvdb.RTx, e *ChannelEdgeInfo, - p1 *ChannelEdgePolicy, - p2 *ChannelEdgePolicy) error { + func(tx kvdb.RTx, e *models.ChannelEdgeInfo, + p1 *models.ChannelEdgePolicy, + p2 *models.ChannelEdgePolicy) error { toNodeCallback := func() route.Vertex { return node.PubKeyBytes @@ -570,9 +567,10 @@ func (c *ChannelGraph) ForEachNodeCached(cb func(node route.Vertex, return err } - var cachedInPolicy *CachedEdgePolicy + var cachedInPolicy *models.CachedEdgePolicy if p2 != nil { - cachedInPolicy := NewCachedPolicy(p2) + cachedInPolicy = + models.NewCachedPolicy(p2) cachedInPolicy.ToNodePubKey = toNodeCallback cachedInPolicy.ToNodeFeatures = @@ -968,7 +966,7 @@ func (c *ChannelGraph) deleteLightningNode(nodes kvdb.RwBucket, // involved in creation of the channel, and the set of features that the channel // supports. The chanPoint and chanID are used to uniquely identify the edge // globally within the database. -func (c *ChannelGraph) AddChannelEdge(edge *ChannelEdgeInfo, +func (c *ChannelGraph) AddChannelEdge(edge *models.ChannelEdgeInfo, op ...batch.SchedulerOption) error { var alreadyExists bool @@ -1011,7 +1009,7 @@ func (c *ChannelGraph) AddChannelEdge(edge *ChannelEdgeInfo, // addChannelEdge is the private form of AddChannelEdge that allows callers to // utilize an existing db transaction. -func (c *ChannelGraph) addChannelEdge(tx kvdb.RwTx, edge *ChannelEdgeInfo) error { +func (c *ChannelGraph) addChannelEdge(tx kvdb.RwTx, edge *models.ChannelEdgeInfo) error { // Construct the channel's primary key which is the 8-byte channel ID. var chanKey [8]byte binary.BigEndian.PutUint64(chanKey[:], edge.ChannelID) @@ -1222,7 +1220,7 @@ func (c *ChannelGraph) HasChannelEdge( // In order to maintain this constraints, we return an error in the scenario // that an edge info hasn't yet been created yet, but someone attempts to update // it. -func (c *ChannelGraph) UpdateChannelEdge(edge *ChannelEdgeInfo) error { +func (c *ChannelGraph) UpdateChannelEdge(edge *models.ChannelEdgeInfo) error { // Construct the channel's primary key which is the 8-byte channel ID. var chanKey [8]byte binary.BigEndian.PutUint64(chanKey[:], edge.ChannelID) @@ -1267,12 +1265,12 @@ const ( // with the current UTXO state. A slice of channels that have been closed by // the target block are returned if the function succeeds without error. func (c *ChannelGraph) PruneGraph(spentOutputs []*wire.OutPoint, - blockHash *chainhash.Hash, blockHeight uint32) ([]*ChannelEdgeInfo, error) { + blockHash *chainhash.Hash, blockHeight uint32) ([]*models.ChannelEdgeInfo, error) { c.cacheMu.Lock() defer c.cacheMu.Unlock() - var chansClosed []*ChannelEdgeInfo + var chansClosed []*models.ChannelEdgeInfo err := kvdb.Update(c.db, func(tx kvdb.RwTx) error { // First grab the edges bucket which houses the information @@ -1520,7 +1518,7 @@ func (c *ChannelGraph) pruneGraphNodes(nodes kvdb.RwBucket, // set to the last prune height valid for the remaining chain. // Channels that were removed from the graph resulting from the // disconnected block are returned. -func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) ([]*ChannelEdgeInfo, +func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) ([]*models.ChannelEdgeInfo, error) { // Every channel having a ShortChannelID starting at 'height' @@ -1543,7 +1541,7 @@ func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) ([]*ChannelEdgeInf defer c.cacheMu.Unlock() // Keep track of the channels that are removed from the graph. - var removedChans []*ChannelEdgeInfo + var removedChans []*models.ChannelEdgeInfo if err := kvdb.Update(c.db, func(tx kvdb.RwTx) error { edges, err := tx.CreateTopLevelBucket(edgeBucket) @@ -1850,15 +1848,15 @@ func (c *ChannelGraph) HighestChanID() (uint64, error) { // edge as well as each of the known advertised edge policies. type ChannelEdge struct { // Info contains all the static information describing the channel. - Info *ChannelEdgeInfo + Info *models.ChannelEdgeInfo // Policy1 points to the "first" edge policy of the channel containing // the dynamic information required to properly route through the edge. - Policy1 *ChannelEdgePolicy + Policy1 *models.ChannelEdgePolicy // Policy2 points to the "second" edge policy of the channel containing // the dynamic information required to properly route through the edge. - Policy2 *ChannelEdgePolicy + Policy2 *models.ChannelEdgePolicy // Node1 is "node 1" in the channel. This is the node that would have // produced Policy1 if it exists. @@ -2338,7 +2336,7 @@ func (c *ChannelGraph) FetchChanInfos(chanIDs []uint64) ([]ChannelEdge, error) { } func delEdgeUpdateIndexEntry(edgesBucket kvdb.RwBucket, chanID uint64, - edge1, edge2 *ChannelEdgePolicy) error { + edge1, edge2 *models.ChannelEdgePolicy) error { // First, we'll fetch the edge update index bucket which currently // stores an entry for the channel we're about to delete. @@ -2475,8 +2473,8 @@ func (c *ChannelGraph) delChannelEdge(edges, edgeIndex, chanIndex, zombieIndex, // the channel. If the channel were to be marked zombie again, it would be // marked with the correct lagging channel since we received an update from only // one side. -func makeZombiePubkeys(info *ChannelEdgeInfo, - e1, e2 *ChannelEdgePolicy) ([33]byte, [33]byte) { +func makeZombiePubkeys(info *models.ChannelEdgeInfo, + e1, e2 *models.ChannelEdgePolicy) ([33]byte, [33]byte) { switch { // If we don't have either edge policy, we'll return both pubkeys so @@ -2506,7 +2504,7 @@ func makeZombiePubkeys(info *ChannelEdgeInfo, // updated, otherwise it's the second node's information. The node ordering is // determined by the lexicographical ordering of the identity public keys of the // nodes on either side of the channel. -func (c *ChannelGraph) UpdateEdgePolicy(edge *ChannelEdgePolicy, +func (c *ChannelGraph) UpdateEdgePolicy(edge *models.ChannelEdgePolicy, op ...batch.SchedulerOption) error { var ( @@ -2554,7 +2552,7 @@ func (c *ChannelGraph) UpdateEdgePolicy(edge *ChannelEdgePolicy, return c.chanScheduler.Execute(r) } -func (c *ChannelGraph) updateEdgeCache(e *ChannelEdgePolicy, isUpdate1 bool) { +func (c *ChannelGraph) updateEdgeCache(e *models.ChannelEdgePolicy, isUpdate1 bool) { // If an entry for this channel is found in reject cache, we'll modify // the entry with the updated timestamp for the direction that was just // written. If the edge doesn't exist, we'll load the cache entry lazily @@ -2586,7 +2584,7 @@ func (c *ChannelGraph) updateEdgeCache(e *ChannelEdgePolicy, isUpdate1 bool) { // buckets using an existing database transaction. The returned boolean will be // true if the updated policy belongs to node1, and false if the policy belonged // to node2. -func updateEdgePolicy(tx kvdb.RwTx, edge *ChannelEdgePolicy, +func updateEdgePolicy(tx kvdb.RwTx, edge *models.ChannelEdgePolicy, graphCache *GraphCache) (bool, error) { edges := tx.ReadWriteBucket(edgeBucket) @@ -2781,8 +2779,8 @@ func (c *ChannelGraph) isPublic(tx kvdb.RTx, nodePub route.Vertex, nodeIsPublic := false errDone := errors.New("done") err := c.ForEachNodeChannel(tx, nodePub, func(tx kvdb.RTx, - info *ChannelEdgeInfo, _ *ChannelEdgePolicy, - _ *ChannelEdgePolicy) error { + info *models.ChannelEdgeInfo, _ *models.ChannelEdgePolicy, + _ *models.ChannelEdgePolicy) error { // If this edge doesn't extend to the source node, we'll // terminate our search as we can now conclude that the node is @@ -2905,8 +2903,8 @@ func (n *graphCacheNode) Features() *lnwire.FeatureVector { // // Unknown policies are passed into the callback as nil values. func (n *graphCacheNode) ForEachChannel(tx kvdb.RTx, - cb func(kvdb.RTx, *ChannelEdgeInfo, *ChannelEdgePolicy, - *ChannelEdgePolicy) error) error { + cb func(kvdb.RTx, *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy) error) error { return nodeTraversal(tx, n.pubKeyBytes[:], nil, cb) } @@ -2966,7 +2964,7 @@ func (c *ChannelGraph) HasLightningNode(nodePub [33]byte) (time.Time, bool, erro // nodeTraversal is used to traverse all channels of a node given by its // public key and passes channel information into the specified callback. func nodeTraversal(tx kvdb.RTx, nodePub []byte, db kvdb.Backend, - cb func(kvdb.RTx, *ChannelEdgeInfo, *ChannelEdgePolicy, *ChannelEdgePolicy) error) error { + cb func(kvdb.RTx, *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, *models.ChannelEdgePolicy) error) error { traversal := func(tx kvdb.RTx) error { edges := tx.ReadBucket(edgeBucket) @@ -3059,194 +3057,17 @@ func nodeTraversal(tx kvdb.RTx, nodePub []byte, db kvdb.Backend, // be nil and a fresh transaction will be created to execute the graph // traversal. func (c *ChannelGraph) ForEachNodeChannel(tx kvdb.RTx, nodePub route.Vertex, - cb func(kvdb.RTx, *ChannelEdgeInfo, *ChannelEdgePolicy, - *ChannelEdgePolicy) error) error { + cb func(kvdb.RTx, *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy) error) error { return nodeTraversal(tx, nodePub[:], c.db, cb) } -// ChannelEdgeInfo represents a fully authenticated channel along with all its -// unique attributes. Once an authenticated channel announcement has been -// processed on the network, then an instance of ChannelEdgeInfo encapsulating -// the channels attributes is stored. The other portions relevant to routing -// policy of a channel are stored within a ChannelEdgePolicy for each direction -// of the channel. -type ChannelEdgeInfo struct { - // ChannelID is the unique channel ID for the channel. The first 3 - // bytes are the block height, the next 3 the index within the block, - // and the last 2 bytes are the output index for the channel. - ChannelID uint64 - - // ChainHash is the hash that uniquely identifies the chain that this - // channel was opened within. - // - // TODO(roasbeef): need to modify db keying for multi-chain - // * must add chain hash to prefix as well - ChainHash chainhash.Hash - - // NodeKey1Bytes is the raw public key of the first node. - NodeKey1Bytes [33]byte - nodeKey1 *btcec.PublicKey - - // NodeKey2Bytes is the raw public key of the first node. - NodeKey2Bytes [33]byte - nodeKey2 *btcec.PublicKey - - // BitcoinKey1Bytes is the raw public key of the first node. - BitcoinKey1Bytes [33]byte - bitcoinKey1 *btcec.PublicKey - - // BitcoinKey2Bytes is the raw public key of the first node. - BitcoinKey2Bytes [33]byte - bitcoinKey2 *btcec.PublicKey - - // Features is an opaque byte slice that encodes the set of channel - // specific features that this channel edge supports. - Features []byte - - // AuthProof is the authentication proof for this channel. This proof - // contains a set of signatures binding four identities, which attests - // to the legitimacy of the advertised channel. - AuthProof *ChannelAuthProof - - // ChannelPoint is the funding outpoint of the channel. This can be - // used to uniquely identify the channel within the channel graph. - ChannelPoint wire.OutPoint - - // Capacity is the total capacity of the channel, this is determined by - // the value output in the outpoint that created this channel. - Capacity btcutil.Amount - - // 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 -} - -// AddNodeKeys is a setter-like method that can be used to replace the set of -// keys for the target ChannelEdgeInfo. -func (c *ChannelEdgeInfo) AddNodeKeys(nodeKey1, nodeKey2, bitcoinKey1, - bitcoinKey2 *btcec.PublicKey) { - - c.nodeKey1 = nodeKey1 - copy(c.NodeKey1Bytes[:], c.nodeKey1.SerializeCompressed()) - - c.nodeKey2 = nodeKey2 - copy(c.NodeKey2Bytes[:], nodeKey2.SerializeCompressed()) - - c.bitcoinKey1 = bitcoinKey1 - copy(c.BitcoinKey1Bytes[:], c.bitcoinKey1.SerializeCompressed()) - - c.bitcoinKey2 = bitcoinKey2 - copy(c.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed()) -} - -// 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 -// that of the other node involved in channel creation. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the pubkey if absolutely necessary. -func (c *ChannelEdgeInfo) NodeKey1() (*btcec.PublicKey, error) { - if c.nodeKey1 != nil { - return c.nodeKey1, nil - } - - key, err := btcec.ParsePubKey(c.NodeKey1Bytes[:]) - if err != nil { - return nil, err - } - c.nodeKey1 = key - - return key, nil -} - -// NodeKey2 is the identity public key of the "second" node that was -// involved in the creation of this channel. A node is considered -// "second" if the lexicographical ordering the its serialized public -// key is "larger" than that of the other node involved in channel -// creation. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the pubkey if absolutely necessary. -func (c *ChannelEdgeInfo) NodeKey2() (*btcec.PublicKey, error) { - if c.nodeKey2 != nil { - return c.nodeKey2, nil - } - - key, err := btcec.ParsePubKey(c.NodeKey2Bytes[:]) - if err != nil { - return nil, err - } - c.nodeKey2 = key - - return key, nil -} - -// BitcoinKey1 is the Bitcoin multi-sig key belonging to the first -// node, that was involved in the funding transaction that originally -// created the channel that this struct represents. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the pubkey if absolutely necessary. -func (c *ChannelEdgeInfo) BitcoinKey1() (*btcec.PublicKey, error) { - if c.bitcoinKey1 != nil { - return c.bitcoinKey1, nil - } - - key, err := btcec.ParsePubKey(c.BitcoinKey1Bytes[:]) - if err != nil { - return nil, err - } - c.bitcoinKey1 = key - - return key, nil -} - -// BitcoinKey2 is the Bitcoin multi-sig key belonging to the second -// node, that was involved in the funding transaction that originally -// created the channel that this struct represents. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the pubkey if absolutely necessary. -func (c *ChannelEdgeInfo) BitcoinKey2() (*btcec.PublicKey, error) { - if c.bitcoinKey2 != nil { - return c.bitcoinKey2, nil - } - - key, err := btcec.ParsePubKey(c.BitcoinKey2Bytes[:]) - if err != nil { - return nil, err - } - c.bitcoinKey2 = key - - return key, nil -} - -// OtherNodeKeyBytes returns the node key bytes of the other end of -// the channel. -func (c *ChannelEdgeInfo) OtherNodeKeyBytes(thisNodeKey []byte) ( - [33]byte, error) { - - switch { - case bytes.Equal(c.NodeKey1Bytes[:], thisNodeKey): - return c.NodeKey2Bytes, nil - case bytes.Equal(c.NodeKey2Bytes[:], thisNodeKey): - return c.NodeKey1Bytes, nil - default: - return [33]byte{}, fmt.Errorf("node not participating in this channel") - } -} - // FetchOtherNode attempts to fetch the full LightningNode that's opposite of // the target node in the channel. This is useful when one knows the pubkey of // one of the nodes, and wishes to obtain the full LightningNode for the other // end of the channel. -func (c *ChannelGraph) FetchOtherNode(tx kvdb.RTx, channel *ChannelEdgeInfo, +func (c *ChannelGraph) FetchOtherNode(tx kvdb.RTx, channel *models.ChannelEdgeInfo, thisNodeKey []byte) (*LightningNode, error) { // Ensure that the node passed in is actually a member of the channel. @@ -3291,269 +3112,18 @@ func (c *ChannelGraph) FetchOtherNode(tx kvdb.RTx, channel *ChannelEdgeInfo, return targetNode, err } -// ChannelAuthProof is the authentication proof (the signature portion) for a -// channel. Using the four signatures contained in the struct, and some -// auxiliary knowledge (the funding script, node identities, and outpoint) nodes -// on the network are able to validate the authenticity and existence of a -// channel. Each of these signatures signs the following digest: chanID || -// nodeID1 || nodeID2 || bitcoinKey1|| bitcoinKey2 || 2-byte-feature-len || -// features. -type ChannelAuthProof struct { - // nodeSig1 is a cached instance of the first node signature. - nodeSig1 *ecdsa.Signature - - // NodeSig1Bytes are the raw bytes of the first node signature encoded - // in DER format. - NodeSig1Bytes []byte - - // nodeSig2 is a cached instance of the second node signature. - nodeSig2 *ecdsa.Signature - - // NodeSig2Bytes are the raw bytes of the second node signature - // encoded in DER format. - NodeSig2Bytes []byte - - // bitcoinSig1 is a cached instance of the first bitcoin signature. - bitcoinSig1 *ecdsa.Signature - - // BitcoinSig1Bytes are the raw bytes of the first bitcoin signature - // encoded in DER format. - BitcoinSig1Bytes []byte - - // bitcoinSig2 is a cached instance of the second bitcoin signature. - bitcoinSig2 *ecdsa.Signature - - // BitcoinSig2Bytes are the raw bytes of the second bitcoin signature - // encoded in DER format. - BitcoinSig2Bytes []byte -} - -// Node1Sig is the signature using the identity key of the node that is first -// in a lexicographical ordering of the serialized public keys of the two nodes -// that created the channel. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the signature if absolutely necessary. -func (c *ChannelAuthProof) Node1Sig() (*ecdsa.Signature, error) { - if c.nodeSig1 != nil { - return c.nodeSig1, nil - } - - sig, err := ecdsa.ParseSignature(c.NodeSig1Bytes) - if err != nil { - return nil, err - } - - c.nodeSig1 = sig - - return sig, nil -} - -// Node2Sig is the signature using the identity key of the node that is second -// in a lexicographical ordering of the serialized public keys of the two nodes -// that created the channel. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the signature if absolutely necessary. -func (c *ChannelAuthProof) Node2Sig() (*ecdsa.Signature, error) { - if c.nodeSig2 != nil { - return c.nodeSig2, nil - } - - sig, err := ecdsa.ParseSignature(c.NodeSig2Bytes) - if err != nil { - return nil, err - } - - c.nodeSig2 = sig - - return sig, nil -} - -// BitcoinSig1 is the signature using the public key of the first node that was -// used in the channel's multi-sig output. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the signature if absolutely necessary. -func (c *ChannelAuthProof) BitcoinSig1() (*ecdsa.Signature, error) { - if c.bitcoinSig1 != nil { - return c.bitcoinSig1, nil - } - - sig, err := ecdsa.ParseSignature(c.BitcoinSig1Bytes) - if err != nil { - return nil, err - } - - c.bitcoinSig1 = sig - - return sig, nil -} - -// BitcoinSig2 is the signature using the public key of the second node that -// was used in the channel's multi-sig output. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the signature if absolutely necessary. -func (c *ChannelAuthProof) BitcoinSig2() (*ecdsa.Signature, error) { - if c.bitcoinSig2 != nil { - return c.bitcoinSig2, nil - } - - sig, err := ecdsa.ParseSignature(c.BitcoinSig2Bytes) - if err != nil { - return nil, err - } - - c.bitcoinSig2 = sig - - return sig, nil -} - -// IsEmpty check is the authentication proof is empty Proof is empty if at -// least one of the signatures are equal to nil. -func (c *ChannelAuthProof) IsEmpty() bool { - return len(c.NodeSig1Bytes) == 0 || - len(c.NodeSig2Bytes) == 0 || - len(c.BitcoinSig1Bytes) == 0 || - len(c.BitcoinSig2Bytes) == 0 -} - -// ChannelEdgePolicy represents a *directed* edge within the channel graph. For -// each channel in the database, there are two distinct edges: one for each -// possible direction of travel along the channel. The edges themselves hold -// information concerning fees, and minimum time-lock information which is -// utilized during path finding. -type ChannelEdgePolicy struct { - // SigBytes is the raw bytes of the signature of the channel edge - // policy. We'll only parse these if the caller needs to access the - // signature for validation purposes. Do not set SigBytes directly, but - // use SetSigBytes instead to make sure that the cache is invalidated. - SigBytes []byte - - // sig is a cached fully parsed signature. - sig *ecdsa.Signature - - // ChannelID is the unique channel ID for the channel. The first 3 - // bytes are the block height, the next 3 the index within the block, - // and the last 2 bytes are the output index for the channel. - ChannelID uint64 - - // LastUpdate is the last time an authenticated edge for this channel - // was received. - LastUpdate time.Time - - // MessageFlags is a bitfield which indicates the presence of optional - // fields (like max_htlc) in the policy. - MessageFlags lnwire.ChanUpdateMsgFlags - - // ChannelFlags is a bitfield which signals the capabilities of the - // channel as well as the directed edge this update applies to. - ChannelFlags lnwire.ChanUpdateChanFlags - - // TimeLockDelta is the number of blocks this node will subtract from - // the expiry of an incoming HTLC. This value expresses the time buffer - // the node would like to HTLC exchanges. - TimeLockDelta uint16 - - // MinHTLC is the smallest value HTLC this node will forward, expressed - // in millisatoshi. - MinHTLC lnwire.MilliSatoshi - - // MaxHTLC is the largest value HTLC this node will forward, expressed - // in millisatoshi. - MaxHTLC lnwire.MilliSatoshi - - // FeeBaseMSat is the base HTLC fee that will be charged for forwarding - // ANY HTLC, expressed in mSAT's. - FeeBaseMSat lnwire.MilliSatoshi - - // FeeProportionalMillionths is the rate that the node will charge for - // HTLCs for each millionth of a satoshi forwarded. - FeeProportionalMillionths lnwire.MilliSatoshi - - // ToNode is the public key of the node that this directed edge leads - // to. Using this pub key, the channel graph can further be traversed. - ToNode [33]byte - - // 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 -} - -// Signature is a channel announcement signature, which is needed for proper -// edge policy announcement. -// -// NOTE: By having this method to access an attribute, we ensure we only need -// to fully deserialize the signature if absolutely necessary. -func (c *ChannelEdgePolicy) Signature() (*ecdsa.Signature, error) { - if c.sig != nil { - return c.sig, nil - } - - sig, err := ecdsa.ParseSignature(c.SigBytes) - if err != nil { - return nil, err - } - - c.sig = sig - - return sig, nil -} - -// SetSigBytes updates the signature and invalidates the cached parsed -// signature. -func (c *ChannelEdgePolicy) SetSigBytes(sig []byte) { - c.SigBytes = sig - c.sig = nil -} - -// IsDisabled determines whether the edge has the disabled bit set. -func (c *ChannelEdgePolicy) IsDisabled() bool { - return c.ChannelFlags.IsDisabled() -} - -// ComputeFee computes the fee to forward an HTLC of `amt` milli-satoshis over -// the passed active payment channel. This value is currently computed as -// specified in BOLT07, but will likely change in the near future. -func (c *ChannelEdgePolicy) ComputeFee( - amt lnwire.MilliSatoshi) lnwire.MilliSatoshi { - - return c.FeeBaseMSat + (amt*c.FeeProportionalMillionths)/feeRateParts -} - -// divideCeil divides dividend by factor and rounds the result up. -func divideCeil(dividend, factor lnwire.MilliSatoshi) lnwire.MilliSatoshi { - return (dividend + factor - 1) / factor -} - -// ComputeFeeFromIncoming computes the fee to forward an HTLC given the incoming -// amount. -func (c *ChannelEdgePolicy) ComputeFeeFromIncoming( - incomingAmt lnwire.MilliSatoshi) lnwire.MilliSatoshi { - - return incomingAmt - divideCeil( - feeRateParts*(incomingAmt-c.FeeBaseMSat), - feeRateParts+c.FeeProportionalMillionths, - ) -} - // FetchChannelEdgesByOutpoint attempts to lookup the two directed edges for // the channel identified by the funding outpoint. If the channel can't be // found, then ErrEdgeNotFound is returned. A struct which houses the general // information for the channel itself is returned as well as two structs that // contain the routing policies for the channel in either direction. func (c *ChannelGraph) FetchChannelEdgesByOutpoint(op *wire.OutPoint, -) (*ChannelEdgeInfo, *ChannelEdgePolicy, *ChannelEdgePolicy, error) { +) (*models.ChannelEdgeInfo, *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) { var ( - edgeInfo *ChannelEdgeInfo - policy1 *ChannelEdgePolicy - policy2 *ChannelEdgePolicy + edgeInfo *models.ChannelEdgeInfo + policy1 *models.ChannelEdgePolicy + policy2 *models.ChannelEdgePolicy ) err := kvdb.View(c.db, func(tx kvdb.RTx) error { @@ -3632,12 +3202,12 @@ func (c *ChannelGraph) FetchChannelEdgesByOutpoint(op *wire.OutPoint, // within the database. In this case, the ChannelEdgePolicy's will be nil, and // the ChannelEdgeInfo will only include the public keys of each node. func (c *ChannelGraph) FetchChannelEdgesByID(chanID uint64, -) (*ChannelEdgeInfo, *ChannelEdgePolicy, *ChannelEdgePolicy, error) { +) (*models.ChannelEdgeInfo, *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) { var ( - edgeInfo *ChannelEdgeInfo - policy1 *ChannelEdgePolicy - policy2 *ChannelEdgePolicy + edgeInfo *models.ChannelEdgeInfo + policy1 *models.ChannelEdgePolicy + policy2 *models.ChannelEdgePolicy channelID [8]byte ) @@ -3688,7 +3258,7 @@ func (c *ChannelGraph) 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 = &ChannelEdgeInfo{ + edgeInfo = &models.ChannelEdgeInfo{ NodeKey1Bytes: pubKey1, NodeKey2Bytes: pubKey2, } @@ -4334,7 +3904,7 @@ func deserializeLightningNode(r io.Reader) (LightningNode, error) { return node, nil } -func putChanEdgeInfo(edgeIndex kvdb.RwBucket, edgeInfo *ChannelEdgeInfo, chanID [8]byte) error { +func putChanEdgeInfo(edgeIndex kvdb.RwBucket, edgeInfo *models.ChannelEdgeInfo, chanID [8]byte) error { var b bytes.Buffer if _, err := b.Write(edgeInfo.NodeKey1Bytes[:]); err != nil { @@ -4401,58 +3971,58 @@ func putChanEdgeInfo(edgeIndex kvdb.RwBucket, edgeInfo *ChannelEdgeInfo, chanID } func fetchChanEdgeInfo(edgeIndex kvdb.RBucket, - chanID []byte) (ChannelEdgeInfo, error) { + chanID []byte) (models.ChannelEdgeInfo, error) { edgeInfoBytes := edgeIndex.Get(chanID) if edgeInfoBytes == nil { - return ChannelEdgeInfo{}, ErrEdgeNotFound + return models.ChannelEdgeInfo{}, ErrEdgeNotFound } edgeInfoReader := bytes.NewReader(edgeInfoBytes) return deserializeChanEdgeInfo(edgeInfoReader) } -func deserializeChanEdgeInfo(r io.Reader) (ChannelEdgeInfo, error) { +func deserializeChanEdgeInfo(r io.Reader) (models.ChannelEdgeInfo, error) { var ( err error - edgeInfo ChannelEdgeInfo + edgeInfo models.ChannelEdgeInfo ) if _, err := io.ReadFull(r, edgeInfo.NodeKey1Bytes[:]); err != nil { - return ChannelEdgeInfo{}, err + return models.ChannelEdgeInfo{}, err } if _, err := io.ReadFull(r, edgeInfo.NodeKey2Bytes[:]); err != nil { - return ChannelEdgeInfo{}, err + return models.ChannelEdgeInfo{}, err } if _, err := io.ReadFull(r, edgeInfo.BitcoinKey1Bytes[:]); err != nil { - return ChannelEdgeInfo{}, err + return models.ChannelEdgeInfo{}, err } if _, err := io.ReadFull(r, edgeInfo.BitcoinKey2Bytes[:]); err != nil { - return ChannelEdgeInfo{}, err + return models.ChannelEdgeInfo{}, err } edgeInfo.Features, err = wire.ReadVarBytes(r, 0, 900, "features") if err != nil { - return ChannelEdgeInfo{}, err + return models.ChannelEdgeInfo{}, err } - proof := &ChannelAuthProof{} + proof := &models.ChannelAuthProof{} proof.NodeSig1Bytes, err = wire.ReadVarBytes(r, 0, 80, "sigs") if err != nil { - return ChannelEdgeInfo{}, err + return models.ChannelEdgeInfo{}, err } proof.NodeSig2Bytes, err = wire.ReadVarBytes(r, 0, 80, "sigs") if err != nil { - return ChannelEdgeInfo{}, err + return models.ChannelEdgeInfo{}, err } proof.BitcoinSig1Bytes, err = wire.ReadVarBytes(r, 0, 80, "sigs") if err != nil { - return ChannelEdgeInfo{}, err + return models.ChannelEdgeInfo{}, err } proof.BitcoinSig2Bytes, err = wire.ReadVarBytes(r, 0, 80, "sigs") if err != nil { - return ChannelEdgeInfo{}, err + return models.ChannelEdgeInfo{}, err } if !proof.IsEmpty() { @@ -4461,17 +4031,17 @@ func deserializeChanEdgeInfo(r io.Reader) (ChannelEdgeInfo, error) { edgeInfo.ChannelPoint = wire.OutPoint{} if err := readOutpoint(r, &edgeInfo.ChannelPoint); err != nil { - return ChannelEdgeInfo{}, err + return models.ChannelEdgeInfo{}, err } if err := binary.Read(r, byteOrder, &edgeInfo.Capacity); err != nil { - return ChannelEdgeInfo{}, err + return models.ChannelEdgeInfo{}, err } if err := binary.Read(r, byteOrder, &edgeInfo.ChannelID); err != nil { - return ChannelEdgeInfo{}, err + return models.ChannelEdgeInfo{}, err } if _, err := io.ReadFull(r, edgeInfo.ChainHash[:]); err != nil { - return ChannelEdgeInfo{}, err + return models.ChannelEdgeInfo{}, err } // We'll try and see if there are any opaque bytes left, if not, then @@ -4483,13 +4053,13 @@ func deserializeChanEdgeInfo(r io.Reader) (ChannelEdgeInfo, error) { case err == io.ErrUnexpectedEOF: case err == io.EOF: case err != nil: - return ChannelEdgeInfo{}, err + return models.ChannelEdgeInfo{}, err } return edgeInfo, nil } -func putChanEdgePolicy(edges kvdb.RwBucket, edge *ChannelEdgePolicy, from, +func putChanEdgePolicy(edges kvdb.RwBucket, edge *models.ChannelEdgePolicy, from, to []byte) error { var edgeKey [33 + 8]byte @@ -4610,7 +4180,7 @@ func putChanEdgePolicyUnknown(edges kvdb.RwBucket, channelID uint64, } func fetchChanEdgePolicy(edges kvdb.RBucket, chanID []byte, - nodePub []byte) (*ChannelEdgePolicy, error) { + nodePub []byte) (*models.ChannelEdgePolicy, error) { var edgeKey [33 + 8]byte copy(edgeKey[:], nodePub) @@ -4643,7 +4213,7 @@ func fetchChanEdgePolicy(edges kvdb.RBucket, chanID []byte, } func fetchChanEdgePolicies(edgeIndex kvdb.RBucket, edges kvdb.RBucket, - chanID []byte) (*ChannelEdgePolicy, *ChannelEdgePolicy, error) { + chanID []byte) (*models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) { edgeInfo := edgeIndex.Get(chanID) if edgeInfo == nil { @@ -4670,7 +4240,7 @@ func fetchChanEdgePolicies(edgeIndex kvdb.RBucket, edges kvdb.RBucket, return edge1, edge2, nil } -func serializeChanEdgePolicy(w io.Writer, edge *ChannelEdgePolicy, +func serializeChanEdgePolicy(w io.Writer, edge *models.ChannelEdgePolicy, to []byte) error { err := wire.WriteVarBytes(w, 0, edge.SigBytes) @@ -4737,7 +4307,7 @@ func serializeChanEdgePolicy(w io.Writer, edge *ChannelEdgePolicy, return nil } -func deserializeChanEdgePolicy(r io.Reader) (*ChannelEdgePolicy, error) { +func deserializeChanEdgePolicy(r io.Reader) (*models.ChannelEdgePolicy, error) { // Deserialize the policy. Note that in case an optional field is not // found, both an error and a populated policy object are returned. edge, deserializeErr := deserializeChanEdgePolicyRaw(r) @@ -4750,8 +4320,8 @@ func deserializeChanEdgePolicy(r io.Reader) (*ChannelEdgePolicy, error) { return edge, deserializeErr } -func deserializeChanEdgePolicyRaw(r io.Reader) (*ChannelEdgePolicy, error) { - edge := &ChannelEdgePolicy{} +func deserializeChanEdgePolicyRaw(r io.Reader) (*models.ChannelEdgePolicy, error) { + edge := &models.ChannelEdgePolicy{} var err error edge.SigBytes, err = wire.ReadVarBytes(r, 0, 80, "sig") diff --git a/channeldb/graph_cache.go b/channeldb/graph_cache.go index 84e340b56..9e142ed73 100644 --- a/channeldb/graph_cache.go +++ b/channeldb/graph_cache.go @@ -5,6 +5,7 @@ import ( "sync" "github.com/btcsuite/btcd/btcutil" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" @@ -27,94 +28,8 @@ type GraphCacheNode interface { // error, then the iteration is halted with the error propagated back up // to the caller. ForEachChannel(kvdb.RTx, - func(kvdb.RTx, *ChannelEdgeInfo, *ChannelEdgePolicy, - *ChannelEdgePolicy) error) error -} - -// CachedEdgePolicy is a struct that only caches the information of a -// ChannelEdgePolicy that we actually use for pathfinding and therefore need to -// store in the cache. -type CachedEdgePolicy struct { - // ChannelID is the unique channel ID for the channel. The first 3 - // bytes are the block height, the next 3 the index within the block, - // and the last 2 bytes are the output index for the channel. - ChannelID uint64 - - // MessageFlags is a bitfield which indicates the presence of optional - // fields (like max_htlc) in the policy. - MessageFlags lnwire.ChanUpdateMsgFlags - - // ChannelFlags is a bitfield which signals the capabilities of the - // channel as well as the directed edge this update applies to. - ChannelFlags lnwire.ChanUpdateChanFlags - - // TimeLockDelta is the number of blocks this node will subtract from - // the expiry of an incoming HTLC. This value expresses the time buffer - // the node would like to HTLC exchanges. - TimeLockDelta uint16 - - // MinHTLC is the smallest value HTLC this node will forward, expressed - // in millisatoshi. - MinHTLC lnwire.MilliSatoshi - - // MaxHTLC is the largest value HTLC this node will forward, expressed - // in millisatoshi. - MaxHTLC lnwire.MilliSatoshi - - // FeeBaseMSat is the base HTLC fee that will be charged for forwarding - // ANY HTLC, expressed in mSAT's. - FeeBaseMSat lnwire.MilliSatoshi - - // FeeProportionalMillionths is the rate that the node will charge for - // HTLCs for each millionth of a satoshi forwarded. - FeeProportionalMillionths lnwire.MilliSatoshi - - // ToNodePubKey is a function that returns the to node of a policy. - // Since we only ever store the inbound policy, this is always the node - // that we query the channels for in ForEachChannel(). Therefore, we can - // save a lot of space by not storing this information in the memory and - // instead just set this function when we copy the policy from cache in - // ForEachChannel(). - ToNodePubKey func() route.Vertex - - // ToNodeFeatures are the to node's features. They are never set while - // the edge is in the cache, only on the copy that is returned in - // ForEachChannel(). - ToNodeFeatures *lnwire.FeatureVector -} - -// ComputeFee computes the fee to forward an HTLC of `amt` milli-satoshis over -// the passed active payment channel. This value is currently computed as -// specified in BOLT07, but will likely change in the near future. -func (c *CachedEdgePolicy) ComputeFee( - amt lnwire.MilliSatoshi) lnwire.MilliSatoshi { - - return c.FeeBaseMSat + (amt*c.FeeProportionalMillionths)/feeRateParts -} - -// ComputeFeeFromIncoming computes the fee to forward an HTLC given the incoming -// amount. -func (c *CachedEdgePolicy) ComputeFeeFromIncoming( - incomingAmt lnwire.MilliSatoshi) lnwire.MilliSatoshi { - - return incomingAmt - divideCeil( - feeRateParts*(incomingAmt-c.FeeBaseMSat), - feeRateParts+c.FeeProportionalMillionths, - ) -} - -// NewCachedPolicy turns a full policy into a minimal one that can be cached. -func NewCachedPolicy(policy *ChannelEdgePolicy) *CachedEdgePolicy { - return &CachedEdgePolicy{ - ChannelID: policy.ChannelID, - MessageFlags: policy.MessageFlags, - ChannelFlags: policy.ChannelFlags, - TimeLockDelta: policy.TimeLockDelta, - MinHTLC: policy.MinHTLC, - MaxHTLC: policy.MaxHTLC, - FeeBaseMSat: policy.FeeBaseMSat, - FeeProportionalMillionths: policy.FeeProportionalMillionths, - } + func(kvdb.RTx, *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy) error) error } // DirectedChannel is a type that stores the channel information as seen from @@ -142,7 +57,7 @@ type DirectedChannel struct { // In path finding, we're walking backward from the destination to the // source, so we're always interested in the edge that arrives to us // from the other node. - InPolicy *CachedEdgePolicy + InPolicy *models.CachedEdgePolicy } // DeepCopy creates a deep copy of the channel, including the incoming policy. @@ -223,9 +138,9 @@ func (c *GraphCache) AddNode(tx kvdb.RTx, node GraphCacheNode) error { c.AddNodeFeatures(node) return node.ForEachChannel( - tx, func(tx kvdb.RTx, info *ChannelEdgeInfo, - outPolicy *ChannelEdgePolicy, - inPolicy *ChannelEdgePolicy) error { + tx, func(tx kvdb.RTx, info *models.ChannelEdgeInfo, + outPolicy *models.ChannelEdgePolicy, + inPolicy *models.ChannelEdgePolicy) error { c.AddChannel(info, outPolicy, inPolicy) @@ -238,8 +153,8 @@ func (c *GraphCache) AddNode(tx kvdb.RTx, node GraphCacheNode) error { // and policy 2 does not matter, the directionality is extracted from the info // and policy flags automatically. The policy will be set as the outgoing policy // on one node and the incoming policy on the peer's side. -func (c *GraphCache) AddChannel(info *ChannelEdgeInfo, - policy1 *ChannelEdgePolicy, policy2 *ChannelEdgePolicy) { +func (c *GraphCache) AddChannel(info *models.ChannelEdgeInfo, + policy1 *models.ChannelEdgePolicy, policy2 *models.ChannelEdgePolicy) { if info == nil { return @@ -301,7 +216,7 @@ func (c *GraphCache) updateOrAddEdge(node route.Vertex, edge *DirectedChannel) { // of the from and to node is not strictly important. But we assume that a // channel edge was added beforehand so that the directed channel struct already // exists in the cache. -func (c *GraphCache) UpdatePolicy(policy *ChannelEdgePolicy, fromNode, +func (c *GraphCache) UpdatePolicy(policy *models.ChannelEdgePolicy, fromNode, toNode route.Vertex, edge1 bool) { c.mtx.Lock() @@ -333,7 +248,7 @@ func (c *GraphCache) UpdatePolicy(policy *ChannelEdgePolicy, fromNode, // The other two cases left mean it's the inbound policy for the // node. default: - channel.InPolicy = NewCachedPolicy(policy) + channel.InPolicy = models.NewCachedPolicy(policy) } } @@ -380,7 +295,7 @@ func (c *GraphCache) removeChannelIfFound(node route.Vertex, chanID uint64) { // UpdateChannel updates the channel edge information for a specific edge. We // expect the edge to already exist and be known. If it does not yet exist, this // call is a no-op. -func (c *GraphCache) UpdateChannel(info *ChannelEdgeInfo) { +func (c *GraphCache) UpdateChannel(info *models.ChannelEdgeInfo) { c.mtx.Lock() defer c.mtx.Unlock() diff --git a/channeldb/graph_cache_test.go b/channeldb/graph_cache_test.go index 4a6711191..f2b0c52f9 100644 --- a/channeldb/graph_cache_test.go +++ b/channeldb/graph_cache_test.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "testing" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" @@ -28,9 +29,9 @@ type node struct { pubKey route.Vertex features *lnwire.FeatureVector - edgeInfos []*ChannelEdgeInfo - outPolicies []*ChannelEdgePolicy - inPolicies []*ChannelEdgePolicy + edgeInfos []*models.ChannelEdgeInfo + outPolicies []*models.ChannelEdgePolicy + inPolicies []*models.ChannelEdgePolicy } func (n *node) PubKey() route.Vertex { @@ -41,8 +42,8 @@ func (n *node) Features() *lnwire.FeatureVector { } func (n *node) ForEachChannel(tx kvdb.RTx, - cb func(kvdb.RTx, *ChannelEdgeInfo, *ChannelEdgePolicy, - *ChannelEdgePolicy) error) error { + cb func(kvdb.RTx, *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy) error) error { for idx := range n.edgeInfos { err := cb( @@ -70,12 +71,12 @@ func TestGraphCacheAddNode(t *testing.T) { channelFlagA, channelFlagB = 1, 0 } - outPolicy1 := &ChannelEdgePolicy{ + outPolicy1 := &models.ChannelEdgePolicy{ ChannelID: 1000, ChannelFlags: lnwire.ChanUpdateChanFlags(channelFlagA), ToNode: nodeB, } - inPolicy1 := &ChannelEdgePolicy{ + inPolicy1 := &models.ChannelEdgePolicy{ ChannelID: 1000, ChannelFlags: lnwire.ChanUpdateChanFlags(channelFlagB), ToNode: nodeA, @@ -83,15 +84,15 @@ func TestGraphCacheAddNode(t *testing.T) { node := &node{ pubKey: nodeA, features: lnwire.EmptyFeatureVector(), - edgeInfos: []*ChannelEdgeInfo{{ + edgeInfos: []*models.ChannelEdgeInfo{{ ChannelID: 1000, // Those are direction independent! NodeKey1Bytes: pubKey1, NodeKey2Bytes: pubKey2, Capacity: 500, }}, - outPolicies: []*ChannelEdgePolicy{outPolicy1}, - inPolicies: []*ChannelEdgePolicy{inPolicy1}, + outPolicies: []*models.ChannelEdgePolicy{outPolicy1}, + inPolicies: []*models.ChannelEdgePolicy{inPolicy1}, } cache := NewGraphCache(10) require.NoError(t, cache.AddNode(nil, node)) @@ -138,8 +139,8 @@ func TestGraphCacheAddNode(t *testing.T) { runTest(pubKey2, pubKey1) } -func assertCachedPolicyEqual(t *testing.T, original *ChannelEdgePolicy, - cached *CachedEdgePolicy) { +func assertCachedPolicyEqual(t *testing.T, original *models.ChannelEdgePolicy, + cached *models.CachedEdgePolicy) { require.Equal(t, original.ChannelID, cached.ChannelID) require.Equal(t, original.MessageFlags, cached.MessageFlags) diff --git a/channeldb/graph_test.go b/channeldb/graph_test.go index f88c46726..25336d28d 100644 --- a/channeldb/graph_test.go +++ b/channeldb/graph_test.go @@ -22,6 +22,7 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/davecgh/go-spew/spew" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" @@ -324,10 +325,10 @@ 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 := ChannelEdgeInfo{ + edgeInfo := models.ChannelEdgeInfo{ ChannelID: chanID, ChainHash: key, - AuthProof: &ChannelAuthProof{ + AuthProof: &models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), @@ -384,7 +385,7 @@ func TestEdgeInsertionDeletion(t *testing.T) { } func createEdge(height, txIndex uint32, txPosition uint16, outPointIndex uint32, - node1, node2 *LightningNode) (ChannelEdgeInfo, lnwire.ShortChannelID) { + node1, node2 *LightningNode) (models.ChannelEdgeInfo, lnwire.ShortChannelID) { shortChanID := lnwire.ShortChannelID{ BlockHeight: height, @@ -398,10 +399,10 @@ func createEdge(height, txIndex uint32, txPosition uint16, outPointIndex uint32, node1Pub, _ := node1.PubKey() node2Pub, _ := node2.PubKey() - edgeInfo := ChannelEdgeInfo{ + edgeInfo := models.ChannelEdgeInfo{ ChannelID: shortChanID.ToUint64(), ChainHash: key, - AuthProof: &ChannelAuthProof{ + AuthProof: &models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), @@ -553,8 +554,8 @@ func TestDisconnectBlockAtHeight(t *testing.T) { } } -func assertEdgeInfoEqual(t *testing.T, e1 *ChannelEdgeInfo, - e2 *ChannelEdgeInfo) { +func assertEdgeInfoEqual(t *testing.T, e1 *models.ChannelEdgeInfo, + e2 *models.ChannelEdgeInfo) { if e1.ChannelID != e2.ChannelID { t.Fatalf("chan id's don't match: %v vs %v", e1.ChannelID, @@ -615,8 +616,8 @@ func assertEdgeInfoEqual(t *testing.T, e1 *ChannelEdgeInfo, } } -func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) (*ChannelEdgeInfo, - *ChannelEdgePolicy, *ChannelEdgePolicy) { +func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) (*models.ChannelEdgeInfo, + *models.ChannelEdgePolicy, *models.ChannelEdgePolicy) { var ( firstNode [33]byte @@ -640,10 +641,10 @@ func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) (*ChannelEd // Add the new edge to the database, this should proceed without any // errors. - edgeInfo := &ChannelEdgeInfo{ + edgeInfo := &models.ChannelEdgeInfo{ ChannelID: chanID, ChainHash: key, - AuthProof: &ChannelAuthProof{ + AuthProof: &models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), @@ -658,7 +659,7 @@ func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) (*ChannelEd copy(edgeInfo.BitcoinKey1Bytes[:], firstNode[:]) copy(edgeInfo.BitcoinKey2Bytes[:], secondNode[:]) - edge1 := &ChannelEdgePolicy{ + edge1 := &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), ChannelID: chanID, LastUpdate: time.Unix(433453, 0), @@ -672,7 +673,7 @@ func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) (*ChannelEd ToNode: secondNode, ExtraOpaqueData: []byte("new unknown feature2"), } - edge2 := &ChannelEdgePolicy{ + edge2 := &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), ChannelID: chanID, LastUpdate: time.Unix(124234, 0), @@ -817,7 +818,7 @@ func assertNodeNotInCache(t *testing.T, g *ChannelGraph, n route.Vertex) { } func assertEdgeWithNoPoliciesInCache(t *testing.T, g *ChannelGraph, - e *ChannelEdgeInfo) { + e *models.ChannelEdgeInfo) { // Let's check the internal view first. require.NotEmpty(t, g.graphCache.nodeChannels[e.NodeKey1Bytes]) @@ -895,7 +896,7 @@ func assertNoEdge(t *testing.T, g *ChannelGraph, chanID uint64) { } func assertEdgeWithPolicyInCache(t *testing.T, g *ChannelGraph, - e *ChannelEdgeInfo, p *ChannelEdgePolicy, policy1 bool) { + e *models.ChannelEdgeInfo, p *models.ChannelEdgePolicy, policy1 bool) { // Check the internal state first. c1, ok := g.graphCache.nodeChannels[e.NodeKey1Bytes][e.ChannelID] @@ -971,16 +972,16 @@ func assertEdgeWithPolicyInCache(t *testing.T, g *ChannelGraph, } } -func randEdgePolicy(chanID uint64, db kvdb.Backend) *ChannelEdgePolicy { +func randEdgePolicy(chanID uint64, db kvdb.Backend) *models.ChannelEdgePolicy { update := prand.Int63() return newEdgePolicy(chanID, db, update) } func newEdgePolicy(chanID uint64, db kvdb.Backend, - updateTime int64) *ChannelEdgePolicy { + updateTime int64) *models.ChannelEdgePolicy { - return &ChannelEdgePolicy{ + return &models.ChannelEdgePolicy{ ChannelID: chanID, LastUpdate: time.Unix(updateTime, 0), MessageFlags: 1, @@ -1037,8 +1038,8 @@ func TestGraphTraversal(t *testing.T) { // Iterate through all the known channels within the graph DB, once // again if the map is empty that indicates that all edges have // properly been reached. - err = graph.ForEachChannel(func(ei *ChannelEdgeInfo, _ *ChannelEdgePolicy, - _ *ChannelEdgePolicy) error { + err = graph.ForEachChannel(func(ei *models.ChannelEdgeInfo, _ *models.ChannelEdgePolicy, + _ *models.ChannelEdgePolicy) error { delete(chanIndex, ei.ChannelID) return nil @@ -1051,8 +1052,8 @@ func TestGraphTraversal(t *testing.T) { numNodeChans := 0 firstNode, secondNode := nodeList[0], nodeList[1] err = graph.ForEachNodeChannel(nil, firstNode.PubKeyBytes, - func(_ kvdb.RTx, _ *ChannelEdgeInfo, outEdge, - inEdge *ChannelEdgePolicy) error { + func(_ kvdb.RTx, _ *models.ChannelEdgeInfo, outEdge, + inEdge *models.ChannelEdgePolicy) error { // All channels between first and second node should // have fully (both sides) specified policies. @@ -1131,9 +1132,9 @@ func TestGraphTraversalCacheable(t *testing.T) { err = graph.db.View(func(tx kvdb.RTx) error { for _, node := range nodes { err := node.ForEachChannel( - tx, func(tx kvdb.RTx, info *ChannelEdgeInfo, - policy *ChannelEdgePolicy, - policy2 *ChannelEdgePolicy) error { + tx, func(tx kvdb.RTx, info *models.ChannelEdgeInfo, + policy *models.ChannelEdgePolicy, + policy2 *models.ChannelEdgePolicy) error { delete(chanIndex, info.ChannelID) return nil @@ -1251,10 +1252,10 @@ func fillTestGraph(t require.TestingT, graph *ChannelGraph, numNodes, Index: 0, } - edgeInfo := ChannelEdgeInfo{ + edgeInfo := models.ChannelEdgeInfo{ ChannelID: chanID, ChainHash: key, - AuthProof: &ChannelAuthProof{ + AuthProof: &models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), @@ -1315,8 +1316,8 @@ func assertPruneTip(t *testing.T, graph *ChannelGraph, blockHash *chainhash.Hash func assertNumChans(t *testing.T, graph *ChannelGraph, n int) { numChans := 0 - if err := graph.ForEachChannel(func(*ChannelEdgeInfo, *ChannelEdgePolicy, - *ChannelEdgePolicy) error { + if err := graph.ForEachChannel(func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy) error { numChans++ return nil @@ -1432,10 +1433,10 @@ func TestGraphPruning(t *testing.T) { channelPoints = append(channelPoints, &op) - edgeInfo := ChannelEdgeInfo{ + edgeInfo := models.ChannelEdgeInfo{ ChannelID: chanID, ChainHash: key, - AuthProof: &ChannelAuthProof{ + AuthProof: &models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), @@ -2283,8 +2284,8 @@ func TestIncompleteChannelPolicies(t *testing.T) { checkPolicies := func(node *LightningNode, expectedIn, expectedOut bool) { calls := 0 err := graph.ForEachNodeChannel(nil, node.PubKeyBytes, - func(_ kvdb.RTx, _ *ChannelEdgeInfo, outEdge, - inEdge *ChannelEdgePolicy) error { + func(_ kvdb.RTx, _ *models.ChannelEdgeInfo, outEdge, + inEdge *models.ChannelEdgePolicy) error { if !expectedOut && outEdge != nil { t.Fatalf("Expected no outgoing policy") @@ -2701,7 +2702,7 @@ func TestNodeIsPublic(t *testing.T) { // After creating all of our nodes and edges, we'll add them to each // participant's graph. nodes := []*LightningNode{aliceNode, bobNode, carolNode} - edges := []*ChannelEdgeInfo{&aliceBobEdge, &bobCarolEdge} + edges := []*models.ChannelEdgeInfo{&aliceBobEdge, &bobCarolEdge} graphs := []*ChannelGraph{aliceGraph, bobGraph, carolGraph} for _, graph := range graphs { for _, node := range nodes { @@ -3153,7 +3154,7 @@ func compareNodes(a, b *LightningNode) error { // compareEdgePolicies is used to compare two ChannelEdgePolices using // compareNodes, so as to exclude comparisons of the Nodes' Features struct. -func compareEdgePolicies(a, b *ChannelEdgePolicy) error { +func compareEdgePolicies(a, b *models.ChannelEdgePolicy) error { if a.ChannelID != b.ChannelID { return fmt.Errorf("ChannelID doesn't match: expected %v, "+ "got %v", a.ChannelID, b.ChannelID) @@ -3245,7 +3246,7 @@ func TestLightningNodeSigVerification(t *testing.T) { // TestComputeFee tests fee calculation based on both in- and outgoing amt. func TestComputeFee(t *testing.T) { var ( - policy = ChannelEdgePolicy{ + policy = models.ChannelEdgePolicy{ FeeBaseMSat: 10000, FeeProportionalMillionths: 30000, } @@ -3319,7 +3320,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 := []ChannelEdgeInfo{edgeInfo, edgeInfo2, edgeInfo3} + edges := []models.ChannelEdgeInfo{edgeInfo, edgeInfo2, edgeInfo3} errChan := make(chan error, len(edges)) errTimeout := errors.New("timeout adding batched channel") @@ -3327,7 +3328,7 @@ func TestBatchedAddChannelEdge(t *testing.T) { var wg sync.WaitGroup for _, edge := range edges { wg.Add(1) - go func(edge ChannelEdgeInfo) { + go func(edge models.ChannelEdgeInfo) { defer wg.Done() select { @@ -3378,7 +3379,7 @@ func TestBatchedUpdateEdgePolicy(t *testing.T) { errTimeout := errors.New("timeout adding batched channel") - updates := []*ChannelEdgePolicy{edge1, edge2} + updates := []*models.ChannelEdgePolicy{edge1, edge2} errChan := make(chan error, len(updates)) @@ -3386,7 +3387,7 @@ func TestBatchedUpdateEdgePolicy(t *testing.T) { var wg sync.WaitGroup for _, update := range updates { wg.Add(1) - go func(update *ChannelEdgePolicy) { + go func(update *models.ChannelEdgePolicy) { defer wg.Done() select { @@ -3436,9 +3437,9 @@ func BenchmarkForEachChannel(b *testing.B) { for _, n := range nodes { err := n.ForEachChannel( tx, func(tx kvdb.RTx, - info *ChannelEdgeInfo, - policy *ChannelEdgePolicy, - policy2 *ChannelEdgePolicy) error { + info *models.ChannelEdgeInfo, + policy *models.ChannelEdgePolicy, + policy2 *models.ChannelEdgePolicy) error { // We need to do something with // the data here, otherwise the diff --git a/channeldb/models/cached_edge_policy.go b/channeldb/models/cached_edge_policy.go new file mode 100644 index 000000000..25bef567e --- /dev/null +++ b/channeldb/models/cached_edge_policy.go @@ -0,0 +1,97 @@ +package models + +import ( + "github.com/lightningnetwork/lnd/lnwire" + "github.com/lightningnetwork/lnd/routing/route" +) + +const ( + // feeRateParts is the total number of parts used to express fee rates. + feeRateParts = 1e6 +) + +// CachedEdgePolicy is a struct that only caches the information of a +// ChannelEdgePolicy that we actually use for pathfinding and therefore need to +// store in the cache. +type CachedEdgePolicy struct { + // ChannelID is the unique channel ID for the channel. The first 3 + // bytes are the block height, the next 3 the index within the block, + // and the last 2 bytes are the output index for the channel. + ChannelID uint64 + + // MessageFlags is a bitfield which indicates the presence of optional + // fields (like max_htlc) in the policy. + MessageFlags lnwire.ChanUpdateMsgFlags + + // ChannelFlags is a bitfield which signals the capabilities of the + // channel as well as the directed edge this update applies to. + ChannelFlags lnwire.ChanUpdateChanFlags + + // TimeLockDelta is the number of blocks this node will subtract from + // the expiry of an incoming HTLC. This value expresses the time buffer + // the node would like to HTLC exchanges. + TimeLockDelta uint16 + + // MinHTLC is the smallest value HTLC this node will forward, expressed + // in millisatoshi. + MinHTLC lnwire.MilliSatoshi + + // MaxHTLC is the largest value HTLC this node will forward, expressed + // in millisatoshi. + MaxHTLC lnwire.MilliSatoshi + + // FeeBaseMSat is the base HTLC fee that will be charged for forwarding + // ANY HTLC, expressed in mSAT's. + FeeBaseMSat lnwire.MilliSatoshi + + // FeeProportionalMillionths is the rate that the node will charge for + // HTLCs for each millionth of a satoshi forwarded. + FeeProportionalMillionths lnwire.MilliSatoshi + + // ToNodePubKey is a function that returns the to node of a policy. + // Since we only ever store the inbound policy, this is always the node + // that we query the channels for in ForEachChannel(). Therefore, we can + // save a lot of space by not storing this information in the memory and + // instead just set this function when we copy the policy from cache in + // ForEachChannel(). + ToNodePubKey func() route.Vertex + + // ToNodeFeatures are the to node's features. They are never set while + // the edge is in the cache, only on the copy that is returned in + // ForEachChannel(). + ToNodeFeatures *lnwire.FeatureVector +} + +// ComputeFee computes the fee to forward an HTLC of `amt` milli-satoshis over +// the passed active payment channel. This value is currently computed as +// specified in BOLT07, but will likely change in the near future. +func (c *CachedEdgePolicy) ComputeFee( + amt lnwire.MilliSatoshi) lnwire.MilliSatoshi { + + return c.FeeBaseMSat + (amt*c.FeeProportionalMillionths)/feeRateParts +} + +// ComputeFeeFromIncoming computes the fee to forward an HTLC given the incoming +// amount. +func (c *CachedEdgePolicy) ComputeFeeFromIncoming( + incomingAmt lnwire.MilliSatoshi) lnwire.MilliSatoshi { + + return incomingAmt - divideCeil( + feeRateParts*(incomingAmt-c.FeeBaseMSat), + feeRateParts+c.FeeProportionalMillionths, + ) +} + +// NewCachedPolicy turns a full policy into a minimal one that can be cached. +func NewCachedPolicy(policy *ChannelEdgePolicy) *CachedEdgePolicy { + return &CachedEdgePolicy{ + ChannelID: policy.ChannelID, + MessageFlags: policy.MessageFlags, + ChannelFlags: policy.ChannelFlags, + TimeLockDelta: policy.TimeLockDelta, + MinHTLC: policy.MinHTLC, + MaxHTLC: policy.MaxHTLC, + FeeBaseMSat: policy.FeeBaseMSat, + FeeProportionalMillionths: policy.FeeProportionalMillionths, + } +} diff --git a/channeldb/models/channel_auth_proof.go b/channeldb/models/channel_auth_proof.go new file mode 100644 index 000000000..134139467 --- /dev/null +++ b/channeldb/models/channel_auth_proof.go @@ -0,0 +1,131 @@ +package models + +import "github.com/btcsuite/btcd/btcec/v2/ecdsa" + +// ChannelAuthProof is the authentication proof (the signature portion) for a +// channel. Using the four signatures contained in the struct, and some +// auxiliary knowledge (the funding script, node identities, and outpoint) nodes +// on the network are able to validate the authenticity and existence of a +// channel. Each of these signatures signs the following digest: chanID || +// nodeID1 || nodeID2 || bitcoinKey1|| bitcoinKey2 || 2-byte-feature-len || +// features. +type ChannelAuthProof struct { + // nodeSig1 is a cached instance of the first node signature. + nodeSig1 *ecdsa.Signature + + // NodeSig1Bytes are the raw bytes of the first node signature encoded + // in DER format. + NodeSig1Bytes []byte + + // nodeSig2 is a cached instance of the second node signature. + nodeSig2 *ecdsa.Signature + + // NodeSig2Bytes are the raw bytes of the second node signature + // encoded in DER format. + NodeSig2Bytes []byte + + // bitcoinSig1 is a cached instance of the first bitcoin signature. + bitcoinSig1 *ecdsa.Signature + + // BitcoinSig1Bytes are the raw bytes of the first bitcoin signature + // encoded in DER format. + BitcoinSig1Bytes []byte + + // bitcoinSig2 is a cached instance of the second bitcoin signature. + bitcoinSig2 *ecdsa.Signature + + // BitcoinSig2Bytes are the raw bytes of the second bitcoin signature + // encoded in DER format. + BitcoinSig2Bytes []byte +} + +// Node1Sig is the signature using the identity key of the node that is first +// in a lexicographical ordering of the serialized public keys of the two nodes +// that created the channel. +// +// NOTE: By having this method to access an attribute, we ensure we only need +// to fully deserialize the signature if absolutely necessary. +func (c *ChannelAuthProof) Node1Sig() (*ecdsa.Signature, error) { + if c.nodeSig1 != nil { + return c.nodeSig1, nil + } + + sig, err := ecdsa.ParseSignature(c.NodeSig1Bytes) + if err != nil { + return nil, err + } + + c.nodeSig1 = sig + + return sig, nil +} + +// Node2Sig is the signature using the identity key of the node that is second +// in a lexicographical ordering of the serialized public keys of the two nodes +// that created the channel. +// +// NOTE: By having this method to access an attribute, we ensure we only need +// to fully deserialize the signature if absolutely necessary. +func (c *ChannelAuthProof) Node2Sig() (*ecdsa.Signature, error) { + if c.nodeSig2 != nil { + return c.nodeSig2, nil + } + + sig, err := ecdsa.ParseSignature(c.NodeSig2Bytes) + if err != nil { + return nil, err + } + + c.nodeSig2 = sig + + return sig, nil +} + +// BitcoinSig1 is the signature using the public key of the first node that was +// used in the channel's multi-sig output. +// +// NOTE: By having this method to access an attribute, we ensure we only need +// to fully deserialize the signature if absolutely necessary. +func (c *ChannelAuthProof) BitcoinSig1() (*ecdsa.Signature, error) { + if c.bitcoinSig1 != nil { + return c.bitcoinSig1, nil + } + + sig, err := ecdsa.ParseSignature(c.BitcoinSig1Bytes) + if err != nil { + return nil, err + } + + c.bitcoinSig1 = sig + + return sig, nil +} + +// BitcoinSig2 is the signature using the public key of the second node that +// was used in the channel's multi-sig output. +// +// NOTE: By having this method to access an attribute, we ensure we only need +// to fully deserialize the signature if absolutely necessary. +func (c *ChannelAuthProof) BitcoinSig2() (*ecdsa.Signature, error) { + if c.bitcoinSig2 != nil { + return c.bitcoinSig2, nil + } + + sig, err := ecdsa.ParseSignature(c.BitcoinSig2Bytes) + if err != nil { + return nil, err + } + + c.bitcoinSig2 = sig + + return sig, nil +} + +// IsEmpty check is the authentication proof is empty Proof is empty if at +// least one of the signatures are equal to nil. +func (c *ChannelAuthProof) IsEmpty() bool { + return len(c.NodeSig1Bytes) == 0 || + len(c.NodeSig2Bytes) == 0 || + len(c.BitcoinSig1Bytes) == 0 || + len(c.BitcoinSig2Bytes) == 0 +} diff --git a/channeldb/models/channel_edge_info.go b/channeldb/models/channel_edge_info.go new file mode 100644 index 000000000..1afa2d627 --- /dev/null +++ b/channeldb/models/channel_edge_info.go @@ -0,0 +1,187 @@ +package models + +import ( + "bytes" + "fmt" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcutil" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/wire" +) + +// ChannelEdgeInfo represents a fully authenticated channel along with all its +// unique attributes. Once an authenticated channel announcement has been +// processed on the network, then an instance of ChannelEdgeInfo encapsulating +// the channels attributes is stored. The other portions relevant to routing +// policy of a channel are stored within a ChannelEdgePolicy for each direction +// of the channel. +type ChannelEdgeInfo struct { + // ChannelID is the unique channel ID for the channel. The first 3 + // bytes are the block height, the next 3 the index within the block, + // and the last 2 bytes are the output index for the channel. + ChannelID uint64 + + // ChainHash is the hash that uniquely identifies the chain that this + // channel was opened within. + // + // TODO(roasbeef): need to modify db keying for multi-chain + // * must add chain hash to prefix as well + ChainHash chainhash.Hash + + // NodeKey1Bytes is the raw public key of the first node. + NodeKey1Bytes [33]byte + nodeKey1 *btcec.PublicKey + + // NodeKey2Bytes is the raw public key of the first node. + NodeKey2Bytes [33]byte + nodeKey2 *btcec.PublicKey + + // BitcoinKey1Bytes is the raw public key of the first node. + BitcoinKey1Bytes [33]byte + bitcoinKey1 *btcec.PublicKey + + // BitcoinKey2Bytes is the raw public key of the first node. + BitcoinKey2Bytes [33]byte + bitcoinKey2 *btcec.PublicKey + + // Features is an opaque byte slice that encodes the set of channel + // specific features that this channel edge supports. + Features []byte + + // AuthProof is the authentication proof for this channel. This proof + // contains a set of signatures binding four identities, which attests + // to the legitimacy of the advertised channel. + AuthProof *ChannelAuthProof + + // ChannelPoint is the funding outpoint of the channel. This can be + // used to uniquely identify the channel within the channel graph. + ChannelPoint wire.OutPoint + + // Capacity is the total capacity of the channel, this is determined by + // the value output in the outpoint that created this channel. + Capacity btcutil.Amount + + // 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 +} + +// AddNodeKeys is a setter-like method that can be used to replace the set of +// keys for the target ChannelEdgeInfo. +func (c *ChannelEdgeInfo) AddNodeKeys(nodeKey1, nodeKey2, bitcoinKey1, + bitcoinKey2 *btcec.PublicKey) { + + c.nodeKey1 = nodeKey1 + copy(c.NodeKey1Bytes[:], c.nodeKey1.SerializeCompressed()) + + c.nodeKey2 = nodeKey2 + copy(c.NodeKey2Bytes[:], nodeKey2.SerializeCompressed()) + + c.bitcoinKey1 = bitcoinKey1 + copy(c.BitcoinKey1Bytes[:], c.bitcoinKey1.SerializeCompressed()) + + c.bitcoinKey2 = bitcoinKey2 + copy(c.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed()) +} + +// 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 +// that of the other node involved in channel creation. +// +// NOTE: By having this method to access an attribute, we ensure we only need +// to fully deserialize the pubkey if absolutely necessary. +func (c *ChannelEdgeInfo) NodeKey1() (*btcec.PublicKey, error) { + if c.nodeKey1 != nil { + return c.nodeKey1, nil + } + + key, err := btcec.ParsePubKey(c.NodeKey1Bytes[:]) + if err != nil { + return nil, err + } + c.nodeKey1 = key + + return key, nil +} + +// NodeKey2 is the identity public key of the "second" node that was involved in +// the creation of this channel. A node is considered "second" if the +// lexicographical ordering the its serialized public key is "larger" than that +// of the other node involved in channel creation. +// +// NOTE: By having this method to access an attribute, we ensure we only need +// to fully deserialize the pubkey if absolutely necessary. +func (c *ChannelEdgeInfo) NodeKey2() (*btcec.PublicKey, error) { + if c.nodeKey2 != nil { + return c.nodeKey2, nil + } + + key, err := btcec.ParsePubKey(c.NodeKey2Bytes[:]) + if err != nil { + return nil, err + } + c.nodeKey2 = key + + return key, nil +} + +// BitcoinKey1 is the Bitcoin multi-sig key belonging to the first node, that +// was involved in the funding transaction that originally created the channel +// that this struct represents. +// +// NOTE: By having this method to access an attribute, we ensure we only need +// to fully deserialize the pubkey if absolutely necessary. +func (c *ChannelEdgeInfo) BitcoinKey1() (*btcec.PublicKey, error) { + if c.bitcoinKey1 != nil { + return c.bitcoinKey1, nil + } + + key, err := btcec.ParsePubKey(c.BitcoinKey1Bytes[:]) + if err != nil { + return nil, err + } + c.bitcoinKey1 = key + + return key, nil +} + +// BitcoinKey2 is the Bitcoin multi-sig key belonging to the second node, that +// was involved in the funding transaction that originally created the channel +// that this struct represents. +// +// NOTE: By having this method to access an attribute, we ensure we only need +// to fully deserialize the pubkey if absolutely necessary. +func (c *ChannelEdgeInfo) BitcoinKey2() (*btcec.PublicKey, error) { + if c.bitcoinKey2 != nil { + return c.bitcoinKey2, nil + } + + key, err := btcec.ParsePubKey(c.BitcoinKey2Bytes[:]) + if err != nil { + return nil, err + } + c.bitcoinKey2 = key + + return key, nil +} + +// OtherNodeKeyBytes returns the node key bytes of the other end of the channel. +func (c *ChannelEdgeInfo) OtherNodeKeyBytes(thisNodeKey []byte) ( + [33]byte, error) { + + switch { + case bytes.Equal(c.NodeKey1Bytes[:], thisNodeKey): + return c.NodeKey2Bytes, nil + case bytes.Equal(c.NodeKey2Bytes[:], thisNodeKey): + return c.NodeKey1Bytes, nil + default: + return [33]byte{}, fmt.Errorf("node not participating in " + + "this channel") + } +} diff --git a/channeldb/models/channel_edge_policy.go b/channeldb/models/channel_edge_policy.go new file mode 100644 index 000000000..50ad20c75 --- /dev/null +++ b/channeldb/models/channel_edge_policy.go @@ -0,0 +1,131 @@ +package models + +import ( + "time" + + "github.com/btcsuite/btcd/btcec/v2/ecdsa" + "github.com/lightningnetwork/lnd/lnwire" +) + +// ChannelEdgePolicy represents a *directed* edge within the channel graph. For +// each channel in the database, there are two distinct edges: one for each +// possible direction of travel along the channel. The edges themselves hold +// information concerning fees, and minimum time-lock information which is +// utilized during path finding. +type ChannelEdgePolicy struct { + // SigBytes is the raw bytes of the signature of the channel edge + // policy. We'll only parse these if the caller needs to access the + // signature for validation purposes. Do not set SigBytes directly, but + // use SetSigBytes instead to make sure that the cache is invalidated. + SigBytes []byte + + // sig is a cached fully parsed signature. + sig *ecdsa.Signature + + // ChannelID is the unique channel ID for the channel. The first 3 + // bytes are the block height, the next 3 the index within the block, + // and the last 2 bytes are the output index for the channel. + ChannelID uint64 + + // LastUpdate is the last time an authenticated edge for this channel + // was received. + LastUpdate time.Time + + // MessageFlags is a bitfield which indicates the presence of optional + // fields (like max_htlc) in the policy. + MessageFlags lnwire.ChanUpdateMsgFlags + + // ChannelFlags is a bitfield which signals the capabilities of the + // channel as well as the directed edge this update applies to. + ChannelFlags lnwire.ChanUpdateChanFlags + + // TimeLockDelta is the number of blocks this node will subtract from + // the expiry of an incoming HTLC. This value expresses the time buffer + // the node would like to HTLC exchanges. + TimeLockDelta uint16 + + // MinHTLC is the smallest value HTLC this node will forward, expressed + // in millisatoshi. + MinHTLC lnwire.MilliSatoshi + + // MaxHTLC is the largest value HTLC this node will forward, expressed + // in millisatoshi. + MaxHTLC lnwire.MilliSatoshi + + // FeeBaseMSat is the base HTLC fee that will be charged for forwarding + // ANY HTLC, expressed in mSAT's. + FeeBaseMSat lnwire.MilliSatoshi + + // FeeProportionalMillionths is the rate that the node will charge for + // HTLCs for each millionth of a satoshi forwarded. + FeeProportionalMillionths lnwire.MilliSatoshi + + // ToNode is the public key of the node that this directed edge leads + // to. Using this pub key, the channel graph can further be traversed. + ToNode [33]byte + + // 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 +} + +// Signature is a channel announcement signature, which is needed for proper +// edge policy announcement. +// +// NOTE: By having this method to access an attribute, we ensure we only need +// to fully deserialize the signature if absolutely necessary. +func (c *ChannelEdgePolicy) Signature() (*ecdsa.Signature, error) { + if c.sig != nil { + return c.sig, nil + } + + sig, err := ecdsa.ParseSignature(c.SigBytes) + if err != nil { + return nil, err + } + + c.sig = sig + + return sig, nil +} + +// SetSigBytes updates the signature and invalidates the cached parsed +// signature. +func (c *ChannelEdgePolicy) SetSigBytes(sig []byte) { + c.SigBytes = sig + c.sig = nil +} + +// IsDisabled determines whether the edge has the disabled bit set. +func (c *ChannelEdgePolicy) IsDisabled() bool { + return c.ChannelFlags.IsDisabled() +} + +// ComputeFee computes the fee to forward an HTLC of `amt` milli-satoshis over +// the passed active payment channel. This value is currently computed as +// specified in BOLT07, but will likely change in the near future. +func (c *ChannelEdgePolicy) ComputeFee( + amt lnwire.MilliSatoshi) lnwire.MilliSatoshi { + + return c.FeeBaseMSat + (amt*c.FeeProportionalMillionths)/feeRateParts +} + +// divideCeil divides dividend by factor and rounds the result up. +func divideCeil(dividend, factor lnwire.MilliSatoshi) lnwire.MilliSatoshi { + return (dividend + factor - 1) / factor +} + +// ComputeFeeFromIncoming computes the fee to forward an HTLC given the incoming +// amount. +func (c *ChannelEdgePolicy) ComputeFeeFromIncoming( + incomingAmt lnwire.MilliSatoshi) lnwire.MilliSatoshi { + + return incomingAmt - divideCeil( + feeRateParts*(incomingAmt-c.FeeBaseMSat), + feeRateParts+c.FeeProportionalMillionths, + ) +} diff --git a/discovery/gossiper.go b/discovery/gossiper.go index eed3cee84..d2d2fb993 100644 --- a/discovery/gossiper.go +++ b/discovery/gossiper.go @@ -19,6 +19,7 @@ import ( "github.com/lightningnetwork/lnd/batch" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lnpeer" @@ -527,10 +528,10 @@ func New(cfg Config, selfKeyDesc *keychain.KeyDescriptor) *AuthenticatedGossiper // EdgeWithInfo contains the information that is required to update an edge. type EdgeWithInfo struct { // Info describes the channel. - Info *channeldb.ChannelEdgeInfo + Info *models.ChannelEdgeInfo // Edge describes the policy in one direction of the channel. - Edge *channeldb.ChannelEdgePolicy + Edge *models.ChannelEdgePolicy } // PropagateChanPolicyUpdate signals the AuthenticatedGossiper to perform the @@ -1574,8 +1575,8 @@ func (d *AuthenticatedGossiper) retransmitStaleAnns(now time.Time) error { // Iterate over all of our channels and check if any of them fall // within the prune interval or re-broadcast interval. type updateTuple struct { - info *channeldb.ChannelEdgeInfo - edge *channeldb.ChannelEdgePolicy + info *models.ChannelEdgeInfo + edge *models.ChannelEdgePolicy } var ( @@ -1584,8 +1585,8 @@ func (d *AuthenticatedGossiper) retransmitStaleAnns(now time.Time) error { ) err := d.cfg.Router.ForAllOutgoingChannels(func( _ kvdb.RTx, - info *channeldb.ChannelEdgeInfo, - edge *channeldb.ChannelEdgePolicy) error { + info *models.ChannelEdgeInfo, + edge *models.ChannelEdgePolicy) error { // If there's no auth proof attached to this edge, it means // that it is a private channel not meant to be announced to @@ -1790,7 +1791,7 @@ func (d *AuthenticatedGossiper) processChanPolicyUpdate( // remotePubFromChanInfo returns the public key of the remote peer given a // ChannelEdgeInfo that describe a channel we have with them. -func remotePubFromChanInfo(chanInfo *channeldb.ChannelEdgeInfo, +func remotePubFromChanInfo(chanInfo *models.ChannelEdgeInfo, chanFlags lnwire.ChanUpdateChanFlags) [33]byte { var remotePubKey [33]byte @@ -1813,7 +1814,7 @@ func remotePubFromChanInfo(chanInfo *channeldb.ChannelEdgeInfo, // assemble the proof and craft the ChannelAnnouncement. func (d *AuthenticatedGossiper) processRejectedEdge( chanAnnMsg *lnwire.ChannelAnnouncement, - proof *channeldb.ChannelAuthProof) ([]networkMsg, error) { + proof *models.ChannelAuthProof) ([]networkMsg, error) { // First, we'll fetch the state of the channel as we know if from the // database. @@ -2022,7 +2023,7 @@ func (d *AuthenticatedGossiper) processNetworkAnnouncement( // processZombieUpdate determines whether the provided channel update should // resurrect a given zombie edge. func (d *AuthenticatedGossiper) processZombieUpdate( - chanInfo *channeldb.ChannelEdgeInfo, msg *lnwire.ChannelUpdate) error { + chanInfo *models.ChannelEdgeInfo, msg *lnwire.ChannelUpdate) error { // The least-significant bit in the flag on the channel update tells us // which edge is being updated. @@ -2125,7 +2126,7 @@ func (d *AuthenticatedGossiper) isMsgStale(msg lnwire.Message) bool { // Otherwise, we'll retrieve the correct policy that we // currently have stored within our graph to check if this // message is stale by comparing its timestamp. - var p *channeldb.ChannelEdgePolicy + var p *models.ChannelEdgePolicy if msg.ChannelFlags&lnwire.ChanUpdateDirection == 0 { p = p1 } else { @@ -2150,8 +2151,8 @@ func (d *AuthenticatedGossiper) isMsgStale(msg lnwire.Message) bool { // updateChannel creates a new fully signed update for the channel, and updates // the underlying graph with the new state. -func (d *AuthenticatedGossiper) updateChannel(info *channeldb.ChannelEdgeInfo, - edge *channeldb.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement, +func (d *AuthenticatedGossiper) updateChannel(info *models.ChannelEdgeInfo, + edge *models.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement, *lnwire.ChannelUpdate, error) { // Parse the unsigned edge into a channel update. @@ -2239,7 +2240,7 @@ func (d *AuthenticatedGossiper) SyncManager() *SyncManager { // keep-alive update based on the previous channel update processed for the same // direction. func IsKeepAliveUpdate(update *lnwire.ChannelUpdate, - prev *channeldb.ChannelEdgePolicy) bool { + prev *models.ChannelEdgePolicy) bool { // Both updates should be from the same direction. if update.ChannelFlags&lnwire.ChanUpdateDirection != @@ -2428,7 +2429,7 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg, // If this is a remote channel announcement, then we'll validate all // the signatures within the proof as it should be well formed. - var proof *channeldb.ChannelAuthProof + var proof *models.ChannelAuthProof if nMsg.isRemote { if err := routing.ValidateChannelAnn(ann); err != nil { err := fmt.Errorf("unable to validate announcement: "+ @@ -2448,7 +2449,7 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg, // If the proof checks out, then we'll save the proof itself to // the database so we can fetch it later when gossiping with // other nodes. - proof = &channeldb.ChannelAuthProof{ + proof = &models.ChannelAuthProof{ NodeSig1Bytes: ann.NodeSig1.ToSignatureBytes(), NodeSig2Bytes: ann.NodeSig2.ToSignatureBytes(), BitcoinSig1Bytes: ann.BitcoinSig1.ToSignatureBytes(), @@ -2465,7 +2466,7 @@ func (d *AuthenticatedGossiper) handleChanAnnouncement(nMsg *networkMsg, return nil, false } - edge := &channeldb.ChannelEdgeInfo{ + edge := &models.ChannelEdgeInfo{ ChannelID: ann.ShortChannelID.ToUint64(), ChainHash: ann.ChainHash, NodeKey1Bytes: ann.NodeID1, @@ -2816,7 +2817,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg, // being updated. var ( pubKey *btcec.PublicKey - edgeToUpdate *channeldb.ChannelEdgePolicy + edgeToUpdate *models.ChannelEdgePolicy ) direction := upd.ChannelFlags & lnwire.ChanUpdateDirection switch direction { @@ -2905,7 +2906,7 @@ func (d *AuthenticatedGossiper) handleChanUpdate(nMsg *networkMsg, // different alias. This might mean that SigBytes is incorrect as it // signs a different SCID than the database SCID, but since there will // only be a difference if AuthProof == nil, this is fine. - update := &channeldb.ChannelEdgePolicy{ + update := &models.ChannelEdgePolicy{ SigBytes: upd.Signature.ToSignatureBytes(), ChannelID: chanInfo.ChannelID, LastUpdate: timestamp, @@ -3217,7 +3218,7 @@ func (d *AuthenticatedGossiper) handleAnnSig(nMsg *networkMsg, // We now have both halves of the channel announcement proof, then // we'll reconstruct the initial announcement so we can validate it // shortly below. - var dbProof channeldb.ChannelAuthProof + var dbProof models.ChannelAuthProof if isFirstNode { dbProof.NodeSig1Bytes = ann.NodeSignature.ToSignatureBytes() dbProof.NodeSig2Bytes = oppProof.NodeSignature.ToSignatureBytes() diff --git a/discovery/gossiper_test.go b/discovery/gossiper_test.go index d364b80ec..7f42ffb76 100644 --- a/discovery/gossiper_test.go +++ b/discovery/gossiper_test.go @@ -24,6 +24,7 @@ import ( "github.com/lightningnetwork/lnd/batch" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lnpeer" @@ -91,8 +92,8 @@ type mockGraphSource struct { mu sync.Mutex nodes []channeldb.LightningNode - infos map[uint64]channeldb.ChannelEdgeInfo - edges map[uint64][]channeldb.ChannelEdgePolicy + infos map[uint64]models.ChannelEdgeInfo + edges map[uint64][]models.ChannelEdgePolicy zombies map[uint64][][33]byte chansToReject map[uint64]struct{} } @@ -100,8 +101,8 @@ type mockGraphSource struct { func newMockRouter(height uint32) *mockGraphSource { return &mockGraphSource{ bestHeight: height, - infos: make(map[uint64]channeldb.ChannelEdgeInfo), - edges: make(map[uint64][]channeldb.ChannelEdgePolicy), + infos: make(map[uint64]models.ChannelEdgeInfo), + edges: make(map[uint64][]models.ChannelEdgePolicy), zombies: make(map[uint64][][33]byte), chansToReject: make(map[uint64]struct{}), } @@ -119,7 +120,7 @@ func (r *mockGraphSource) AddNode(node *channeldb.LightningNode, return nil } -func (r *mockGraphSource) AddEdge(info *channeldb.ChannelEdgeInfo, +func (r *mockGraphSource) AddEdge(info *models.ChannelEdgeInfo, _ ...batch.SchedulerOption) error { r.mu.Lock() @@ -144,14 +145,14 @@ func (r *mockGraphSource) queueValidationFail(chanID uint64) { r.chansToReject[chanID] = struct{}{} } -func (r *mockGraphSource) UpdateEdge(edge *channeldb.ChannelEdgePolicy, +func (r *mockGraphSource) UpdateEdge(edge *models.ChannelEdgePolicy, _ ...batch.SchedulerOption) error { r.mu.Lock() defer r.mu.Unlock() if len(r.edges[edge.ChannelID]) == 0 { - r.edges[edge.ChannelID] = make([]channeldb.ChannelEdgePolicy, 2) + r.edges[edge.ChannelID] = make([]models.ChannelEdgePolicy, 2) } if edge.ChannelFlags&lnwire.ChanUpdateDirection == 0 { @@ -168,7 +169,7 @@ func (r *mockGraphSource) CurrentBlockHeight() (uint32, error) { } func (r *mockGraphSource) AddProof(chanID lnwire.ShortChannelID, - proof *channeldb.ChannelAuthProof) error { + proof *models.ChannelAuthProof) error { r.mu.Lock() defer r.mu.Unlock() @@ -190,8 +191,8 @@ func (r *mockGraphSource) ForEachNode(func(node *channeldb.LightningNode) error) } func (r *mockGraphSource) ForAllOutgoingChannels(cb func(tx kvdb.RTx, - i *channeldb.ChannelEdgeInfo, - c *channeldb.ChannelEdgePolicy) error) error { + i *models.ChannelEdgeInfo, + c *models.ChannelEdgePolicy) error) error { r.mu.Lock() defer r.mu.Unlock() @@ -221,15 +222,15 @@ func (r *mockGraphSource) ForAllOutgoingChannels(cb func(tx kvdb.RTx, return nil } -func (r *mockGraphSource) ForEachChannel(func(chanInfo *channeldb.ChannelEdgeInfo, - e1, e2 *channeldb.ChannelEdgePolicy) error) error { +func (r *mockGraphSource) ForEachChannel(func(chanInfo *models.ChannelEdgeInfo, + e1, e2 *models.ChannelEdgePolicy) error) error { return nil } func (r *mockGraphSource) GetChannelByID(chanID lnwire.ShortChannelID) ( - *channeldb.ChannelEdgeInfo, - *channeldb.ChannelEdgePolicy, - *channeldb.ChannelEdgePolicy, error) { + *models.ChannelEdgeInfo, + *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy, error) { r.mu.Lock() defer r.mu.Unlock() @@ -242,7 +243,7 @@ func (r *mockGraphSource) GetChannelByID(chanID lnwire.ShortChannelID) ( return nil, nil, nil, channeldb.ErrEdgeNotFound } - return &channeldb.ChannelEdgeInfo{ + return &models.ChannelEdgeInfo{ NodeKey1Bytes: pubKeys[0], NodeKey2Bytes: pubKeys[1], }, nil, nil, channeldb.ErrZombieEdge @@ -253,13 +254,13 @@ func (r *mockGraphSource) GetChannelByID(chanID lnwire.ShortChannelID) ( return &chanInfo, nil, nil, nil } - var edge1 *channeldb.ChannelEdgePolicy - if !reflect.DeepEqual(edges[0], channeldb.ChannelEdgePolicy{}) { + var edge1 *models.ChannelEdgePolicy + if !reflect.DeepEqual(edges[0], models.ChannelEdgePolicy{}) { edge1 = &edges[0] } - var edge2 *channeldb.ChannelEdgePolicy - if !reflect.DeepEqual(edges[1], channeldb.ChannelEdgePolicy{}) { + var edge2 *models.ChannelEdgePolicy + if !reflect.DeepEqual(edges[1], models.ChannelEdgePolicy{}) { edge2 = &edges[1] } @@ -359,12 +360,12 @@ func (r *mockGraphSource) IsStaleEdgePolicy(chanID lnwire.ShortChannelID, switch { case flags&lnwire.ChanUpdateDirection == 0 && - !reflect.DeepEqual(edges[0], channeldb.ChannelEdgePolicy{}): + !reflect.DeepEqual(edges[0], models.ChannelEdgePolicy{}): return !timestamp.After(edges[0].LastUpdate) case flags&lnwire.ChanUpdateDirection == 1 && - !reflect.DeepEqual(edges[1], channeldb.ChannelEdgePolicy{}): + !reflect.DeepEqual(edges[1], models.ChannelEdgePolicy{}): return !timestamp.After(edges[1].LastUpdate) @@ -3443,8 +3444,8 @@ out: var edgesToUpdate []EdgeWithInfo err = ctx.router.ForAllOutgoingChannels(func( _ kvdb.RTx, - info *channeldb.ChannelEdgeInfo, - edge *channeldb.ChannelEdgePolicy) error { + info *models.ChannelEdgeInfo, + edge *models.ChannelEdgePolicy) error { edge.TimeLockDelta = uint16(newTimeLockDelta) edgesToUpdate = append(edgesToUpdate, EdgeWithInfo{ diff --git a/funding/manager.go b/funding/manager.go index bee3f1481..f87db443d 100644 --- a/funding/manager.go +++ b/funding/manager.go @@ -524,7 +524,7 @@ type Config struct { // DeleteAliasEdge allows the Manager to delete an alias channel edge // from the graph. It also returns our local to-be-deleted policy. DeleteAliasEdge func(scid lnwire.ShortChannelID) ( - *channeldb.ChannelEdgePolicy, error) + *models.ChannelEdgePolicy, error) // AliasManager is an implementation of the aliasHandler interface that // abstracts away the handling of many alias functions. @@ -3335,7 +3335,7 @@ func (f *Manager) extractAnnounceParams(c *channeldb.OpenChannel) ( func (f *Manager) addToRouterGraph(completeChan *channeldb.OpenChannel, shortChanID *lnwire.ShortChannelID, peerAlias *lnwire.ShortChannelID, - ourPolicy *channeldb.ChannelEdgePolicy) error { + ourPolicy *models.ChannelEdgePolicy) error { chanID := lnwire.NewChanIDFromOutPoint(&completeChan.FundingOutpoint) @@ -4067,7 +4067,7 @@ func (f *Manager) newChanAnnouncement(localPubKey, remotePubKey *btcec.PublicKey, localFundingKey *keychain.KeyDescriptor, remoteFundingKey *btcec.PublicKey, shortChanID lnwire.ShortChannelID, chanID lnwire.ChannelID, fwdMinHTLC, fwdMaxHTLC lnwire.MilliSatoshi, - ourPolicy *channeldb.ChannelEdgePolicy, + ourPolicy *models.ChannelEdgePolicy, chanType channeldb.ChannelType) (*chanAnnouncement, error) { chainHash := *f.cfg.Wallet.Cfg.NetParams.GenesisHash diff --git a/funding/manager_test.go b/funding/manager_test.go index 2c77d377e..d6a0a4427 100644 --- a/funding/manager_test.go +++ b/funding/manager_test.go @@ -550,7 +550,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey, OpenChannelPredicate: chainedAcceptor, NotifyPendingOpenChannelEvent: evt.NotifyPendingOpenChannelEvent, DeleteAliasEdge: func(scid lnwire.ShortChannelID) ( - *channeldb.ChannelEdgePolicy, error) { + *models.ChannelEdgePolicy, error) { return nil, nil }, diff --git a/lnrpc/devrpc/dev_server.go b/lnrpc/devrpc/dev_server.go index 462328ea3..152d988b6 100644 --- a/lnrpc/devrpc/dev_server.go +++ b/lnrpc/devrpc/dev_server.go @@ -17,6 +17,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/lncfg" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnwire" @@ -261,7 +262,7 @@ func (s *Server) ImportGraph(ctx context.Context, for _, rpcEdge := range graph.Edges { rpcEdge := rpcEdge - edge := &channeldb.ChannelEdgeInfo{ + edge := &models.ChannelEdgeInfo{ ChannelID: rpcEdge.ChannelId, ChainHash: *s.cfg.ActiveNetParams.GenesisHash, Capacity: btcutil.Amount(rpcEdge.Capacity), @@ -288,8 +289,8 @@ func (s *Server) ImportGraph(ctx context.Context, rpcEdge.ChanPoint, err) } - makePolicy := func(rpcPolicy *lnrpc.RoutingPolicy) *channeldb.ChannelEdgePolicy { - policy := &channeldb.ChannelEdgePolicy{ + makePolicy := func(rpcPolicy *lnrpc.RoutingPolicy) *models.ChannelEdgePolicy { + policy := &models.ChannelEdgePolicy{ ChannelID: rpcEdge.ChannelId, LastUpdate: time.Unix( int64(rpcPolicy.LastUpdate), 0, diff --git a/lnrpc/invoicesrpc/addinvoice.go b/lnrpc/invoicesrpc/addinvoice.go index f300e4380..8b38b76a2 100644 --- a/lnrpc/invoicesrpc/addinvoice.go +++ b/lnrpc/invoicesrpc/addinvoice.go @@ -17,6 +17,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/invoices" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" @@ -489,7 +490,7 @@ func AddInvoice(ctx context.Context, cfg *AddInvoiceConfig, // chanCanBeHopHint returns true if the target channel is eligible to be a hop // hint. func chanCanBeHopHint(channel *HopHintInfo, cfg *SelectHopHintsCfg) ( - *channeldb.ChannelEdgePolicy, bool) { + *models.ChannelEdgePolicy, bool) { // Since we're only interested in our private channels, we'll skip // public ones. @@ -544,7 +545,7 @@ func chanCanBeHopHint(channel *HopHintInfo, cfg *SelectHopHintsCfg) ( // Now, we'll need to determine which is the correct policy for HTLCs // being sent from the remote node. - var remotePolicy *channeldb.ChannelEdgePolicy + var remotePolicy *models.ChannelEdgePolicy if bytes.Equal(remotePub[:], info.NodeKey1Bytes[:]) { remotePolicy = p1 } else { @@ -604,7 +605,7 @@ func newHopHintInfo(c *channeldb.OpenChannel, isActive bool) *HopHintInfo { // newHopHint returns a new hop hint using the relevant data from a hopHintInfo // and a ChannelEdgePolicy. func newHopHint(hopHintInfo *HopHintInfo, - chanPolicy *channeldb.ChannelEdgePolicy) zpay32.HopHint { + chanPolicy *models.ChannelEdgePolicy) zpay32.HopHint { return zpay32.HopHint{ NodeID: hopHintInfo.RemotePubkey, @@ -627,8 +628,8 @@ type SelectHopHintsCfg struct { // FetchChannelEdgesByID attempts to lookup the two directed edges for // the channel identified by the channel ID. - FetchChannelEdgesByID func(chanID uint64) (*channeldb.ChannelEdgeInfo, - *channeldb.ChannelEdgePolicy, *channeldb.ChannelEdgePolicy, + FetchChannelEdgesByID func(chanID uint64) (*models.ChannelEdgeInfo, + *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) // GetAlias allows the peer's alias SCID to be retrieved for private diff --git a/lnrpc/invoicesrpc/addinvoice_test.go b/lnrpc/invoicesrpc/addinvoice_test.go index 2dcb516a6..26641648d 100644 --- a/lnrpc/invoicesrpc/addinvoice_test.go +++ b/lnrpc/invoicesrpc/addinvoice_test.go @@ -8,6 +8,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/zpay32" "github.com/stretchr/testify/mock" @@ -51,8 +52,8 @@ func (h *hopHintsConfigMock) FetchAllChannels() ([]*channeldb.OpenChannel, // FetchChannelEdgesByID attempts to lookup the two directed edges for // the channel identified by the channel ID. func (h *hopHintsConfigMock) FetchChannelEdgesByID(chanID uint64) ( - *channeldb.ChannelEdgeInfo, *channeldb.ChannelEdgePolicy, - *channeldb.ChannelEdgePolicy, error) { + *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy, error) { args := h.Mock.Called(chanID) @@ -64,9 +65,9 @@ func (h *hopHintsConfigMock) FetchChannelEdgesByID(chanID uint64) ( return nil, nil, nil, err } - edgeInfo := args.Get(0).(*channeldb.ChannelEdgeInfo) - policy1 := args.Get(1).(*channeldb.ChannelEdgePolicy) - policy2 := args.Get(2).(*channeldb.ChannelEdgePolicy) + edgeInfo := args.Get(0).(*models.ChannelEdgeInfo) + policy1 := args.Get(1).(*models.ChannelEdgePolicy) + policy2 := args.Get(2).(*models.ChannelEdgePolicy) return edgeInfo, policy1, policy2, err } @@ -215,9 +216,9 @@ var shouldIncludeChannelTestCases = []struct { h.Mock.On( "FetchChannelEdgesByID", mock.Anything, ).Once().Return( - &channeldb.ChannelEdgeInfo{}, - &channeldb.ChannelEdgePolicy{}, - &channeldb.ChannelEdgePolicy{}, nil, + &models.ChannelEdgeInfo{}, + &models.ChannelEdgePolicy{}, + &models.ChannelEdgePolicy{}, nil, ) h.Mock.On( @@ -253,9 +254,9 @@ var shouldIncludeChannelTestCases = []struct { h.Mock.On( "FetchChannelEdgesByID", mock.Anything, ).Once().Return( - &channeldb.ChannelEdgeInfo{}, - &channeldb.ChannelEdgePolicy{}, - &channeldb.ChannelEdgePolicy{}, nil, + &models.ChannelEdgeInfo{}, + &models.ChannelEdgePolicy{}, + &models.ChannelEdgePolicy{}, nil, ) alias := lnwire.ShortChannelID{TxPosition: 5} h.Mock.On( @@ -294,15 +295,15 @@ var shouldIncludeChannelTestCases = []struct { h.Mock.On( "FetchChannelEdgesByID", mock.Anything, ).Once().Return( - &channeldb.ChannelEdgeInfo{ + &models.ChannelEdgeInfo{ NodeKey1Bytes: selectedPolicy, }, - &channeldb.ChannelEdgePolicy{ + &models.ChannelEdgePolicy{ FeeBaseMSat: 1000, FeeProportionalMillionths: 20, TimeLockDelta: 13, }, - &channeldb.ChannelEdgePolicy{}, + &models.ChannelEdgePolicy{}, nil, ) }, @@ -342,9 +343,9 @@ var shouldIncludeChannelTestCases = []struct { h.Mock.On( "FetchChannelEdgesByID", mock.Anything, ).Once().Return( - &channeldb.ChannelEdgeInfo{}, - &channeldb.ChannelEdgePolicy{}, - &channeldb.ChannelEdgePolicy{ + &models.ChannelEdgeInfo{}, + &models.ChannelEdgePolicy{}, + &models.ChannelEdgePolicy{ FeeBaseMSat: 1000, FeeProportionalMillionths: 20, TimeLockDelta: 13, @@ -387,9 +388,9 @@ var shouldIncludeChannelTestCases = []struct { h.Mock.On( "FetchChannelEdgesByID", mock.Anything, ).Once().Return( - &channeldb.ChannelEdgeInfo{}, - &channeldb.ChannelEdgePolicy{}, - &channeldb.ChannelEdgePolicy{ + &models.ChannelEdgeInfo{}, + &models.ChannelEdgePolicy{}, + &models.ChannelEdgePolicy{ FeeBaseMSat: 1000, FeeProportionalMillionths: 20, TimeLockDelta: 13, @@ -554,9 +555,9 @@ var populateHopHintsTestCases = []struct { h.Mock.On( "FetchChannelEdgesByID", mock.Anything, ).Once().Return( - &channeldb.ChannelEdgeInfo{}, - &channeldb.ChannelEdgePolicy{}, - &channeldb.ChannelEdgePolicy{}, nil, + &models.ChannelEdgeInfo{}, + &models.ChannelEdgePolicy{}, + &models.ChannelEdgePolicy{}, nil, ) }, maxHopHints: 1, @@ -604,9 +605,9 @@ var populateHopHintsTestCases = []struct { h.Mock.On( "FetchChannelEdgesByID", mock.Anything, ).Once().Return( - &channeldb.ChannelEdgeInfo{}, - &channeldb.ChannelEdgePolicy{}, - &channeldb.ChannelEdgePolicy{}, nil, + &models.ChannelEdgeInfo{}, + &models.ChannelEdgePolicy{}, + &models.ChannelEdgePolicy{}, nil, ) }, maxHopHints: 10, @@ -655,9 +656,9 @@ var populateHopHintsTestCases = []struct { h.Mock.On( "FetchChannelEdgesByID", mock.Anything, ).Once().Return( - &channeldb.ChannelEdgeInfo{}, - &channeldb.ChannelEdgePolicy{}, - &channeldb.ChannelEdgePolicy{}, nil, + &models.ChannelEdgeInfo{}, + &models.ChannelEdgePolicy{}, + &models.ChannelEdgePolicy{}, nil, ) }, maxHopHints: 1, @@ -688,9 +689,9 @@ var populateHopHintsTestCases = []struct { h.Mock.On( "FetchChannelEdgesByID", mock.Anything, ).Once().Return( - &channeldb.ChannelEdgeInfo{}, - &channeldb.ChannelEdgePolicy{}, - &channeldb.ChannelEdgePolicy{}, nil, + &models.ChannelEdgeInfo{}, + &models.ChannelEdgePolicy{}, + &models.ChannelEdgePolicy{}, nil, ) // Prepare the mock for the second channel. @@ -705,9 +706,9 @@ var populateHopHintsTestCases = []struct { h.Mock.On( "FetchChannelEdgesByID", mock.Anything, ).Once().Return( - &channeldb.ChannelEdgeInfo{}, - &channeldb.ChannelEdgePolicy{}, - &channeldb.ChannelEdgePolicy{}, nil, + &models.ChannelEdgeInfo{}, + &models.ChannelEdgePolicy{}, + &models.ChannelEdgePolicy{}, nil, ) }, maxHopHints: 10, @@ -742,9 +743,9 @@ var populateHopHintsTestCases = []struct { h.Mock.On( "FetchChannelEdgesByID", mock.Anything, ).Once().Return( - &channeldb.ChannelEdgeInfo{}, - &channeldb.ChannelEdgePolicy{}, - &channeldb.ChannelEdgePolicy{}, nil, + &models.ChannelEdgeInfo{}, + &models.ChannelEdgePolicy{}, + &models.ChannelEdgePolicy{}, nil, ) // Prepare the mock for the second channel. @@ -759,9 +760,9 @@ var populateHopHintsTestCases = []struct { h.Mock.On( "FetchChannelEdgesByID", mock.Anything, ).Once().Return( - &channeldb.ChannelEdgeInfo{}, - &channeldb.ChannelEdgePolicy{}, - &channeldb.ChannelEdgePolicy{}, nil, + &models.ChannelEdgeInfo{}, + &models.ChannelEdgePolicy{}, + &models.ChannelEdgePolicy{}, nil, ) }, maxHopHints: 10, @@ -797,9 +798,9 @@ var populateHopHintsTestCases = []struct { h.Mock.On( "FetchChannelEdgesByID", mock.Anything, ).Once().Return( - &channeldb.ChannelEdgeInfo{}, - &channeldb.ChannelEdgePolicy{}, - &channeldb.ChannelEdgePolicy{}, nil, + &models.ChannelEdgeInfo{}, + &models.ChannelEdgePolicy{}, + &models.ChannelEdgePolicy{}, nil, ) }, maxHopHints: 1, diff --git a/lnrpc/routerrpc/router_backend.go b/lnrpc/routerrpc/router_backend.go index feb3d4b85..549443f0f 100644 --- a/lnrpc/routerrpc/router_backend.go +++ b/lnrpc/routerrpc/router_backend.go @@ -15,6 +15,7 @@ import ( "github.com/btcsuite/btcd/wire" sphinx "github.com/lightningnetwork/lightning-onion" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/feature" "github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/lnrpc" @@ -272,7 +273,7 @@ func (r *RouterBackend) parseQueryRoutesRequest(in *lnrpc.QueryRoutesRequest) ( // inside of the path rather than the request's fields. var ( targetPubKey *route.Vertex - routeHintEdges map[route.Vertex][]*channeldb.CachedEdgePolicy + routeHintEdges map[route.Vertex][]*models.CachedEdgePolicy blindedPmt *routing.BlindedPayment // finalCLTVDelta varies depending on whether we're sending to diff --git a/netann/chan_status_manager_test.go b/netann/chan_status_manager_test.go index e068184f8..cb871ba01 100644 --- a/netann/chan_status_manager_test.go +++ b/netann/chan_status_manager_test.go @@ -14,6 +14,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/netann" @@ -65,8 +66,8 @@ func createChannel(t *testing.T) *channeldb.OpenChannel { // our `pubkey` with the direction bit set appropriately in the policies. Our // update will be created with the disabled bit set if startEnabled is false. func createEdgePolicies(t *testing.T, channel *channeldb.OpenChannel, - pubkey *btcec.PublicKey, startEnabled bool) (*channeldb.ChannelEdgeInfo, - *channeldb.ChannelEdgePolicy, *channeldb.ChannelEdgePolicy) { + pubkey *btcec.PublicKey, startEnabled bool) (*models.ChannelEdgeInfo, + *models.ChannelEdgePolicy, *models.ChannelEdgePolicy) { var ( pubkey1 [33]byte @@ -98,18 +99,18 @@ func createEdgePolicies(t *testing.T, channel *channeldb.OpenChannel, // bit. dir2 |= lnwire.ChanUpdateDirection - return &channeldb.ChannelEdgeInfo{ + return &models.ChannelEdgeInfo{ ChannelPoint: channel.FundingOutpoint, NodeKey1Bytes: pubkey1, NodeKey2Bytes: pubkey2, }, - &channeldb.ChannelEdgePolicy{ + &models.ChannelEdgePolicy{ ChannelID: channel.ShortChanID().ToUint64(), ChannelFlags: dir1, LastUpdate: time.Now(), SigBytes: testSigBytes, }, - &channeldb.ChannelEdgePolicy{ + &models.ChannelEdgePolicy{ ChannelID: channel.ShortChanID().ToUint64(), ChannelFlags: dir2, LastUpdate: time.Now(), @@ -120,9 +121,9 @@ func createEdgePolicies(t *testing.T, channel *channeldb.OpenChannel, type mockGraph struct { mu sync.Mutex channels []*channeldb.OpenChannel - chanInfos map[wire.OutPoint]*channeldb.ChannelEdgeInfo - chanPols1 map[wire.OutPoint]*channeldb.ChannelEdgePolicy - chanPols2 map[wire.OutPoint]*channeldb.ChannelEdgePolicy + chanInfos map[wire.OutPoint]*models.ChannelEdgeInfo + chanPols1 map[wire.OutPoint]*models.ChannelEdgePolicy + chanPols2 map[wire.OutPoint]*models.ChannelEdgePolicy sidToCid map[lnwire.ShortChannelID]wire.OutPoint updates chan *lnwire.ChannelUpdate @@ -133,9 +134,9 @@ func newMockGraph(t *testing.T, numChannels int, g := &mockGraph{ channels: make([]*channeldb.OpenChannel, 0, numChannels), - chanInfos: make(map[wire.OutPoint]*channeldb.ChannelEdgeInfo), - chanPols1: make(map[wire.OutPoint]*channeldb.ChannelEdgePolicy), - chanPols2: make(map[wire.OutPoint]*channeldb.ChannelEdgePolicy), + chanInfos: make(map[wire.OutPoint]*models.ChannelEdgeInfo), + chanPols1: make(map[wire.OutPoint]*models.ChannelEdgePolicy), + chanPols2: make(map[wire.OutPoint]*models.ChannelEdgePolicy), sidToCid: make(map[lnwire.ShortChannelID]wire.OutPoint), updates: make(chan *lnwire.ChannelUpdate, 2*numChannels), } @@ -159,8 +160,8 @@ func (g *mockGraph) FetchAllOpenChannels() ([]*channeldb.OpenChannel, error) { } func (g *mockGraph) FetchChannelEdgesByOutpoint( - op *wire.OutPoint) (*channeldb.ChannelEdgeInfo, - *channeldb.ChannelEdgePolicy, *channeldb.ChannelEdgePolicy, error) { + op *wire.OutPoint) (*models.ChannelEdgeInfo, + *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) { g.mu.Lock() defer g.mu.Unlock() @@ -209,7 +210,7 @@ func (g *mockGraph) ApplyChannelUpdate(update *lnwire.ChannelUpdate, timestamp := time.Unix(int64(update.Timestamp), 0) - policy := &channeldb.ChannelEdgePolicy{ + policy := &models.ChannelEdgePolicy{ ChannelID: update.ShortChannelID.ToUint64(), ChannelFlags: update.ChannelFlags, LastUpdate: timestamp, @@ -247,8 +248,8 @@ func (g *mockGraph) addChannel(channel *channeldb.OpenChannel) { } func (g *mockGraph) addEdgePolicy(c *channeldb.OpenChannel, - info *channeldb.ChannelEdgeInfo, - pol1, pol2 *channeldb.ChannelEdgePolicy) { + info *models.ChannelEdgeInfo, + pol1, pol2 *models.ChannelEdgePolicy) { g.mu.Lock() defer g.mu.Unlock() diff --git a/netann/channel_announcement.go b/netann/channel_announcement.go index 0ae8d606d..8fc040f6f 100644 --- a/netann/channel_announcement.go +++ b/netann/channel_announcement.go @@ -3,7 +3,7 @@ package netann import ( "bytes" - "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/lnwire" ) @@ -12,9 +12,9 @@ import ( // function is used to transform out database structs into the corresponding wire // structs for announcing new channels to other peers, or simply syncing up a // peer's initial routing table upon connect. -func CreateChanAnnouncement(chanProof *channeldb.ChannelAuthProof, - chanInfo *channeldb.ChannelEdgeInfo, - e1, e2 *channeldb.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement, +func CreateChanAnnouncement(chanProof *models.ChannelAuthProof, + chanInfo *models.ChannelEdgeInfo, + e1, e2 *models.ChannelEdgePolicy) (*lnwire.ChannelAnnouncement, *lnwire.ChannelUpdate, *lnwire.ChannelUpdate, error) { // First, using the parameters of the channel, along with the channel diff --git a/netann/channel_announcement_test.go b/netann/channel_announcement_test.go index bc2460b9a..92a6c74ce 100644 --- a/netann/channel_announcement_test.go +++ b/netann/channel_announcement_test.go @@ -7,7 +7,7 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" - "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/lnwire" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -39,13 +39,13 @@ func TestCreateChanAnnouncement(t *testing.T) { ExtraOpaqueData: []byte{0x1}, } - chanProof := &channeldb.ChannelAuthProof{ + chanProof := &models.ChannelAuthProof{ NodeSig1Bytes: expChanAnn.NodeSig1.ToSignatureBytes(), NodeSig2Bytes: expChanAnn.NodeSig2.ToSignatureBytes(), BitcoinSig1Bytes: expChanAnn.BitcoinSig1.ToSignatureBytes(), BitcoinSig2Bytes: expChanAnn.BitcoinSig2.ToSignatureBytes(), } - chanInfo := &channeldb.ChannelEdgeInfo{ + chanInfo := &models.ChannelEdgeInfo{ ChainHash: expChanAnn.ChainHash, ChannelID: expChanAnn.ShortChannelID.ToUint64(), ChannelPoint: wire.OutPoint{Index: 1}, diff --git a/netann/channel_update.go b/netann/channel_update.go index b6555f37b..b93deb1d0 100644 --- a/netann/channel_update.go +++ b/netann/channel_update.go @@ -6,7 +6,7 @@ import ( "time" "github.com/btcsuite/btcd/btcec/v2" - "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" @@ -84,12 +84,12 @@ func SignChannelUpdate(signer lnwallet.MessageSigner, keyLoc keychain.KeyLocator // // NOTE: The passed policies can be nil. func ExtractChannelUpdate(ownerPubKey []byte, - info *channeldb.ChannelEdgeInfo, - policies ...*channeldb.ChannelEdgePolicy) ( + info *models.ChannelEdgeInfo, + policies ...*models.ChannelEdgePolicy) ( *lnwire.ChannelUpdate, error) { // Helper function to extract the owner of the given policy. - owner := func(edge *channeldb.ChannelEdgePolicy) []byte { + owner := func(edge *models.ChannelEdgePolicy) []byte { var pubKey *btcec.PublicKey if edge.ChannelFlags&lnwire.ChanUpdateDirection == 0 { pubKey, _ = info.NodeKey1() @@ -117,8 +117,8 @@ func ExtractChannelUpdate(ownerPubKey []byte, // UnsignedChannelUpdateFromEdge reconstructs an unsigned ChannelUpdate from the // given edge info and policy. -func UnsignedChannelUpdateFromEdge(info *channeldb.ChannelEdgeInfo, - policy *channeldb.ChannelEdgePolicy) *lnwire.ChannelUpdate { +func UnsignedChannelUpdateFromEdge(info *models.ChannelEdgeInfo, + policy *models.ChannelEdgePolicy) *lnwire.ChannelUpdate { return &lnwire.ChannelUpdate{ ChainHash: info.ChainHash, @@ -137,8 +137,8 @@ func UnsignedChannelUpdateFromEdge(info *channeldb.ChannelEdgeInfo, // ChannelUpdateFromEdge reconstructs a signed ChannelUpdate from the given edge // info and policy. -func ChannelUpdateFromEdge(info *channeldb.ChannelEdgeInfo, - policy *channeldb.ChannelEdgePolicy) (*lnwire.ChannelUpdate, error) { +func ChannelUpdateFromEdge(info *models.ChannelEdgeInfo, + policy *models.ChannelEdgePolicy) (*lnwire.ChannelUpdate, error) { update := UnsignedChannelUpdateFromEdge(info, policy) diff --git a/netann/interface.go b/netann/interface.go index 79c0c114f..d6cdb46d0 100644 --- a/netann/interface.go +++ b/netann/interface.go @@ -3,6 +3,7 @@ package netann import ( "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" ) // DB abstracts the required database functionality needed by the @@ -18,6 +19,6 @@ type DB interface { type ChannelGraph interface { // FetchChannelEdgesByOutpoint returns the channel edge info and most // recent channel edge policies for a given outpoint. - FetchChannelEdgesByOutpoint(*wire.OutPoint) (*channeldb.ChannelEdgeInfo, - *channeldb.ChannelEdgePolicy, *channeldb.ChannelEdgePolicy, error) + FetchChannelEdgesByOutpoint(*wire.OutPoint) (*models.ChannelEdgeInfo, + *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) } diff --git a/peer/brontide.go b/peer/brontide.go index 9453be39f..9600263e8 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -933,7 +933,7 @@ func (p *Brontide) loadActiveChannels(chans []*channeldb.OpenChannel) ( // // TODO(roasbeef): can add helper method to get policy for // particular channel. - var selfPolicy *channeldb.ChannelEdgePolicy + var selfPolicy *models.ChannelEdgePolicy if info != nil && bytes.Equal(info.NodeKey1Bytes[:], p.cfg.ServerPubKey[:]) { diff --git a/routing/blinding.go b/routing/blinding.go index 143808646..50d3b6f79 100644 --- a/routing/blinding.go +++ b/routing/blinding.go @@ -5,7 +5,7 @@ import ( "fmt" sphinx "github.com/lightningnetwork/lightning-onion" - "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" ) @@ -99,7 +99,7 @@ func (b *BlindedPayment) toRouteHints() RouteHints { hintCount := len(b.BlindedPath.BlindedHops) - 1 hints := make( - map[route.Vertex][]*channeldb.CachedEdgePolicy, hintCount, + map[route.Vertex][]*models.CachedEdgePolicy, hintCount, ) // Start at the unblinded introduction node, because our pathfinding @@ -116,7 +116,7 @@ func (b *BlindedPayment) toRouteHints() RouteHints { // will ensure that pathfinding provides sufficient fees/delay for the // blinded portion to the introduction node. firstBlindedHop := b.BlindedPath.BlindedHops[1].BlindedNodePub - hints[fromNode] = []*channeldb.CachedEdgePolicy{ + hints[fromNode] = []*models.CachedEdgePolicy{ { TimeLockDelta: b.CltvExpiryDelta, MinHTLC: lnwire.MilliSatoshi(b.HtlcMinimum), @@ -156,14 +156,14 @@ func (b *BlindedPayment) toRouteHints() RouteHints { b.BlindedPath.BlindedHops[nextHopIdx].BlindedNodePub, ) - hint := &channeldb.CachedEdgePolicy{ + hint := &models.CachedEdgePolicy{ ToNodePubKey: func() route.Vertex { return nextNode }, ToNodeFeatures: features, } - hints[fromNode] = []*channeldb.CachedEdgePolicy{ + hints[fromNode] = []*models.CachedEdgePolicy{ hint, } } diff --git a/routing/heap.go b/routing/heap.go index 36563bb66..261ced8f9 100644 --- a/routing/heap.go +++ b/routing/heap.go @@ -3,7 +3,7 @@ package routing import ( "container/heap" - "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" ) @@ -39,7 +39,7 @@ type nodeWithDist struct { weight int64 // nextHop is the edge this route comes from. - nextHop *channeldb.CachedEdgePolicy + nextHop *models.CachedEdgePolicy // routingInfoSize is the total size requirement for the payloads field // in the onion packet from this hop towards the final destination. diff --git a/routing/localchans/manager.go b/routing/localchans/manager.go index 3a4e2416a..64641c739 100644 --- a/routing/localchans/manager.go +++ b/routing/localchans/manager.go @@ -31,8 +31,8 @@ type Manager struct { // ForAllOutgoingChannels is required to iterate over all our local // channels. ForAllOutgoingChannels func(cb func(kvdb.RTx, - *channeldb.ChannelEdgeInfo, - *channeldb.ChannelEdgePolicy) error) error + *models.ChannelEdgeInfo, + *models.ChannelEdgePolicy) error) error // FetchChannel is used to query local channel parameters. Optionally an // existing db tx can be supplied. @@ -73,8 +73,8 @@ func (r *Manager) UpdatePolicy(newSchema routing.ChannelPolicy, // otherwise we'll collect them all. err := r.ForAllOutgoingChannels(func( tx kvdb.RTx, - info *channeldb.ChannelEdgeInfo, - edge *channeldb.ChannelEdgePolicy) error { + info *models.ChannelEdgeInfo, + edge *models.ChannelEdgePolicy) error { // If we have a channel filter, and this channel isn't a part // of it, then we'll skip it. @@ -172,7 +172,7 @@ func (r *Manager) UpdatePolicy(newSchema routing.ChannelPolicy, // updateEdge updates the given edge with the new schema. func (r *Manager) updateEdge(tx kvdb.RTx, chanPoint wire.OutPoint, - edge *channeldb.ChannelEdgePolicy, + edge *models.ChannelEdgePolicy, newSchema routing.ChannelPolicy) error { // Update forwarding fee scheme and required time lock delta. diff --git a/routing/localchans/manager_test.go b/routing/localchans/manager_test.go index b14093a01..b103ef31f 100644 --- a/routing/localchans/manager_test.go +++ b/routing/localchans/manager_test.go @@ -22,7 +22,7 @@ func TestManager(t *testing.T) { t.Parallel() type channel struct { - edgeInfo *channeldb.ChannelEdgeInfo + edgeInfo *models.ChannelEdgeInfo } var ( @@ -44,7 +44,7 @@ func TestManager(t *testing.T) { MaxHTLC: 5000, } - currentPolicy := channeldb.ChannelEdgePolicy{ + currentPolicy := models.ChannelEdgePolicy{ MinHTLC: minHTLC, MessageFlags: lnwire.ChanUpdateRequiredMaxHtlc, } @@ -107,8 +107,8 @@ func TestManager(t *testing.T) { } forAllOutgoingChannels := func(cb func(kvdb.RTx, - *channeldb.ChannelEdgeInfo, - *channeldb.ChannelEdgePolicy) error) error { + *models.ChannelEdgeInfo, + *models.ChannelEdgePolicy) error) error { for _, c := range channelSet { if err := cb(nil, c.edgeInfo, ¤tPolicy); err != nil { @@ -152,7 +152,7 @@ func TestManager(t *testing.T) { tests := []struct { name string - currentPolicy channeldb.ChannelEdgePolicy + currentPolicy models.ChannelEdgePolicy newPolicy routing.ChannelPolicy channelSet []channel specifiedChanPoints []wire.OutPoint @@ -166,7 +166,7 @@ func TestManager(t *testing.T) { newPolicy: newPolicy, channelSet: []channel{ { - edgeInfo: &channeldb.ChannelEdgeInfo{ + edgeInfo: &models.ChannelEdgeInfo{ Capacity: chanCap, ChannelPoint: chanPointValid, }, @@ -183,7 +183,7 @@ func TestManager(t *testing.T) { newPolicy: newPolicy, channelSet: []channel{ { - edgeInfo: &channeldb.ChannelEdgeInfo{ + edgeInfo: &models.ChannelEdgeInfo{ Capacity: chanCap, ChannelPoint: chanPointValid, }, @@ -200,7 +200,7 @@ func TestManager(t *testing.T) { newPolicy: newPolicy, channelSet: []channel{ { - edgeInfo: &channeldb.ChannelEdgeInfo{ + edgeInfo: &models.ChannelEdgeInfo{ Capacity: chanCap, ChannelPoint: chanPointValid, }, @@ -221,7 +221,7 @@ func TestManager(t *testing.T) { newPolicy: noMaxHtlcPolicy, channelSet: []channel{ { - edgeInfo: &channeldb.ChannelEdgeInfo{ + edgeInfo: &models.ChannelEdgeInfo{ Capacity: chanCap, ChannelPoint: chanPointValid, }, diff --git a/routing/mock_graph_test.go b/routing/mock_graph_test.go index dfbfd6aba..2ec9a0f98 100644 --- a/routing/mock_graph_test.go +++ b/routing/mock_graph_test.go @@ -8,6 +8,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" ) @@ -193,7 +194,7 @@ func (m *mockGraph) forEachNodeChannel(nodePub route.Vertex, OtherNode: peer, Capacity: channel.capacity, OutPolicySet: true, - InPolicy: &channeldb.CachedEdgePolicy{ + InPolicy: &models.CachedEdgePolicy{ ChannelID: channel.id, ToNodePubKey: func() route.Vertex { return nodePub diff --git a/routing/mock_test.go b/routing/mock_test.go index c24ca2508..6ab8f7083 100644 --- a/routing/mock_test.go +++ b/routing/mock_test.go @@ -8,6 +8,7 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/go-errors/errors" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" @@ -174,13 +175,13 @@ func (m *mockPaymentSessionOld) RequestRoute(_, _ lnwire.MilliSatoshi, } func (m *mockPaymentSessionOld) UpdateAdditionalEdge(_ *lnwire.ChannelUpdate, - _ *btcec.PublicKey, _ *channeldb.CachedEdgePolicy) bool { + _ *btcec.PublicKey, _ *models.CachedEdgePolicy) bool { return false } func (m *mockPaymentSessionOld) GetAdditionalEdgePolicy(_ *btcec.PublicKey, - _ uint64) *channeldb.CachedEdgePolicy { + _ uint64) *models.CachedEdgePolicy { return nil } @@ -676,17 +677,17 @@ func (m *mockPaymentSession) RequestRoute(maxAmt, feeLimit lnwire.MilliSatoshi, } func (m *mockPaymentSession) UpdateAdditionalEdge(msg *lnwire.ChannelUpdate, - pubKey *btcec.PublicKey, policy *channeldb.CachedEdgePolicy) bool { + pubKey *btcec.PublicKey, policy *models.CachedEdgePolicy) bool { args := m.Called(msg, pubKey, policy) return args.Bool(0) } func (m *mockPaymentSession) GetAdditionalEdgePolicy(pubKey *btcec.PublicKey, - channelID uint64) *channeldb.CachedEdgePolicy { + channelID uint64) *models.CachedEdgePolicy { args := m.Called(pubKey, channelID) - return args.Get(0).(*channeldb.CachedEdgePolicy) + return args.Get(0).(*models.CachedEdgePolicy) } type mockControlTower struct { diff --git a/routing/notifications.go b/routing/notifications.go index 387bd9126..9d6c4b51f 100644 --- a/routing/notifications.go +++ b/routing/notifications.go @@ -12,6 +12,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/go-errors/errors" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/lnwire" ) @@ -212,7 +213,7 @@ type ClosedChanSummary struct { // createCloseSummaries takes in a slice of channels closed at the target block // height and creates a slice of summaries which of each channel closure. func createCloseSummaries(blockHeight uint32, - closedChans ...*channeldb.ChannelEdgeInfo) []*ClosedChanSummary { + closedChans ...*models.ChannelEdgeInfo) []*ClosedChanSummary { closeSummaries := make([]*ClosedChanSummary, len(closedChans)) for i, closedChan := range closedChans { @@ -333,12 +334,12 @@ func addToTopologyChange(graph *channeldb.ChannelGraph, update *TopologyChange, // We ignore initial channel announcements as we'll only send out // updates once the individual edges themselves have been updated. - case *channeldb.ChannelEdgeInfo: + case *models.ChannelEdgeInfo: return nil // Any new ChannelUpdateAnnouncements will generate a corresponding // ChannelEdgeUpdate notification. - case *channeldb.ChannelEdgePolicy: + case *models.ChannelEdgePolicy: // We'll need to fetch the edge's information from the database // in order to get the information concerning which nodes are // being connected. diff --git a/routing/notifications_test.go b/routing/notifications_test.go index 50788fc67..f3bc24ad8 100644 --- a/routing/notifications_test.go +++ b/routing/notifications_test.go @@ -16,6 +16,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/go-errors/errors" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet/btcwallet" @@ -74,9 +75,9 @@ func createTestNode() (*channeldb.LightningNode, error) { } func randEdgePolicy(chanID *lnwire.ShortChannelID, - node *channeldb.LightningNode) *channeldb.ChannelEdgePolicy { + node *channeldb.LightningNode) *models.ChannelEdgePolicy { - return &channeldb.ChannelEdgePolicy{ + return &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), ChannelID: chanID.ToUint64(), LastUpdate: time.Unix(int64(prand.Int31()), 0), @@ -431,11 +432,11 @@ 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 := &channeldb.ChannelEdgeInfo{ + edge := &models.ChannelEdgeInfo{ ChannelID: chanID.ToUint64(), NodeKey1Bytes: node1.PubKeyBytes, NodeKey2Bytes: node2.PubKeyBytes, - AuthProof: &channeldb.ChannelAuthProof{ + AuthProof: &models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), @@ -469,7 +470,7 @@ func TestEdgeUpdateNotification(t *testing.T) { } assertEdgeCorrect := func(t *testing.T, edgeUpdate *ChannelEdgeUpdate, - edgeAnn *channeldb.ChannelEdgePolicy) { + edgeAnn *models.ChannelEdgePolicy) { if edgeUpdate.ChanID != edgeAnn.ChannelID { t.Fatalf("channel ID of edge doesn't match: "+ "expected %v, got %v", chanID.ToUint64(), edgeUpdate.ChanID) @@ -613,11 +614,11 @@ func TestNodeUpdateNotification(t *testing.T) { testFeaturesBuf := new(bytes.Buffer) require.NoError(t, testFeatures.Encode(testFeaturesBuf)) - edge := &channeldb.ChannelEdgeInfo{ + edge := &models.ChannelEdgeInfo{ ChannelID: chanID.ToUint64(), NodeKey1Bytes: node1.PubKeyBytes, NodeKey2Bytes: node2.PubKeyBytes, - AuthProof: &channeldb.ChannelAuthProof{ + AuthProof: &models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), @@ -799,11 +800,11 @@ func TestNotificationCancellation(t *testing.T) { // to the client. ntfnClient.Cancel() - edge := &channeldb.ChannelEdgeInfo{ + edge := &models.ChannelEdgeInfo{ ChannelID: chanID.ToUint64(), NodeKey1Bytes: node1.PubKeyBytes, NodeKey2Bytes: node2.PubKeyBytes, - AuthProof: &channeldb.ChannelAuthProof{ + AuthProof: &models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), @@ -870,11 +871,11 @@ 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 := &channeldb.ChannelEdgeInfo{ + edge := &models.ChannelEdgeInfo{ ChannelID: chanID.ToUint64(), NodeKey1Bytes: node1.PubKeyBytes, NodeKey2Bytes: node2.PubKeyBytes, - AuthProof: &channeldb.ChannelAuthProof{ + AuthProof: &models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), diff --git a/routing/pathfind.go b/routing/pathfind.go index d007be05e..091c18d92 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -11,6 +11,7 @@ import ( "github.com/btcsuite/btcd/btcutil" sphinx "github.com/lightningnetwork/lightning-onion" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/feature" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/record" @@ -49,7 +50,7 @@ const ( type pathFinder = func(g *graphParams, r *RestrictParams, cfg *PathFindingConfig, source, target route.Vertex, amt lnwire.MilliSatoshi, timePref float64, finalHtlcExpiry int32) ( - []*channeldb.CachedEdgePolicy, float64, error) + []*models.CachedEdgePolicy, float64, error) var ( // DefaultEstimator is the default estimator used for computing @@ -87,7 +88,7 @@ var ( // of the edge. type edgePolicyWithSource struct { sourceNode route.Vertex - edge *channeldb.CachedEdgePolicy + edge *models.CachedEdgePolicy } // finalHopParams encapsulates various parameters for route construction that @@ -125,7 +126,7 @@ type finalHopParams struct { // NOTE: If a non-nil blinded path is provided it is assumed to have been // validated by the caller. func newRoute(sourceVertex route.Vertex, - pathEdges []*channeldb.CachedEdgePolicy, currentHeight uint32, + pathEdges []*models.CachedEdgePolicy, currentHeight uint32, finalHop finalHopParams, blindedPath *sphinx.BlindedPath) ( *route.Route, error) { @@ -355,7 +356,7 @@ type graphParams struct { // additionalEdges is an optional set of edges that should be // considered during path finding, that is not already found in the // channel graph. - additionalEdges map[route.Vertex][]*channeldb.CachedEdgePolicy + additionalEdges map[route.Vertex][]*models.CachedEdgePolicy // bandwidthHints is an interface that provides bandwidth hints that // can provide a better estimate of the current channel bandwidth than @@ -493,7 +494,7 @@ func getOutgoingBalance(node route.Vertex, outgoingChans map[uint64]struct{}, // available bandwidth. func findPath(g *graphParams, r *RestrictParams, cfg *PathFindingConfig, source, target route.Vertex, amt lnwire.MilliSatoshi, timePref float64, - finalHtlcExpiry int32) ([]*channeldb.CachedEdgePolicy, float64, error) { + finalHtlcExpiry int32) ([]*models.CachedEdgePolicy, float64, error) { // Pathfinding can be a significant portion of the total payment // latency, especially on low-powered devices. Log several metrics to @@ -994,7 +995,7 @@ func findPath(g *graphParams, r *RestrictParams, cfg *PathFindingConfig, // Use the distance map to unravel the forward path from source to // target. - var pathEdges []*channeldb.CachedEdgePolicy + var pathEdges []*models.CachedEdgePolicy currentNode := source for { // Determine the next hop forward using the next map. diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index ddb847722..a0dd1fa66 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -23,6 +23,7 @@ import ( "github.com/btcsuite/btcd/wire" sphinx "github.com/lightningnetwork/lightning-onion" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lnwire" @@ -96,7 +97,7 @@ var ( _ = testSScalar.SetByteSlice(testSBytes) testSig = ecdsa.NewSignature(testRScalar, testSScalar) - testAuthProof = channeldb.ChannelAuthProof{ + testAuthProof = models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), @@ -335,7 +336,7 @@ func parseTestGraph(t *testing.T, useCache bool, path string) ( // We first insert the existence of the edge between the two // nodes. - edgeInfo := channeldb.ChannelEdgeInfo{ + edgeInfo := models.ChannelEdgeInfo{ ChannelID: edge.ChannelID, AuthProof: &testAuthProof, ChannelPoint: fundingPoint, @@ -366,7 +367,7 @@ func parseTestGraph(t *testing.T, useCache bool, path string) ( targetNode = edgeInfo.NodeKey2Bytes } - edgePolicy := &channeldb.ChannelEdgePolicy{ + edgePolicy := &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), MessageFlags: lnwire.ChanUpdateMsgFlags(edge.MessageFlags), ChannelFlags: channelFlags, @@ -644,7 +645,7 @@ func createTestGraphFromChannels(t *testing.T, useCache bool, // We first insert the existence of the edge between the two // nodes. - edgeInfo := channeldb.ChannelEdgeInfo{ + edgeInfo := models.ChannelEdgeInfo{ ChannelID: channelID, AuthProof: &testAuthProof, ChannelPoint: *fundingPoint, @@ -671,7 +672,7 @@ func createTestGraphFromChannels(t *testing.T, useCache bool, channelFlags |= lnwire.ChanUpdateDisabled } - edgePolicy := &channeldb.ChannelEdgePolicy{ + edgePolicy := &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), MessageFlags: msgFlags, ChannelFlags: channelFlags, @@ -700,7 +701,7 @@ func createTestGraphFromChannels(t *testing.T, useCache bool, } channelFlags |= lnwire.ChanUpdateDirection - edgePolicy := &channeldb.ChannelEdgePolicy{ + edgePolicy := &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), MessageFlags: msgFlags, ChannelFlags: channelFlags, @@ -1203,7 +1204,7 @@ func runPathFindingWithAdditionalEdges(t *testing.T, useCache bool) { // Create the channel edge going from songoku to doge and include it in // our map of additional edges. - songokuToDoge := &channeldb.CachedEdgePolicy{ + songokuToDoge := &models.CachedEdgePolicy{ ToNodePubKey: func() route.Vertex { return doge.PubKeyBytes }, @@ -1214,12 +1215,12 @@ func runPathFindingWithAdditionalEdges(t *testing.T, useCache bool) { TimeLockDelta: 9, } - additionalEdges := map[route.Vertex][]*channeldb.CachedEdgePolicy{ + additionalEdges := map[route.Vertex][]*models.CachedEdgePolicy{ graph.aliasMap["songoku"]: {songokuToDoge}, } find := func(r *RestrictParams) ( - []*channeldb.CachedEdgePolicy, error) { + []*models.CachedEdgePolicy, error) { return dbFindPath( graph.graph, additionalEdges, &mockBandwidthHints{}, @@ -1289,7 +1290,7 @@ func runPathFindingWithRedundantAdditionalEdges(t *testing.T, useCache bool) { // Create the channel edge going from alice to bob and include it in // our map of additional edges. - aliceToBob := &channeldb.CachedEdgePolicy{ + aliceToBob := &models.CachedEdgePolicy{ ToNodePubKey: func() route.Vertex { return target }, @@ -1300,7 +1301,7 @@ func runPathFindingWithRedundantAdditionalEdges(t *testing.T, useCache bool) { TimeLockDelta: 9, } - additionalEdges := map[route.Vertex][]*channeldb.CachedEdgePolicy{ + additionalEdges := map[route.Vertex][]*models.CachedEdgePolicy{ ctx.source: {aliceToBob}, } @@ -1334,9 +1335,9 @@ func TestNewRoute(t *testing.T) { createHop := func(baseFee lnwire.MilliSatoshi, feeRate lnwire.MilliSatoshi, bandwidth lnwire.MilliSatoshi, - timeLockDelta uint16) *channeldb.CachedEdgePolicy { + timeLockDelta uint16) *models.CachedEdgePolicy { - return &channeldb.CachedEdgePolicy{ + return &models.CachedEdgePolicy{ ToNodePubKey: func() route.Vertex { return route.Vertex{} }, @@ -1353,7 +1354,7 @@ func TestNewRoute(t *testing.T) { // hops is the list of hops (the route) that gets passed into // the call to newRoute. - hops []*channeldb.CachedEdgePolicy + hops []*models.CachedEdgePolicy // paymentAmount is the amount that is send into the route // indicated by hops. @@ -1405,7 +1406,7 @@ func TestNewRoute(t *testing.T) { // For a single hop payment, no fees are expected to be paid. name: "single hop", paymentAmount: 100000, - hops: []*channeldb.CachedEdgePolicy{ + hops: []*models.CachedEdgePolicy{ createHop(100, 1000, 1000000, 10), }, metadata: []byte{1, 2, 3}, @@ -1419,7 +1420,7 @@ func TestNewRoute(t *testing.T) { // a fee to receive the payment. name: "two hop", paymentAmount: 100000, - hops: []*channeldb.CachedEdgePolicy{ + hops: []*models.CachedEdgePolicy{ createHop(0, 1000, 1000000, 10), createHop(30, 1000, 1000000, 5), }, @@ -1434,7 +1435,7 @@ func TestNewRoute(t *testing.T) { name: "two hop tlv onion feature", destFeatures: tlvFeatures, paymentAmount: 100000, - hops: []*channeldb.CachedEdgePolicy{ + hops: []*models.CachedEdgePolicy{ createHop(0, 1000, 1000000, 10), createHop(30, 1000, 1000000, 5), }, @@ -1451,7 +1452,7 @@ func TestNewRoute(t *testing.T) { destFeatures: tlvPayAddrFeatures, paymentAddr: &testPaymentAddr, paymentAmount: 100000, - hops: []*channeldb.CachedEdgePolicy{ + hops: []*models.CachedEdgePolicy{ createHop(0, 1000, 1000000, 10), createHop(30, 1000, 1000000, 5), }, @@ -1471,7 +1472,7 @@ func TestNewRoute(t *testing.T) { // gets rounded down to 1. name: "three hop", paymentAmount: 100000, - hops: []*channeldb.CachedEdgePolicy{ + hops: []*models.CachedEdgePolicy{ createHop(0, 10, 1000000, 10), createHop(0, 10, 1000000, 5), createHop(0, 10, 1000000, 3), @@ -1486,7 +1487,7 @@ func TestNewRoute(t *testing.T) { // because of the increase amount to forward. name: "three hop with fee carry over", paymentAmount: 100000, - hops: []*channeldb.CachedEdgePolicy{ + hops: []*models.CachedEdgePolicy{ createHop(0, 10000, 1000000, 10), createHop(0, 10000, 1000000, 5), createHop(0, 10000, 1000000, 3), @@ -1501,7 +1502,7 @@ func TestNewRoute(t *testing.T) { // effect. name: "three hop with minimal fees for carry over", paymentAmount: 100000, - hops: []*channeldb.CachedEdgePolicy{ + hops: []*models.CachedEdgePolicy{ createHop(0, 10000, 1000000, 10), // First hop charges 0.1% so the second hop fee @@ -1740,7 +1741,7 @@ func runDestTLVGraphFallback(t *testing.T, useCache bool) { require.NoError(t, err, "unable to fetch source node") find := func(r *RestrictParams, - target route.Vertex) ([]*channeldb.CachedEdgePolicy, error) { + target route.Vertex) ([]*models.CachedEdgePolicy, error) { return dbFindPath( ctx.graph, nil, &mockBandwidthHints{}, @@ -2398,7 +2399,7 @@ func TestPathFindSpecExample(t *testing.T) { } func assertExpectedPath(t *testing.T, aliasMap map[string]route.Vertex, - path []*channeldb.CachedEdgePolicy, nodeAliases ...string) { + path []*models.CachedEdgePolicy, nodeAliases ...string) { if len(path) != len(nodeAliases) { t.Fatal("number of hops and number of aliases do not match") @@ -3043,7 +3044,7 @@ func (c *pathFindingTestContext) aliasFromKey(pubKey route.Vertex) string { } func (c *pathFindingTestContext) findPath(target route.Vertex, - amt lnwire.MilliSatoshi) ([]*channeldb.CachedEdgePolicy, + amt lnwire.MilliSatoshi) ([]*models.CachedEdgePolicy, error) { return dbFindPath( @@ -3052,7 +3053,7 @@ func (c *pathFindingTestContext) findPath(target route.Vertex, ) } -func (c *pathFindingTestContext) assertPath(path []*channeldb.CachedEdgePolicy, +func (c *pathFindingTestContext) assertPath(path []*models.CachedEdgePolicy, expected []uint64) { if len(path) != len(expected) { @@ -3071,11 +3072,11 @@ func (c *pathFindingTestContext) assertPath(path []*channeldb.CachedEdgePolicy, // dbFindPath calls findPath after getting a db transaction from the database // graph. func dbFindPath(graph *channeldb.ChannelGraph, - additionalEdges map[route.Vertex][]*channeldb.CachedEdgePolicy, + additionalEdges map[route.Vertex][]*models.CachedEdgePolicy, bandwidthHints bandwidthHints, r *RestrictParams, cfg *PathFindingConfig, source, target route.Vertex, amt lnwire.MilliSatoshi, timePref float64, - finalHtlcExpiry int32) ([]*channeldb.CachedEdgePolicy, error) { + finalHtlcExpiry int32) ([]*models.CachedEdgePolicy, error) { sourceNode, err := graph.SourceNode() if err != nil { @@ -3179,7 +3180,7 @@ func TestBlindedRouteConstruction(t *testing.T) { // route. Proportional fees are omitted for easy test // calculations, but non-zero base fees ensure our fee is // still accounted for. - aliceBobEdge = &channeldb.CachedEdgePolicy{ + aliceBobEdge = &models.CachedEdgePolicy{ ChannelID: 1, // We won't actually use this timelock / fee (since // it's the sender's outbound channel), but we include @@ -3193,7 +3194,7 @@ func TestBlindedRouteConstruction(t *testing.T) { ToNodeFeatures: tlvFeatures, } - bobCarolEdge = &channeldb.CachedEdgePolicy{ + bobCarolEdge = &models.CachedEdgePolicy{ ChannelID: 2, TimeLockDelta: 15, FeeBaseMSat: 20, @@ -3226,7 +3227,7 @@ func TestBlindedRouteConstruction(t *testing.T) { carolDaveEdge := blindedEdges[carolVertex][0] daveEveEdge := blindedEdges[daveBlindedVertex][0] - edges := []*channeldb.CachedEdgePolicy{ + edges := []*models.CachedEdgePolicy{ aliceBobEdge, bobCarolEdge, carolDaveEdge, diff --git a/routing/payment_lifecycle.go b/routing/payment_lifecycle.go index d84c264c2..b2c3834f2 100644 --- a/routing/payment_lifecycle.go +++ b/routing/payment_lifecycle.go @@ -9,6 +9,7 @@ import ( "github.com/go-errors/errors" sphinx "github.com/lightningnetwork/lightning-onion" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" @@ -874,7 +875,7 @@ func (p *shardHandler) handleFailureMessage(rt *route.Route, var ( isAdditionalEdge bool - policy *channeldb.CachedEdgePolicy + policy *models.CachedEdgePolicy ) // Before we apply the channel update, we need to decide whether the diff --git a/routing/payment_session.go b/routing/payment_session.go index 0a9078502..a04a4de55 100644 --- a/routing/payment_session.go +++ b/routing/payment_session.go @@ -8,6 +8,7 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" ) @@ -144,13 +145,13 @@ type PaymentSession interface { // a boolean to indicate whether the update has been applied without // error. UpdateAdditionalEdge(msg *lnwire.ChannelUpdate, pubKey *btcec.PublicKey, - policy *channeldb.CachedEdgePolicy) bool + policy *models.CachedEdgePolicy) bool // GetAdditionalEdgePolicy uses the public key and channel ID to query // the ephemeral channel edge policy for additional edges. Returns a nil // if nothing found. GetAdditionalEdgePolicy(pubKey *btcec.PublicKey, - channelID uint64) *channeldb.CachedEdgePolicy + channelID uint64) *models.CachedEdgePolicy } // paymentSession is used during an HTLC routings session to prune the local @@ -162,7 +163,7 @@ type PaymentSession interface { // loop if payment attempts take long enough. An additional set of edges can // also be provided to assist in reaching the payment's destination. type paymentSession struct { - additionalEdges map[route.Vertex][]*channeldb.CachedEdgePolicy + additionalEdges map[route.Vertex][]*models.CachedEdgePolicy getBandwidthHints func(routingGraph) (bandwidthHints, error) @@ -405,7 +406,7 @@ func (p *paymentSession) RequestRoute(maxAmt, feeLimit lnwire.MilliSatoshi, // updates to the supplied policy. It returns a boolean to indicate whether // there's an error when applying the updates. func (p *paymentSession) UpdateAdditionalEdge(msg *lnwire.ChannelUpdate, - pubKey *btcec.PublicKey, policy *channeldb.CachedEdgePolicy) bool { + pubKey *btcec.PublicKey, policy *models.CachedEdgePolicy) bool { // Validate the message signature. if err := VerifyChannelUpdateSignature(msg, pubKey); err != nil { @@ -430,7 +431,7 @@ func (p *paymentSession) UpdateAdditionalEdge(msg *lnwire.ChannelUpdate, // ephemeral channel edge policy for additional edges. Returns a nil if nothing // found. func (p *paymentSession) GetAdditionalEdgePolicy(pubKey *btcec.PublicKey, - channelID uint64) *channeldb.CachedEdgePolicy { + channelID uint64) *models.CachedEdgePolicy { target := route.NewVertex(pubKey) diff --git a/routing/payment_session_source.go b/routing/payment_session_source.go index 9527e4e13..229c932f3 100644 --- a/routing/payment_session_source.go +++ b/routing/payment_session_source.go @@ -3,6 +3,7 @@ package routing import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" "github.com/lightningnetwork/lnd/zpay32" @@ -94,9 +95,9 @@ func (m *SessionSource) NewPaymentSessionEmpty() PaymentSession { // RouteHintsToEdges converts a list of invoice route hints to an edge map that // can be passed into pathfinding. func RouteHintsToEdges(routeHints [][]zpay32.HopHint, target route.Vertex) ( - map[route.Vertex][]*channeldb.CachedEdgePolicy, error) { + map[route.Vertex][]*models.CachedEdgePolicy, error) { - edges := make(map[route.Vertex][]*channeldb.CachedEdgePolicy) + edges := make(map[route.Vertex][]*models.CachedEdgePolicy) // Traverse through all of the available hop hints and include them in // our edges map, indexed by the public key of the channel's starting @@ -126,7 +127,7 @@ func RouteHintsToEdges(routeHints [][]zpay32.HopHint, target route.Vertex) ( // Finally, create the channel edge from the hop hint // and add it to list of edges corresponding to the node // at the start of the channel. - edge := &channeldb.CachedEdgePolicy{ + edge := &models.CachedEdgePolicy{ ToNodePubKey: func() route.Vertex { return endNode.PubKeyBytes }, diff --git a/routing/payment_session_test.go b/routing/payment_session_test.go index 18858f1f9..1c199ff40 100644 --- a/routing/payment_session_test.go +++ b/routing/payment_session_test.go @@ -5,6 +5,7 @@ import ( "time" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" @@ -211,7 +212,7 @@ func TestRequestRoute(t *testing.T) { // Override pathfinder with a mock. session.pathFinder = func(_ *graphParams, r *RestrictParams, _ *PathFindingConfig, _, _ route.Vertex, _ lnwire.MilliSatoshi, - _ float64, _ int32) ([]*channeldb.CachedEdgePolicy, float64, + _ float64, _ int32) ([]*models.CachedEdgePolicy, float64, error) { // We expect find path to receive a cltv limit excluding the @@ -220,7 +221,7 @@ func TestRequestRoute(t *testing.T) { t.Fatal("wrong cltv limit") } - path := []*channeldb.CachedEdgePolicy{ + path := []*models.CachedEdgePolicy{ { ToNodePubKey: func() route.Vertex { return route.Vertex{} diff --git a/routing/router.go b/routing/router.go index 50aa6b43e..fa255544c 100644 --- a/routing/router.go +++ b/routing/router.go @@ -21,6 +21,7 @@ import ( "github.com/lightningnetwork/lnd/batch" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/input" @@ -135,17 +136,17 @@ type ChannelGraphSource interface { // AddEdge is used to add edge/channel to the topology of the router, // after all information about channel will be gathered this // edge/channel might be used in construction of payment path. - AddEdge(edge *channeldb.ChannelEdgeInfo, + AddEdge(edge *models.ChannelEdgeInfo, op ...batch.SchedulerOption) error // AddProof updates the channel edge info with proof which is needed to // properly announce the edge to the rest of the network. AddProof(chanID lnwire.ShortChannelID, - proof *channeldb.ChannelAuthProof) error + proof *models.ChannelAuthProof) error // UpdateEdge is used to update edge information, without this message // edge considered as not fully constructed. - UpdateEdge(policy *channeldb.ChannelEdgePolicy, + UpdateEdge(policy *models.ChannelEdgePolicy, op ...batch.SchedulerOption) error // IsStaleNode returns true if the graph source has a node announcement @@ -176,8 +177,8 @@ type ChannelGraphSource interface { // emanating from the "source" node which is the center of the // star-graph. ForAllOutgoingChannels(cb func(tx kvdb.RTx, - c *channeldb.ChannelEdgeInfo, - e *channeldb.ChannelEdgePolicy) error) error + c *models.ChannelEdgeInfo, + e *models.ChannelEdgePolicy) error) error // CurrentBlockHeight returns the block height from POV of the router // subsystem. @@ -185,8 +186,8 @@ type ChannelGraphSource interface { // GetChannelByID return the channel by the channel id. GetChannelByID(chanID lnwire.ShortChannelID) ( - *channeldb.ChannelEdgeInfo, *channeldb.ChannelEdgePolicy, - *channeldb.ChannelEdgePolicy, error) + *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy, error) // FetchLightningNode attempts to look up a target node by its identity // public key. channeldb.ErrGraphNodeNotFound is returned if the node @@ -897,15 +898,15 @@ func (r *ChannelRouter) pruneZombieChans() error { log.Infof("Examining channel graph for zombie channels") // A helper method to detect if the channel belongs to this node - isSelfChannelEdge := func(info *channeldb.ChannelEdgeInfo) bool { + isSelfChannelEdge := func(info *models.ChannelEdgeInfo) bool { return info.NodeKey1Bytes == r.selfNode.PubKeyBytes || info.NodeKey2Bytes == r.selfNode.PubKeyBytes } // First, we'll collect all the channels which are eligible for garbage // collection due to being zombies. - filterPruneChans := func(info *channeldb.ChannelEdgeInfo, - e1, e2 *channeldb.ChannelEdgePolicy) error { + filterPruneChans := func(info *models.ChannelEdgeInfo, + e1, e2 *models.ChannelEdgePolicy) error { // Exit early in case this channel is already marked to be pruned if _, markedToPrune := chansToPrune[info.ChannelID]; markedToPrune { @@ -1539,7 +1540,7 @@ func (r *ChannelRouter) processUpdate(msg interface{}, log.Tracef("Updated vertex data for node=%x", msg.PubKeyBytes) r.stats.incNumNodeUpdates() - case *channeldb.ChannelEdgeInfo: + case *models.ChannelEdgeInfo: log.Debugf("Received ChannelEdgeInfo for channel %v", msg.ChannelID) @@ -1706,7 +1707,7 @@ func (r *ChannelRouter) processUpdate(msg interface{}, "view: %v", err) } - case *channeldb.ChannelEdgePolicy: + case *models.ChannelEdgePolicy: log.Debugf("Received ChannelEdgePolicy for channel %v", msg.ChannelID) @@ -1883,7 +1884,7 @@ type RouteRequest struct { // RouteHints is an alias type for a set of route hints, with the source node // as the map's key and the details of the hint(s) in the edge policy. -type RouteHints map[route.Vertex][]*channeldb.CachedEdgePolicy +type RouteHints map[route.Vertex][]*models.CachedEdgePolicy // NewRouteRequest produces a new route request for a regular payment or one // to a blinded route, validating that the target, routeHints and finalExpiry @@ -2668,7 +2669,7 @@ func (r *ChannelRouter) applyChannelUpdate(msg *lnwire.ChannelUpdate) bool { return false } - err = r.UpdateEdge(&channeldb.ChannelEdgePolicy{ + err = r.UpdateEdge(&models.ChannelEdgePolicy{ SigBytes: msg.Signature.ToSignatureBytes(), ChannelID: msg.ShortChannelID.ToUint64(), LastUpdate: time.Unix(int64(msg.Timestamp), 0), @@ -2720,7 +2721,7 @@ func (r *ChannelRouter) AddNode(node *channeldb.LightningNode, // in construction of payment path. // // NOTE: This method is part of the ChannelGraphSource interface. -func (r *ChannelRouter) AddEdge(edge *channeldb.ChannelEdgeInfo, +func (r *ChannelRouter) AddEdge(edge *models.ChannelEdgeInfo, op ...batch.SchedulerOption) error { rMsg := &routingMsg{ @@ -2746,7 +2747,7 @@ func (r *ChannelRouter) AddEdge(edge *channeldb.ChannelEdgeInfo, // considered as not fully constructed. // // NOTE: This method is part of the ChannelGraphSource interface. -func (r *ChannelRouter) UpdateEdge(update *channeldb.ChannelEdgePolicy, +func (r *ChannelRouter) UpdateEdge(update *models.ChannelEdgePolicy, op ...batch.SchedulerOption) error { rMsg := &routingMsg{ @@ -2787,9 +2788,9 @@ func (r *ChannelRouter) SyncedHeight() uint32 { // // NOTE: This method is part of the ChannelGraphSource interface. func (r *ChannelRouter) GetChannelByID(chanID lnwire.ShortChannelID) ( - *channeldb.ChannelEdgeInfo, - *channeldb.ChannelEdgePolicy, - *channeldb.ChannelEdgePolicy, error) { + *models.ChannelEdgeInfo, + *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy, error) { return r.cfg.Graph.FetchChannelEdgesByID(chanID.ToUint64()) } @@ -2822,12 +2823,12 @@ func (r *ChannelRouter) ForEachNode( // // NOTE: This method is part of the ChannelGraphSource interface. func (r *ChannelRouter) ForAllOutgoingChannels(cb func(kvdb.RTx, - *channeldb.ChannelEdgeInfo, *channeldb.ChannelEdgePolicy) error) error { + *models.ChannelEdgeInfo, *models.ChannelEdgePolicy) error) error { return r.cfg.Graph.ForEachNodeChannel(nil, r.selfNode.PubKeyBytes, - func(tx kvdb.RTx, c *channeldb.ChannelEdgeInfo, - e *channeldb.ChannelEdgePolicy, - _ *channeldb.ChannelEdgePolicy) error { + func(tx kvdb.RTx, c *models.ChannelEdgeInfo, + e *models.ChannelEdgePolicy, + _ *models.ChannelEdgePolicy) error { if e == nil { return fmt.Errorf("channel from self node " + @@ -2844,7 +2845,7 @@ func (r *ChannelRouter) ForAllOutgoingChannels(cb func(kvdb.RTx, // // NOTE: This method is part of the ChannelGraphSource interface. func (r *ChannelRouter) AddProof(chanID lnwire.ShortChannelID, - proof *channeldb.ChannelAuthProof) error { + proof *models.ChannelAuthProof) error { info, _, _, err := r.cfg.Graph.FetchChannelEdgesByID(chanID.ToUint64()) if err != nil { @@ -3129,14 +3130,14 @@ func getRouteUnifiers(source route.Vertex, hops []route.Vertex, // including fees, to send the payment. func getPathEdges(source route.Vertex, receiverAmt lnwire.MilliSatoshi, unifiers []*edgeUnifier, bandwidthHints *bandwidthManager, - hops []route.Vertex) ([]*channeldb.CachedEdgePolicy, + hops []route.Vertex) ([]*models.CachedEdgePolicy, lnwire.MilliSatoshi, error) { // Now that we arrived at the start of the route and found out the route // total amount, we make a forward pass. Because the amount may have // been increased in the backward pass, fees need to be recalculated and // amount ranges re-checked. - var pathEdges []*channeldb.CachedEdgePolicy + var pathEdges []*models.CachedEdgePolicy for i, unifier := range unifiers { edge := unifier.getEdge(receiverAmt, bandwidthHints) if edge == nil { diff --git a/routing/router_test.go b/routing/router_test.go index 7ff5f2acf..14e2ae839 100644 --- a/routing/router_test.go +++ b/routing/router_test.go @@ -19,6 +19,7 @@ import ( sphinx "github.com/lightningnetwork/lightning-onion" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/htlcswitch" lnmock "github.com/lightningnetwork/lnd/lntest/mock" @@ -1241,7 +1242,7 @@ func TestAddProof(t *testing.T) { ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight) // After utxo was recreated adding the edge without the proof. - edge := &channeldb.ChannelEdgeInfo{ + edge := &models.ChannelEdgeInfo{ ChannelID: chanID.ToUint64(), NodeKey1Bytes: node1.PubKeyBytes, NodeKey2Bytes: node2.PubKeyBytes, @@ -1330,7 +1331,7 @@ func TestIgnoreChannelEdgePolicyForUnknownChannel(t *testing.T) { } ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight) - edge := &channeldb.ChannelEdgeInfo{ + edge := &models.ChannelEdgeInfo{ ChannelID: chanID.ToUint64(), NodeKey1Bytes: pub1, NodeKey2Bytes: pub2, @@ -1338,7 +1339,7 @@ func TestIgnoreChannelEdgePolicyForUnknownChannel(t *testing.T) { BitcoinKey2Bytes: pub2, AuthProof: nil, } - edgePolicy := &channeldb.ChannelEdgePolicy{ + edgePolicy := &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), ChannelID: edge.ChannelID, LastUpdate: testTime, @@ -1408,7 +1409,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { } ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight) - edge := &channeldb.ChannelEdgeInfo{ + edge := &models.ChannelEdgeInfo{ ChannelID: chanID.ToUint64(), NodeKey1Bytes: pub1, NodeKey2Bytes: pub2, @@ -1423,7 +1424,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { // We must add the edge policy to be able to use the edge for route // finding. - edgePolicy := &channeldb.ChannelEdgePolicy{ + edgePolicy := &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), ChannelID: edge.ChannelID, LastUpdate: testTime, @@ -1440,7 +1441,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { } // Create edge in the other direction as well. - edgePolicy = &channeldb.ChannelEdgePolicy{ + edgePolicy = &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), ChannelID: edge.ChannelID, LastUpdate: testTime, @@ -1503,7 +1504,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { } ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight) - edge = &channeldb.ChannelEdgeInfo{ + edge = &models.ChannelEdgeInfo{ ChannelID: chanID.ToUint64(), AuthProof: nil, } @@ -1516,7 +1517,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { t.Fatalf("unable to add edge to the channel graph: %v.", err) } - edgePolicy = &channeldb.ChannelEdgePolicy{ + edgePolicy = &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), ChannelID: edge.ChannelID, LastUpdate: testTime, @@ -1532,7 +1533,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) { t.Fatalf("unable to update edge policy: %v", err) } - edgePolicy = &channeldb.ChannelEdgePolicy{ + edgePolicy = &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), ChannelID: edge.ChannelID, LastUpdate: testTime, @@ -1702,11 +1703,11 @@ func TestWakeUpOnStaleBranch(t *testing.T) { node2, err := createTestNode() require.NoError(t, err, "unable to create test node") - edge1 := &channeldb.ChannelEdgeInfo{ + edge1 := &models.ChannelEdgeInfo{ ChannelID: chanID1, NodeKey1Bytes: node1.PubKeyBytes, NodeKey2Bytes: node2.PubKeyBytes, - AuthProof: &channeldb.ChannelAuthProof{ + AuthProof: &models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), @@ -1720,11 +1721,11 @@ func TestWakeUpOnStaleBranch(t *testing.T) { t.Fatalf("unable to add edge: %v", err) } - edge2 := &channeldb.ChannelEdgeInfo{ + edge2 := &models.ChannelEdgeInfo{ ChannelID: chanID2, NodeKey1Bytes: node1.PubKeyBytes, NodeKey2Bytes: node2.PubKeyBytes, - AuthProof: &channeldb.ChannelAuthProof{ + AuthProof: &models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), @@ -1910,13 +1911,13 @@ func TestDisconnectedBlocks(t *testing.T) { node2, err := createTestNode() require.NoError(t, err, "unable to create test node") - edge1 := &channeldb.ChannelEdgeInfo{ + edge1 := &models.ChannelEdgeInfo{ ChannelID: chanID1, NodeKey1Bytes: node1.PubKeyBytes, NodeKey2Bytes: node2.PubKeyBytes, BitcoinKey1Bytes: node1.PubKeyBytes, BitcoinKey2Bytes: node2.PubKeyBytes, - AuthProof: &channeldb.ChannelAuthProof{ + AuthProof: &models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), @@ -1930,13 +1931,13 @@ func TestDisconnectedBlocks(t *testing.T) { t.Fatalf("unable to add edge: %v", err) } - edge2 := &channeldb.ChannelEdgeInfo{ + edge2 := &models.ChannelEdgeInfo{ ChannelID: chanID2, NodeKey1Bytes: node1.PubKeyBytes, NodeKey2Bytes: node2.PubKeyBytes, BitcoinKey1Bytes: node1.PubKeyBytes, BitcoinKey2Bytes: node2.PubKeyBytes, - AuthProof: &channeldb.ChannelAuthProof{ + AuthProof: &models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), @@ -2061,11 +2062,11 @@ func TestRouterChansClosedOfflinePruneGraph(t *testing.T) { require.NoError(t, err, "unable to create test node") node2, err := createTestNode() require.NoError(t, err, "unable to create test node") - edge1 := &channeldb.ChannelEdgeInfo{ + edge1 := &models.ChannelEdgeInfo{ ChannelID: chanID1.ToUint64(), NodeKey1Bytes: node1.PubKeyBytes, NodeKey2Bytes: node2.PubKeyBytes, - AuthProof: &channeldb.ChannelAuthProof{ + AuthProof: &models.ChannelAuthProof{ NodeSig1Bytes: testSig.Serialize(), NodeSig2Bytes: testSig.Serialize(), BitcoinSig1Bytes: testSig.Serialize(), @@ -2500,7 +2501,7 @@ func TestIsStaleNode(t *testing.T) { } ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight) - edge := &channeldb.ChannelEdgeInfo{ + edge := &models.ChannelEdgeInfo{ ChannelID: chanID.ToUint64(), NodeKey1Bytes: pub1, NodeKey2Bytes: pub2, @@ -2576,7 +2577,7 @@ func TestIsKnownEdge(t *testing.T) { } ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight) - edge := &channeldb.ChannelEdgeInfo{ + edge := &models.ChannelEdgeInfo{ ChannelID: chanID.ToUint64(), NodeKey1Bytes: pub1, NodeKey2Bytes: pub2, @@ -2632,7 +2633,7 @@ func TestIsStaleEdgePolicy(t *testing.T) { t.Fatalf("router failed to detect fresh edge policy") } - edge := &channeldb.ChannelEdgeInfo{ + edge := &models.ChannelEdgeInfo{ ChannelID: chanID.ToUint64(), NodeKey1Bytes: pub1, NodeKey2Bytes: pub2, @@ -2645,7 +2646,7 @@ func TestIsStaleEdgePolicy(t *testing.T) { } // We'll also add two edge policies, one for each direction. - edgePolicy := &channeldb.ChannelEdgePolicy{ + edgePolicy := &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), ChannelID: edge.ChannelID, LastUpdate: updateTimeStamp, @@ -2659,7 +2660,7 @@ func TestIsStaleEdgePolicy(t *testing.T) { t.Fatalf("unable to update edge policy: %v", err) } - edgePolicy = &channeldb.ChannelEdgePolicy{ + edgePolicy = &models.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), ChannelID: edge.ChannelID, LastUpdate: updateTimeStamp, @@ -3202,7 +3203,7 @@ func TestGetPathEdges(t *testing.T) { bandwidthHints *bandwidthManager hops []route.Vertex - expectedEdges []*channeldb.CachedEdgePolicy + expectedEdges []*models.CachedEdgePolicy expectedAmt lnwire.MilliSatoshi expectedErr string }{{ @@ -3257,7 +3258,7 @@ const ( // newChannelEdgeInfo is a helper function used to create a new channel edge, // possibly skipping adding it to parts of the chain/state as well. func newChannelEdgeInfo(ctx *testCtx, fundingHeight uint32, - ecm edgeCreationModifier) (*channeldb.ChannelEdgeInfo, error) { + ecm edgeCreationModifier) (*models.ChannelEdgeInfo, error) { node1, err := createTestNode() if err != nil { @@ -3276,7 +3277,7 @@ func newChannelEdgeInfo(ctx *testCtx, fundingHeight uint32, return nil, fmt.Errorf("unable to create edge: %w", err) } - edge := &channeldb.ChannelEdgeInfo{ + edge := &models.ChannelEdgeInfo{ ChannelID: chanID.ToUint64(), NodeKey1Bytes: node1.PubKeyBytes, NodeKey2Bytes: node2.PubKeyBytes, @@ -3307,7 +3308,7 @@ func newChannelEdgeInfo(ctx *testCtx, fundingHeight uint32, } func assertChanChainRejection(t *testing.T, ctx *testCtx, - edge *channeldb.ChannelEdgeInfo, failCode errorCode) { + edge *models.ChannelEdgeInfo, failCode errorCode) { t.Helper() @@ -4715,7 +4716,7 @@ func TestNewRouteRequest(t *testing.T) { name: "hints and blinded", blindedPayment: blindedMultiHop, routeHints: make( - map[route.Vertex][]*channeldb.CachedEdgePolicy, + map[route.Vertex][]*models.CachedEdgePolicy, ), err: ErrHintsAndBlinded, }, diff --git a/routing/unified_edges.go b/routing/unified_edges.go index e8c2a9270..aee168348 100644 --- a/routing/unified_edges.go +++ b/routing/unified_edges.go @@ -3,6 +3,7 @@ package routing import ( "github.com/btcsuite/btcd/btcutil" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" @@ -41,7 +42,7 @@ func newNodeEdgeUnifier(sourceNode, toNode route.Vertex, // addPolicy adds a single channel policy. Capacity may be zero if unknown // (light clients). func (u *nodeEdgeUnifier) addPolicy(fromNode route.Vertex, - edge *channeldb.CachedEdgePolicy, capacity btcutil.Amount) { + edge *models.CachedEdgePolicy, capacity btcutil.Amount) { localChan := fromNode == u.sourceNode @@ -93,7 +94,7 @@ func (u *nodeEdgeUnifier) addGraphPolicies(g routingGraph) error { // unifiedEdge is the individual channel data that is kept inside an edgeUnifier // object. type unifiedEdge struct { - policy *channeldb.CachedEdgePolicy + policy *models.CachedEdgePolicy capacity btcutil.Amount } @@ -233,7 +234,7 @@ func (u *edgeUnifier) getEdgeLocal(amt lnwire.MilliSatoshi, // forwarding context. func (u *edgeUnifier) getEdgeNetwork(amt lnwire.MilliSatoshi) *unifiedEdge { var ( - bestPolicy *channeldb.CachedEdgePolicy + bestPolicy *models.CachedEdgePolicy maxFee lnwire.MilliSatoshi maxTimelock uint16 maxCapMsat lnwire.MilliSatoshi diff --git a/routing/unified_edges_test.go b/routing/unified_edges_test.go index 752a79718..9b603d78c 100644 --- a/routing/unified_edges_test.go +++ b/routing/unified_edges_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/btcsuite/btcd/btcutil" - "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" "github.com/stretchr/testify/require" @@ -21,7 +21,7 @@ func TestNodeEdgeUnifier(t *testing.T) { bandwidthHints := &mockBandwidthHints{} // Add two channels between the pair of nodes. - p1 := channeldb.CachedEdgePolicy{ + p1 := models.CachedEdgePolicy{ FeeProportionalMillionths: 100000, FeeBaseMSat: 30, TimeLockDelta: 60, @@ -29,7 +29,7 @@ func TestNodeEdgeUnifier(t *testing.T) { MaxHTLC: 5000, MinHTLC: 100, } - p2 := channeldb.CachedEdgePolicy{ + p2 := models.CachedEdgePolicy{ FeeProportionalMillionths: 190000, FeeBaseMSat: 10, TimeLockDelta: 40, @@ -49,7 +49,7 @@ func TestNodeEdgeUnifier(t *testing.T) { unifierNoCapacity.addPolicy(fromNode, &p2, 0) unifierNoInfo := newNodeEdgeUnifier(source, toNode, nil) - unifierNoInfo.addPolicy(fromNode, &channeldb.CachedEdgePolicy{}, 0) + unifierNoInfo.addPolicy(fromNode, &models.CachedEdgePolicy{}, 0) tests := []struct { name string diff --git a/routing/validation_barrier.go b/routing/validation_barrier.go index a7c6561ac..aeef3d4b8 100644 --- a/routing/validation_barrier.go +++ b/routing/validation_barrier.go @@ -5,6 +5,7 @@ import ( "sync" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/routing/route" ) @@ -125,7 +126,7 @@ func (v *ValidationBarrier) InitJobDependencies(job interface{}) { v.nodeAnnDependencies[route.Vertex(msg.NodeID1)] = signals v.nodeAnnDependencies[route.Vertex(msg.NodeID2)] = signals } - case *channeldb.ChannelEdgeInfo: + case *models.ChannelEdgeInfo: shortID := lnwire.NewShortChanIDFromInt(msg.ChannelID) if _, ok := v.chanAnnFinSignal[shortID]; !ok { @@ -143,7 +144,7 @@ func (v *ValidationBarrier) InitJobDependencies(job interface{}) { // These other types don't have any dependants, so no further // initialization needs to be done beyond just occupying a job slot. - case *channeldb.ChannelEdgePolicy: + case *models.ChannelEdgePolicy: return case *lnwire.ChannelUpdate: return @@ -187,7 +188,7 @@ func (v *ValidationBarrier) WaitForDependants(job interface{}) error { switch msg := job.(type) { // Any ChannelUpdate or NodeAnnouncement jobs will need to wait on the // completion of any active ChannelAnnouncement jobs related to them. - case *channeldb.ChannelEdgePolicy: + case *models.ChannelEdgePolicy: shortID := lnwire.NewShortChanIDFromInt(msg.ChannelID) signals, ok = v.chanEdgeDependencies[shortID] @@ -217,7 +218,7 @@ func (v *ValidationBarrier) WaitForDependants(job interface{}) error { // return directly. case *lnwire.AnnounceSignatures: // TODO(roasbeef): need to wait on chan ann? - case *channeldb.ChannelEdgeInfo: + case *models.ChannelEdgeInfo: case *lnwire.ChannelAnnouncement: } @@ -263,7 +264,7 @@ func (v *ValidationBarrier) SignalDependants(job interface{}, allow bool) { // If we've just finished executing a ChannelAnnouncement, then we'll // close out the signal, and remove the signal from the map of active // ones. This will allow/deny any dependent jobs to continue execution. - case *channeldb.ChannelEdgeInfo: + case *models.ChannelEdgeInfo: shortID := lnwire.NewShortChanIDFromInt(msg.ChannelID) finSignals, ok := v.chanAnnFinSignal[shortID] if ok { @@ -296,7 +297,7 @@ func (v *ValidationBarrier) SignalDependants(job interface{}, allow bool) { delete(v.nodeAnnDependencies, route.Vertex(msg.NodeID)) case *lnwire.ChannelUpdate: delete(v.chanEdgeDependencies, msg.ShortChannelID) - case *channeldb.ChannelEdgePolicy: + case *models.ChannelEdgePolicy: shortID := lnwire.NewShortChanIDFromInt(msg.ChannelID) delete(v.chanEdgeDependencies, shortID) diff --git a/rpcserver.go b/rpcserver.go index a9bd480cf..ec14b5539 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -38,6 +38,7 @@ import ( "github.com/lightningnetwork/lnd/chanbackup" "github.com/lightningnetwork/lnd/chanfitness" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/channelnotifier" "github.com/lightningnetwork/lnd/contractcourt" "github.com/lightningnetwork/lnd/discovery" @@ -5921,8 +5922,8 @@ func (r *rpcServer) DescribeGraph(ctx context.Context, // Next, for each active channel we know of within the graph, create a // similar response which details both the edge information as well as // the routing policies of th nodes connecting the two edges. - err = graph.ForEachChannel(func(edgeInfo *channeldb.ChannelEdgeInfo, - c1, c2 *channeldb.ChannelEdgePolicy) error { + err = graph.ForEachChannel(func(edgeInfo *models.ChannelEdgeInfo, + c1, c2 *models.ChannelEdgePolicy) error { // Do not include unannounced channels unless specifically // requested. Unannounced channels include both private channels as @@ -5977,8 +5978,8 @@ func marshalExtraOpaqueData(data []byte) map[uint64][]byte { return records } -func marshalDbEdge(edgeInfo *channeldb.ChannelEdgeInfo, - c1, c2 *channeldb.ChannelEdgePolicy) *lnrpc.ChannelEdge { +func marshalDbEdge(edgeInfo *models.ChannelEdgeInfo, + c1, c2 *models.ChannelEdgePolicy) *lnrpc.ChannelEdge { // Make sure the policies match the node they belong to. c1 should point // to the policy for NodeKey1, and c2 for NodeKey2. @@ -6021,7 +6022,7 @@ func marshalDbEdge(edgeInfo *channeldb.ChannelEdgeInfo, } func marshalDBRoutingPolicy( - policy *channeldb.ChannelEdgePolicy) *lnrpc.RoutingPolicy { + policy *models.ChannelEdgePolicy) *lnrpc.RoutingPolicy { disabled := policy.ChannelFlags&lnwire.ChanUpdateDisabled != 0 @@ -6152,8 +6153,8 @@ func (r *rpcServer) GetNodeInfo(ctx context.Context, ) err = graph.ForEachNodeChannel(nil, node.PubKeyBytes, - func(_ kvdb.RTx, edge *channeldb.ChannelEdgeInfo, - c1, c2 *channeldb.ChannelEdgePolicy) error { + func(_ kvdb.RTx, edge *models.ChannelEdgeInfo, + c1, c2 *models.ChannelEdgePolicy) error { numChannels++ totalCapacity += edge.Capacity @@ -6767,8 +6768,8 @@ func (r *rpcServer) FeeReport(ctx context.Context, var feeReports []*lnrpc.ChannelFeeReport err = channelGraph.ForEachNodeChannel(nil, selfNode.PubKeyBytes, - func(_ kvdb.RTx, chanInfo *channeldb.ChannelEdgeInfo, - edgePolicy, _ *channeldb.ChannelEdgePolicy) error { + func(_ kvdb.RTx, chanInfo *models.ChannelEdgeInfo, + edgePolicy, _ *models.ChannelEdgePolicy) error { // Self node should always have policies for its // channels. diff --git a/server.go b/server.go index e9da0dc35..fcc489435 100644 --- a/server.go +++ b/server.go @@ -32,6 +32,7 @@ import ( "github.com/lightningnetwork/lnd/chanbackup" "github.com/lightningnetwork/lnd/chanfitness" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/channeldb/models" "github.com/lightningnetwork/lnd/channelnotifier" "github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/contractcourt" @@ -1232,7 +1233,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr, // Wrap the DeleteChannelEdges method so that the funding manager can // use it without depending on several layers of indirection. deleteAliasEdge := func(scid lnwire.ShortChannelID) ( - *channeldb.ChannelEdgePolicy, error) { + *models.ChannelEdgePolicy, error) { info, e1, e2, err := s.graphDB.FetchChannelEdgesByID( scid.ToUint64(), @@ -1251,7 +1252,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr, var ourKey [33]byte copy(ourKey[:], nodeKeyDesc.PubKey.SerializeCompressed()) - var ourPolicy *channeldb.ChannelEdgePolicy + var ourPolicy *models.ChannelEdgePolicy if info != nil && info.NodeKey1Bytes == ourKey { ourPolicy = e1 } else { @@ -3094,8 +3095,8 @@ func (s *server) establishPersistentConnections() error { selfPub := s.identityECDH.PubKey().SerializeCompressed() err = s.graphDB.ForEachNodeChannel(nil, sourceNode.PubKeyBytes, func( tx kvdb.RTx, - chanInfo *channeldb.ChannelEdgeInfo, - policy, _ *channeldb.ChannelEdgePolicy) error { + chanInfo *models.ChannelEdgeInfo, + policy, _ *models.ChannelEdgePolicy) error { // If the remote party has announced the channel to us, but we // haven't yet, then we won't have a policy. However, we don't From 0e82293e45d75aceddb7816adf9af07a4fc7072a Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Wed, 8 Nov 2023 11:40:20 +0200 Subject: [PATCH 12/12] multi: address linter issues --- channeldb/graph.go | 48 ++++++++++++++++---------- channeldb/graph_cache.go | 3 +- channeldb/graph_test.go | 51 +++++++++++++++------------- discovery/gossiper_test.go | 5 --- lnrpc/devrpc/dev_server.go | 2 +- lnrpc/invoicesrpc/addinvoice_test.go | 20 ++++++++--- routing/notifications_test.go | 1 + rpcserver.go | 8 ++--- 8 files changed, 82 insertions(+), 56 deletions(-) diff --git a/channeldb/graph.go b/channeldb/graph.go index 5647326dc..c0cbc3287 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -1009,7 +1009,9 @@ func (c *ChannelGraph) AddChannelEdge(edge *models.ChannelEdgeInfo, // addChannelEdge is the private form of AddChannelEdge that allows callers to // utilize an existing db transaction. -func (c *ChannelGraph) addChannelEdge(tx kvdb.RwTx, edge *models.ChannelEdgeInfo) error { +func (c *ChannelGraph) addChannelEdge(tx kvdb.RwTx, + edge *models.ChannelEdgeInfo) error { + // Construct the channel's primary key which is the 8-byte channel ID. var chanKey [8]byte binary.BigEndian.PutUint64(chanKey[:], edge.ChannelID) @@ -1265,7 +1267,8 @@ const ( // with the current UTXO state. A slice of channels that have been closed by // the target block are returned if the function succeeds without error. func (c *ChannelGraph) PruneGraph(spentOutputs []*wire.OutPoint, - blockHash *chainhash.Hash, blockHeight uint32) ([]*models.ChannelEdgeInfo, error) { + blockHash *chainhash.Hash, blockHeight uint32) ( + []*models.ChannelEdgeInfo, error) { c.cacheMu.Lock() defer c.cacheMu.Unlock() @@ -1518,8 +1521,8 @@ func (c *ChannelGraph) pruneGraphNodes(nodes kvdb.RwBucket, // set to the last prune height valid for the remaining chain. // Channels that were removed from the graph resulting from the // disconnected block are returned. -func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) ([]*models.ChannelEdgeInfo, - error) { +func (c *ChannelGraph) DisconnectBlockAtHeight(height uint32) ( + []*models.ChannelEdgeInfo, error) { // Every channel having a ShortChannelID starting at 'height' // will no longer be confirmed. @@ -2552,7 +2555,9 @@ func (c *ChannelGraph) UpdateEdgePolicy(edge *models.ChannelEdgePolicy, return c.chanScheduler.Execute(r) } -func (c *ChannelGraph) updateEdgeCache(e *models.ChannelEdgePolicy, isUpdate1 bool) { +func (c *ChannelGraph) updateEdgeCache(e *models.ChannelEdgePolicy, + isUpdate1 bool) { + // If an entry for this channel is found in reject cache, we'll modify // the entry with the updated timestamp for the direction that was just // written. If the edge doesn't exist, we'll load the cache entry lazily @@ -2964,7 +2969,8 @@ func (c *ChannelGraph) HasLightningNode(nodePub [33]byte) (time.Time, bool, erro // nodeTraversal is used to traverse all channels of a node given by its // public key and passes channel information into the specified callback. func nodeTraversal(tx kvdb.RTx, nodePub []byte, db kvdb.Backend, - cb func(kvdb.RTx, *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, *models.ChannelEdgePolicy) error) error { + cb func(kvdb.RTx, *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy) error) error { traversal := func(tx kvdb.RTx) error { edges := tx.ReadBucket(edgeBucket) @@ -3067,8 +3073,9 @@ func (c *ChannelGraph) ForEachNodeChannel(tx kvdb.RTx, nodePub route.Vertex, // the target node in the channel. This is useful when one knows the pubkey of // one of the nodes, and wishes to obtain the full LightningNode for the other // end of the channel. -func (c *ChannelGraph) FetchOtherNode(tx kvdb.RTx, channel *models.ChannelEdgeInfo, - thisNodeKey []byte) (*LightningNode, error) { +func (c *ChannelGraph) FetchOtherNode(tx kvdb.RTx, + channel *models.ChannelEdgeInfo, thisNodeKey []byte) (*LightningNode, + error) { // Ensure that the node passed in is actually a member of the channel. var targetNodeBytes [33]byte @@ -3117,8 +3124,9 @@ func (c *ChannelGraph) FetchOtherNode(tx kvdb.RTx, channel *models.ChannelEdgeIn // found, then ErrEdgeNotFound is returned. A struct which houses the general // information for the channel itself is returned as well as two structs that // contain the routing policies for the channel in either direction. -func (c *ChannelGraph) FetchChannelEdgesByOutpoint(op *wire.OutPoint, -) (*models.ChannelEdgeInfo, *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) { +func (c *ChannelGraph) FetchChannelEdgesByOutpoint(op *wire.OutPoint) ( + *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy, error) { var ( edgeInfo *models.ChannelEdgeInfo @@ -3201,8 +3209,9 @@ func (c *ChannelGraph) FetchChannelEdgesByOutpoint(op *wire.OutPoint, // ErrZombieEdge an be returned if the edge is currently marked as a zombie // within the database. In this case, the ChannelEdgePolicy's will be nil, and // the ChannelEdgeInfo will only include the public keys of each node. -func (c *ChannelGraph) FetchChannelEdgesByID(chanID uint64, -) (*models.ChannelEdgeInfo, *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) { +func (c *ChannelGraph) FetchChannelEdgesByID(chanID uint64) ( + *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy, error) { var ( edgeInfo *models.ChannelEdgeInfo @@ -3904,7 +3913,9 @@ func deserializeLightningNode(r io.Reader) (LightningNode, error) { return node, nil } -func putChanEdgeInfo(edgeIndex kvdb.RwBucket, edgeInfo *models.ChannelEdgeInfo, chanID [8]byte) error { +func putChanEdgeInfo(edgeIndex kvdb.RwBucket, + edgeInfo *models.ChannelEdgeInfo, chanID [8]byte) error { + var b bytes.Buffer if _, err := b.Write(edgeInfo.NodeKey1Bytes[:]); err != nil { @@ -4059,8 +4070,8 @@ func deserializeChanEdgeInfo(r io.Reader) (models.ChannelEdgeInfo, error) { return edgeInfo, nil } -func putChanEdgePolicy(edges kvdb.RwBucket, edge *models.ChannelEdgePolicy, from, - to []byte) error { +func putChanEdgePolicy(edges kvdb.RwBucket, edge *models.ChannelEdgePolicy, + from, to []byte) error { var edgeKey [33 + 8]byte copy(edgeKey[:], from) @@ -4213,7 +4224,8 @@ func fetchChanEdgePolicy(edges kvdb.RBucket, chanID []byte, } func fetchChanEdgePolicies(edgeIndex kvdb.RBucket, edges kvdb.RBucket, - chanID []byte) (*models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) { + chanID []byte) (*models.ChannelEdgePolicy, *models.ChannelEdgePolicy, + error) { edgeInfo := edgeIndex.Get(chanID) if edgeInfo == nil { @@ -4320,7 +4332,9 @@ func deserializeChanEdgePolicy(r io.Reader) (*models.ChannelEdgePolicy, error) { return edge, deserializeErr } -func deserializeChanEdgePolicyRaw(r io.Reader) (*models.ChannelEdgePolicy, error) { +func deserializeChanEdgePolicyRaw(r io.Reader) (*models.ChannelEdgePolicy, + error) { + edge := &models.ChannelEdgePolicy{} var err error diff --git a/channeldb/graph_cache.go b/channeldb/graph_cache.go index 9e142ed73..7bf9c41d9 100644 --- a/channeldb/graph_cache.go +++ b/channeldb/graph_cache.go @@ -28,7 +28,8 @@ type GraphCacheNode interface { // error, then the iteration is halted with the error propagated back up // to the caller. ForEachChannel(kvdb.RTx, - func(kvdb.RTx, *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + func(kvdb.RTx, *models.ChannelEdgeInfo, + *models.ChannelEdgePolicy, *models.ChannelEdgePolicy) error) error } diff --git a/channeldb/graph_test.go b/channeldb/graph_test.go index 25336d28d..12e20a9e2 100644 --- a/channeldb/graph_test.go +++ b/channeldb/graph_test.go @@ -385,7 +385,8 @@ func TestEdgeInsertionDeletion(t *testing.T) { } func createEdge(height, txIndex uint32, txPosition uint16, outPointIndex uint32, - node1, node2 *LightningNode) (models.ChannelEdgeInfo, lnwire.ShortChannelID) { + node1, node2 *LightningNode) (models.ChannelEdgeInfo, + lnwire.ShortChannelID) { shortChanID := lnwire.ShortChannelID{ BlockHeight: height, @@ -616,8 +617,9 @@ func assertEdgeInfoEqual(t *testing.T, e1 *models.ChannelEdgeInfo, } } -func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) (*models.ChannelEdgeInfo, - *models.ChannelEdgePolicy, *models.ChannelEdgePolicy) { +func createChannelEdge(db kvdb.Backend, node1, node2 *LightningNode) ( + *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy) { var ( firstNode [33]byte @@ -1038,7 +1040,8 @@ func TestGraphTraversal(t *testing.T) { // Iterate through all the known channels within the graph DB, once // again if the map is empty that indicates that all edges have // properly been reached. - err = graph.ForEachChannel(func(ei *models.ChannelEdgeInfo, _ *models.ChannelEdgePolicy, + err = graph.ForEachChannel(func(ei *models.ChannelEdgeInfo, + _ *models.ChannelEdgePolicy, _ *models.ChannelEdgePolicy) error { delete(chanIndex, ei.ChannelID) @@ -1132,9 +1135,10 @@ func TestGraphTraversalCacheable(t *testing.T) { err = graph.db.View(func(tx kvdb.RTx) error { for _, node := range nodes { err := node.ForEachChannel( - tx, func(tx kvdb.RTx, info *models.ChannelEdgeInfo, + tx, func(tx kvdb.RTx, + info *models.ChannelEdgeInfo, policy *models.ChannelEdgePolicy, - policy2 *models.ChannelEdgePolicy) error { + policy2 *models.ChannelEdgePolicy) error { //nolint:lll delete(chanIndex, info.ChannelID) return nil @@ -1316,7 +1320,8 @@ func assertPruneTip(t *testing.T, graph *ChannelGraph, blockHash *chainhash.Hash func assertNumChans(t *testing.T, graph *ChannelGraph, n int) { numChans := 0 - if err := graph.ForEachChannel(func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + if err := graph.ForEachChannel(func(*models.ChannelEdgeInfo, + *models.ChannelEdgePolicy, *models.ChannelEdgePolicy) error { numChans++ @@ -3435,24 +3440,24 @@ func BenchmarkForEachChannel(b *testing.B) { err = graph.db.View(func(tx kvdb.RTx) error { for _, n := range nodes { - err := n.ForEachChannel( - tx, func(tx kvdb.RTx, - info *models.ChannelEdgeInfo, - policy *models.ChannelEdgePolicy, - policy2 *models.ChannelEdgePolicy) error { + cb := func(tx kvdb.RTx, + info *models.ChannelEdgeInfo, + policy *models.ChannelEdgePolicy, + policy2 *models.ChannelEdgePolicy) error { //nolint:lll - // We need to do something with - // the data here, otherwise the - // compiler is going to optimize - // this away, and we get bogus - // results. - totalCapacity += info.Capacity - maxHTLCs += policy.MaxHTLC - maxHTLCs += policy2.MaxHTLC + // We need to do something with + // the data here, otherwise the + // compiler is going to optimize + // this away, and we get bogus + // results. + totalCapacity += info.Capacity + maxHTLCs += policy.MaxHTLC + maxHTLCs += policy2.MaxHTLC - return nil - }, - ) + return nil + } + + err := n.ForEachChannel(tx, cb) if err != nil { return err } diff --git a/discovery/gossiper_test.go b/discovery/gossiper_test.go index 7f42ffb76..a47d98bb9 100644 --- a/discovery/gossiper_test.go +++ b/discovery/gossiper_test.go @@ -222,11 +222,6 @@ func (r *mockGraphSource) ForAllOutgoingChannels(cb func(tx kvdb.RTx, return nil } -func (r *mockGraphSource) ForEachChannel(func(chanInfo *models.ChannelEdgeInfo, - e1, e2 *models.ChannelEdgePolicy) error) error { - return nil -} - func (r *mockGraphSource) GetChannelByID(chanID lnwire.ShortChannelID) ( *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, diff --git a/lnrpc/devrpc/dev_server.go b/lnrpc/devrpc/dev_server.go index 152d988b6..afe30b361 100644 --- a/lnrpc/devrpc/dev_server.go +++ b/lnrpc/devrpc/dev_server.go @@ -289,7 +289,7 @@ func (s *Server) ImportGraph(ctx context.Context, rpcEdge.ChanPoint, err) } - makePolicy := func(rpcPolicy *lnrpc.RoutingPolicy) *models.ChannelEdgePolicy { + makePolicy := func(rpcPolicy *lnrpc.RoutingPolicy) *models.ChannelEdgePolicy { //nolint:lll policy := &models.ChannelEdgePolicy{ ChannelID: rpcEdge.ChannelId, LastUpdate: time.Unix( diff --git a/lnrpc/invoicesrpc/addinvoice_test.go b/lnrpc/invoicesrpc/addinvoice_test.go index 26641648d..1b15921d0 100644 --- a/lnrpc/invoicesrpc/addinvoice_test.go +++ b/lnrpc/invoicesrpc/addinvoice_test.go @@ -16,9 +16,14 @@ import ( ) type hopHintsConfigMock struct { + t *testing.T mock.Mock } +func newHopHintsConfigMock(t *testing.T) *hopHintsConfigMock { + return &hopHintsConfigMock{t: t} +} + // IsPublicNode mocks node public state lookup. func (h *hopHintsConfigMock) IsPublicNode(pubKey [33]byte) (bool, error) { args := h.Mock.Called(pubKey) @@ -65,9 +70,14 @@ func (h *hopHintsConfigMock) FetchChannelEdgesByID(chanID uint64) ( return nil, nil, nil, err } - edgeInfo := args.Get(0).(*models.ChannelEdgeInfo) - policy1 := args.Get(1).(*models.ChannelEdgePolicy) - policy2 := args.Get(2).(*models.ChannelEdgePolicy) + edgeInfo, ok := args.Get(0).(*models.ChannelEdgeInfo) + require.True(h.t, ok) + + policy1, ok := args.Get(1).(*models.ChannelEdgePolicy) + require.True(h.t, ok) + + policy2, ok := args.Get(2).(*models.ChannelEdgePolicy) + require.True(h.t, ok) return edgeInfo, policy1, policy2, err } @@ -429,7 +439,7 @@ func TestShouldIncludeChannel(t *testing.T) { t.Parallel() // Create mock and prime it for the test case. - mock := &hopHintsConfigMock{} + mock := newHopHintsConfigMock(t) if tc.setupMock != nil { tc.setupMock(mock) } @@ -862,7 +872,7 @@ func TestPopulateHopHints(t *testing.T) { t.Parallel() // Create mock and prime it for the test case. - mock := &hopHintsConfigMock{} + mock := newHopHintsConfigMock(t) if tc.setupMock != nil { tc.setupMock(mock) } diff --git a/routing/notifications_test.go b/routing/notifications_test.go index f3bc24ad8..5d6695010 100644 --- a/routing/notifications_test.go +++ b/routing/notifications_test.go @@ -471,6 +471,7 @@ func TestEdgeUpdateNotification(t *testing.T) { assertEdgeCorrect := func(t *testing.T, edgeUpdate *ChannelEdgeUpdate, edgeAnn *models.ChannelEdgePolicy) { + if edgeUpdate.ChanID != edgeAnn.ChannelID { t.Fatalf("channel ID of edge doesn't match: "+ "expected %v, got %v", chanID.ToUint64(), edgeUpdate.ChanID) diff --git a/rpcserver.go b/rpcserver.go index ec14b5539..fa23f0485 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -5933,7 +5933,7 @@ func (r *rpcServer) DescribeGraph(ctx context.Context, return nil } - edge := marshalDbEdge(edgeInfo, c1, c2) + edge := marshalDBEdge(edgeInfo, c1, c2) resp.Edges = append(resp.Edges, edge) return nil @@ -5978,7 +5978,7 @@ func marshalExtraOpaqueData(data []byte) map[uint64][]byte { return records } -func marshalDbEdge(edgeInfo *models.ChannelEdgeInfo, +func marshalDBEdge(edgeInfo *models.ChannelEdgeInfo, c1, c2 *models.ChannelEdgePolicy) *lnrpc.ChannelEdge { // Make sure the policies match the node they belong to. c1 should point @@ -6114,7 +6114,7 @@ func (r *rpcServer) GetChanInfo(ctx context.Context, // Convert the database's edge format into the network/RPC edge format // which couples the edge itself along with the directional node // routing policies of each node involved within the channel. - channelEdge := marshalDbEdge(edgeInfo, edge1, edge2) + channelEdge := marshalDBEdge(edgeInfo, edge1, edge2) return channelEdge, nil } @@ -6171,7 +6171,7 @@ func (r *rpcServer) GetNodeInfo(ctx context.Context, // Convert the database's edge format into the // network/RPC edge format. - channelEdge := marshalDbEdge(edge, c1, c2) + channelEdge := marshalDBEdge(edge, c1, c2) channels = append(channels, channelEdge) }