From 348a66ed13b6802ce44d3cefac9c2e39ceb02e60 Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Sat, 8 Dec 2018 18:42:46 -0800 Subject: [PATCH 1/2] routing: update test edge policy fields to include max htlc + new flags Since the MaxHTLC field was recently added to the ChannelEdgePolicy struct, and the Flags field was broken into ChannelFlags and MessageFlags, the test edge policies should be updated accordingly. --- routing/pathfind_test.go | 32 ++++-- routing/router_test.go | 42 ++++---- routing/testdata/basic_graph.json | 64 +++++++++--- routing/testdata/excessive_hops.json | 144 +++++++++++++++++---------- routing/testdata/spec_example.json | 32 ++++-- 5 files changed, 215 insertions(+), 99 deletions(-) diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index ce4e1a3f..f55e5f63 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -89,9 +89,11 @@ type testChan struct { Node2 string `json:"node_2"` ChannelID uint64 `json:"channel_id"` ChannelPoint string `json:"channel_point"` - Flags uint16 `json:"flags"` + ChannelFlags uint8 `json:"channel_flags"` + MessageFlags uint8 `json:"message_flags"` Expiry uint16 `json:"expiry"` MinHTLC int64 `json:"min_htlc"` + MaxHTLC int64 `json:"max_htlc"` FeeBaseMsat int64 `json:"fee_base_msat"` FeeRate int64 `json:"fee_rate"` Capacity int64 `json:"capacity"` @@ -271,12 +273,13 @@ func parseTestGraph(path string) (*testGraphInstance, error) { edgePolicy := &channeldb.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), - MessageFlags: lnwire.ChanUpdateMsgFlags(edge.Flags >> 8), - ChannelFlags: lnwire.ChanUpdateChanFlags(edge.Flags), + MessageFlags: lnwire.ChanUpdateMsgFlags(edge.MessageFlags), + ChannelFlags: lnwire.ChanUpdateChanFlags(edge.ChannelFlags), ChannelID: edge.ChannelID, LastUpdate: testTime, TimeLockDelta: edge.Expiry, MinHTLC: lnwire.MilliSatoshi(edge.MinHTLC), + MaxHTLC: lnwire.MilliSatoshi(edge.MaxHTLC), FeeBaseMSat: lnwire.MilliSatoshi(edge.FeeBaseMsat), FeeProportionalMillionths: lnwire.MilliSatoshi(edge.FeeRate), } @@ -295,6 +298,7 @@ func parseTestGraph(path string) (*testGraphInstance, error) { type testChannelPolicy struct { Expiry uint16 MinHTLC lnwire.MilliSatoshi + MaxHTLC lnwire.MilliSatoshi FeeBaseMsat lnwire.MilliSatoshi FeeRate lnwire.MilliSatoshi } @@ -304,12 +308,13 @@ type testChannelEnd struct { testChannelPolicy } -func defaultTestChannelEnd(alias string) *testChannelEnd { +func defaultTestChannelEnd(alias string, capacity btcutil.Amount) *testChannelEnd { return &testChannelEnd{ Alias: alias, testChannelPolicy: testChannelPolicy{ Expiry: 144, MinHTLC: lnwire.MilliSatoshi(1000), + MaxHTLC: lnwire.NewMSatFromSatoshis(capacity), FeeBaseMsat: lnwire.MilliSatoshi(1000), FeeRate: lnwire.MilliSatoshi(1), }, @@ -486,14 +491,19 @@ func createTestGraphFromChannels(testChannels []*testChannel) (*testGraphInstanc return nil, err } + var msgFlags lnwire.ChanUpdateMsgFlags + if testChannel.Node1.MaxHTLC != 0 { + msgFlags = 1 + } edgePolicy := &channeldb.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), - MessageFlags: 0, + MessageFlags: msgFlags, ChannelFlags: 0, ChannelID: channelID, LastUpdate: testTime, TimeLockDelta: testChannel.Node1.Expiry, MinHTLC: testChannel.Node1.MinHTLC, + MaxHTLC: testChannel.Node1.MaxHTLC, FeeBaseMSat: testChannel.Node1.FeeBaseMsat, FeeProportionalMillionths: testChannel.Node1.FeeRate, } @@ -501,14 +511,19 @@ func createTestGraphFromChannels(testChannels []*testChannel) (*testGraphInstanc return nil, err } + msgFlags = 0 + if testChannel.Node2.MaxHTLC != 0 { + msgFlags = 1 + } edgePolicy = &channeldb.ChannelEdgePolicy{ SigBytes: testSig.Serialize(), - MessageFlags: 0, + MessageFlags: msgFlags, ChannelFlags: lnwire.ChanUpdateDirection, ChannelID: channelID, LastUpdate: testTime, TimeLockDelta: testChannel.Node2.Expiry, MinHTLC: testChannel.Node2.MinHTLC, + MaxHTLC: testChannel.Node2.MaxHTLC, FeeBaseMSat: testChannel.Node2.FeeBaseMsat, FeeProportionalMillionths: testChannel.Node2.FeeRate, } @@ -543,26 +558,31 @@ func TestFindLowestFeePath(t *testing.T) { Expiry: 144, FeeRate: 400, MinHTLC: 1, + MaxHTLC: 100000000, }), symmetricTestChannel("first", "a", 100000, &testChannelPolicy{ Expiry: 144, FeeRate: 400, MinHTLC: 1, + MaxHTLC: 100000000, }), symmetricTestChannel("a", "target", 100000, &testChannelPolicy{ Expiry: 144, FeeRate: 400, MinHTLC: 1, + MaxHTLC: 100000000, }), symmetricTestChannel("first", "b", 100000, &testChannelPolicy{ Expiry: 144, FeeRate: 100, MinHTLC: 1, + MaxHTLC: 100000000, }), symmetricTestChannel("b", "target", 100000, &testChannelPolicy{ Expiry: 144, FeeRate: 600, MinHTLC: 1, + MaxHTLC: 100000000, }), } diff --git a/routing/router_test.go b/routing/router_test.go index c79af2b2..d96d5d4c 100644 --- a/routing/router_test.go +++ b/routing/router_test.go @@ -12,6 +12,7 @@ import ( "github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" + "github.com/btcsuite/btcutil" "github.com/davecgh/go-spew/spew" sphinx "github.com/lightningnetwork/lightning-onion" @@ -361,16 +362,19 @@ func TestChannelUpdateValidation(t *testing.T) { t.Parallel() // Setup a three node network. + chanCapSat := btcutil.Amount(100000) testChannels := []*testChannel{ - symmetricTestChannel("a", "b", 100000, &testChannelPolicy{ + symmetricTestChannel("a", "b", chanCapSat, &testChannelPolicy{ Expiry: 144, FeeRate: 400, MinHTLC: 1, + MaxHTLC: lnwire.NewMSatFromSatoshis(chanCapSat), }, 1), - symmetricTestChannel("b", "c", 100000, &testChannelPolicy{ + symmetricTestChannel("b", "c", chanCapSat, &testChannelPolicy{ Expiry: 144, FeeRate: 400, MinHTLC: 1, + MaxHTLC: lnwire.NewMSatFromSatoshis(chanCapSat), }, 2), } @@ -542,20 +546,21 @@ func TestSendPaymentErrorRepeatedFeeInsufficient(t *testing.T) { // son goku. We'll obtain this as we'll need to to generate the // FeeInsufficient error that we'll send back. chanID := uint64(12345) - _, _, edgeUpateToFail, err := ctx.graph.FetchChannelEdgesByID(chanID) + _, _, edgeUpdateToFail, err := ctx.graph.FetchChannelEdgesByID(chanID) if err != nil { t.Fatalf("unable to fetch chan id: %v", err) } errChanUpdate := lnwire.ChannelUpdate{ ShortChannelID: lnwire.NewShortChanIDFromInt(chanID), - Timestamp: uint32(edgeUpateToFail.LastUpdate.Unix()), - MessageFlags: edgeUpateToFail.MessageFlags, - ChannelFlags: edgeUpateToFail.ChannelFlags, - TimeLockDelta: edgeUpateToFail.TimeLockDelta, - HtlcMinimumMsat: edgeUpateToFail.MinHTLC, - BaseFee: uint32(edgeUpateToFail.FeeBaseMSat), - FeeRate: uint32(edgeUpateToFail.FeeProportionalMillionths), + Timestamp: uint32(edgeUpdateToFail.LastUpdate.Unix()), + MessageFlags: edgeUpdateToFail.MessageFlags, + ChannelFlags: edgeUpdateToFail.ChannelFlags, + TimeLockDelta: edgeUpdateToFail.TimeLockDelta, + HtlcMinimumMsat: edgeUpdateToFail.MinHTLC, + HtlcMaximumMsat: edgeUpdateToFail.MaxHTLC, + BaseFee: uint32(edgeUpdateToFail.FeeBaseMSat), + FeeRate: uint32(edgeUpdateToFail.FeeProportionalMillionths), } // The error will be returned by Son Goku. @@ -649,20 +654,21 @@ func TestSendPaymentErrorNonFinalTimeLockErrors(t *testing.T) { // block height is. chanID := uint64(12345) roasbeefSongoku := lnwire.NewShortChanIDFromInt(chanID) - _, _, edgeUpateToFail, err := ctx.graph.FetchChannelEdgesByID(chanID) + _, _, edgeUpdateToFail, err := ctx.graph.FetchChannelEdgesByID(chanID) if err != nil { t.Fatalf("unable to fetch chan id: %v", err) } errChanUpdate := lnwire.ChannelUpdate{ ShortChannelID: lnwire.NewShortChanIDFromInt(chanID), - Timestamp: uint32(edgeUpateToFail.LastUpdate.Unix()), - MessageFlags: edgeUpateToFail.MessageFlags, - ChannelFlags: edgeUpateToFail.ChannelFlags, - TimeLockDelta: edgeUpateToFail.TimeLockDelta, - HtlcMinimumMsat: edgeUpateToFail.MinHTLC, - BaseFee: uint32(edgeUpateToFail.FeeBaseMSat), - FeeRate: uint32(edgeUpateToFail.FeeProportionalMillionths), + Timestamp: uint32(edgeUpdateToFail.LastUpdate.Unix()), + MessageFlags: edgeUpdateToFail.MessageFlags, + ChannelFlags: edgeUpdateToFail.ChannelFlags, + TimeLockDelta: edgeUpdateToFail.TimeLockDelta, + HtlcMinimumMsat: edgeUpdateToFail.MinHTLC, + HtlcMaximumMsat: edgeUpdateToFail.MaxHTLC, + BaseFee: uint32(edgeUpdateToFail.FeeBaseMSat), + FeeRate: uint32(edgeUpdateToFail.FeeProportionalMillionths), } // The error will be returned by Son Goku. diff --git a/routing/testdata/basic_graph.json b/routing/testdata/basic_graph.json index 80c3c20c..c04430b6 100644 --- a/routing/testdata/basic_graph.json +++ b/routing/testdata/basic_graph.json @@ -74,9 +74,11 @@ "node_2": "036264734b40c9e91d3d990a8cdfbbe23b5b0b7ad3cd0e080a25dcd05d39eeb7eb", "channel_id": 15433, "channel_point": "33bd5d49a50e284221561b91e781f1fca0d60341c9f9dd785b5e379a6d88af3d:0", - "flags": 1, + "channel_flags": 1, + "message_flags": 1, "expiry": 1, "min_htlc": 1000, + "max_htlc": 100000000, "fee_base_msat": 200, "fee_rate": 0, "capacity": 100000 @@ -86,9 +88,11 @@ "node_2": "036264734b40c9e91d3d990a8cdfbbe23b5b0b7ad3cd0e080a25dcd05d39eeb7eb", "channel_id": 15433, "channel_point": "33bd5d49a50e284221561b91e781f1fca0d60341c9f9dd785b5e379a6d88af3d:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, "min_htlc": 1000, + "max_htlc": 100000000, "fee_base_msat": 200, "fee_rate": 0, "capacity": 100000 @@ -98,9 +102,11 @@ "node_2": "0367cec75158a4129177bfb8b269cb586efe93d751b43800d456485e81c2620ca6", "channel_id": 999991, "channel_point": "48a0e8b856fef01d9feda7d25a4fac6dae48749e28ba356b92d712ab7f5bd2d0:0", - "flags": 1, + "channel_flags": 1, + "message_flags": 1, "expiry": 1, "min_htlc": 1000, + "max_htlc": 120000000, "fee_base_msat": 10000, "fee_rate": 100000, "capacity": 120000 @@ -110,9 +116,11 @@ "node_2": "0367cec75158a4129177bfb8b269cb586efe93d751b43800d456485e81c2620ca6", "channel_id": 999991, "channel_point": "48a0e8b856fef01d9feda7d25a4fac6dae48749e28ba356b92d712ab7f5bd2d0:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, "min_htlc": 1000, + "max_htlc": 120000000, "fee_base_msat": 10000, "fee_rate": 100000, "capacity": 120000 @@ -122,9 +130,11 @@ "node_2": "036264734b40c9e91d3d990a8cdfbbe23b5b0b7ad3cd0e080a25dcd05d39eeb7eb", "channel_id": 99999, "channel_point": "05ffda8890d0a4fffe0ddca0b1932ba0415b1d5868a99515384a4e7883d96b88:0", - "flags": 1, + "channel_flags": 1, + "message_flags": 1, "expiry": 1, "min_htlc": 1000, + "max_htlc": 120000000, "fee_base_msat": 10000, "fee_rate": 100000, "capacity": 120000 @@ -134,9 +144,11 @@ "node_2": "036264734b40c9e91d3d990a8cdfbbe23b5b0b7ad3cd0e080a25dcd05d39eeb7eb", "channel_id": 99999, "channel_point": "05ffda8890d0a4fffe0ddca0b1932ba0415b1d5868a99515384a4e7883d96b88:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, "min_htlc": 1000, + "max_htlc": 120000000, "fee_base_msat": 10000, "fee_rate": 100000, "capacity": 120000 @@ -146,9 +158,11 @@ "node_2": "0367cec75158a4129177bfb8b269cb586efe93d751b43800d456485e81c2620ca6", "channel_id": 12345, "channel_point": "89dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 1, + "channel_flags": 1, + "message_flags": 1, "expiry": 1, "min_htlc": 1000, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 1000, "capacity": 100000 @@ -158,9 +172,11 @@ "node_2": "0367cec75158a4129177bfb8b269cb586efe93d751b43800d456485e81c2620ca6", "channel_id": 12345, "channel_point": "89dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 1000, "capacity": 100000 @@ -170,9 +186,11 @@ "node_2": "036264734b40c9e91d3d990a8cdfbbe23b5b0b7ad3cd0e080a25dcd05d39eeb7eb", "channel_id": 3495345, "channel_point": "9f155756b33a0a6827713965babbd561b55f9520444ac5db0cf7cb2eb0deb5bc:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, "min_htlc": 1, + "max_htlc": 110000000, "fee_base_msat": 10, "fee_rate": 1000, "capacity": 110000 @@ -182,9 +200,11 @@ "node_2": "036264734b40c9e91d3d990a8cdfbbe23b5b0b7ad3cd0e080a25dcd05d39eeb7eb", "channel_id": 3495345, "channel_point": "9f155756b33a0a6827713965babbd561b55f9520444ac5db0cf7cb2eb0deb5bc:0", - "flags": 1, + "channel_flags": 1, + "message_flags": 1, "expiry": 1, "min_htlc": 1, + "max_htlc": 110000000, "fee_base_msat": 10, "fee_rate": 1000, "capacity": 110000 @@ -194,9 +214,11 @@ "node_2": "03c19f0027ffbb0ae0e14a4d958788793f9d74e107462473ec0c3891e4feb12e99", "channel_id": 2340213491, "channel_point": "72cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, "min_htlc": 1, + "max_htlc": 10000000, "fee_base_msat": 10, "fee_rate": 1000, "capacity": 10000 @@ -206,9 +228,11 @@ "node_2": "03c19f0027ffbb0ae0e14a4d958788793f9d74e107462473ec0c3891e4feb12e99", "channel_id": 2340213491, "channel_point": "72cd6e8422c407fb6d098690f1130b7ded7ec2f7f5e1d30bd9d521f015363793:0", - "flags": 1, + "channel_flags": 1, + "message_flags": 1, "expiry": 1, "min_htlc": 1, + "max_htlc": 10000000, "fee_base_msat": 10, "fee_rate": 1000, "capacity": 10000 @@ -218,9 +242,11 @@ "node_2": "0367cec75158a4129177bfb8b269cb586efe93d751b43800d456485e81c2620ca6", "channel_id": 689530843, "channel_point": "25376aa6cb81913ad30416bd22d4083241bd6d68e811d0284d3c3a17795c458a:0", - "flags": 1, + "channel_flags": 1, + "message_flags": 1, "expiry": 10, "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 1000, "capacity": 100000 @@ -230,9 +256,11 @@ "node_2": "0367cec75158a4129177bfb8b269cb586efe93d751b43800d456485e81c2620ca6", "channel_id": 689530843, "channel_point": "25376aa6cb81913ad30416bd22d4083241bd6d68e811d0284d3c3a17795c458a:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 1000, "capacity": 100000 @@ -242,9 +270,11 @@ "node_2": "03c19f0027ffbb0ae0e14a4d958788793f9d74e107462473ec0c3891e4feb12e99", "channel_id": 523452362, "channel_point": "704a5675c91b1c674309a6475fc51072c2913d6117ee6103c9f1b86956bcbe02:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, "min_htlc": 1, + "max_htlc": 50000000, "fee_base_msat": 10, "fee_rate": 1000, "capacity": 50000 @@ -254,9 +284,11 @@ "node_2": "03c19f0027ffbb0ae0e14a4d958788793f9d74e107462473ec0c3891e4feb12e99", "channel_id": 523452362, "channel_point": "704a5675c91b1c674309a6475fc51072c2913d6117ee6103c9f1b86956bcbe02:0", - "flags": 1, + "channel_flags": 1, + "message_flags": 1, "expiry": 1, "min_htlc": 1, + "max_htlc": 50000000, "fee_base_msat": 10, "fee_rate": 1000, "capacity": 50000 diff --git a/routing/testdata/excessive_hops.json b/routing/testdata/excessive_hops.json index 4eff08d9..3094f1b4 100644 --- a/routing/testdata/excessive_hops.json +++ b/routing/testdata/excessive_hops.json @@ -115,35 +115,41 @@ { "node_1": "021b96642e723592ee0b095983fe3a26c8b40b8926968d8b7510e51c9429d4562c", "node_2": "022096b2b0ac083e708074a5ab57288bc821b6bef7b964185b307e073772c3748f", - "channel_id": 12345, - "channel_point": "99dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_id": 12345, + "channel_point": "99dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, - "fee_base_msat": 10, - "fee_rate": 0.001, + "min_htlc": 1, + "max_htlc": 100000000, + "fee_base_msat": 10, + "fee_rate": 0.001, "capacity": 100000 }, { "node_1": "022096b2b0ac083e708074a5ab57288bc821b6bef7b964185b307e073772c3748f", "node_2": "022a190ce901ab2b6f349483f18b28a1d72c64a7bccb8057291f25784c0899840f", - "channel_id": 12346, + "channel_id": 12346, "channel_point": "79dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, - "fee_base_msat": 10, - "fee_rate": 0.001, + "min_htlc": 1, + "max_htlc": 100000000, + "fee_base_msat": 10, + "fee_rate": 0.001, "capacity": 100000 }, { "node_1": "022a190ce901ab2b6f349483f18b28a1d72c64a7bccb8057291f25784c0899840f", "node_2": "022d855d09971dd047b7ecf929b23c6f147b568d4668af67fb2226eb8c15c4660d", - "channel_id": 12347, - "channel_point": "69dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_id": 12347, + "channel_point": "69dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -153,9 +159,11 @@ "node_2": "024ca436834b0d38d9dc7ee4d95aa21db321c45598dc5921a4a52304a8e0dd2952", "channel_id": 12348, "channel_point": "59dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -165,9 +173,11 @@ "node_2": "025234a0c44cbf1b20c18e2c397107ad731376831e1c43ddb360b41dbb98c10266", "channel_id": 12349, "channel_point": "49dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -177,9 +187,11 @@ "node_2": "0253e9d03030f2ff08d3a7f1d824ad6d8c0dae422f324e72d5bb313e3f2a2d45a8", "channel_id": 12340, "channel_point": "39dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -189,9 +201,11 @@ "node_2": "0263d4f2baca258ff3bd5bce86c2754e95daaea27f268ae1a048c1253ff20de56e", "channel_id": 12344, "channel_point": "29dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -201,9 +215,11 @@ "node_2": "02650db8e44302f75e265e9427264bc0d7e2337831d6b9ceb7c58ed1e725d4576a", "channel_id": 12343, "channel_point": "19dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -213,9 +229,11 @@ "node_2": "02727bfd298aa055a6419404931dfc1ccb4f0eb7c9660a7df346b93d0025df3ba1", "channel_id": 12342, "channel_point": "88dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -225,9 +243,11 @@ "node_2": "0280c83b3eded413dcec12f7952410e2738f079bd9cbc9a7c462e32ed4d74bd5b7", "channel_id": 12341, "channel_point": "87dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -237,9 +257,11 @@ "node_2": "0290bf454f4b95baf9227801301b331e35d477c6b6e7f36a599983ae58747b3828", "channel_id": 12355, "channel_point": "86dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -249,9 +271,11 @@ "node_2": "0297c8de635d17e3dd5775edfa2797be0874c53b0026f69009787cecd2fa577de8", "channel_id": 12365, "channel_point": "85dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -261,9 +285,11 @@ "node_2": "02a27227113c71eab0c8609ac0cdc7e76791fc3163c16e643cb4658d1080c7e336", "channel_id": 12375, "channel_point": "84dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -273,9 +299,11 @@ "node_2": "02f5f6bb6373fc60528118003f803557b916fbecd90c3a0c5df4c86c6a6e962fd1", "channel_id": 12385, "channel_point": "83dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -285,9 +313,11 @@ "node_2": "02fd7a5f04d550cf0ba8af6053a20e0080d956f41b1221357a35fab3a363e5f78e", "channel_id": 12395, "channel_point": "82dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -297,9 +327,11 @@ "node_2": "030da942ed7cfc7d3096811b3264e15115778e692eaacb2b7a76fb27a58cbb5359", "channel_id": 12305, "channel_point": "81dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -309,9 +341,11 @@ "node_2": "0319d6b038e26ac89802e856d7e78f293e9d109c414614f98e3fa5c626f20934be", "channel_id": 12335, "channel_point": "80dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -321,9 +355,11 @@ "node_2": "03384439e78e87d168fecabe8d88218dfd5983c5e14fd8fa6dc89caeb3cc0fb171", "channel_id": 12325, "channel_point": "89ec56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -333,9 +369,11 @@ "node_2": "0362002b8fbc1a799c839c8bcea43fce38a147467a00bc450414bbeab5c7a19efe", "channel_id": 12315, "channel_point": "89fc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -345,9 +383,11 @@ "node_2": "0369bca64993fce966745d32c09b882f668958d9bd7aabb60ba35ef1884013be1d", "channel_id": 12445, "channel_point": "89cc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 @@ -357,9 +397,11 @@ "node_2": "0367cec75158a4129177bfb8b269cb586efe93d751b43800d456485e81c2620ca6", "channel_id": 12545, "channel_point": "89bc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 1, - "min_htlc": 1, + "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 10, "fee_rate": 0.001, "capacity": 100000 diff --git a/routing/testdata/spec_example.json b/routing/testdata/spec_example.json index 892d99b7..f0a730c3 100644 --- a/routing/testdata/spec_example.json +++ b/routing/testdata/spec_example.json @@ -29,9 +29,11 @@ "node_2": "0367cec75158a4129177bfb8b269cb586efe93d751b43800d456485e81c2620ca6", "channel_id": 12345, "channel_point": "89dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 1, + "channel_flags": 1, + "message_flags": 1, "expiry": 10, "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 100, "fee_rate": 1000, "capacity": 100000 @@ -42,9 +44,11 @@ "node_2": "0367cec75158a4129177bfb8b269cb586efe93d751b43800d456485e81c2620ca6", "channel_id": 12345, "channel_point": "89dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 20, "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 200, "fee_rate": 2000, "capacity": 100000 @@ -55,9 +59,11 @@ "node_2": "0367cec75158a4129177bfb8b269cb586efe93d751b43800d456485e81c2620ca6", "channel_id": 12345839, "channel_point": "89dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 1, + "channel_flags": 1, + "message_flags": 1, "expiry": 10, "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 100, "fee_rate": 1000, "capacity": 100000 @@ -68,9 +74,11 @@ "node_2": "0367cec75158a4129177bfb8b269cb586efe93d751b43800d456485e81c2620ca6", "channel_id": 12345839, "channel_point": "89dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 40, "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 400, "fee_rate": 4000, "capacity": 100000 @@ -81,9 +89,11 @@ "node_2": "03c19f0027ffbb0ae0e14a4d958788793f9d74e107462473ec0c3891e4feb12e99", "channel_id": 1234583, "channel_point": "89dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 40, "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 400, "fee_rate": 4000, "capacity": 100000 @@ -94,9 +104,11 @@ "node_2": "03c19f0027ffbb0ae0e14a4d958788793f9d74e107462473ec0c3891e4feb12e99", "channel_id": 1234583, "channel_point": "89dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 1, + "channel_flags": 1, + "message_flags": 1, "expiry": 30, "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 300, "fee_rate": 3000, "capacity": 100000 @@ -107,9 +119,11 @@ "node_2": "03c19f0027ffbb0ae0e14a4d958788793f9d74e107462473ec0c3891e4feb12e99", "channel_id": 1234589, "channel_point": "89dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 1, + "channel_flags": 1, + "message_flags": 1, "expiry": 30, "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 300, "fee_rate": 3000, "capacity": 100000 @@ -120,9 +134,11 @@ "node_2": "03c19f0027ffbb0ae0e14a4d958788793f9d74e107462473ec0c3891e4feb12e99", "channel_id": 1234589, "channel_point": "89dc56859c6a082d15ba1a7f6cb6be3fea62e1746e2cb8497b1189155c21a233:0", - "flags": 0, + "channel_flags": 0, + "message_flags": 1, "expiry": 20, "min_htlc": 1, + "max_htlc": 100000000, "fee_base_msat": 200, "fee_rate": 2000, "capacity": 100000 From 648adaea690b7bf8c4bfb90c3f7ecc3fd33b4e44 Mon Sep 17 00:00:00 2001 From: Valentine Wallace Date: Sat, 8 Dec 2018 18:32:49 -0800 Subject: [PATCH 2/2] routing/pathfind: ensure max htlc is considered during path finding In this commit, we update the path finding logic to ignore a channel if the HTLC value (including the fees at the point) exceeds the max HTLC value (if set) of the link. --- routing/pathfind.go | 7 ++++ routing/pathfind_test.go | 90 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/routing/pathfind.go b/routing/pathfind.go index 21906b7c..74630933 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -576,6 +576,13 @@ func findPath(g *graphParams, r *restrictParams, return } + // If this edge was constructed from a hop hint, we won't have access to + // its max HTLC. Therefore, only consider discarding this edge here if + // the field is set. + if edge.MaxHTLC != 0 && edge.MaxHTLC < amountToSend { + return + } + // Compute fee that fromNode is charging. It is based on the // amount that needs to be sent to the next node in the route. // diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index f55e5f63..f2eae6fe 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -1451,6 +1451,96 @@ func TestRouteFailMinHTLC(t *testing.T) { } } +// TestRouteFailMaxHTLC tests that if we attempt to route an HTLC which is +// larger than the advertised max HTLC of an edge, then path finding fails. +func TestRouteFailMaxHTLC(t *testing.T) { + t.Parallel() + + // Set up a test graph: + // roasbeef <--> firstHop <--> secondHop <--> target + // We will be adjusting the max HTLC of the edge between the first and + // second hops. + var firstToSecondID uint64 = 1 + testChannels := []*testChannel{ + symmetricTestChannel("roasbeef", "first", 100000, &testChannelPolicy{ + Expiry: 144, + FeeRate: 400, + MinHTLC: 1, + MaxHTLC: 100000001, + }), + symmetricTestChannel("first", "second", 100000, &testChannelPolicy{ + Expiry: 144, + FeeRate: 400, + MinHTLC: 1, + MaxHTLC: 100000002, + }, firstToSecondID), + symmetricTestChannel("second", "target", 100000, &testChannelPolicy{ + Expiry: 144, + FeeRate: 400, + MinHTLC: 1, + MaxHTLC: 100000003, + }), + } + + graph, err := createTestGraphFromChannels(testChannels) + if err != nil { + t.Fatalf("unable to create graph: %v", err) + } + defer graph.cleanUp() + + sourceNode, err := graph.graph.SourceNode() + if err != nil { + t.Fatalf("unable to fetch source node: %v", err) + } + ignoredEdges := make(map[edgeLocator]struct{}) + ignoredVertexes := make(map[Vertex]struct{}) + + // First, attempt to send a payment greater than the max HTLC we are + // about to set, which should succeed. + target := graph.aliasMap["target"] + payAmt := lnwire.MilliSatoshi(100001) + _, err = findPath( + &graphParams{ + graph: graph.graph, + }, + &restrictParams{ + ignoredNodes: ignoredVertexes, + ignoredEdges: ignoredEdges, + feeLimit: noFeeLimit, + }, + sourceNode, target, payAmt, + ) + if err != nil { + t.Fatalf("graph should've been able to support payment: %v", err) + } + + // Next, update the middle edge policy to only allow payments up to 100k + // msat. + _, midEdge, _, err := graph.graph.FetchChannelEdgesByID(firstToSecondID) + midEdge.MessageFlags = 1 + midEdge.MaxHTLC = payAmt - 1 + if err := graph.graph.UpdateEdgePolicy(midEdge); err != nil { + t.Fatalf("unable to update edge: %v", err) + } + + // We'll now attempt to route through that edge with a payment above + // 100k msat, which should fail. + _, err = findPath( + &graphParams{ + graph: graph.graph, + }, + &restrictParams{ + ignoredNodes: ignoredVertexes, + ignoredEdges: ignoredEdges, + feeLimit: noFeeLimit, + }, + sourceNode, target, payAmt, + ) + if !IsError(err, ErrNoPathFound) { + t.Fatalf("graph shouldn't be able to support payment: %v", err) + } +} + // TestRouteFailDisabledEdge tests that if we attempt to route to an edge // that's disabled, then that edge is disqualified, and the routing attempt // will fail. We also test that this is true only for non-local edges, as we'll