routing: update package to account for recent channeldb API changes

This commit is contained in:
Olaoluwa Osuntokun 2018-01-30 20:26:26 -08:00
parent cb48a5827a
commit 6751cd8b9f
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21
8 changed files with 274 additions and 228 deletions

@ -239,7 +239,7 @@ func (p *paymentSession) RequestRoute(payment *LightningPayment,
// With the next candidate path found, we'll attempt to turn this into // With the next candidate path found, we'll attempt to turn this into
// a route by applying the time-lock and fee requirements. // a route by applying the time-lock and fee requirements.
sourceVertex := NewVertex(p.mc.selfNode.PubKey) sourceVertex := Vertex(p.mc.selfNode.PubKeyBytes)
route, err := newRoute(payment.Amount, sourceVertex, path, height, route, err := newRoute(payment.Amount, sourceVertex, path, height,
finalCltvDelta) finalCltvDelta)
if err != nil { if err != nil {

@ -296,9 +296,13 @@ func addToTopologyChange(graph *channeldb.ChannelGraph, update *TopologyChange,
// Any node announcement maps directly to a NetworkNodeUpdate struct. // Any node announcement maps directly to a NetworkNodeUpdate struct.
// No further data munging or db queries are required. // No further data munging or db queries are required.
case *channeldb.LightningNode: case *channeldb.LightningNode:
pubKey, err := m.PubKey()
if err != nil {
return err
}
nodeUpdate := &NetworkNodeUpdate{ nodeUpdate := &NetworkNodeUpdate{
Addresses: m.Addresses, Addresses: m.Addresses,
IdentityKey: m.PubKey, IdentityKey: pubKey,
Alias: m.Alias, Alias: m.Alias,
} }
nodeUpdate.IdentityKey.Curve = nil nodeUpdate.IdentityKey.Curve = nil
@ -332,6 +336,15 @@ func addToTopologyChange(graph *channeldb.ChannelGraph, update *TopologyChange,
connectingNode = edgeInfo.NodeKey1 connectingNode = edgeInfo.NodeKey1
} }
aNode, err := sourceNode()
if err != nil {
return err
}
cNode, err := connectingNode()
if err != nil {
return err
}
edgeUpdate := &ChannelEdgeUpdate{ edgeUpdate := &ChannelEdgeUpdate{
ChanID: m.ChannelID, ChanID: m.ChannelID,
ChanPoint: edgeInfo.ChannelPoint, ChanPoint: edgeInfo.ChannelPoint,
@ -340,8 +353,8 @@ func addToTopologyChange(graph *channeldb.ChannelGraph, update *TopologyChange,
MinHTLC: m.MinHTLC, MinHTLC: m.MinHTLC,
BaseFee: m.FeeBaseMSat, BaseFee: m.FeeBaseMSat,
FeeRate: m.FeeProportionalMillionths, FeeRate: m.FeeProportionalMillionths,
AdvertisingNode: sourceNode, AdvertisingNode: aNode,
ConnectingNode: connectingNode, ConnectingNode: cNode,
} }
edgeUpdate.AdvertisingNode.Curve = nil edgeUpdate.AdvertisingNode.Curve = nil
edgeUpdate.ConnectingNode.Curve = nil edgeUpdate.ConnectingNode.Curve = nil

@ -51,23 +51,25 @@ func createTestNode() (*channeldb.LightningNode, error) {
} }
pub := priv.PubKey().SerializeCompressed() pub := priv.PubKey().SerializeCompressed()
return &channeldb.LightningNode{ n := &channeldb.LightningNode{
HaveNodeAnnouncement: true, HaveNodeAnnouncement: true,
LastUpdate: time.Unix(updateTime, 0), LastUpdate: time.Unix(updateTime, 0),
Addresses: testAddrs, Addresses: testAddrs,
PubKey: priv.PubKey(),
Color: color.RGBA{1, 2, 3, 0}, Color: color.RGBA{1, 2, 3, 0},
Alias: "kek" + string(pub[:]), Alias: "kek" + string(pub[:]),
AuthSig: testSig, AuthSigBytes: testSig.Serialize(),
Features: testFeatures, Features: testFeatures,
}, nil }
copy(n.PubKeyBytes[:], pub)
return n, nil
} }
func randEdgePolicy(chanID *lnwire.ShortChannelID, func randEdgePolicy(chanID *lnwire.ShortChannelID,
node *channeldb.LightningNode) *channeldb.ChannelEdgePolicy { node *channeldb.LightningNode) *channeldb.ChannelEdgePolicy {
return &channeldb.ChannelEdgePolicy{ return &channeldb.ChannelEdgePolicy{
Signature: testSig, SigBytes: testSig.Serialize(),
ChannelID: chanID.ToUint64(), ChannelID: chanID.ToUint64(),
LastUpdate: time.Unix(int64(prand.Int31()), 0), LastUpdate: time.Unix(int64(prand.Int31()), 0),
TimeLockDelta: uint16(prand.Int63()), TimeLockDelta: uint16(prand.Int63()),
@ -371,18 +373,18 @@ func TestEdgeUpdateNotification(t *testing.T) {
// Finally, to conclude our test set up, we'll create a channel // Finally, to conclude our test set up, we'll create a channel
// update to announce the created channel between the two nodes. // update to announce the created channel between the two nodes.
edge := &channeldb.ChannelEdgeInfo{ edge := &channeldb.ChannelEdgeInfo{
ChannelID: chanID.ToUint64(), ChannelID: chanID.ToUint64(),
NodeKey1: node1.PubKey, NodeKey1Bytes: node1.PubKeyBytes,
NodeKey2: node2.PubKey, NodeKey2Bytes: node2.PubKeyBytes,
BitcoinKey1: bitcoinKey1,
BitcoinKey2: bitcoinKey2,
AuthProof: &channeldb.ChannelAuthProof{ AuthProof: &channeldb.ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
}, },
} }
copy(edge.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
copy(edge.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed())
if err := ctx.router.AddEdge(edge); err != nil { if err := ctx.router.AddEdge(edge); err != nil {
t.Fatalf("unable to add edge: %v", err) t.Fatalf("unable to add edge: %v", err)
@ -450,8 +452,17 @@ func TestEdgeUpdateNotification(t *testing.T) {
// Create lookup map for notifications we are intending to receive. Entries // Create lookup map for notifications we are intending to receive. Entries
// are removed from the map when the anticipated notification is received. // are removed from the map when the anticipated notification is received.
var waitingFor = map[Vertex]int{ var waitingFor = map[Vertex]int{
NewVertex(node1.PubKey): 1, Vertex(node1.PubKeyBytes): 1,
NewVertex(node2.PubKey): 2, Vertex(node2.PubKeyBytes): 2,
}
node1Pub, err := node1.PubKey()
if err != nil {
t.Fatalf("unable to encode key: %v", err)
}
node2Pub, err := node2.PubKey()
if err != nil {
t.Fatalf("unable to encode key: %v", err)
} }
const numEdgePolicies = 2 const numEdgePolicies = 2
@ -473,20 +484,20 @@ func TestEdgeUpdateNotification(t *testing.T) {
case 1: case 1:
// Received notification corresponding to edge1. // Received notification corresponding to edge1.
assertEdgeCorrect(t, edgeUpdate, edge1) assertEdgeCorrect(t, edgeUpdate, edge1)
if !edgeUpdate.AdvertisingNode.IsEqual(node1.PubKey) { if !edgeUpdate.AdvertisingNode.IsEqual(node1Pub) {
t.Fatal("advertising node mismatch") t.Fatal("advertising node mismatch")
} }
if !edgeUpdate.ConnectingNode.IsEqual(node2.PubKey) { if !edgeUpdate.ConnectingNode.IsEqual(node2Pub) {
t.Fatal("connecting node mismatch") t.Fatal("connecting node mismatch")
} }
case 2: case 2:
// Received notification corresponding to edge2. // Received notification corresponding to edge2.
assertEdgeCorrect(t, edgeUpdate, edge2) assertEdgeCorrect(t, edgeUpdate, edge2)
if !edgeUpdate.AdvertisingNode.IsEqual(node2.PubKey) { if !edgeUpdate.AdvertisingNode.IsEqual(node2Pub) {
t.Fatal("advertising node mismatch") t.Fatal("advertising node mismatch")
} }
if !edgeUpdate.ConnectingNode.IsEqual(node1.PubKey) { if !edgeUpdate.ConnectingNode.IsEqual(node1Pub) {
t.Fatal("connecting node mismatch") t.Fatal("connecting node mismatch")
} }
@ -494,8 +505,8 @@ func TestEdgeUpdateNotification(t *testing.T) {
t.Fatal("invalid edge index") t.Fatal("invalid edge index")
} }
// Remove entry from waitingFor map to ensure we don't double count a // Remove entry from waitingFor map to ensure
// repeat notification. // we don't double count a repeat notification.
delete(waitingFor, nodeVertex) delete(waitingFor, nodeVertex)
} else { } else {
@ -552,18 +563,18 @@ func TestNodeUpdateNotification(t *testing.T) {
} }
edge := &channeldb.ChannelEdgeInfo{ edge := &channeldb.ChannelEdgeInfo{
ChannelID: chanID.ToUint64(), ChannelID: chanID.ToUint64(),
NodeKey1: node1.PubKey, NodeKey1Bytes: node1.PubKeyBytes,
NodeKey2: node2.PubKey, NodeKey2Bytes: node2.PubKeyBytes,
BitcoinKey1: bitcoinKey1,
BitcoinKey2: bitcoinKey2,
AuthProof: &channeldb.ChannelAuthProof{ AuthProof: &channeldb.ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
}, },
} }
copy(edge.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
copy(edge.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed())
// Adding the edge will add the nodes to the graph, but with no info // Adding the edge will add the nodes to the graph, but with no info
// except the pubkey known. // except the pubkey known.
@ -589,15 +600,17 @@ func TestNodeUpdateNotification(t *testing.T) {
assertNodeNtfnCorrect := func(t *testing.T, ann *channeldb.LightningNode, assertNodeNtfnCorrect := func(t *testing.T, ann *channeldb.LightningNode,
nodeUpdate *NetworkNodeUpdate) { nodeUpdate *NetworkNodeUpdate) {
nodeKey, _ := ann.PubKey()
// The notification received should directly map the // The notification received should directly map the
// announcement originally sent. // announcement originally sent.
if nodeUpdate.Addresses[0] != ann.Addresses[0] { if nodeUpdate.Addresses[0] != ann.Addresses[0] {
t.Fatalf("node address doesn't match: expected %v, got %v", t.Fatalf("node address doesn't match: expected %v, got %v",
nodeUpdate.Addresses[0], ann.Addresses[0]) nodeUpdate.Addresses[0], ann.Addresses[0])
} }
if !nodeUpdate.IdentityKey.IsEqual(ann.PubKey) { if !nodeUpdate.IdentityKey.IsEqual(nodeKey) {
t.Fatalf("node identity keys don't match: expected %x, "+ t.Fatalf("node identity keys don't match: expected %x, "+
"got %x", ann.PubKey.SerializeCompressed(), "got %x", nodeKey.SerializeCompressed(),
nodeUpdate.IdentityKey.SerializeCompressed()) nodeUpdate.IdentityKey.SerializeCompressed())
} }
if nodeUpdate.Alias != ann.Alias { if nodeUpdate.Alias != ann.Alias {
@ -609,8 +622,8 @@ func TestNodeUpdateNotification(t *testing.T) {
// Create lookup map for notifications we are intending to receive. Entries // Create lookup map for notifications we are intending to receive. Entries
// are removed from the map when the anticipated notification is received. // are removed from the map when the anticipated notification is received.
var waitingFor = map[Vertex]int{ var waitingFor = map[Vertex]int{
NewVertex(node1.PubKey): 1, Vertex(node1.PubKeyBytes): 1,
NewVertex(node2.PubKey): 2, Vertex(node2.PubKeyBytes): 2,
} }
// Exactly two notifications should be sent, each corresponding to the // Exactly two notifications should be sent, each corresponding to the
@ -738,18 +751,18 @@ func TestNotificationCancellation(t *testing.T) {
ntfnClient.Cancel() ntfnClient.Cancel()
edge := &channeldb.ChannelEdgeInfo{ edge := &channeldb.ChannelEdgeInfo{
ChannelID: chanID.ToUint64(), ChannelID: chanID.ToUint64(),
NodeKey1: node1.PubKey, NodeKey1Bytes: node1.PubKeyBytes,
NodeKey2: node2.PubKey, NodeKey2Bytes: node2.PubKeyBytes,
BitcoinKey1: bitcoinKey1,
BitcoinKey2: bitcoinKey2,
AuthProof: &channeldb.ChannelAuthProof{ AuthProof: &channeldb.ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
}, },
} }
copy(edge.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
copy(edge.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed())
if err := ctx.router.AddEdge(edge); err != nil { if err := ctx.router.AddEdge(edge); err != nil {
t.Fatalf("unable to add edge: %v", err) t.Fatalf("unable to add edge: %v", err)
} }
@ -819,18 +832,18 @@ func TestChannelCloseNotification(t *testing.T) {
// Finally, to conclude our test set up, we'll create a channel // Finally, to conclude our test set up, we'll create a channel
// announcement to announce the created channel between the two nodes. // announcement to announce the created channel between the two nodes.
edge := &channeldb.ChannelEdgeInfo{ edge := &channeldb.ChannelEdgeInfo{
ChannelID: chanID.ToUint64(), ChannelID: chanID.ToUint64(),
NodeKey1: node1.PubKey, NodeKey1Bytes: node1.PubKeyBytes,
NodeKey2: node2.PubKey, NodeKey2Bytes: node2.PubKeyBytes,
BitcoinKey1: bitcoinKey1,
BitcoinKey2: bitcoinKey2,
AuthProof: &channeldb.ChannelAuthProof{ AuthProof: &channeldb.ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
}, },
} }
copy(edge.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
copy(edge.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed())
if err := ctx.router.AddEdge(edge); err != nil { if err := ctx.router.AddEdge(edge); err != nil {
t.Fatalf("unable to add edge: %v", err) t.Fatalf("unable to add edge: %v", err)
} }

@ -1,6 +1,7 @@
package routing package routing
import ( import (
"bytes"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"math" "math"
@ -148,7 +149,7 @@ type Route struct {
// target node is not found in the route, then false is returned. // target node is not found in the route, then false is returned.
func (r *Route) nextHopVertex(n *btcec.PublicKey) (Vertex, bool) { func (r *Route) nextHopVertex(n *btcec.PublicKey) (Vertex, bool) {
hop, ok := r.nextHopMap[NewVertex(n)] hop, ok := r.nextHopMap[NewVertex(n)]
return NewVertex(hop.Node.PubKey), ok return Vertex(hop.Node.PubKeyBytes), ok
} }
// nextHopChannel returns the uint64 channel ID of the next hop after the // nextHopChannel returns the uint64 channel ID of the next hop after the
@ -259,7 +260,7 @@ func newRoute(amtToSend lnwire.MilliSatoshi, sourceVertex Vertex,
// First, we'll update both the node and channel index, to // First, we'll update both the node and channel index, to
// indicate that this Vertex, and outgoing channel link are // indicate that this Vertex, and outgoing channel link are
// present within this route. // present within this route.
v := NewVertex(edge.Node.PubKey) v := Vertex(edge.Node.PubKeyBytes)
route.nodeIndex[v] = struct{}{} route.nodeIndex[v] = struct{}{}
route.chanIndex[edge.ChannelID] = struct{}{} route.chanIndex[edge.ChannelID] = struct{}{}
@ -314,7 +315,6 @@ func newRoute(amtToSend lnwire.MilliSatoshi, sourceVertex Vertex,
AmtToForward: amtToForward, AmtToForward: amtToForward,
Fee: fee, Fee: fee,
} }
edge.Node.PubKey.Curve = nil
route.TotalFees += nextHop.Fee route.TotalFees += nextHop.Fee
@ -361,7 +361,7 @@ func newRoute(amtToSend lnwire.MilliSatoshi, sourceVertex Vertex,
// We'll then make a second run through our route in order to set up // We'll then make a second run through our route in order to set up
// our prev hop mapping. // our prev hop mapping.
for _, hop := range route.Hops { for _, hop := range route.Hops {
vertex := NewVertex(hop.Channel.Node.PubKey) vertex := Vertex(hop.Channel.Node.PubKeyBytes)
route.prevHopMap[vertex] = hop.Channel route.prevHopMap[vertex] = hop.Channel
} }
@ -393,7 +393,7 @@ func (v Vertex) String() string {
// directional edge with the node's ID in the opposite direction. // directional edge with the node's ID in the opposite direction.
type edgeWithPrev struct { type edgeWithPrev struct {
edge *ChannelHop edge *ChannelHop
prevNode *btcec.PublicKey prevNode [33]byte
} }
// edgeWeight computes the weight of an edge. This value is used when searching // edgeWeight computes the weight of an edge. This value is used when searching
@ -440,7 +440,7 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
if err := graph.ForEachNode(tx, func(_ *bolt.Tx, node *channeldb.LightningNode) error { if err := graph.ForEachNode(tx, func(_ *bolt.Tx, node *channeldb.LightningNode) error {
// TODO(roasbeef): with larger graph can just use disk seeks // TODO(roasbeef): with larger graph can just use disk seeks
// with a visited map // with a visited map
distance[NewVertex(node.PubKey)] = nodeWithDist{ distance[Vertex(node.PubKeyBytes)] = nodeWithDist{
dist: infinity, dist: infinity,
node: node, node: node,
} }
@ -455,7 +455,7 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
// To start, we add the source of our path finding attempt to the // To start, we add the source of our path finding attempt to the
// distance map with with a distance of 0. This indicates our starting // distance map with with a distance of 0. This indicates our starting
// point in the graph traversal. // point in the graph traversal.
sourceVertex := NewVertex(sourceNode.PubKey) sourceVertex := Vertex(sourceNode.PubKeyBytes)
distance[sourceVertex] = nodeWithDist{ distance[sourceVertex] = nodeWithDist{
dist: 0, dist: 0,
node: sourceNode, node: sourceNode,
@ -465,6 +465,8 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
// heap. // heap.
heap.Push(&nodeHeap, distance[sourceVertex]) heap.Push(&nodeHeap, distance[sourceVertex])
targetBytes := target.SerializeCompressed()
// We'll use this map as a series of "previous" hop pointers. So to get // We'll use this map as a series of "previous" hop pointers. So to get
// to `Vertex` we'll take the edge that it's mapped to within `prev`. // to `Vertex` we'll take the edge that it's mapped to within `prev`.
prev := make(map[Vertex]edgeWithPrev) prev := make(map[Vertex]edgeWithPrev)
@ -477,19 +479,19 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
// If we've reached our target (or we don't have any outgoing // If we've reached our target (or we don't have any outgoing
// edges), then we're done here and can exit the graph // edges), then we're done here and can exit the graph
// traversal early. // traversal early.
if bestNode.PubKey.IsEqual(target) { if bytes.Equal(bestNode.PubKeyBytes[:], targetBytes) {
break break
} }
// Now that we've found the next potential step to take we'll // Now that we've found the next potential step to take we'll
// examine all the outgoing edge (channels) from this node to // examine all the outgoing edge (channels) from this node to
// further our graph traversal. // further our graph traversal.
pivot := NewVertex(bestNode.PubKey) pivot := Vertex(bestNode.PubKeyBytes)
err := bestNode.ForEachChannel(tx, func(tx *bolt.Tx, err := bestNode.ForEachChannel(tx, func(tx *bolt.Tx,
edgeInfo *channeldb.ChannelEdgeInfo, edgeInfo *channeldb.ChannelEdgeInfo,
outEdge, inEdge *channeldb.ChannelEdgePolicy) error { outEdge, inEdge *channeldb.ChannelEdgePolicy) error {
v := NewVertex(outEdge.Node.PubKey) v := Vertex(outEdge.Node.PubKeyBytes)
// If the outgoing edge is currently disabled, then // If the outgoing edge is currently disabled, then
// we'll stop here, as we shouldn't attempt to route // we'll stop here, as we shouldn't attempt to route
@ -538,7 +540,7 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
ChannelEdgePolicy: outEdge, ChannelEdgePolicy: outEdge,
Capacity: edgeInfo.Capacity, Capacity: edgeInfo.Capacity,
}, },
prevNode: bestNode.PubKey, prevNode: bestNode.PubKeyBytes,
} }
// Add this new node to our heap as we'd like // Add this new node to our heap as we'd like
@ -573,9 +575,8 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph,
// backwards from this hop via the prev pointer for this hop // backwards from this hop via the prev pointer for this hop
// within the prevHop map. // within the prevHop map.
pathEdges = append(pathEdges, prev[prevNode].edge) pathEdges = append(pathEdges, prev[prevNode].edge)
prev[prevNode].edge.Node.PubKey.Curve = nil
prevNode = NewVertex(prev[prevNode].prevNode) prevNode = Vertex(prev[prevNode].prevNode)
} }
// The route is invalid if it spans more than 20 hops. The current // The route is invalid if it spans more than 20 hops. The current
@ -648,8 +649,6 @@ func findPaths(tx *bolt.Tx, graph *channeldb.ChannelGraph,
shortestPaths = append(shortestPaths, firstPath) shortestPaths = append(shortestPaths, firstPath)
source.PubKey.Curve = nil
// While we still have candidate paths to explore we'll keep exploring // While we still have candidate paths to explore we'll keep exploring
// the sub-graphs created to find the next k-th shortest path. // the sub-graphs created to find the next k-th shortest path.
for k := 1; k < 100; k++ { for k := 1; k < 100; k++ {
@ -688,12 +687,12 @@ func findPaths(tx *bolt.Tx, graph *channeldb.ChannelGraph,
// Next we'll remove all entries in the root path that // Next we'll remove all entries in the root path that
// aren't the current spur node from the graph. // aren't the current spur node from the graph.
for _, hop := range rootPath { for _, hop := range rootPath {
node := hop.Node.PubKey node := hop.Node.PubKeyBytes
if node.IsEqual(spurNode.PubKey) { if node == spurNode.PubKeyBytes {
continue continue
} }
ignoredVertexes[NewVertex(node)] = struct{}{} ignoredVertexes[Vertex(node)] = struct{}{}
} }
// With the edges that are part of our root path, and // With the edges that are part of our root path, and

@ -53,10 +53,10 @@ var (
_, _ = testSig.S.SetString("18801056069249825825291287104931333862866033135609736119018462340006816851118", 10) _, _ = testSig.S.SetString("18801056069249825825291287104931333862866033135609736119018462340006816851118", 10)
testAuthProof = channeldb.ChannelAuthProof{ testAuthProof = channeldb.ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
} }
) )
@ -165,20 +165,16 @@ func parseTestGraph(path string) (*channeldb.ChannelGraph, func(), aliasMap, err
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err
} }
pub, err := btcec.ParsePubKey(pubBytes, btcec.S256())
if err != nil {
return nil, nil, nil, err
}
dbNode := &channeldb.LightningNode{ dbNode := &channeldb.LightningNode{
HaveNodeAnnouncement: true, HaveNodeAnnouncement: true,
AuthSig: testSig, AuthSigBytes: testSig.Serialize(),
LastUpdate: time.Now(), LastUpdate: time.Now(),
Addresses: testAddrs, Addresses: testAddrs,
PubKey: pub,
Alias: node.Alias, Alias: node.Alias,
Features: testFeatures, Features: testFeatures,
} }
copy(dbNode.PubKeyBytes[:], pubBytes)
// We require all aliases within the graph to be unique for our // We require all aliases within the graph to be unique for our
// tests. // tests.
@ -187,6 +183,11 @@ func parseTestGraph(path string) (*channeldb.ChannelGraph, func(), aliasMap, err
"must be unique!") "must be unique!")
} }
pub, err := btcec.ParsePubKey(pubBytes, btcec.S256())
if err != nil {
return nil, nil, nil, err
}
// If the alias is unique, then add the node to the // If the alias is unique, then add the node to the
// alias map for easy lookup. // alias map for easy lookup.
aliasMap[node.Alias] = pub aliasMap[node.Alias] = pub
@ -228,19 +229,11 @@ func parseTestGraph(path string) (*channeldb.ChannelGraph, func(), aliasMap, err
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err
} }
node1Pub, err := btcec.ParsePubKey(node1Bytes, btcec.S256())
if err != nil {
return nil, nil, nil, err
}
node2Bytes, err := hex.DecodeString(edge.Node2) node2Bytes, err := hex.DecodeString(edge.Node2)
if err != nil { if err != nil {
return nil, nil, nil, err return nil, nil, nil, err
} }
node2Pub, err := btcec.ParsePubKey(node2Bytes, btcec.S256())
if err != nil {
return nil, nil, nil, err
}
fundingTXID := strings.Split(edge.ChannelPoint, ":")[0] fundingTXID := strings.Split(edge.ChannelPoint, ":")[0]
txidBytes, err := chainhash.NewHashFromStr(fundingTXID) txidBytes, err := chainhash.NewHashFromStr(fundingTXID)
@ -256,21 +249,23 @@ func parseTestGraph(path string) (*channeldb.ChannelGraph, func(), aliasMap, err
// nodes. // nodes.
edgeInfo := channeldb.ChannelEdgeInfo{ edgeInfo := channeldb.ChannelEdgeInfo{
ChannelID: edge.ChannelID, ChannelID: edge.ChannelID,
NodeKey1: node1Pub,
NodeKey2: node2Pub,
BitcoinKey1: node1Pub,
BitcoinKey2: node2Pub,
AuthProof: &testAuthProof, AuthProof: &testAuthProof,
ChannelPoint: fundingPoint, ChannelPoint: fundingPoint,
Capacity: btcutil.Amount(edge.Capacity), Capacity: btcutil.Amount(edge.Capacity),
} }
copy(edgeInfo.NodeKey1Bytes[:], node1Bytes)
copy(edgeInfo.NodeKey2Bytes[:], node2Bytes)
copy(edgeInfo.BitcoinKey1Bytes[:], node1Bytes)
copy(edgeInfo.BitcoinKey2Bytes[:], node2Bytes)
err = graph.AddChannelEdge(&edgeInfo) err = graph.AddChannelEdge(&edgeInfo)
if err != nil && err != channeldb.ErrEdgeAlreadyExist { if err != nil && err != channeldb.ErrEdgeAlreadyExist {
return nil, nil, nil, err return nil, nil, nil, err
} }
edgePolicy := &channeldb.ChannelEdgePolicy{ edgePolicy := &channeldb.ChannelEdgePolicy{
Signature: testSig, SigBytes: testSig.Serialize(),
Flags: lnwire.ChanUpdateFlag(edge.Flags), Flags: lnwire.ChanUpdateFlag(edge.Flags),
ChannelID: edge.ChannelID, ChannelID: edge.ChannelID,
LastUpdate: time.Now(), LastUpdate: time.Now(),
@ -300,7 +295,7 @@ func TestBasicGraphPathFinding(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unable to fetch source node: %v", err) t.Fatalf("unable to fetch source node: %v", err)
} }
sourceVertex := NewVertex(sourceNode.PubKey) sourceVertex := Vertex(sourceNode.PubKeyBytes)
ignoredEdges := make(map[uint64]struct{}) ignoredEdges := make(map[uint64]struct{})
ignoredVertexes := make(map[Vertex]struct{}) ignoredVertexes := make(map[Vertex]struct{})
@ -342,13 +337,17 @@ func TestBasicGraphPathFinding(t *testing.T) {
} }
// The first hop in the path should be an edge from roasbeef to goku. // The first hop in the path should be an edge from roasbeef to goku.
if !route.Hops[0].Channel.Node.PubKey.IsEqual(aliases["songoku"]) { if !bytes.Equal(route.Hops[0].Channel.Node.PubKeyBytes[:],
aliases["songoku"].SerializeCompressed()) {
t.Fatalf("first hop should be goku, is instead: %v", t.Fatalf("first hop should be goku, is instead: %v",
route.Hops[0].Channel.Node.Alias) route.Hops[0].Channel.Node.Alias)
} }
// The second hop should be from goku to sophon. // The second hop should be from goku to sophon.
if !route.Hops[1].Channel.Node.PubKey.IsEqual(aliases["sophon"]) { if !bytes.Equal(route.Hops[1].Channel.Node.PubKeyBytes[:],
aliases["sophon"].SerializeCompressed()) {
t.Fatalf("second hop should be sophon, is instead: %v", t.Fatalf("second hop should be sophon, is instead: %v",
route.Hops[0].Channel.Node.Alias) route.Hops[0].Channel.Node.Alias)
} }
@ -833,7 +832,7 @@ func TestPathFindSpecExample(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unable to retrieve source node: %v", err) t.Fatalf("unable to retrieve source node: %v", err)
} }
if !source.PubKey.IsEqual(alice) { if !bytes.Equal(source.PubKeyBytes[:], alice.SerializeCompressed()) {
t.Fatalf("source node not set") t.Fatalf("source node not set")
} }

@ -814,7 +814,7 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
// attack by node announcements, we will ignore such nodes. If // attack by node announcements, we will ignore such nodes. If
// we do know about this node, check that this update brings // we do know about this node, check that this update brings
// info newer than what we already have. // info newer than what we already have.
lastUpdate, exists, err := r.cfg.Graph.HasLightningNode(msg.PubKey) lastUpdate, exists, err := r.cfg.Graph.HasLightningNode(msg.PubKeyBytes)
if err != nil { if err != nil {
return errors.Errorf("unable to query for the "+ return errors.Errorf("unable to query for the "+
"existence of node: %v", err) "existence of node: %v", err)
@ -822,7 +822,7 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
if !exists { if !exists {
return newErrf(ErrIgnored, "Ignoring node announcement"+ return newErrf(ErrIgnored, "Ignoring node announcement"+
" for node not found in channel graph (%x)", " for node not found in channel graph (%x)",
msg.PubKey.SerializeCompressed()) msg.PubKeyBytes)
} }
// If we've reached this point then we're aware of the vertex // If we've reached this point then we're aware of the vertex
@ -833,16 +833,15 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
lastUpdate.Equal(msg.LastUpdate) { lastUpdate.Equal(msg.LastUpdate) {
return newErrf(ErrOutdated, "Ignoring outdated "+ return newErrf(ErrOutdated, "Ignoring outdated "+
"announcement for %x", msg.PubKey.SerializeCompressed()) "announcement for %x", msg.PubKeyBytes)
} }
if err := r.cfg.Graph.AddLightningNode(msg); err != nil { if err := r.cfg.Graph.AddLightningNode(msg); err != nil {
return errors.Errorf("unable to add node %v to the "+ return errors.Errorf("unable to add node %v to the "+
"graph: %v", msg.PubKey.SerializeCompressed(), err) "graph: %v", msg.PubKeyBytes, err)
} }
log.Infof("Updated vertex data for node=%x", log.Infof("Updated vertex data for node=%x", msg.PubKeyBytes)
msg.PubKey.SerializeCompressed())
case *channeldb.ChannelEdgeInfo: case *channeldb.ChannelEdgeInfo:
// Prior to processing the announcement we first check if we // Prior to processing the announcement we first check if we
@ -859,30 +858,28 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
// Query the database for the existence of the two nodes in this // Query the database for the existence of the two nodes in this
// channel. If not found, add a partial node to the database, // channel. If not found, add a partial node to the database,
// containing only the node keys. // containing only the node keys.
_, exists, _ = r.cfg.Graph.HasLightningNode(msg.NodeKey1) _, exists, _ = r.cfg.Graph.HasLightningNode(msg.NodeKey1Bytes)
if !exists { if !exists {
node1 := &channeldb.LightningNode{ node1 := &channeldb.LightningNode{
PubKey: msg.NodeKey1, PubKeyBytes: msg.NodeKey1Bytes,
HaveNodeAnnouncement: false, HaveNodeAnnouncement: false,
} }
err := r.cfg.Graph.AddLightningNode(node1) err := r.cfg.Graph.AddLightningNode(node1)
if err != nil { if err != nil {
return errors.Errorf("unable to add node %v to"+ return errors.Errorf("unable to add node %v to"+
" the graph: %v", " the graph: %v", node1.PubKeyBytes, err)
node1.PubKey.SerializeCompressed(), err)
} }
} }
_, exists, _ = r.cfg.Graph.HasLightningNode(msg.NodeKey2) _, exists, _ = r.cfg.Graph.HasLightningNode(msg.NodeKey2Bytes)
if !exists { if !exists {
node2 := &channeldb.LightningNode{ node2 := &channeldb.LightningNode{
PubKey: msg.NodeKey2, PubKeyBytes: msg.NodeKey2Bytes,
HaveNodeAnnouncement: false, HaveNodeAnnouncement: false,
} }
err := r.cfg.Graph.AddLightningNode(node2) err := r.cfg.Graph.AddLightningNode(node2)
if err != nil { if err != nil {
return errors.Errorf("unable to add node %v to"+ return errors.Errorf("unable to add node %v to"+
" the graph: %v", " the graph: %v", node2.PubKeyBytes, err)
node2.PubKey.SerializeCompressed(), err)
} }
} }
@ -911,8 +908,7 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
// edge bitcoin keys and channel value corresponds to the // edge bitcoin keys and channel value corresponds to the
// reality. // reality.
_, witnessOutput, err := lnwallet.GenFundingPkScript( _, witnessOutput, err := lnwallet.GenFundingPkScript(
msg.BitcoinKey1.SerializeCompressed(), msg.BitcoinKey1Bytes[:], msg.BitcoinKey2Bytes[:],
msg.BitcoinKey2.SerializeCompressed(),
chanUtxo.Value, chanUtxo.Value,
) )
if err != nil { if err != nil {
@ -942,8 +938,7 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
log.Infof("New channel discovered! Link "+ log.Infof("New channel discovered! Link "+
"connects %x and %x with ChannelPoint(%v): "+ "connects %x and %x with ChannelPoint(%v): "+
"chan_id=%v, capacity=%v", "chan_id=%v, capacity=%v",
msg.NodeKey1.SerializeCompressed(), msg.NodeKey1Bytes, msg.NodeKey2Bytes,
msg.NodeKey2.SerializeCompressed(),
fundingPoint, msg.ChannelID, msg.Capacity) fundingPoint, msg.ChannelID, msg.Capacity)
// As a new edge has been added to the channel graph, we'll // As a new edge has been added to the channel graph, we'll
@ -1183,7 +1178,8 @@ func (r *ChannelRouter) FindRoutes(target *btcec.PublicKey,
// We can short circuit the routing by opportunistically checking to // We can short circuit the routing by opportunistically checking to
// see if the target vertex event exists in the current graph. // see if the target vertex event exists in the current graph.
if _, exists, err := r.cfg.Graph.HasLightningNode(target); err != nil { targetVertex := NewVertex(target)
if _, exists, err := r.cfg.Graph.HasLightningNode(targetVertex); err != nil {
return nil, err return nil, err
} else if !exists { } else if !exists {
log.Debugf("Target %x is not in known graph", dest) log.Debugf("Target %x is not in known graph", dest)
@ -1221,7 +1217,7 @@ func (r *ChannelRouter) FindRoutes(target *btcec.PublicKey,
// aren't able to support the total satoshis flow once fees have been // aren't able to support the total satoshis flow once fees have been
// factored in. // factored in.
validRoutes := make([]*Route, 0, len(shortestPaths)) validRoutes := make([]*Route, 0, len(shortestPaths))
sourceVertex := NewVertex(r.selfNode.PubKey) sourceVertex := Vertex(r.selfNode.PubKeyBytes)
for _, path := range shortestPaths { for _, path := range shortestPaths {
// Attempt to make the path into a route. We snip off the first // Attempt to make the path into a route. We snip off the first
// hop in the path as it contains a "self-hop" that is inserted // hop in the path as it contains a "self-hop" that is inserted
@ -1289,10 +1285,14 @@ func generateSphinxPacket(route *Route, paymentHash []byte) ([]byte,
// We create a new instance of the public key to avoid possibly // We create a new instance of the public key to avoid possibly
// mutating the curve parameters, which are unset in a higher // mutating the curve parameters, which are unset in a higher
// level in order to avoid spamming the logs. // level in order to avoid spamming the logs.
nodePub, err := hop.Channel.Node.PubKey()
if err != nil {
return nil, nil, err
}
pub := btcec.PublicKey{ pub := btcec.PublicKey{
Curve: btcec.S256(), Curve: btcec.S256(),
X: hop.Channel.Node.PubKey.X, X: nodePub.X,
Y: hop.Channel.Node.PubKey.Y, Y: nodePub.Y,
} }
nodes[i] = &pub nodes[i] = &pub
} }
@ -1453,7 +1453,7 @@ func (r *ChannelRouter) SendPayment(payment *LightningPayment) ([32]byte, *Route
// Attempt to send this payment through the network to complete // Attempt to send this payment through the network to complete
// the payment. If this attempt fails, then we'll continue on // the payment. If this attempt fails, then we'll continue on
// to the next available route. // to the next available route.
firstHop := route.Hops[0].Channel.Node.PubKey firstHop := route.Hops[0].Channel.Node.PubKeyBytes
preImage, sendError = r.cfg.SendToSwitch(firstHop, htlcAdd, preImage, sendError = r.cfg.SendToSwitch(firstHop, htlcAdd,
circuit) circuit)
if sendError != nil { if sendError != nil {
@ -1693,7 +1693,7 @@ func (r *ChannelRouter) applyChannelUpdate(msg *lnwire.ChannelUpdate) error {
} }
err := r.UpdateEdge(&channeldb.ChannelEdgePolicy{ err := r.UpdateEdge(&channeldb.ChannelEdgePolicy{
Signature: msg.Signature, SigBytes: msg.Signature.ToSignatureBytes(),
ChannelID: msg.ShortChannelID.ToUint64(), ChannelID: msg.ShortChannelID.ToUint64(),
LastUpdate: time.Unix(int64(msg.Timestamp), 0), LastUpdate: time.Unix(int64(msg.Timestamp), 0),
Flags: msg.Flags, Flags: msg.Flags,

@ -42,7 +42,7 @@ func (c *testCtx) RestartRouter() error {
Graph: c.graph, Graph: c.graph,
Chain: c.chain, Chain: c.chain,
ChainView: c.chainView, ChainView: c.chainView,
SendToSwitch: func(_ *btcec.PublicKey, SendToSwitch: func(_ [33]byte,
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) { _ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
return [32]byte{}, nil return [32]byte{}, nil
}, },
@ -117,8 +117,9 @@ func createTestCtx(startingHeight uint32, testGraph ...string) (*testCtx, func()
Graph: graph, Graph: graph,
Chain: chain, Chain: chain,
ChainView: chainView, ChainView: chainView,
SendToSwitch: func(_ *btcec.PublicKey, SendToSwitch: func(_ [33]byte, _ *lnwire.UpdateAddHTLC,
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) { _ *sphinx.Circuit) ([32]byte, error) {
return [32]byte{}, nil return [32]byte{}, nil
}, },
ChannelPruneExpiry: time.Hour * 24, ChannelPruneExpiry: time.Hour * 24,
@ -230,12 +231,16 @@ func TestSendPaymentRouteFailureFallback(t *testing.T) {
// router's configuration to ignore the path that has luo ji as the // router's configuration to ignore the path that has luo ji as the
// first hop. This should force the router to instead take the // first hop. This should force the router to instead take the
// available two hop path (through satoshi). // available two hop path (through satoshi).
ctx.router.cfg.SendToSwitch = func(n *btcec.PublicKey, ctx.router.cfg.SendToSwitch = func(n [33]byte,
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) { _ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
if ctx.aliases["luoji"].IsEqual(n) { if bytes.Equal(ctx.aliases["luoji"].SerializeCompressed(), n[:]) {
pub, err := sourceNode.PubKey()
if err != nil {
return preImage, err
}
return [32]byte{}, &htlcswitch.ForwardingError{ return [32]byte{}, &htlcswitch.ForwardingError{
ErrorSource: sourceNode.PubKey, ErrorSource: pub,
// TODO(roasbeef): temp node failure should be? // TODO(roasbeef): temp node failure should be?
FailureMessage: &lnwire.FailTemporaryChannelFailure{}, FailureMessage: &lnwire.FailTemporaryChannelFailure{},
} }
@ -301,21 +306,26 @@ func TestSendPaymentErrorPathPruning(t *testing.T) {
t.Fatalf("unable to fetch source node: %v", err) t.Fatalf("unable to fetch source node: %v", err)
} }
sourcePub, err := sourceNode.PubKey()
if err != nil {
t.Fatalf("unable to fetch source node pub: %v", err)
}
// First, we'll modify the SendToSwitch method to return an error // First, we'll modify the SendToSwitch method to return an error
// indicating that the channel from roasbeef to luoji is not operable // indicating that the channel from roasbeef to luoji is not operable
// with an UnknownNextPeer. // with an UnknownNextPeer.
// //
// TODO(roasbeef): filtering should be intelligent enough so just not // TODO(roasbeef): filtering should be intelligent enough so just not
// go through satoshi at all at this point. // go through satoshi at all at this point.
ctx.router.cfg.SendToSwitch = func(n *btcec.PublicKey, ctx.router.cfg.SendToSwitch = func(n [33]byte,
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) { _ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
if ctx.aliases["luoji"].IsEqual(n) { if bytes.Equal(ctx.aliases["luoji"].SerializeCompressed(), n[:]) {
// We'll first simulate an error from the first // We'll first simulate an error from the first
// outgoing link to simulate the channel from luo ji to // outgoing link to simulate the channel from luo ji to
// roasbeef not having enough capacity. // roasbeef not having enough capacity.
return [32]byte{}, &htlcswitch.ForwardingError{ return [32]byte{}, &htlcswitch.ForwardingError{
ErrorSource: sourceNode.PubKey, ErrorSource: sourcePub,
FailureMessage: &lnwire.FailTemporaryChannelFailure{}, FailureMessage: &lnwire.FailTemporaryChannelFailure{},
} }
} }
@ -323,7 +333,7 @@ func TestSendPaymentErrorPathPruning(t *testing.T) {
// Next, we'll create an error from satoshi to indicate // Next, we'll create an error from satoshi to indicate
// that the luoji node is not longer online, which should // that the luoji node is not longer online, which should
// prune out the rest of the routes. // prune out the rest of the routes.
if ctx.aliases["satoshi"].IsEqual(n) { if bytes.Equal(ctx.aliases["satoshi"].SerializeCompressed(), n[:]) {
return [32]byte{}, &htlcswitch.ForwardingError{ return [32]byte{}, &htlcswitch.ForwardingError{
ErrorSource: ctx.aliases["satoshi"], ErrorSource: ctx.aliases["satoshi"],
FailureMessage: &lnwire.FailUnknownNextPeer{}, FailureMessage: &lnwire.FailUnknownNextPeer{},
@ -353,12 +363,12 @@ func TestSendPaymentErrorPathPruning(t *testing.T) {
// Next, we'll modify the SendToSwitch method to indicate that luo ji // Next, we'll modify the SendToSwitch method to indicate that luo ji
// wasn't originally online. This should also halt the send all // wasn't originally online. This should also halt the send all
// together as all paths contain luoji and he can't be reached. // together as all paths contain luoji and he can't be reached.
ctx.router.cfg.SendToSwitch = func(n *btcec.PublicKey, ctx.router.cfg.SendToSwitch = func(n [33]byte,
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) { _ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
if ctx.aliases["luoji"].IsEqual(n) { if bytes.Equal(ctx.aliases["luoji"].SerializeCompressed(), n[:]) {
return [32]byte{}, &htlcswitch.ForwardingError{ return [32]byte{}, &htlcswitch.ForwardingError{
ErrorSource: sourceNode.PubKey, ErrorSource: sourcePub,
FailureMessage: &lnwire.FailUnknownNextPeer{}, FailureMessage: &lnwire.FailUnknownNextPeer{},
} }
} }
@ -380,14 +390,14 @@ func TestSendPaymentErrorPathPruning(t *testing.T) {
// Finally, we'll modify the SendToSwitch function to indicate that the // Finally, we'll modify the SendToSwitch function to indicate that the
// roasbeef -> luoji channel has insufficient capacity. // roasbeef -> luoji channel has insufficient capacity.
ctx.router.cfg.SendToSwitch = func(n *btcec.PublicKey, ctx.router.cfg.SendToSwitch = func(n [33]byte,
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) { _ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
if ctx.aliases["luoji"].IsEqual(n) { if bytes.Equal(ctx.aliases["luoji"].SerializeCompressed(), n[:]) {
// We'll first simulate an error from the first // We'll first simulate an error from the first
// outgoing link to simulate the channel from luo ji to // outgoing link to simulate the channel from luo ji to
// roasbeef not having enough capacity. // roasbeef not having enough capacity.
return [32]byte{}, &htlcswitch.ForwardingError{ return [32]byte{}, &htlcswitch.ForwardingError{
ErrorSource: sourceNode.PubKey, ErrorSource: sourcePub,
FailureMessage: &lnwire.FailTemporaryChannelFailure{}, FailureMessage: &lnwire.FailTemporaryChannelFailure{},
} }
} }
@ -457,13 +467,13 @@ func TestAddProof(t *testing.T) {
// After utxo was recreated adding the edge without the proof. // After utxo was recreated adding the edge without the proof.
edge := &channeldb.ChannelEdgeInfo{ edge := &channeldb.ChannelEdgeInfo{
ChannelID: chanID.ToUint64(), ChannelID: chanID.ToUint64(),
NodeKey1: copyPubKey(node1.PubKey), NodeKey1Bytes: node1.PubKeyBytes,
NodeKey2: copyPubKey(node2.PubKey), NodeKey2Bytes: node2.PubKeyBytes,
BitcoinKey1: copyPubKey(bitcoinKey1), AuthProof: nil,
BitcoinKey2: copyPubKey(bitcoinKey2),
AuthProof: nil,
} }
copy(edge.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
copy(edge.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed())
if err := ctx.router.AddEdge(edge); err != nil { if err := ctx.router.AddEdge(edge); err != nil {
t.Fatalf("unable to add edge: %v", err) t.Fatalf("unable to add edge: %v", err)
@ -495,16 +505,17 @@ func TestIgnoreNodeAnnouncement(t *testing.T) {
t.Fatalf("unable to create router: %v", err) t.Fatalf("unable to create router: %v", err)
} }
pub := priv1.PubKey()
node := &channeldb.LightningNode{ node := &channeldb.LightningNode{
HaveNodeAnnouncement: true, HaveNodeAnnouncement: true,
LastUpdate: time.Unix(123, 0), LastUpdate: time.Unix(123, 0),
Addresses: testAddrs, Addresses: testAddrs,
PubKey: copyPubKey(priv1.PubKey()),
Color: color.RGBA{1, 2, 3, 0}, Color: color.RGBA{1, 2, 3, 0},
Alias: "node11", Alias: "node11",
AuthSig: testSig, AuthSigBytes: testSig.Serialize(),
Features: testFeatures, Features: testFeatures,
} }
copy(node.PubKeyBytes[:], pub.SerializeCompressed())
err = ctx.router.AddNode(node) err = ctx.router.AddNode(node)
if !IsError(err, ErrIgnored) { if !IsError(err, ErrIgnored) {
@ -527,15 +538,21 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
t.Fatalf("unable to create router: %v", err) t.Fatalf("unable to create router: %v", err)
} }
var pub1 [33]byte
copy(pub1[:], priv1.PubKey().SerializeCompressed())
var pub2 [33]byte
copy(pub2[:], priv2.PubKey().SerializeCompressed())
// The two nodes we are about to add should not exist yet. // The two nodes we are about to add should not exist yet.
_, exists1, err := ctx.graph.HasLightningNode(priv1.PubKey()) _, exists1, err := ctx.graph.HasLightningNode(pub1)
if err != nil { if err != nil {
t.Fatalf("unable to query graph: %v", err) t.Fatalf("unable to query graph: %v", err)
} }
if exists1 { if exists1 {
t.Fatalf("node already existed") t.Fatalf("node already existed")
} }
_, exists2, err := ctx.graph.HasLightningNode(priv2.PubKey()) _, exists2, err := ctx.graph.HasLightningNode(pub2)
if err != nil { if err != nil {
t.Fatalf("unable to query graph: %v", err) t.Fatalf("unable to query graph: %v", err)
} }
@ -558,12 +575,12 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight) ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight)
edge := &channeldb.ChannelEdgeInfo{ edge := &channeldb.ChannelEdgeInfo{
ChannelID: chanID.ToUint64(), ChannelID: chanID.ToUint64(),
NodeKey1: copyPubKey(priv1.PubKey()), NodeKey1Bytes: pub1,
NodeKey2: copyPubKey(priv2.PubKey()), NodeKey2Bytes: pub2,
BitcoinKey1: copyPubKey(bitcoinKey1), BitcoinKey1Bytes: pub1,
BitcoinKey2: copyPubKey(bitcoinKey2), BitcoinKey2Bytes: pub2,
AuthProof: nil, AuthProof: nil,
} }
if err := ctx.router.AddEdge(edge); err != nil { if err := ctx.router.AddEdge(edge); err != nil {
t.Fatalf("expected to be able to add edge to the channel graph,"+ t.Fatalf("expected to be able to add edge to the channel graph,"+
@ -573,7 +590,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
// We must add the edge policy to be able to use the edge for route // We must add the edge policy to be able to use the edge for route
// finding. // finding.
edgePolicy := &channeldb.ChannelEdgePolicy{ edgePolicy := &channeldb.ChannelEdgePolicy{
Signature: testSig, SigBytes: testSig.Serialize(),
ChannelID: edge.ChannelID, ChannelID: edge.ChannelID,
LastUpdate: time.Now(), LastUpdate: time.Now(),
TimeLockDelta: 10, TimeLockDelta: 10,
@ -589,7 +606,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
// Create edge in the other direction as well. // Create edge in the other direction as well.
edgePolicy = &channeldb.ChannelEdgePolicy{ edgePolicy = &channeldb.ChannelEdgePolicy{
Signature: testSig, SigBytes: testSig.Serialize(),
ChannelID: edge.ChannelID, ChannelID: edge.ChannelID,
LastUpdate: time.Now(), LastUpdate: time.Now(),
TimeLockDelta: 10, TimeLockDelta: 10,
@ -605,14 +622,14 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
// After adding the edge between the two previously unknown nodes, they // After adding the edge between the two previously unknown nodes, they
// should have been added to the graph. // should have been added to the graph.
_, exists1, err = ctx.graph.HasLightningNode(priv1.PubKey()) _, exists1, err = ctx.graph.HasLightningNode(pub1)
if err != nil { if err != nil {
t.Fatalf("unable to query graph: %v", err) t.Fatalf("unable to query graph: %v", err)
} }
if !exists1 { if !exists1 {
t.Fatalf("node1 was not added to the graph") t.Fatalf("node1 was not added to the graph")
} }
_, exists2, err = ctx.graph.HasLightningNode(priv2.PubKey()) _, exists2, err = ctx.graph.HasLightningNode(pub2)
if err != nil { if err != nil {
t.Fatalf("unable to query graph: %v", err) t.Fatalf("unable to query graph: %v", err)
} }
@ -656,20 +673,20 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight) ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight)
edge = &channeldb.ChannelEdgeInfo{ edge = &channeldb.ChannelEdgeInfo{
ChannelID: chanID.ToUint64(), ChannelID: chanID.ToUint64(),
NodeKey1: pubKey1, AuthProof: nil,
NodeKey2: pubKey2,
BitcoinKey1: pubKey1,
BitcoinKey2: pubKey2,
AuthProof: nil,
} }
copy(edge.NodeKey1Bytes[:], node1Bytes)
copy(edge.NodeKey2Bytes[:], node2Bytes)
copy(edge.BitcoinKey1Bytes[:], node1Bytes)
copy(edge.BitcoinKey2Bytes[:], node2Bytes)
if err := ctx.router.AddEdge(edge); err != nil { if err := ctx.router.AddEdge(edge); err != nil {
t.Fatalf("unable to add edge to the channel graph: %v.", err) t.Fatalf("unable to add edge to the channel graph: %v.", err)
} }
edgePolicy = &channeldb.ChannelEdgePolicy{ edgePolicy = &channeldb.ChannelEdgePolicy{
Signature: testSig, SigBytes: testSig.Serialize(),
ChannelID: edge.ChannelID, ChannelID: edge.ChannelID,
LastUpdate: time.Now(), LastUpdate: time.Now(),
TimeLockDelta: 10, TimeLockDelta: 10,
@ -684,7 +701,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
} }
edgePolicy = &channeldb.ChannelEdgePolicy{ edgePolicy = &channeldb.ChannelEdgePolicy{
Signature: testSig, SigBytes: testSig.Serialize(),
ChannelID: edge.ChannelID, ChannelID: edge.ChannelID,
LastUpdate: time.Now(), LastUpdate: time.Now(),
TimeLockDelta: 10, TimeLockDelta: 10,
@ -716,12 +733,12 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
HaveNodeAnnouncement: true, HaveNodeAnnouncement: true,
LastUpdate: time.Unix(123, 0), LastUpdate: time.Unix(123, 0),
Addresses: testAddrs, Addresses: testAddrs,
PubKey: copyPubKey(priv1.PubKey()),
Color: color.RGBA{1, 2, 3, 0}, Color: color.RGBA{1, 2, 3, 0},
Alias: "node11", Alias: "node11",
AuthSig: testSig, AuthSigBytes: testSig.Serialize(),
Features: testFeatures, Features: testFeatures,
} }
copy(n1.PubKeyBytes[:], priv1.PubKey().SerializeCompressed())
if err := ctx.router.AddNode(n1); err != nil { if err := ctx.router.AddNode(n1); err != nil {
t.Fatalf("could not add node: %v", err) t.Fatalf("could not add node: %v", err)
@ -731,12 +748,12 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
HaveNodeAnnouncement: true, HaveNodeAnnouncement: true,
LastUpdate: time.Unix(123, 0), LastUpdate: time.Unix(123, 0),
Addresses: testAddrs, Addresses: testAddrs,
PubKey: copyPubKey(priv2.PubKey()),
Color: color.RGBA{1, 2, 3, 0}, Color: color.RGBA{1, 2, 3, 0},
Alias: "node22", Alias: "node22",
AuthSig: testSig, AuthSigBytes: testSig.Serialize(),
Features: testFeatures, Features: testFeatures,
} }
copy(n2.PubKeyBytes[:], priv2.PubKey().SerializeCompressed())
if err := ctx.router.AddNode(n2); err != nil { if err := ctx.router.AddNode(n2); err != nil {
t.Fatalf("could not add node: %v", err) t.Fatalf("could not add node: %v", err)
@ -865,36 +882,36 @@ func TestWakeUpOnStaleBranch(t *testing.T) {
} }
edge1 := &channeldb.ChannelEdgeInfo{ edge1 := &channeldb.ChannelEdgeInfo{
ChannelID: chanID1, ChannelID: chanID1,
NodeKey1: copyPubKey(node1.PubKey), NodeKey1Bytes: node1.PubKeyBytes,
NodeKey2: copyPubKey(node2.PubKey), NodeKey2Bytes: node2.PubKeyBytes,
BitcoinKey1: copyPubKey(bitcoinKey1),
BitcoinKey2: copyPubKey(bitcoinKey2),
AuthProof: &channeldb.ChannelAuthProof{ AuthProof: &channeldb.ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
}, },
} }
copy(edge1.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
copy(edge1.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed())
if err := ctx.router.AddEdge(edge1); err != nil { if err := ctx.router.AddEdge(edge1); err != nil {
t.Fatalf("unable to add edge: %v", err) t.Fatalf("unable to add edge: %v", err)
} }
edge2 := &channeldb.ChannelEdgeInfo{ edge2 := &channeldb.ChannelEdgeInfo{
ChannelID: chanID2, ChannelID: chanID2,
NodeKey1: copyPubKey(node1.PubKey), NodeKey1Bytes: node1.PubKeyBytes,
NodeKey2: copyPubKey(node2.PubKey), NodeKey2Bytes: node2.PubKeyBytes,
BitcoinKey1: copyPubKey(bitcoinKey1),
BitcoinKey2: copyPubKey(bitcoinKey2),
AuthProof: &channeldb.ChannelAuthProof{ AuthProof: &channeldb.ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
}, },
} }
copy(edge2.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
copy(edge2.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed())
if err := ctx.router.AddEdge(edge2); err != nil { if err := ctx.router.AddEdge(edge2); err != nil {
t.Fatalf("unable to add edge: %v", err) t.Fatalf("unable to add edge: %v", err)
@ -940,7 +957,7 @@ func TestWakeUpOnStaleBranch(t *testing.T) {
Graph: ctx.graph, Graph: ctx.graph,
Chain: ctx.chain, Chain: ctx.chain,
ChainView: ctx.chainView, ChainView: ctx.chainView,
SendToSwitch: func(_ *btcec.PublicKey, SendToSwitch: func(_ [33]byte,
_ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) { _ *lnwire.UpdateAddHTLC, _ *sphinx.Circuit) ([32]byte, error) {
return [32]byte{}, nil return [32]byte{}, nil
}, },
@ -1067,36 +1084,40 @@ func TestDisconnectedBlocks(t *testing.T) {
} }
edge1 := &channeldb.ChannelEdgeInfo{ edge1 := &channeldb.ChannelEdgeInfo{
ChannelID: chanID1, ChannelID: chanID1,
NodeKey1: copyPubKey(node1.PubKey), NodeKey1Bytes: node1.PubKeyBytes,
NodeKey2: copyPubKey(node2.PubKey), NodeKey2Bytes: node2.PubKeyBytes,
BitcoinKey1: copyPubKey(bitcoinKey1), BitcoinKey1Bytes: node1.PubKeyBytes,
BitcoinKey2: copyPubKey(bitcoinKey2), BitcoinKey2Bytes: node2.PubKeyBytes,
AuthProof: &channeldb.ChannelAuthProof{ AuthProof: &channeldb.ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
}, },
} }
copy(edge1.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
copy(edge1.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed())
if err := ctx.router.AddEdge(edge1); err != nil { if err := ctx.router.AddEdge(edge1); err != nil {
t.Fatalf("unable to add edge: %v", err) t.Fatalf("unable to add edge: %v", err)
} }
edge2 := &channeldb.ChannelEdgeInfo{ edge2 := &channeldb.ChannelEdgeInfo{
ChannelID: chanID2, ChannelID: chanID2,
NodeKey1: copyPubKey(node1.PubKey), NodeKey1Bytes: node1.PubKeyBytes,
NodeKey2: copyPubKey(node2.PubKey), NodeKey2Bytes: node2.PubKeyBytes,
BitcoinKey1: copyPubKey(bitcoinKey1), BitcoinKey1Bytes: node1.PubKeyBytes,
BitcoinKey2: copyPubKey(bitcoinKey2), BitcoinKey2Bytes: node2.PubKeyBytes,
AuthProof: &channeldb.ChannelAuthProof{ AuthProof: &channeldb.ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
}, },
} }
copy(edge2.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
copy(edge2.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed())
if err := ctx.router.AddEdge(edge2); err != nil { if err := ctx.router.AddEdge(edge2); err != nil {
t.Fatalf("unable to add edge: %v", err) t.Fatalf("unable to add edge: %v", err)
@ -1207,18 +1228,18 @@ func TestRouterChansClosedOfflinePruneGraph(t *testing.T) {
t.Fatalf("unable to create test node: %v", err) t.Fatalf("unable to create test node: %v", err)
} }
edge1 := &channeldb.ChannelEdgeInfo{ edge1 := &channeldb.ChannelEdgeInfo{
ChannelID: chanID1.ToUint64(), ChannelID: chanID1.ToUint64(),
NodeKey1: copyPubKey(node1.PubKey), NodeKey1Bytes: node1.PubKeyBytes,
NodeKey2: copyPubKey(node2.PubKey), NodeKey2Bytes: node2.PubKeyBytes,
BitcoinKey1: copyPubKey(bitcoinKey1),
BitcoinKey2: copyPubKey(bitcoinKey2),
AuthProof: &channeldb.ChannelAuthProof{ AuthProof: &channeldb.ChannelAuthProof{
NodeSig1: testSig, NodeSig1Bytes: testSig.Serialize(),
NodeSig2: testSig, NodeSig2Bytes: testSig.Serialize(),
BitcoinSig1: testSig, BitcoinSig1Bytes: testSig.Serialize(),
BitcoinSig2: testSig, BitcoinSig2Bytes: testSig.Serialize(),
}, },
} }
copy(edge1.BitcoinKey1Bytes[:], bitcoinKey1.SerializeCompressed())
copy(edge1.BitcoinKey2Bytes[:], bitcoinKey2.SerializeCompressed())
if err := ctx.router.AddEdge(edge1); err != nil { if err := ctx.router.AddEdge(edge1); err != nil {
t.Fatalf("unable to add edge: %v", err) t.Fatalf("unable to add edge: %v", err)
} }

@ -104,8 +104,8 @@ func (v *ValidationBarrier) InitJobDependencies(job interface{}) {
v.chanAnnFinSignal[msg.ShortChannelID] = annFinCond v.chanAnnFinSignal[msg.ShortChannelID] = annFinCond
v.chanEdgeDependencies[msg.ShortChannelID] = annFinCond v.chanEdgeDependencies[msg.ShortChannelID] = annFinCond
v.nodeAnnDependencies[NewVertex(msg.NodeID1)] = annFinCond v.nodeAnnDependencies[Vertex(msg.NodeID1)] = annFinCond
v.nodeAnnDependencies[NewVertex(msg.NodeID2)] = annFinCond v.nodeAnnDependencies[Vertex(msg.NodeID2)] = annFinCond
} }
case *channeldb.ChannelEdgeInfo: case *channeldb.ChannelEdgeInfo:
@ -116,8 +116,8 @@ func (v *ValidationBarrier) InitJobDependencies(job interface{}) {
v.chanAnnFinSignal[shortID] = annFinCond v.chanAnnFinSignal[shortID] = annFinCond
v.chanEdgeDependencies[shortID] = annFinCond v.chanEdgeDependencies[shortID] = annFinCond
v.nodeAnnDependencies[NewVertex(msg.NodeKey1)] = annFinCond v.nodeAnnDependencies[Vertex(msg.NodeKey1)] = annFinCond
v.nodeAnnDependencies[NewVertex(msg.NodeKey2)] = annFinCond v.nodeAnnDependencies[Vertex(msg.NodeKey2)] = annFinCond
} }
// These other types don't have any dependants, so no further // These other types don't have any dependants, so no further
@ -127,6 +127,7 @@ func (v *ValidationBarrier) InitJobDependencies(job interface{}) {
case *lnwire.ChannelUpdate: case *lnwire.ChannelUpdate:
return return
case *lnwire.NodeAnnouncement: case *lnwire.NodeAnnouncement:
// TODO(roasbeef): node ann needs to wait on existing channel updates
return return
case *channeldb.LightningNode: case *channeldb.LightningNode:
return return
@ -167,12 +168,12 @@ func (v *ValidationBarrier) WaitForDependants(job interface{}) {
shortID := lnwire.NewShortChanIDFromInt(msg.ChannelID) shortID := lnwire.NewShortChanIDFromInt(msg.ChannelID)
signal, ok = v.chanEdgeDependencies[shortID] signal, ok = v.chanEdgeDependencies[shortID]
case *channeldb.LightningNode: case *channeldb.LightningNode:
vertex := NewVertex(msg.PubKey) vertex := Vertex(msg.PubKey)
signal, ok = v.nodeAnnDependencies[vertex] signal, ok = v.nodeAnnDependencies[vertex]
case *lnwire.ChannelUpdate: case *lnwire.ChannelUpdate:
signal, ok = v.chanEdgeDependencies[msg.ShortChannelID] signal, ok = v.chanEdgeDependencies[msg.ShortChannelID]
case *lnwire.NodeAnnouncement: case *lnwire.NodeAnnouncement:
vertex := NewVertex(msg.NodeID) vertex := Vertex(msg.NodeID)
signal, ok = v.nodeAnnDependencies[vertex] signal, ok = v.nodeAnnDependencies[vertex]
// Other types of jobs can be executed immediately, so we'll just // Other types of jobs can be executed immediately, so we'll just
@ -233,9 +234,9 @@ func (v *ValidationBarrier) SignalDependants(job interface{}) {
// map, as if we reach this point, then all dependants have already // map, as if we reach this point, then all dependants have already
// finished executing and we can proceed. // finished executing and we can proceed.
case *channeldb.LightningNode: case *channeldb.LightningNode:
delete(v.nodeAnnDependencies, NewVertex(msg.PubKey)) delete(v.nodeAnnDependencies, Vertex(msg.PubKey))
case *lnwire.NodeAnnouncement: case *lnwire.NodeAnnouncement:
delete(v.nodeAnnDependencies, NewVertex(msg.NodeID)) delete(v.nodeAnnDependencies, Vertex(msg.NodeID))
case *lnwire.ChannelUpdate: case *lnwire.ChannelUpdate:
delete(v.chanEdgeDependencies, msg.ShortChannelID) delete(v.chanEdgeDependencies, msg.ShortChannelID)
case *channeldb.ChannelEdgePolicy: case *channeldb.ChannelEdgePolicy: