mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-09-19 20:15:18 +02:00
itest: add test for failing send after queryroutes
This commit is contained in:
@@ -354,6 +354,10 @@ var allTestCases = []*lntest.TestCase{
|
|||||||
Name: "route fee cutoff",
|
Name: "route fee cutoff",
|
||||||
TestFunc: testRouteFeeCutoff,
|
TestFunc: testRouteFeeCutoff,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "route fee limit after queryroutes",
|
||||||
|
TestFunc: testFeeLimitAfterQueryRoutes,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "rpc middleware interceptor",
|
Name: "rpc middleware interceptor",
|
||||||
TestFunc: testRPCMiddlewareInterceptor,
|
TestFunc: testRPCMiddlewareInterceptor,
|
||||||
|
@@ -1331,6 +1331,84 @@ func testRouteFeeCutoff(ht *lntest.HarnessTest) {
|
|||||||
ht.CloseChannel(carol, chanPointCarolDave)
|
ht.CloseChannel(carol, chanPointCarolDave)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// testFeeLimitAfterQueryRoutes tests that a payment's fee limit is consistent
|
||||||
|
// with the fee of a queried route.
|
||||||
|
func testFeeLimitAfterQueryRoutes(ht *lntest.HarnessTest) {
|
||||||
|
// Create a three hop network: Alice -> Bob -> Carol.
|
||||||
|
chanAmt := btcutil.Amount(100000)
|
||||||
|
chanPoints, nodes := createSimpleNetwork(
|
||||||
|
ht, []string{}, 3, lntest.OpenChannelParams{Amt: chanAmt},
|
||||||
|
)
|
||||||
|
alice, bob, carol := nodes[0], nodes[1], nodes[2]
|
||||||
|
chanPointAliceBob, chanPointBobCarol := chanPoints[0], chanPoints[1]
|
||||||
|
|
||||||
|
// We set an inbound fee discount on Bob's channel to Alice to
|
||||||
|
// effectively set the outbound fees charged to Carol to zero.
|
||||||
|
expectedPolicy := &lnrpc.RoutingPolicy{
|
||||||
|
FeeBaseMsat: 1000,
|
||||||
|
FeeRateMilliMsat: 1,
|
||||||
|
InboundFeeBaseMsat: -1000,
|
||||||
|
InboundFeeRateMilliMsat: -1,
|
||||||
|
TimeLockDelta: uint32(
|
||||||
|
chainreg.DefaultBitcoinTimeLockDelta,
|
||||||
|
),
|
||||||
|
MinHtlc: 1000,
|
||||||
|
MaxHtlcMsat: lntest.CalculateMaxHtlc(chanAmt),
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFeeReq := &lnrpc.PolicyUpdateRequest{
|
||||||
|
Scope: &lnrpc.PolicyUpdateRequest_ChanPoint{
|
||||||
|
ChanPoint: chanPointAliceBob,
|
||||||
|
},
|
||||||
|
BaseFeeMsat: expectedPolicy.FeeBaseMsat,
|
||||||
|
FeeRatePpm: uint32(expectedPolicy.FeeRateMilliMsat),
|
||||||
|
TimeLockDelta: expectedPolicy.TimeLockDelta,
|
||||||
|
MaxHtlcMsat: expectedPolicy.MaxHtlcMsat,
|
||||||
|
InboundFee: &lnrpc.InboundFee{
|
||||||
|
BaseFeeMsat: expectedPolicy.InboundFeeBaseMsat,
|
||||||
|
FeeRatePpm: expectedPolicy.InboundFeeRateMilliMsat,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
bob.RPC.UpdateChannelPolicy(updateFeeReq)
|
||||||
|
|
||||||
|
// Wait for Alice to receive the channel update from Bob.
|
||||||
|
ht.AssertChannelPolicyUpdate(
|
||||||
|
alice, bob, expectedPolicy, chanPointAliceBob, false,
|
||||||
|
)
|
||||||
|
|
||||||
|
// We query the only route available to Carol.
|
||||||
|
queryRoutesReq := &lnrpc.QueryRoutesRequest{
|
||||||
|
PubKey: carol.PubKeyStr,
|
||||||
|
Amt: paymentAmt,
|
||||||
|
}
|
||||||
|
routesResp := alice.RPC.QueryRoutes(queryRoutesReq)
|
||||||
|
|
||||||
|
// Verify that the route has zero fees.
|
||||||
|
require.Len(ht, routesResp.Routes, 1)
|
||||||
|
require.Len(ht, routesResp.Routes[0].Hops, 2)
|
||||||
|
require.Zero(ht, routesResp.Routes[0].TotalFeesMsat)
|
||||||
|
|
||||||
|
// Attempt a payment with a fee limit of zero.
|
||||||
|
invoice := &lnrpc.Invoice{Value: paymentAmt}
|
||||||
|
invoiceResp := carol.RPC.AddInvoice(invoice)
|
||||||
|
sendReq := &routerrpc.SendPaymentRequest{
|
||||||
|
PaymentRequest: invoiceResp.PaymentRequest,
|
||||||
|
TimeoutSeconds: 60,
|
||||||
|
FeeLimitMsat: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
// We assert that the payment fails because the fee limit doesn't work
|
||||||
|
// correctly. This is fixed in the next commit.
|
||||||
|
ht.SendPaymentAssertFail(
|
||||||
|
alice, sendReq,
|
||||||
|
lnrpc.PaymentFailureReason_FAILURE_REASON_NO_ROUTE,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Once we're done, close the channels.
|
||||||
|
ht.CloseChannel(alice, chanPointAliceBob)
|
||||||
|
ht.CloseChannel(bob, chanPointBobCarol)
|
||||||
|
}
|
||||||
|
|
||||||
// computeFee calculates the payment fee as specified in BOLT07.
|
// computeFee calculates the payment fee as specified in BOLT07.
|
||||||
func computeFee(baseFee, feeRate, amt lnwire.MilliSatoshi) lnwire.MilliSatoshi {
|
func computeFee(baseFee, feeRate, amt lnwire.MilliSatoshi) lnwire.MilliSatoshi {
|
||||||
return baseFee + amt*feeRate/1000000
|
return baseFee + amt*feeRate/1000000
|
||||||
|
@@ -221,7 +221,7 @@ func (nw *nodeWatcher) WaitForChannelPolicyUpdate(
|
|||||||
select {
|
select {
|
||||||
// Send a watch request every second.
|
// Send a watch request every second.
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
// Did the event can close in the meantime? We want to
|
// Did the event chan close in the meantime? We want to
|
||||||
// avoid a "close of closed channel" panic since we're
|
// avoid a "close of closed channel" panic since we're
|
||||||
// re-using the same event chan for multiple requests.
|
// re-using the same event chan for multiple requests.
|
||||||
select {
|
select {
|
||||||
|
Reference in New Issue
Block a user