routing: reject channel announcement if connected vertexes are unknown

This commit modifies the processing in the routing package eo new
announcements. Previously,  if we cgot a cnew channel announcement but
didn’t yet know of the verses that the chanell connected, the
cnnounacment would be accepted. This behavior was eronoues as if the
channel were to be queried for, the DB query would fail as we would be
unable to retrieve the two nodes involved int he channel.

To avoid such an error case, we will now _reject_ any channel
announcements in which we don’t yet have a valid node announcement for
the connected nodes. This case has been inserted into the handling of
channel announcement, a new test has been added, and finally older
tests have also been updated to ensure that nodes are added to the
database _before_ the edge is.
This commit is contained in:
Olaoluwa Osuntokun 2017-05-14 19:27:14 -07:00
parent 34959e4648
commit cc19695dad
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
4 changed files with 80 additions and 10 deletions

View File

@ -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 (

View File

@ -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.

View File

@ -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(),

View File

@ -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")
}
}