Merge pull request #2549 from halseth/router-ignore-unknown-chanupdate
routing: ignore ChannelUpdates for unknown channels
This commit is contained in:
commit
acd458db56
@ -729,6 +729,14 @@ func TestEdgeInfoUpdates(t *testing.T) {
|
|||||||
|
|
||||||
// Create an edge and add it to the db.
|
// Create an edge and add it to the db.
|
||||||
edgeInfo, edge1, edge2 := createChannelEdge(db, node1, node2)
|
edgeInfo, edge1, edge2 := createChannelEdge(db, node1, node2)
|
||||||
|
|
||||||
|
// Make sure inserting the policy at this point, before the edge info
|
||||||
|
// is added, will fail.
|
||||||
|
if err := graph.UpdateEdgePolicy(edge1); err != ErrEdgeNotFound {
|
||||||
|
t.Fatalf("expected ErrEdgeNotFound, got: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the edge info.
|
||||||
if err := graph.AddChannelEdge(edgeInfo); err != nil {
|
if err := graph.AddChannelEdge(edgeInfo); err != nil {
|
||||||
t.Fatalf("unable to create channel edge: %v", err)
|
t.Fatalf("unable to create channel edge: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -1125,8 +1125,6 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
|
|||||||
}
|
}
|
||||||
r.rejectMtx.RUnlock()
|
r.rejectMtx.RUnlock()
|
||||||
|
|
||||||
channelID := lnwire.NewShortChanIDFromInt(msg.ChannelID)
|
|
||||||
|
|
||||||
// We make sure to hold the mutex for this channel ID,
|
// We make sure to hold the mutex for this channel ID,
|
||||||
// such that no other goroutine is concurrently doing
|
// such that no other goroutine is concurrently doing
|
||||||
// database accesses for the same channel ID.
|
// database accesses for the same channel ID.
|
||||||
@ -1142,6 +1140,15 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the channel doesn't exist in our database, we cannot
|
||||||
|
// apply the updated policy.
|
||||||
|
if !exists {
|
||||||
|
return newErrf(ErrIgnored, "Ignoring update "+
|
||||||
|
"(flags=%v|%v) for unknown chan_id=%v",
|
||||||
|
msg.MessageFlags, msg.ChannelFlags,
|
||||||
|
msg.ChannelID)
|
||||||
|
}
|
||||||
|
|
||||||
// As edges are directional edge node has a unique policy for
|
// As edges are directional edge node has a unique policy for
|
||||||
// the direction of the edge they control. Therefore we first
|
// the direction of the edge they control. Therefore we first
|
||||||
// check if we already have the most up to date information for
|
// check if we already have the most up to date information for
|
||||||
@ -1174,36 +1181,6 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !exists && !r.cfg.AssumeChannelValid {
|
|
||||||
// Before we can update the channel information, we'll
|
|
||||||
// ensure that the target channel is still open by
|
|
||||||
// querying the utxo-set for its existence.
|
|
||||||
chanPoint, fundingTxOut, err := r.fetchChanPoint(
|
|
||||||
&channelID,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
r.rejectMtx.Lock()
|
|
||||||
r.rejectCache[msg.ChannelID] = struct{}{}
|
|
||||||
r.rejectMtx.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("unable to fetch chan "+
|
|
||||||
"point for chan_id=%v: %v",
|
|
||||||
msg.ChannelID, err)
|
|
||||||
}
|
|
||||||
_, err = r.cfg.Chain.GetUtxo(
|
|
||||||
chanPoint, fundingTxOut.PkScript,
|
|
||||||
channelID.BlockHeight,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
r.rejectMtx.Lock()
|
|
||||||
r.rejectCache[msg.ChannelID] = struct{}{}
|
|
||||||
r.rejectMtx.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("unable to fetch utxo for "+
|
|
||||||
"chan_id=%v: %v", msg.ChannelID, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now that we know this isn't a stale update, we'll apply the
|
// Now that we know this isn't a stale update, we'll apply the
|
||||||
// new edge policy to the proper directional edge within the
|
// new edge policy to the proper directional edge within the
|
||||||
// channel graph.
|
// channel graph.
|
||||||
|
@ -14,7 +14,7 @@ import (
|
|||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
|
||||||
"github.com/lightningnetwork/lightning-onion"
|
sphinx "github.com/lightningnetwork/lightning-onion"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
"github.com/lightningnetwork/lnd/htlcswitch"
|
"github.com/lightningnetwork/lnd/htlcswitch"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
@ -1025,6 +1025,86 @@ func TestIgnoreNodeAnnouncement(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestIgnoreChannelEdgePolicyForUnknownChannel checks that a router will
|
||||||
|
// ignore a channel policy for a channel not in the graph.
|
||||||
|
func TestIgnoreChannelEdgePolicyForUnknownChannel(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
const startingBlockHeight = 101
|
||||||
|
|
||||||
|
// Setup an initially empty network.
|
||||||
|
testChannels := []*testChannel{}
|
||||||
|
testGraph, err := createTestGraphFromChannels(testChannels)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to create graph: %v", err)
|
||||||
|
}
|
||||||
|
defer testGraph.cleanUp()
|
||||||
|
|
||||||
|
ctx, cleanUp, err := createTestCtxFromGraphInstance(
|
||||||
|
startingBlockHeight, testGraph,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to create router: %v", err)
|
||||||
|
}
|
||||||
|
defer cleanUp()
|
||||||
|
|
||||||
|
var pub1 [33]byte
|
||||||
|
copy(pub1[:], priv1.PubKey().SerializeCompressed())
|
||||||
|
|
||||||
|
var pub2 [33]byte
|
||||||
|
copy(pub2[:], priv2.PubKey().SerializeCompressed())
|
||||||
|
|
||||||
|
// Add the edge between the two unknown nodes to the graph, and check
|
||||||
|
// that the nodes are found after the fact.
|
||||||
|
fundingTx, _, chanID, err := createChannelEdge(
|
||||||
|
ctx, bitcoinKey1.SerializeCompressed(),
|
||||||
|
bitcoinKey2.SerializeCompressed(), 10000, 500,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to create channel edge: %v", err)
|
||||||
|
}
|
||||||
|
fundingBlock := &wire.MsgBlock{
|
||||||
|
Transactions: []*wire.MsgTx{fundingTx},
|
||||||
|
}
|
||||||
|
ctx.chain.addBlock(fundingBlock, chanID.BlockHeight, chanID.BlockHeight)
|
||||||
|
|
||||||
|
edge := &channeldb.ChannelEdgeInfo{
|
||||||
|
ChannelID: chanID.ToUint64(),
|
||||||
|
NodeKey1Bytes: pub1,
|
||||||
|
NodeKey2Bytes: pub2,
|
||||||
|
BitcoinKey1Bytes: pub1,
|
||||||
|
BitcoinKey2Bytes: pub2,
|
||||||
|
AuthProof: nil,
|
||||||
|
}
|
||||||
|
edgePolicy := &channeldb.ChannelEdgePolicy{
|
||||||
|
SigBytes: testSig.Serialize(),
|
||||||
|
ChannelID: edge.ChannelID,
|
||||||
|
LastUpdate: testTime,
|
||||||
|
TimeLockDelta: 10,
|
||||||
|
MinHTLC: 1,
|
||||||
|
FeeBaseMSat: 10,
|
||||||
|
FeeProportionalMillionths: 10000,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to update the edge. This should be ignored, since the edge
|
||||||
|
// is not yet added to the router.
|
||||||
|
err = ctx.router.UpdateEdge(edgePolicy)
|
||||||
|
if !IsError(err, ErrIgnored) {
|
||||||
|
t.Fatalf("expected to get ErrIgnore, instead got: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the edge.
|
||||||
|
if err := ctx.router.AddEdge(edge); err != nil {
|
||||||
|
t.Fatalf("expected to be able to add edge to the channel graph,"+
|
||||||
|
" even though the vertexes were unknown: %v.", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now updating the edge policy should succeed.
|
||||||
|
if err := ctx.router.UpdateEdge(edgePolicy); err != nil {
|
||||||
|
t.Fatalf("unable to update edge policy: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestAddEdgeUnknownVertexes tests that if an edge is added that contains two
|
// TestAddEdgeUnknownVertexes tests that if an edge is added that contains two
|
||||||
// vertexes which we don't know of, the edge should be available for use
|
// vertexes which we don't know of, the edge should be available for use
|
||||||
// regardless. This is due to the fact that we don't actually need node
|
// regardless. This is due to the fact that we don't actually need node
|
||||||
|
Loading…
Reference in New Issue
Block a user