discovery+routing: split 'routing' package on 'routing' and 'discovery'
In this commit the routing package was divided on two separete one, this was done because 'routing' package start take too much responsibily on themself, so with following commit: Routing pacakge: Enitites: * channeldb.ChannelEdge * channeldb.ChannelPolicy * channeldb.NodeLightning Responsibilities: * send topology notification * find payment paths * send payment * apply topology changes to the graph * prune graph * validate that funding point exist and corresponds to given one * to be the source of topology data Discovery package: Entities: * lnwire.AnnounceSignature * lnwire.ChannelAnnouncement * lnwire.NodeAnnouncement * lnwire.ChannelUpdateAnnouncement Responsibilities: * validate announcement signatures * sync topology with newly connected peers * handle the premature annoucement * redirect topology changes to the router susbsystem * broadcast announcement to the rest of the network * exchange channel announcement proofs Before that moment all that was in the 'routing' which is quite big for one subsystem. split
This commit is contained in:
1 parent
0e96d273d9
commit
b4ac7071ff
11 files changed
+1543
-683
No files matched your search
+70
-10
@@ -1,31 +1,91 @@
|
||||
package routing
|
||||
|
||||
import "errors"
|
||||
import "github.com/go-errors/errors"
|
||||
|
||||
var (
|
||||
// errorCode represent the error code and is used for compile time check.
|
||||
type errorCode uint8
|
||||
|
||||
const (
|
||||
// ErrNoPathFound is returned when a path to the target destination
|
||||
// does not exist in the graph.
|
||||
ErrNoPathFound = errors.New("unable to find a path to " +
|
||||
"destination")
|
||||
ErrNoPathFound errorCode = iota
|
||||
|
||||
// ErrNoRouteFound is returned when the router is unable to find a
|
||||
// valid route to the target destination after fees and time-lock
|
||||
// limitations are factored in.
|
||||
ErrNoRouteFound = errors.New("unable to find a eligible route to " +
|
||||
"the destination")
|
||||
ErrNoRouteFound
|
||||
|
||||
// ErrInsufficientCapacity is returned when a path if found, yet the
|
||||
// capacity of one of the channels in the path is insufficient to carry
|
||||
// the payment.
|
||||
ErrInsufficientCapacity = errors.New("channel graph has " +
|
||||
"insufficient capacity for the payment")
|
||||
ErrInsufficientCapacity
|
||||
|
||||
// ErrMaxHopsExceeded is returned when a candidate path is found, but
|
||||
// the length of that path exceeds HopLimit.
|
||||
ErrMaxHopsExceeded = errors.New("potential path has too many hops")
|
||||
ErrMaxHopsExceeded
|
||||
|
||||
// ErrTargetNotInNetwork is returned when the target of a path-finding
|
||||
// or payment attempt isn't known to be within the current version of
|
||||
// the channel graph.
|
||||
ErrTargetNotInNetwork = errors.New("target not found")
|
||||
ErrTargetNotInNetwork
|
||||
|
||||
// ErrOutdated is returned when the routing update already have
|
||||
// been applied.
|
||||
ErrOutdated
|
||||
|
||||
// ErrIgnored is returned when the update have been ignored because
|
||||
// this update can't bring us something new.
|
||||
ErrIgnored
|
||||
)
|
||||
|
||||
// routerError is a structure that represent the error inside the routing package,
|
||||
// this structure carries additional information about error code in order to
|
||||
// be able distinguish errors outside of the current package.
|
||||
type routerError struct {
|
||||
err *errors.Error
|
||||
code errorCode
|
||||
}
|
||||
|
||||
// Error represents errors as the string
|
||||
// NOTE: Part of the error interface.
|
||||
func (e *routerError) Error() string {
|
||||
return e.err.Error()
|
||||
}
|
||||
|
||||
// A compile time check to ensure routerError implements the error interface.
|
||||
var _ error = (*routerError)(nil)
|
||||
|
||||
// newErr creates an routerError by the given error description and its
|
||||
// corresponding error code.
|
||||
func newErr(code errorCode, a interface{}) *routerError {
|
||||
return &routerError{
|
||||
code: code,
|
||||
err: errors.New(a),
|
||||
}
|
||||
}
|
||||
|
||||
// newErrf creates an routerError by the given error formatted description and
|
||||
// its corresponding error code.
|
||||
func newErrf(code errorCode, format string, a ...interface{}) *routerError {
|
||||
return &routerError{
|
||||
code: code,
|
||||
err: errors.Errorf(format, a...),
|
||||
}
|
||||
}
|
||||
|
||||
// IsError is a helper function which is needed to have ability to check that
|
||||
// returned error has specific error code.
|
||||
func IsError(e interface{}, codes ...errorCode) bool {
|
||||
err, ok := e.(*routerError)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, code := range codes {
|
||||
if err.code == code {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
+14
-15
@@ -1,14 +1,13 @@
|
||||
package routing
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/roasbeef/btcd/btcec"
|
||||
"github.com/roasbeef/btcd/wire"
|
||||
"github.com/roasbeef/btcutil"
|
||||
@@ -277,17 +276,17 @@ type ChannelEdgeUpdate struct {
|
||||
// information required to create the topology change update from the graph
|
||||
// database.
|
||||
func addToTopologyChange(graph *channeldb.ChannelGraph, update *TopologyChange,
|
||||
msg lnwire.Message) error {
|
||||
msg interface{}) error {
|
||||
|
||||
switch m := msg.(type) {
|
||||
|
||||
// Any node announcement maps directly to a NetworkNodeUpdate struct.
|
||||
// No further data munging or db queries are required.
|
||||
case *lnwire.NodeAnnouncement:
|
||||
case *channeldb.LightningNode:
|
||||
nodeUpdate := &NetworkNodeUpdate{
|
||||
Addresses: m.Addresses,
|
||||
IdentityKey: m.NodeID,
|
||||
Alias: m.Alias.String(),
|
||||
IdentityKey: m.PubKey,
|
||||
Alias: m.Alias,
|
||||
}
|
||||
nodeUpdate.IdentityKey.Curve = nil
|
||||
|
||||
@@ -296,19 +295,19 @@ 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 *lnwire.ChannelAnnouncement:
|
||||
case *channeldb.ChannelEdgeInfo:
|
||||
return nil
|
||||
|
||||
// Any new ChannelUpdateAnnouncements will generate a corresponding
|
||||
// ChannelEdgeUpdate notification.
|
||||
case *lnwire.ChannelUpdateAnnouncement:
|
||||
case *channeldb.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.
|
||||
chanID := m.ChannelID.ToUint64()
|
||||
edgeInfo, _, _, err := graph.FetchChannelEdgesByID(chanID)
|
||||
edgeInfo, _, _, err := graph.FetchChannelEdgesByID(m.ChannelID)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Errorf("unable fetch channel edge: %v",
|
||||
err)
|
||||
}
|
||||
|
||||
// If the flag is one, then the advertising node is actually
|
||||
@@ -321,13 +320,13 @@ func addToTopologyChange(graph *channeldb.ChannelGraph, update *TopologyChange,
|
||||
}
|
||||
|
||||
edgeUpdate := &ChannelEdgeUpdate{
|
||||
ChanID: chanID,
|
||||
ChanID: m.ChannelID,
|
||||
ChanPoint: edgeInfo.ChannelPoint,
|
||||
TimeLockDelta: m.TimeLockDelta,
|
||||
Capacity: edgeInfo.Capacity,
|
||||
MinHTLC: btcutil.Amount(m.HtlcMinimumMsat),
|
||||
BaseFee: btcutil.Amount(m.FeeBaseMsat),
|
||||
FeeRate: btcutil.Amount(m.FeeProportionalMillionths),
|
||||
MinHTLC: m.MinHTLC,
|
||||
BaseFee: m.FeeBaseMSat,
|
||||
FeeRate: m.FeeProportionalMillionths,
|
||||
AdvertisingNode: sourceNode,
|
||||
ConnectingNode: connectingNode,
|
||||
}
|
||||
|
||||
+117
-91
@@ -53,7 +53,7 @@ func createGraphNode() (*channeldb.LightningNode, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func createTestWireNode() (*lnwire.NodeAnnouncement, error) {
|
||||
func createTestNode() (*channeldb.LightningNode, error) {
|
||||
priv, err := btcec.NewPrivateKey(btcec.S256())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -66,25 +66,26 @@ func createTestWireNode() (*lnwire.NodeAnnouncement, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &lnwire.NodeAnnouncement{
|
||||
Timestamp: uint32(prand.Int31()),
|
||||
Addresses: testAddrs,
|
||||
NodeID: priv.PubKey(),
|
||||
Alias: alias,
|
||||
return &channeldb.LightningNode{
|
||||
LastUpdate: time.Now(),
|
||||
Address: testAddr,
|
||||
PubKey: priv.PubKey(),
|
||||
Alias: alias.String(),
|
||||
Features: testFeatures,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func randEdgePolicyAnn(chanID lnwire.ChannelID) *lnwire.ChannelUpdateAnnouncement {
|
||||
func randEdgePolicy(chanID lnwire.ChannelID,
|
||||
node *channeldb.LightningNode) *channeldb.ChannelEdgePolicy {
|
||||
|
||||
return &lnwire.ChannelUpdateAnnouncement{
|
||||
Signature: testSig,
|
||||
ChannelID: chanID,
|
||||
Timestamp: uint32(prand.Int31()),
|
||||
return &channeldb.ChannelEdgePolicy{
|
||||
ChannelID: chanID.ToUint64(),
|
||||
LastUpdate: time.Unix(int64(prand.Int31()), 0),
|
||||
TimeLockDelta: uint16(prand.Int63()),
|
||||
HtlcMinimumMsat: uint32(prand.Int31()),
|
||||
FeeBaseMsat: uint32(prand.Int31()),
|
||||
FeeProportionalMillionths: uint32(prand.Int31()),
|
||||
MinHTLC: btcutil.Amount(prand.Int31()),
|
||||
FeeBaseMSat: btcutil.Amount(prand.Int31()),
|
||||
FeeProportionalMillionths: btcutil.Amount(prand.Int31()),
|
||||
Node: node,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,7 +269,7 @@ func (m *mockNotifier) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TestEdgeUpdateNotification tests that when edges are updated or discovered,
|
||||
// TestEdgeUpdateNotification tests that when edges are updated or added,
|
||||
// a proper notification is sent of to all registered clients.
|
||||
func TestEdgeUpdateNotification(t *testing.T) {
|
||||
const startingBlockHeight = 101
|
||||
@@ -292,34 +293,43 @@ func TestEdgeUpdateNotification(t *testing.T) {
|
||||
|
||||
// Next we'll create two test nodes that the fake channel will be open
|
||||
// between and add then as members of the channel graph.
|
||||
node1, err := createTestWireNode()
|
||||
node1, err := createTestNode()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create test node: %v", err)
|
||||
}
|
||||
node2, err := createTestWireNode()
|
||||
node2, err := createTestNode()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create test node: %v", err)
|
||||
}
|
||||
|
||||
// Send the two node announcements to the channel router so they can be
|
||||
// validated and stored within the graph database.
|
||||
ctx.router.ProcessRoutingMessage(node1, node1.NodeID)
|
||||
ctx.router.ProcessRoutingMessage(node2, node2.NodeID)
|
||||
// Send the two node topology updates to the channel router so they
|
||||
// can be validated and stored within the graph database.
|
||||
if err := ctx.router.AddNode(node1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ctx.router.AddNode(node2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Finally, to conclude our test set up, we'll create a channel
|
||||
// announcement to announce the created channel between the two nodes.
|
||||
channelAnn := &lnwire.ChannelAnnouncement{
|
||||
FirstNodeSig: testSig,
|
||||
SecondNodeSig: testSig,
|
||||
ChannelID: chanID,
|
||||
FirstBitcoinSig: testSig,
|
||||
SecondBitcoinSig: testSig,
|
||||
FirstNodeID: node1.NodeID,
|
||||
SecondNodeID: node2.NodeID,
|
||||
FirstBitcoinKey: node1.NodeID,
|
||||
SecondBitcoinKey: node2.NodeID,
|
||||
// update to announce the created channel between the two nodes.
|
||||
edge := &channeldb.ChannelEdgeInfo{
|
||||
ChannelID: chanID.ToUint64(),
|
||||
NodeKey1: node1.PubKey,
|
||||
NodeKey2: node2.PubKey,
|
||||
BitcoinKey1: node1.PubKey,
|
||||
BitcoinKey2: node2.PubKey,
|
||||
AuthProof: &channeldb.ChannelAuthProof{
|
||||
NodeSig1: testSig,
|
||||
NodeSig2: testSig,
|
||||
BitcoinSig1: testSig,
|
||||
BitcoinSig2: testSig,
|
||||
},
|
||||
}
|
||||
|
||||
if err := ctx.router.AddEdge(edge); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ctx.router.ProcessRoutingMessage(channelAnn, node1.NodeID)
|
||||
|
||||
// With the channel edge now in place, we'll subscribe for topology
|
||||
// notifications.
|
||||
@@ -330,17 +340,21 @@ func TestEdgeUpdateNotification(t *testing.T) {
|
||||
|
||||
// Create random policy edges that are stemmed to the channel id
|
||||
// created above.
|
||||
edge1 := randEdgePolicyAnn(chanID)
|
||||
edge1 := randEdgePolicy(chanID, node1)
|
||||
edge1.Flags = 0
|
||||
edge2 := randEdgePolicyAnn(chanID)
|
||||
edge2 := randEdgePolicy(chanID, node2)
|
||||
edge2.Flags = 1
|
||||
|
||||
ctx.router.ProcessRoutingMessage(edge1, node1.NodeID)
|
||||
ctx.router.ProcessRoutingMessage(edge2, node2.NodeID)
|
||||
if err := ctx.router.UpdateEdge(edge1); err != nil {
|
||||
t.Fatalf("unable to add edge update: %v", err)
|
||||
}
|
||||
if err := ctx.router.UpdateEdge(edge2); err != nil {
|
||||
t.Fatalf("unable to add edge update: %v", err)
|
||||
}
|
||||
|
||||
assertEdgeAnnCorrect := func(t *testing.T, edgeUpdate *ChannelEdgeUpdate,
|
||||
edgeAnn *lnwire.ChannelUpdateAnnouncement) {
|
||||
if edgeUpdate.ChanID != edgeAnn.ChannelID.ToUint64() {
|
||||
assertEdgeCorrect := func(t *testing.T, edgeUpdate *ChannelEdgeUpdate,
|
||||
edgeAnn *channeldb.ChannelEdgePolicy) {
|
||||
if edgeUpdate.ChanID != edgeAnn.ChannelID {
|
||||
t.Fatalf("channel ID of edge doesn't match: "+
|
||||
"expected %v, got %v", chanID.ToUint64(), edgeUpdate.ChanID)
|
||||
}
|
||||
@@ -354,14 +368,14 @@ func TestEdgeUpdateNotification(t *testing.T) {
|
||||
t.Fatalf("capacity of edge doesn't match: "+
|
||||
"expected %v, got %v", chanValue, edgeUpdate.Capacity)
|
||||
}
|
||||
if edgeUpdate.MinHTLC != btcutil.Amount(edgeAnn.HtlcMinimumMsat) {
|
||||
if edgeUpdate.MinHTLC != btcutil.Amount(edgeAnn.MinHTLC) {
|
||||
t.Fatalf("min HTLC of edge doesn't match: "+
|
||||
"expected %v, got %v", btcutil.Amount(edgeAnn.HtlcMinimumMsat),
|
||||
"expected %v, got %v", btcutil.Amount(edgeAnn.MinHTLC),
|
||||
edgeUpdate.MinHTLC)
|
||||
}
|
||||
if edgeUpdate.BaseFee != btcutil.Amount(edgeAnn.FeeBaseMsat) {
|
||||
if edgeUpdate.BaseFee != btcutil.Amount(edgeAnn.FeeBaseMSat) {
|
||||
t.Fatalf("base fee of edge doesn't match: "+
|
||||
"expected %v, got %v", edgeAnn.FeeBaseMsat,
|
||||
"expected %v, got %v", edgeAnn.FeeBaseMSat,
|
||||
edgeUpdate.BaseFee)
|
||||
}
|
||||
if edgeUpdate.FeeRate != btcutil.Amount(edgeAnn.FeeProportionalMillionths) {
|
||||
@@ -382,26 +396,26 @@ func TestEdgeUpdateNotification(t *testing.T) {
|
||||
case ntfn := <-ntfnClient.TopologyChanges:
|
||||
edgeUpdate := ntfn.ChannelEdgeUpdates[0]
|
||||
if i == 0 {
|
||||
assertEdgeAnnCorrect(t, edgeUpdate, edge1)
|
||||
if !edgeUpdate.AdvertisingNode.IsEqual(node1.NodeID) {
|
||||
t.Fatalf("advertising node mismatch")
|
||||
assertEdgeCorrect(t, edgeUpdate, edge1)
|
||||
if !edgeUpdate.AdvertisingNode.IsEqual(node1.PubKey) {
|
||||
t.Fatal("advertising node mismatch")
|
||||
}
|
||||
if !edgeUpdate.ConnectingNode.IsEqual(node2.NodeID) {
|
||||
t.Fatalf("connecting node mismatch")
|
||||
if !edgeUpdate.ConnectingNode.IsEqual(node2.PubKey) {
|
||||
t.Fatal("connecting node mismatch")
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
assertEdgeAnnCorrect(t, edgeUpdate, edge2)
|
||||
if !edgeUpdate.ConnectingNode.IsEqual(node1.NodeID) {
|
||||
t.Fatalf("connecting node mismatch")
|
||||
assertEdgeCorrect(t, edgeUpdate, edge2)
|
||||
if !edgeUpdate.ConnectingNode.IsEqual(node1.PubKey) {
|
||||
t.Fatal("connecting node mismatch")
|
||||
}
|
||||
if !edgeUpdate.AdvertisingNode.IsEqual(node2.NodeID) {
|
||||
t.Fatalf("advertising node mismatch")
|
||||
if !edgeUpdate.AdvertisingNode.IsEqual(node2.PubKey) {
|
||||
t.Fatal("advertising node mismatch")
|
||||
}
|
||||
case <-time.After(time.Second * 5):
|
||||
t.Fatalf("update not received")
|
||||
t.Fatal("update not received")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -424,20 +438,24 @@ func TestNodeUpdateNotification(t *testing.T) {
|
||||
|
||||
// Create two random nodes to add to send as node announcement messages
|
||||
// to trigger notifications.
|
||||
node1Ann, err := createTestWireNode()
|
||||
node1, err := createTestNode()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create test node: %v", err)
|
||||
}
|
||||
node2Ann, err := createTestWireNode()
|
||||
node2, err := createTestNode()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create test node: %v", err)
|
||||
}
|
||||
|
||||
// Send both announcement message to the channel router.
|
||||
ctx.router.ProcessRoutingMessage(node1Ann, node1Ann.NodeID)
|
||||
ctx.router.ProcessRoutingMessage(node2Ann, node2Ann.NodeID)
|
||||
// Change network topology by adding nodes to the channel router.
|
||||
if err := ctx.router.AddNode(node1); err != nil {
|
||||
t.Fatalf("unable to add node: %v", err)
|
||||
}
|
||||
if err := ctx.router.AddNode(node2); err != nil {
|
||||
t.Fatalf("unable to add node: %v", err)
|
||||
}
|
||||
|
||||
assertNodeNtfnCorrect := func(t *testing.T, ann *lnwire.NodeAnnouncement,
|
||||
assertNodeNtfnCorrect := func(t *testing.T, ann *channeldb.LightningNode,
|
||||
ntfns []*NetworkNodeUpdate) {
|
||||
|
||||
// For each processed announcement we should only receive a
|
||||
@@ -454,14 +472,14 @@ func TestNodeUpdateNotification(t *testing.T) {
|
||||
t.Fatalf("node address doesn't match: expected %v, got %v",
|
||||
nodeNtfn.Addresses[0], ann.Addresses[0])
|
||||
}
|
||||
if !nodeNtfn.IdentityKey.IsEqual(ann.NodeID) {
|
||||
if !nodeNtfn.IdentityKey.IsEqual(ann.PubKey) {
|
||||
t.Fatalf("node identity keys don't match: expected %x, "+
|
||||
"got %x", ann.NodeID.SerializeCompressed(),
|
||||
"got %x", ann.PubKey.SerializeCompressed(),
|
||||
nodeNtfn.IdentityKey.SerializeCompressed())
|
||||
}
|
||||
if nodeNtfn.Alias != ann.Alias.String() {
|
||||
if nodeNtfn.Alias != ann.Alias {
|
||||
t.Fatalf("node alias doesn't match: expected %v, got %v",
|
||||
ann.Alias.String(), nodeNtfn.Alias)
|
||||
ann.Alias, nodeNtfn.Alias)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,11 +490,11 @@ func TestNodeUpdateNotification(t *testing.T) {
|
||||
select {
|
||||
case ntfn := <-ntfnClient.TopologyChanges:
|
||||
if i == 0 {
|
||||
assertNodeNtfnCorrect(t, node1Ann, ntfn.NodeUpdates)
|
||||
assertNodeNtfnCorrect(t, node1, ntfn.NodeUpdates)
|
||||
continue
|
||||
}
|
||||
|
||||
assertNodeNtfnCorrect(t, node2Ann, ntfn.NodeUpdates)
|
||||
assertNodeNtfnCorrect(t, node2, ntfn.NodeUpdates)
|
||||
case <-time.After(time.Second * 5):
|
||||
}
|
||||
}
|
||||
@@ -484,11 +502,13 @@ func TestNodeUpdateNotification(t *testing.T) {
|
||||
// If we receive a new update from a node (with a higher timestamp),
|
||||
// then it should trigger a new notification.
|
||||
// TODO(roasbeef): assume monotonic time.
|
||||
nodeUpdateAnn := *node1Ann
|
||||
nodeUpdateAnn.Timestamp = node1Ann.Timestamp + 300
|
||||
nodeUpdateAnn := *node1
|
||||
nodeUpdateAnn.LastUpdate = node1.LastUpdate.Add(300 * time.Millisecond)
|
||||
|
||||
// Send off the new node announcement to the channel router.
|
||||
ctx.router.ProcessRoutingMessage(&nodeUpdateAnn, node1Ann.NodeID)
|
||||
// Add new node topology update to the channel router.
|
||||
if err := ctx.router.AddNode(&nodeUpdateAnn); err != nil {
|
||||
t.Fatalf("unable to add node: %v", err)
|
||||
}
|
||||
|
||||
// Once again a notification should be received reflecting the up to
|
||||
// date node announcement.
|
||||
@@ -515,9 +535,9 @@ func TestNotificationCancellation(t *testing.T) {
|
||||
t.Fatalf("unable to subscribe for channel notifications: %v", err)
|
||||
}
|
||||
|
||||
// We'll create a fresh new node announcement to feed to the channel
|
||||
// We'll create a fresh new node topology update to feed to the channel
|
||||
// router.
|
||||
node1Ann, err := createTestWireNode()
|
||||
node, err := createTestNode()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create test node: %v", err)
|
||||
}
|
||||
@@ -528,7 +548,9 @@ func TestNotificationCancellation(t *testing.T) {
|
||||
// client.
|
||||
ntfnClient.Cancel()
|
||||
|
||||
ctx.router.ProcessRoutingMessage(node1Ann, node1Ann.NodeID)
|
||||
if err := ctx.router.AddNode(node); err != nil {
|
||||
t.Fatalf("unable to add node: %v", err)
|
||||
}
|
||||
|
||||
select {
|
||||
// The notification shouldn't be sent, however, the channel should be
|
||||
@@ -538,10 +560,10 @@ func TestNotificationCancellation(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
t.Fatalf("notification sent but shouldn't have been")
|
||||
t.Fatal("notification sent but shouldn't have been")
|
||||
|
||||
case <-time.After(time.Second * 5):
|
||||
t.Fatalf("notification client never cancelled")
|
||||
t.Fatal("notification client never cancelled")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -569,29 +591,33 @@ func TestChannelCloseNotification(t *testing.T) {
|
||||
|
||||
// Next we'll create two test nodes that the fake channel will be open
|
||||
// between and add then as members of the channel graph.
|
||||
node1, err := createTestWireNode()
|
||||
node1, err := createTestNode()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create test node: %v", err)
|
||||
}
|
||||
node2, err := createTestWireNode()
|
||||
node2, err := createTestNode()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create test node: %v", err)
|
||||
}
|
||||
|
||||
// Finally, to conclude our test set up, we'll create a channel
|
||||
// announcement to announce the created channel between the two nodes.
|
||||
channelAnn := lnwire.ChannelAnnouncement{
|
||||
FirstNodeSig: testSig,
|
||||
SecondNodeSig: testSig,
|
||||
ChannelID: chanID,
|
||||
FirstBitcoinSig: testSig,
|
||||
SecondBitcoinSig: testSig,
|
||||
FirstNodeID: node1.NodeID,
|
||||
SecondNodeID: node2.NodeID,
|
||||
FirstBitcoinKey: node1.NodeID,
|
||||
SecondBitcoinKey: node2.NodeID,
|
||||
edge := &channeldb.ChannelEdgeInfo{
|
||||
ChannelID: chanID.ToUint64(),
|
||||
NodeKey1: node1.PubKey,
|
||||
NodeKey2: node2.PubKey,
|
||||
BitcoinKey1: node1.PubKey,
|
||||
BitcoinKey2: node2.PubKey,
|
||||
AuthProof: &channeldb.ChannelAuthProof{
|
||||
NodeSig1: testSig,
|
||||
NodeSig2: testSig,
|
||||
BitcoinSig1: testSig,
|
||||
BitcoinSig2: testSig,
|
||||
},
|
||||
}
|
||||
if err := ctx.router.AddEdge(edge); err != nil {
|
||||
t.Fatalf("unable to add edge: %v", err)
|
||||
}
|
||||
ctx.router.ProcessRoutingMessage(&channelAnn, node1.NodeID)
|
||||
|
||||
// With the channel edge now in place, we'll subscribe for topology
|
||||
// notifications.
|
||||
@@ -626,7 +652,7 @@ func TestChannelCloseNotification(t *testing.T) {
|
||||
// "closed" above.
|
||||
closedChans := ntfn.ClosedChannels
|
||||
if len(closedChans) == 0 {
|
||||
t.Fatalf("close channel ntfn not populated")
|
||||
t.Fatal("close channel ntfn not populated")
|
||||
} else if len(closedChans) != 1 {
|
||||
t.Fatalf("only one should've been detected as closed, "+
|
||||
"instead %v were", len(closedChans))
|
||||
@@ -656,6 +682,6 @@ func TestChannelCloseNotification(t *testing.T) {
|
||||
}
|
||||
|
||||
case <-time.After(time.Second * 5):
|
||||
t.Fatalf("notification not sent")
|
||||
t.Fatal("notification not sent")
|
||||
}
|
||||
}
|
||||
+7
-4
@@ -187,7 +187,8 @@ func newRoute(amtToSend btcutil.Amount, pathEdges []*ChannelHop) (*Route, error)
|
||||
// enough capacity to forward the required amount which
|
||||
// includes the fee dictated at each hop.
|
||||
if nextHop.AmtToForward > nextHop.Channel.Capacity {
|
||||
return nil, ErrInsufficientCapacity
|
||||
return nil, newErrf(ErrInsufficientCapacity, "channel graph has "+
|
||||
"insufficient capacity for the payment")
|
||||
}
|
||||
|
||||
// We don't pay any fees to ourselves on the first-hop channel,
|
||||
@@ -373,7 +374,8 @@ func findPath(graph *channeldb.ChannelGraph, sourceNode *channeldb.LightningNode
|
||||
// If the target node isn't found in the prev hop map, then a path
|
||||
// doesn't exist, so we terminate in an error.
|
||||
if _, ok := prev[newVertex(target)]; !ok {
|
||||
return nil, ErrNoPathFound
|
||||
return nil, newErrf(ErrNoPathFound, "unable to find a path to "+
|
||||
"destination")
|
||||
}
|
||||
|
||||
// If the potential route if below the max hop limit, then we'll use
|
||||
@@ -398,7 +400,8 @@ func findPath(graph *channeldb.ChannelGraph, sourceNode *channeldb.LightningNode
|
||||
// hops, then it's invalid.
|
||||
numEdges := len(pathEdges)
|
||||
if numEdges > HopLimit {
|
||||
return nil, ErrMaxHopsExceeded
|
||||
return nil, newErr(ErrMaxHopsExceeded, "potential path has "+
|
||||
"too many hops")
|
||||
}
|
||||
|
||||
// As our traversal of the prev map above walked backwards from the
|
||||
@@ -515,7 +518,7 @@ func findPaths(graph *channeldb.ChannelGraph, source *channeldb.LightningNode,
|
||||
|
||||
// If we weren't able to find a path, we'll continue to
|
||||
// the next round.
|
||||
if err == ErrNoPathFound {
|
||||
if IsError(err, ErrNoPathFound) {
|
||||
continue
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -508,7 +508,7 @@ func TestPathNotAvailable(t *testing.T) {
|
||||
|
||||
_, err = findPath(graph, sourceNode, unknownNode, ignoredVertexes,
|
||||
ignoredEdges, 100)
|
||||
if err != ErrNoPathFound {
|
||||
if !IsError(err, ErrNoPathFound) {
|
||||
t.Fatalf("path shouldn't have been found: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -540,7 +540,7 @@ func TestPathInsufficientCapacity(t *testing.T) {
|
||||
const payAmt = btcutil.SatoshiPerBitcoin
|
||||
_, err = findPath(graph, sourceNode, target, ignoredVertexes,
|
||||
ignoredEdges, payAmt)
|
||||
if err != ErrNoPathFound {
|
||||
if !IsError(err, ErrNoPathFound) {
|
||||
t.Fatalf("graph shouldn't be able to support payment: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
+238
-555
File diff suppressed because it is too large.
Load diff
@@ -77,12 +77,6 @@ func createTestCtx(startingHeight uint32, testGraph ...string) (*testCtx, func()
|
||||
Graph: graph,
|
||||
Chain: chain,
|
||||
Notifier: notifier,
|
||||
Broadcast: func(_ *btcec.PublicKey, msg ...lnwire.Message) error {
|
||||
return nil
|
||||
},
|
||||
SendMessages: func(_ *btcec.PublicKey, msg ...lnwire.Message) error {
|
||||
return nil
|
||||
},
|
||||
SendToSwitch: func(_ *btcec.PublicKey,
|
||||
_ *lnwire.UpdateAddHTLC) ([32]byte, error) {
|
||||
return [32]byte{}, nil
|
||||
|
||||
Reference in new issue
Block a user