diff --git a/routing/errors.go b/routing/errors.go index f4a1177f..1a122c06 100644 --- a/routing/errors.go +++ b/routing/errors.go @@ -2,7 +2,8 @@ package routing import "github.com/go-errors/errors" -// errorCode represent the error code and is used for compile time check. +// errorCode is used to represent the various errors that can occur within this +// package. type errorCode uint8 const ( diff --git a/routing/notifications_test.go b/routing/notifications_test.go index bd4c7123..21ac129a 100644 --- a/routing/notifications_test.go +++ b/routing/notifications_test.go @@ -602,10 +602,16 @@ func TestChannelCloseNotification(t *testing.T) { if err != nil { t.Fatalf("unable to create test node: %v", err) } + if err := ctx.router.AddNode(node1); err != nil { + t.Fatal(err) + } node2, err := createTestNode() if err != nil { t.Fatalf("unable to create test node: %v", 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. diff --git a/routing/router.go b/routing/router.go index 33e8bda1..a0c945c4 100644 --- a/routing/router.go +++ b/routing/router.go @@ -560,6 +560,22 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error { "chan_id=%v", msg.ChannelID) } + // If we don't yet know about this edge, then we'll do an + // additional check to ensure that we have information about + // the two nodes that this edge connects. + _, exists, _ = r.cfg.Graph.HasLightningNode(msg.NodeKey1) + if !exists { + return errors.Errorf("unable to add channel edge, info "+ + "for node %x is missing", + msg.NodeKey1.SerializeCompressed()) + } + _, exists, _ = r.cfg.Graph.HasLightningNode(msg.NodeKey2) + if !exists { + return errors.Errorf("unable to add channel edge, info "+ + "for node %x is missing", + msg.NodeKey1.SerializeCompressed()) + } + // Before we can add the channel to the channel graph, we need // to obtain the full funding outpoint that's encoded within // the channel ID. @@ -580,9 +596,9 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error { "chan_id=%v: %v", msg.ChannelID, err) } - // Recreate witness output to be sure that declared in - // channel edge bitcoin keys and channel value corresponds to - // the reality. + // Recreate witness output to be sure that declared in channel + // edge bitcoin keys and channel value corresponds to the + // reality. _, witnessOutput, err := lnwallet.GenFundingPkScript( msg.BitcoinKey1.SerializeCompressed(), msg.BitcoinKey2.SerializeCompressed(), diff --git a/routing/router_test.go b/routing/router_test.go index ee2bd6c5..6804b9c7 100644 --- a/routing/router_test.go +++ b/routing/router_test.go @@ -216,15 +216,31 @@ func TestAddProof(t *testing.T) { } defer cleanup() - // In order to be able to add the edge we should have the valud - // funding UTXO within the blockchain. + // Before creating out edge, we'll create two new nodes within the + // network that the channel will connect. + node1, err := createTestNode() + if err != nil { + t.Fatal(err) + } + if err := ctx.router.AddNode(node1); err != nil { + t.Fatal(err) + } + node2, err := createTestNode() + if err != nil { + t.Fatal(err) + } + if err := ctx.router.AddNode(node2); err != nil { + t.Fatal(err) + } + + // In order to be able to add the edge we should have a valid funding + // UTXO within the blockchain. fundingTx, _, chanID, err := createChannelEdge(ctx, bitcoinKey1.SerializeCompressed(), bitcoinKey2.SerializeCompressed(), 100, 0) if err != nil { t.Fatalf("unable create channel edge: %v", err) } - fundingBlock := &wire.MsgBlock{ Transactions: []*wire.MsgTx{fundingTx}, } @@ -233,8 +249,8 @@ func TestAddProof(t *testing.T) { // After utxo was recreated adding the edge without the proof. edge := &channeldb.ChannelEdgeInfo{ ChannelID: chanID.ToUint64(), - NodeKey1: priv1.PubKey(), - NodeKey2: priv1.PubKey(), + NodeKey1: node1.PubKey, + NodeKey2: node2.PubKey, BitcoinKey1: bitcoinKey1, BitcoinKey2: bitcoinKey2, AuthProof: nil, @@ -244,7 +260,8 @@ func TestAddProof(t *testing.T) { t.Fatalf("unable to add edge: %v", err) } - // No trying to update the proof and checking that it have been updated. + // Now we'll attempt to update the proof and check that it has been + // properly updated. if err := ctx.router.AddProof(*chanID, &testAuthProof); err != nil { t.Fatalf("unable to add proof: %v", err) } @@ -254,3 +271,33 @@ func TestAddProof(t *testing.T) { t.Fatal("proof have been updated") } } + +// TestAddEdgeUnknownVertexes tests that if an edge is added that contains two +// vertex which we don't know of, then the edge is rejected. +func TestAddEdgeUnknownVertexes(t *testing.T) { + ctx, cleanup, err := createTestCtx(0) + if err != nil { + t.Fatal(err) + } + defer cleanup() + + _, _, chanID, err := createChannelEdge(ctx, + bitcoinKey1.SerializeCompressed(), bitcoinKey2.SerializeCompressed(), + 10000, 500) + if err != nil { + t.Fatal("unable to create channel edge: %v", err) + } + + edge := &channeldb.ChannelEdgeInfo{ + ChannelID: chanID.ToUint64(), + NodeKey1: priv1.PubKey(), + NodeKey2: priv1.PubKey(), + BitcoinKey1: bitcoinKey1, + BitcoinKey2: bitcoinKey2, + AuthProof: nil, + } + if err := ctx.router.AddEdge(edge); err == nil { + t.Fatal("edge should have been rejected due to unknown " + + "vertexes, but wasn't") + } +}