@@ -1331,6 +1331,80 @@ func testRouteFeeCutoff(ht *lntest.HarnessTest) {
13311331 ht .CloseChannel (carol , chanPointCarolDave )
13321332}
13331333
1334+ // testFeeLimitAfterQueryRoutes tests that a payment's fee limit is consistent
1335+ // with the fee of a queried route.
1336+ func testFeeLimitAfterQueryRoutes (ht * lntest.HarnessTest ) {
1337+ // Create a three hop network: Alice -> Bob -> Carol.
1338+ chanAmt := btcutil .Amount (100000 )
1339+ chanPoints , nodes := createSimpleNetwork (
1340+ ht , []string {}, 3 , lntest.OpenChannelParams {Amt : chanAmt },
1341+ )
1342+ alice , bob , carol := nodes [0 ], nodes [1 ], nodes [2 ]
1343+ chanPointAliceBob , chanPointBobCarol := chanPoints [0 ], chanPoints [1 ]
1344+
1345+ // We set an inbound fee discount on Bob's channel to Alice to
1346+ // effectively set the outbound fees charged to Carol to zero.
1347+ expectedPolicy := & lnrpc.RoutingPolicy {
1348+ FeeBaseMsat : 1000 ,
1349+ FeeRateMilliMsat : 1 ,
1350+ InboundFeeBaseMsat : - 1000 ,
1351+ InboundFeeRateMilliMsat : - 1 ,
1352+ TimeLockDelta : uint32 (
1353+ chainreg .DefaultBitcoinTimeLockDelta ,
1354+ ),
1355+ MinHtlc : 1000 ,
1356+ MaxHtlcMsat : lntest .CalculateMaxHtlc (chanAmt ),
1357+ }
1358+
1359+ updateFeeReq := & lnrpc.PolicyUpdateRequest {
1360+ Scope : & lnrpc.PolicyUpdateRequest_ChanPoint {
1361+ ChanPoint : chanPointAliceBob ,
1362+ },
1363+ BaseFeeMsat : expectedPolicy .FeeBaseMsat ,
1364+ FeeRatePpm : uint32 (expectedPolicy .FeeRateMilliMsat ),
1365+ TimeLockDelta : expectedPolicy .TimeLockDelta ,
1366+ MaxHtlcMsat : expectedPolicy .MaxHtlcMsat ,
1367+ InboundFee : & lnrpc.InboundFee {
1368+ BaseFeeMsat : expectedPolicy .InboundFeeBaseMsat ,
1369+ FeeRatePpm : expectedPolicy .InboundFeeRateMilliMsat ,
1370+ },
1371+ }
1372+ bob .RPC .UpdateChannelPolicy (updateFeeReq )
1373+
1374+ // Wait for Alice to receive the channel update from Bob.
1375+ ht .AssertChannelPolicyUpdate (
1376+ alice , bob , expectedPolicy , chanPointAliceBob , false ,
1377+ )
1378+
1379+ // We query the only route available to Carol.
1380+ queryRoutesReq := & lnrpc.QueryRoutesRequest {
1381+ PubKey : carol .PubKeyStr ,
1382+ Amt : paymentAmt ,
1383+ }
1384+ routesResp := alice .RPC .QueryRoutes (queryRoutesReq )
1385+
1386+ // Verify that the route has zero fees.
1387+ require .Len (ht , routesResp .Routes , 1 )
1388+ require .Len (ht , routesResp .Routes [0 ].Hops , 2 )
1389+ require .Zero (ht , routesResp .Routes [0 ].TotalFeesMsat )
1390+
1391+ // Attempt a payment with a fee limit of zero.
1392+ invoice := & lnrpc.Invoice {Value : paymentAmt }
1393+ invoiceResp := carol .RPC .AddInvoice (invoice )
1394+ sendReq := & routerrpc.SendPaymentRequest {
1395+ PaymentRequest : invoiceResp .PaymentRequest ,
1396+ TimeoutSeconds : 60 ,
1397+ FeeLimitMsat : 0 ,
1398+ }
1399+
1400+ // We assert that a route compatible with the fee limit is available.
1401+ ht .SendPaymentAssertSettled (alice , sendReq )
1402+
1403+ // Once we're done, close the channels.
1404+ ht .CloseChannel (alice , chanPointAliceBob )
1405+ ht .CloseChannel (bob , chanPointBobCarol )
1406+ }
1407+
13341408// computeFee calculates the payment fee as specified in BOLT07.
13351409func computeFee (baseFee , feeRate , amt lnwire.MilliSatoshi ) lnwire.MilliSatoshi {
13361410 return baseFee + amt * feeRate / 1000000
0 commit comments