itest: switch over to routerrpc.SendPaymentV2

This commit is contained in:
Joost Jager 2020-03-31 12:44:18 +02:00
parent ca9c58aec9
commit e201ed8106
No known key found for this signature in database
GPG Key ID: A61B9D4C393C59C7
13 changed files with 464 additions and 410 deletions

@ -4,7 +4,6 @@ package itest
import (
"context"
"encoding/hex"
"strings"
"time"
@ -177,24 +176,18 @@ out:
// TODO(roasbeef): return failure response rather than failing entire
// stream on payment error.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
sendReq := &lnrpc.SendRequest{
PaymentHashString: hex.EncodeToString(makeFakePayHash(t)),
DestString: hex.EncodeToString(carol.PubKey[:]),
Amt: payAmt,
FinalCltvDelta: int32(carolPayReq.CltvExpiry),
sendReq := &routerrpc.SendPaymentRequest{
PaymentHash: makeFakePayHash(t),
Dest: carol.PubKey[:],
Amt: payAmt,
FinalCltvDelta: int32(carolPayReq.CltvExpiry),
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
}
resp, err := net.Alice.SendPaymentSync(ctxt, sendReq)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
// The payment should have resulted in an error since we sent it with the
// wrong payment hash.
if resp.PaymentError == "" {
t.Fatalf("payment should have been rejected due to invalid " +
"payment hash")
}
sendAndAssertFailure(
t, net.Alice,
sendReq, lnrpc.PaymentFailureReason_FAILURE_REASON_INCORRECT_PAYMENT_DETAILS,
)
assertLastHTLCError(
t, net.Alice,
lnrpc.Failure_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS,
@ -219,25 +212,18 @@ out:
// Next, we'll test the case of a recognized payHash but, an incorrect
// value on the extended HTLC.
htlcAmt := lnwire.NewMSatFromSatoshis(1000)
sendReq = &lnrpc.SendRequest{
PaymentHashString: hex.EncodeToString(carolInvoice.RHash),
DestString: hex.EncodeToString(carol.PubKey[:]),
Amt: int64(htlcAmt.ToSatoshis()), // 10k satoshis are expected.
FinalCltvDelta: int32(carolPayReq.CltvExpiry),
sendReq = &routerrpc.SendPaymentRequest{
PaymentHash: carolInvoice.RHash,
Dest: carol.PubKey[:],
Amt: int64(htlcAmt.ToSatoshis()), // 10k satoshis are expected.
FinalCltvDelta: int32(carolPayReq.CltvExpiry),
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
resp, err = net.Alice.SendPaymentSync(ctxt, sendReq)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
// The payment should fail with an error since we sent 1k satoshis isn't of
// 10k as was requested.
if resp.PaymentError == "" {
t.Fatalf("payment should have been rejected due to wrong " +
"HTLC amount")
}
sendAndAssertFailure(
t, net.Alice,
sendReq, lnrpc.PaymentFailureReason_FAILURE_REASON_INCORRECT_PAYMENT_DETAILS,
)
assertLastHTLCError(
t, net.Alice,
lnrpc.Failure_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS,
@ -262,14 +248,7 @@ out:
// Next we'll test an error that occurs mid-route due to an outgoing
// link having insufficient capacity. In order to do so, we'll first
// need to unbalance the link connecting Bob<->Carol.
ctx, cancel := context.WithCancel(ctxb)
defer cancel()
bobPayStream, err := net.Bob.SendPayment(ctx)
if err != nil {
t.Fatalf("unable to create payment stream: %v", err)
}
//
// To do so, we'll push most of the funds in the channel over to
// Alice's side, leaving on 10k satoshis of available balance for bob.
// There's a max payment amount, so we'll have to do this
@ -294,17 +273,14 @@ out:
if err != nil {
t.Fatalf("unable to generate carol invoice: %v", err)
}
if err := bobPayStream.Send(&lnrpc.SendRequest{
PaymentRequest: carolInvoice2.PaymentRequest,
}); err != nil {
t.Fatalf("unable to send payment: %v", err)
}
if resp, err := bobPayStream.Recv(); err != nil {
t.Fatalf("payment stream has been closed: %v", err)
} else if resp.PaymentError != "" {
t.Fatalf("bob's payment failed: %v", resp.PaymentError)
}
sendAndAssertSuccess(
t, net.Bob,
&routerrpc.SendPaymentRequest{
PaymentRequest: carolInvoice2.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
// For each send bob makes, we need to check that bob has a
// forward and settle event for his send, and carol has a
@ -331,19 +307,15 @@ out:
t.Fatalf("unable to generate carol invoice: %v", err)
}
sendReq = &lnrpc.SendRequest{
sendReq = &routerrpc.SendPaymentRequest{
PaymentRequest: carolInvoice3.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
resp, err = net.Alice.SendPaymentSync(ctxt, sendReq)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
if resp.PaymentError == "" {
t.Fatalf("payment should fail due to insufficient "+
"capacity: %v", err)
}
sendAndAssertFailure(
t, net.Alice,
sendReq, lnrpc.PaymentFailureReason_FAILURE_REASON_NO_ROUTE,
)
assertLastHTLCError(
t, net.Alice, lnrpc.Failure_TEMPORARY_CHANNEL_FAILURE,
)
@ -382,19 +354,15 @@ out:
t.Fatalf("unable to reset mission control: %v", err)
}
sendReq = &lnrpc.SendRequest{
PaymentRequest: carolInvoice.PaymentRequest,
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
resp, err = net.Alice.SendPaymentSync(ctxt, sendReq)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
if resp.PaymentError == "" {
t.Fatalf("payment should have failed")
}
sendAndAssertFailure(
t, net.Alice,
&routerrpc.SendPaymentRequest{
PaymentRequest: carolInvoice.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
lnrpc.PaymentFailureReason_FAILURE_REASON_NO_ROUTE,
)
assertLastHTLCError(t, net.Alice, lnrpc.Failure_UNKNOWN_NEXT_PEER)
// Alice should have a forwarding event and subsequent fail.

@ -217,7 +217,9 @@ func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
// Using Carol as the source, pay to the 5 invoices from Bob created
// above.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, carol, payReqs, true)
err = completePaymentRequests(
ctxt, carol, carol.RouterClient, payReqs, true,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}

@ -13,6 +13,7 @@ import (
"github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/lightningnetwork/lnd/lntest/wait"
"github.com/lightningnetwork/lnd/lntypes"
@ -62,13 +63,14 @@ func testMultiHopHtlcLocalChainClaim(net *lntest.NetworkHarness, t *harnessTest,
ctx, cancel := context.WithCancel(ctxb)
defer cancel()
alicePayStream, err := alice.SendPayment(ctx)
if err != nil {
t.Fatalf("unable to create payment stream for alice: %v", err)
}
err = alicePayStream.Send(&lnrpc.SendRequest{
PaymentRequest: carolInvoice.PaymentRequest,
})
_, err = alice.RouterClient.SendPaymentV2(
ctx,
&routerrpc.SendPaymentRequest{
PaymentRequest: carolInvoice.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}

@ -14,6 +14,7 @@ import (
"github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/lightningnetwork/lnd/lntest/wait"
)
@ -52,31 +53,38 @@ func testMultiHopHtlcLocalTimeout(net *lntest.NetworkHarness, t *harnessTest,
ctx, cancel := context.WithCancel(ctxb)
defer cancel()
alicePayStream, err := alice.SendPayment(ctx)
if err != nil {
t.Fatalf("unable to create payment stream for alice: %v", err)
}
// We'll create two random payment hashes unknown to carol, then send
// each of them by manually specifying the HTLC details.
carolPubKey := carol.PubKey[:]
dustPayHash := makeFakePayHash(t)
payHash := makeFakePayHash(t)
err = alicePayStream.Send(&lnrpc.SendRequest{
Dest: carolPubKey,
Amt: int64(dustHtlcAmt),
PaymentHash: dustPayHash,
FinalCltvDelta: finalCltvDelta,
})
_, err := alice.RouterClient.SendPaymentV2(
ctx,
&routerrpc.SendPaymentRequest{
Dest: carolPubKey,
Amt: int64(dustHtlcAmt),
PaymentHash: dustPayHash,
FinalCltvDelta: finalCltvDelta,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
if err != nil {
t.Fatalf("unable to send alice htlc: %v", err)
}
err = alicePayStream.Send(&lnrpc.SendRequest{
Dest: carolPubKey,
Amt: int64(htlcAmt),
PaymentHash: payHash,
FinalCltvDelta: finalCltvDelta,
})
_, err = alice.RouterClient.SendPaymentV2(
ctx,
&routerrpc.SendPaymentRequest{
Dest: carolPubKey,
Amt: int64(htlcAmt),
PaymentHash: payHash,
FinalCltvDelta: finalCltvDelta,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
if err != nil {
t.Fatalf("unable to send alice htlc: %v", err)
}

@ -13,6 +13,7 @@ import (
"github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/lightningnetwork/lnd/lntest/wait"
"github.com/lightningnetwork/lnd/lntypes"
@ -64,13 +65,14 @@ func testMultiHopReceiverChainClaim(net *lntest.NetworkHarness, t *harnessTest,
ctx, cancel := context.WithCancel(ctxb)
defer cancel()
alicePayStream, err := alice.SendPayment(ctx)
if err != nil {
t.Fatalf("unable to create payment stream for alice: %v", err)
}
err = alicePayStream.Send(&lnrpc.SendRequest{
PaymentRequest: carolInvoice.PaymentRequest,
})
_, err = alice.RouterClient.SendPaymentV2(
ctx,
&routerrpc.SendPaymentRequest{
PaymentRequest: carolInvoice.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}

@ -13,6 +13,7 @@ import (
"github.com/lightningnetwork/lnd/lncfg"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/lightningnetwork/lnd/lntest/wait"
"github.com/lightningnetwork/lnd/lntypes"
@ -62,13 +63,14 @@ func testMultiHopHtlcRemoteChainClaim(net *lntest.NetworkHarness, t *harnessTest
ctx, cancel := context.WithCancel(ctxb)
defer cancel()
alicePayStream, err := alice.SendPayment(ctx)
if err != nil {
t.Fatalf("unable to create payment stream for alice: %v", err)
}
err = alicePayStream.Send(&lnrpc.SendRequest{
PaymentRequest: carolInvoice.PaymentRequest,
})
_, err = alice.RouterClient.SendPaymentV2(
ctx,
&routerrpc.SendPaymentRequest{
PaymentRequest: carolInvoice.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}

@ -10,6 +10,7 @@ import (
"github.com/btcsuite/btcutil"
"github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/lightningnetwork/lnd/lntest/wait"
)
@ -44,20 +45,20 @@ func testMultiHopLocalForceCloseOnChainHtlcTimeout(net *lntest.NetworkHarness,
ctx, cancel := context.WithCancel(ctxb)
defer cancel()
alicePayStream, err := alice.SendPayment(ctx)
if err != nil {
t.Fatalf("unable to create payment stream for alice: %v", err)
}
// We'll now send a single HTLC across our multi-hop network.
carolPubKey := carol.PubKey[:]
payHash := makeFakePayHash(t)
err = alicePayStream.Send(&lnrpc.SendRequest{
Dest: carolPubKey,
Amt: int64(htlcAmt),
PaymentHash: payHash,
FinalCltvDelta: finalCltvDelta,
})
_, err := alice.RouterClient.SendPaymentV2(
ctx,
&routerrpc.SendPaymentRequest{
Dest: carolPubKey,
Amt: int64(htlcAmt),
PaymentHash: payHash,
FinalCltvDelta: finalCltvDelta,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
if err != nil {
t.Fatalf("unable to send alice htlc: %v", err)
}

@ -10,6 +10,7 @@ import (
"github.com/btcsuite/btcutil"
"github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/lightningnetwork/lnd/lntest/wait"
)
@ -45,20 +46,20 @@ func testMultiHopRemoteForceCloseOnChainHtlcTimeout(net *lntest.NetworkHarness,
ctx, cancel := context.WithCancel(ctxb)
defer cancel()
alicePayStream, err := alice.SendPayment(ctx)
if err != nil {
t.Fatalf("unable to create payment stream for alice: %v", err)
}
// We'll now send a single HTLC across our multi-hop network.
carolPubKey := carol.PubKey[:]
payHash := makeFakePayHash(t)
err = alicePayStream.Send(&lnrpc.SendRequest{
Dest: carolPubKey,
Amt: int64(htlcAmt),
PaymentHash: payHash,
FinalCltvDelta: finalCltvDelta,
})
_, err := alice.RouterClient.SendPaymentV2(
ctx,
&routerrpc.SendPaymentRequest{
Dest: carolPubKey,
Amt: int64(htlcAmt),
PaymentHash: payHash,
FinalCltvDelta: finalCltvDelta,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
if err != nil {
t.Fatalf("unable to send alice htlc: %v", err)
}

@ -74,7 +74,7 @@ func testSendMultiPathPayment(net *lntest.NetworkHarness, t *harnessTest) {
t, net.Alice,
&routerrpc.SendPaymentRequest{
PaymentRequest: payReq,
MaxParts: 10,
MaxParts: 10,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},

@ -5,11 +5,13 @@ package itest
import (
"bytes"
"context"
"encoding/hex"
"time"
"github.com/btcsuite/btcutil"
"github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
"github.com/lightningnetwork/lnd/lntest"
"github.com/lightningnetwork/lnd/lntest/wait"
"github.com/lightningnetwork/lnd/lntypes"
@ -62,21 +64,17 @@ func testSingleHopInvoice(net *lntest.NetworkHarness, t *harnessTest) {
// With the invoice for Bob added, send a payment towards Alice paying
// to the above generated invoice.
sendReq := &lnrpc.SendRequest{
PaymentRequest: invoiceResp.PaymentRequest,
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
resp, err := net.Alice.SendPaymentSync(ctxt, sendReq)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
// Ensure we obtain the proper preimage in the response.
if resp.PaymentError != "" {
t.Fatalf("error when attempting recv: %v", resp.PaymentError)
} else if !bytes.Equal(preimage, resp.PaymentPreimage) {
resp := sendAndAssertSuccess(
t, net.Alice,
&routerrpc.SendPaymentRequest{
PaymentRequest: invoiceResp.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
if hex.EncodeToString(preimage) != resp.PaymentPreimage {
t.Fatalf("preimage mismatch: expected %v, got %v", preimage,
resp.GetPaymentPreimage())
resp.PaymentPreimage)
}
// Bob's invoice should now be found and marked as settled.
@ -118,17 +116,14 @@ func testSingleHopInvoice(net *lntest.NetworkHarness, t *harnessTest) {
// Next send another payment, but this time using a zpay32 encoded
// invoice rather than manually specifying the payment details.
sendReq = &lnrpc.SendRequest{
PaymentRequest: invoiceResp.PaymentRequest,
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
resp, err = net.Alice.SendPaymentSync(ctxt, sendReq)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
if resp.PaymentError != "" {
t.Fatalf("error when attempting recv: %v", resp.PaymentError)
}
sendAndAssertSuccess(
t, net.Alice,
&routerrpc.SendPaymentRequest{
PaymentRequest: invoiceResp.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
// The second payment should also have succeeded, with the balances
// being update accordingly.
@ -144,23 +139,20 @@ func testSingleHopInvoice(net *lntest.NetworkHarness, t *harnessTest) {
keySendPreimage := lntypes.Preimage{3, 4, 5, 11}
keySendHash := keySendPreimage.Hash()
sendReq = &lnrpc.SendRequest{
Dest: net.Bob.PubKey[:],
Amt: paymentAmt,
FinalCltvDelta: 40,
PaymentHash: keySendHash[:],
DestCustomRecords: map[uint64][]byte{
record.KeySendType: keySendPreimage[:],
sendAndAssertSuccess(
t, net.Alice,
&routerrpc.SendPaymentRequest{
Dest: net.Bob.PubKey[:],
Amt: paymentAmt,
FinalCltvDelta: 40,
PaymentHash: keySendHash[:],
DestCustomRecords: map[uint64][]byte{
record.KeySendType: keySendPreimage[:],
},
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
resp, err = net.Alice.SendPaymentSync(ctxt, sendReq)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
if resp.PaymentError != "" {
t.Fatalf("error when attempting recv: %v", resp.PaymentError)
}
)
// The keysend payment should also have succeeded, with the balances
// being update accordingly.

@ -647,7 +647,8 @@ func shutdownAndAssert(net *lntest.NetworkHarness, t *harnessTest,
// payment requests. If the awaitResponse parameter is true, this function
// does not return until all payments successfully complete without errors.
func completePaymentRequests(ctx context.Context, client lnrpc.LightningClient,
paymentRequests []string, awaitResponse bool) error {
routerClient routerrpc.RouterClient, paymentRequests []string,
awaitResponse bool) error {
// We start by getting the current state of the client's channels. This
// is needed to ensure the payments actually have been committed before
@ -659,36 +660,54 @@ func completePaymentRequests(ctx context.Context, client lnrpc.LightningClient,
return err
}
ctxc, cancel := context.WithCancel(ctx)
defer cancel()
// send sends a payment and returns an error if it doesn't succeeded.
send := func(payReq string) error {
ctxc, cancel := context.WithCancel(ctx)
defer cancel()
payStream, err := client.SendPayment(ctxc)
if err != nil {
return err
}
for _, payReq := range paymentRequests {
sendReq := &lnrpc.SendRequest{
PaymentRequest: payReq,
}
err := payStream.Send(sendReq)
payStream, err := routerClient.SendPaymentV2(
ctxc,
&routerrpc.SendPaymentRequest{
PaymentRequest: payReq,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
if err != nil {
return err
}
resp, err := getPaymentResult(payStream)
if err != nil {
return err
}
if resp.Status != lnrpc.Payment_SUCCEEDED {
return errors.New(resp.FailureReason)
}
return nil
}
// Launch all payments simultaneously.
results := make(chan error)
for _, payReq := range paymentRequests {
payReqCopy := payReq
go func() {
err := send(payReqCopy)
if awaitResponse {
results <- err
}
}()
}
// If awaiting a response, verify that all payments succeeded.
if awaitResponse {
for range paymentRequests {
resp, err := payStream.Recv()
err := <-results
if err != nil {
return err
}
if resp.PaymentError != "" {
return fmt.Errorf("received payment error: %v",
resp.PaymentError)
}
}
return nil
}
@ -1530,17 +1549,14 @@ func testPaymentFollowingChannelOpen(net *lntest.NetworkHarness, t *harnessTest)
// Send payment to Bob so that a channel update to disk will be
// executed.
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
_, err = net.Alice.SendPaymentSync(
ctxt,
&lnrpc.SendRequest{
sendAndAssertSuccess(
t, net.Alice,
&routerrpc.SendPaymentRequest{
PaymentRequest: bobPayReqs[0],
TimeoutSeconds: 60,
FeeLimitSat: 1000000,
},
)
if err != nil {
t.Fatalf("unable to create payment stream for alice: %v", err)
}
// At this point we want to make sure the channel is opened and not
// pending.
@ -1968,15 +1984,15 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(
ctxt, net.Alice, []string{resp.PaymentRequest}, true,
ctxt, net.Alice, net.Alice.RouterClient,
[]string{resp.PaymentRequest}, true,
)
// Alice knows about the channel policy of Carol and should therefore
// not be able to find a path during routing.
expErr := channeldb.FailureReasonNoRoute.Error()
if err == nil ||
!strings.Contains(err.Error(), expErr) {
t.Fatalf("expected payment to fail, instead got %v", err)
expErr := lnrpc.PaymentFailureReason_FAILURE_REASON_NO_ROUTE
if err.Error() != expErr.String() {
t.Fatalf("expected %v, instead got %v", expErr, err)
}
// Now we try to send a payment over the channel with a value too low
@ -2141,7 +2157,8 @@ func testUpdateChannelPolicy(net *lntest.NetworkHarness, t *harnessTest) {
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(
ctxt, net.Alice, []string{resp.PaymentRequest}, true,
ctxt, net.Alice, net.Alice.RouterClient,
[]string{resp.PaymentRequest}, true,
)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
@ -2949,27 +2966,26 @@ func testChannelUnsettledBalance(net *lntest.NetworkHarness, t *harnessTest) {
numInvoices = 6
)
// Create a paystream from Alice to Carol to enable Alice to make
// a series of payments.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
alicePayStream, err := net.Alice.SendPayment(ctxt)
if err != nil {
t.Fatalf("unable to create payment stream for alice: %v", err)
}
// Send payments from Alice to Carol a number of numInvoices
// times.
// Simulateneously send numInvoices payments from Alice to Carol.
carolPubKey := carol.PubKey[:]
errChan := make(chan error)
for i := 0; i < numInvoices; i++ {
err = alicePayStream.Send(&lnrpc.SendRequest{
Dest: carolPubKey,
Amt: int64(payAmt),
PaymentHash: makeFakePayHash(t),
FinalCltvDelta: lnd.DefaultBitcoinTimeLockDelta,
})
if err != nil {
t.Fatalf("unable to send alice htlc: %v", err)
}
go func() {
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
_, err := net.Alice.RouterClient.SendPaymentV2(ctxt,
&routerrpc.SendPaymentRequest{
Dest: carolPubKey,
Amt: int64(payAmt),
PaymentHash: makeFakePayHash(t),
FinalCltvDelta: lnd.DefaultBitcoinTimeLockDelta,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
})
if err != nil {
errChan <- err
}
}()
}
// Test that the UnsettledBalance for both Alice and Carol
@ -3013,6 +3029,13 @@ func testChannelUnsettledBalance(net *lntest.NetworkHarness, t *harnessTest) {
t.Fatalf("unsettled balace error: %v", unsettledErr)
}
// Check for payment errors.
select {
case err := <-errChan:
t.Fatalf("payment error: %v", err)
default:
}
// Force and assert the channel closure.
ctxt, _ = context.WithTimeout(ctxb, channelCloseTimeout)
closeChannelAndAssert(ctxt, t, net, net.Alice, chanPointAlice, true)
@ -3283,22 +3306,22 @@ func channelForceClosureTest(net *lntest.NetworkHarness, t *harnessTest,
// Send payments from Alice to Carol, since Carol is htlchodl mode, the
// htlc outputs should be left unsettled, and should be swept by the
// utxo nursery.
ctx, cancel := context.WithCancel(ctxb)
defer cancel()
alicePayStream, err := alice.SendPayment(ctx)
if err != nil {
t.Fatalf("unable to create payment stream for alice: %v", err)
}
carolPubKey := carol.PubKey[:]
for i := 0; i < numInvoices; i++ {
err = alicePayStream.Send(&lnrpc.SendRequest{
Dest: carolPubKey,
Amt: int64(paymentAmt),
PaymentHash: makeFakePayHash(t),
FinalCltvDelta: lnd.DefaultBitcoinTimeLockDelta,
})
ctx, cancel := context.WithCancel(ctxb)
defer cancel()
_, err := alice.RouterClient.SendPaymentV2(
ctx,
&routerrpc.SendPaymentRequest{
Dest: carolPubKey,
Amt: int64(paymentAmt),
PaymentHash: makeFakePayHash(t),
FinalCltvDelta: lnd.DefaultBitcoinTimeLockDelta,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
if err != nil {
t.Fatalf("unable to send alice htlc: %v", err)
}
@ -4255,17 +4278,18 @@ func testSphinxReplayPersistence(net *lntest.NetworkHarness, t *harnessTest) {
ctx, cancel := context.WithCancel(ctxb)
defer cancel()
payStream, err := fred.SendPayment(ctx)
payStream, err := fred.RouterClient.SendPaymentV2(
ctx,
&routerrpc.SendPaymentRequest{
PaymentRequest: invoiceResp.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
if err != nil {
t.Fatalf("unable to open payment stream: %v", err)
}
sendReq := &lnrpc.SendRequest{PaymentRequest: invoiceResp.PaymentRequest}
err = payStream.Send(sendReq)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
time.Sleep(200 * time.Millisecond)
// Dave's invoice should not be marked as settled.
@ -4303,14 +4327,14 @@ func testSphinxReplayPersistence(net *lntest.NetworkHarness, t *harnessTest) {
// pending payment. Even though he still holds the original settle, if
// he does fail, it is almost certainly caused by the sphinx replay
// protection, as it is the only validation we do in hodl mode.
resp, err := payStream.Recv()
result, err := getPaymentResult(payStream)
if err != nil {
t.Fatalf("unable to receive payment response: %v", err)
}
// Assert that Fred receives the expected failure after Carol sent a
// duplicate packet that fails due to sphinx replay detection.
if resp.PaymentError == "" {
if result.Status == lnrpc.Payment_SUCCEEDED {
t.Fatalf("expected payment error")
}
assertLastHTLCError(t, fred, lnrpc.Failure_INVALID_ONION_KEY)
@ -4395,17 +4419,14 @@ func testListPayments(net *lntest.NetworkHarness, t *harnessTest) {
// With the invoice for Bob added, send a payment towards Alice paying
// to the above generated invoice.
sendReq := &lnrpc.SendRequest{
PaymentRequest: invoiceResp.PaymentRequest,
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
resp, err := net.Alice.SendPaymentSync(ctxt, sendReq)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
if resp.PaymentError != "" {
t.Fatalf("error when attempting recv: %v", resp.PaymentError)
}
sendAndAssertSuccess(
t, net.Alice,
&routerrpc.SendPaymentRequest{
PaymentRequest: invoiceResp.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitSat: 1000000,
},
)
// Grab Alice's list of payments, she should show the existence of
// exactly one payment.
@ -5647,7 +5668,9 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) {
// Let Carol pay the invoices.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, carol, payReqs, true)
err = completePaymentRequests(
ctxt, carol, carol.RouterClient, payReqs, true,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -5703,7 +5726,9 @@ func testPrivateChannels(net *lntest.NetworkHarness, t *harnessTest) {
// Let Bob pay the invoices.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, net.Alice, payReqs, true)
err = completePaymentRequests(
ctxt, net.Alice, net.Alice.RouterClient, payReqs, true,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -6179,7 +6204,9 @@ func testMultiHopOverPrivateChannels(net *lntest.NetworkHarness, t *harnessTest)
// Let Alice pay the invoice.
payReqs := []string{resp.PaymentRequest}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, net.Alice, payReqs, true)
err = completePaymentRequests(
ctxt, net.Alice, net.Alice.RouterClient, payReqs, true,
)
if err != nil {
t.Fatalf("unable to send payments from alice to dave: %v", err)
}
@ -6315,18 +6342,25 @@ func testInvoiceSubscriptions(net *lntest.NetworkHarness, t *harnessTest) {
// With the assertion above set up, send a payment from Alice to Bob
// which should finalize and settle the invoice.
sendReq := &lnrpc.SendRequest{
sendReq := &routerrpc.SendPaymentRequest{
PaymentRequest: invoiceResp.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
resp, err := net.Alice.SendPaymentSync(ctxt, sendReq)
stream, err := net.Alice.RouterClient.SendPaymentV2(ctxt, sendReq)
if err != nil {
close(quit)
t.Fatalf("unable to send payment: %v", err)
}
if resp.PaymentError != "" {
result, err := getPaymentResult(stream)
if err != nil {
close(quit)
t.Fatalf("error when attempting recv: %v", resp.PaymentError)
t.Fatalf("cannot get payment result: %v", err)
}
if result.Status != lnrpc.Payment_SUCCEEDED {
close(quit)
t.Fatalf("error when attempting recv: %v", result.Status)
}
select {
@ -6390,7 +6424,7 @@ func testInvoiceSubscriptions(net *lntest.NetworkHarness, t *harnessTest) {
// can test that all settled invoices are properly notified.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(
ctxt, net.Alice, payReqs, true,
ctxt, net.Alice, net.Alice.RouterClient, payReqs, true,
)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
@ -6970,7 +7004,9 @@ func testFailingChannel(net *lntest.NetworkHarness, t *harnessTest) {
// Send the payment from Alice to Carol. We expect Carol to attempt to
// settle this payment with the wrong preimage.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, net.Alice, carolPayReqs, false)
err = completePaymentRequests(
ctxt, net.Alice, net.Alice.RouterClient, carolPayReqs, false,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -7442,8 +7478,10 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) {
// Send payments from Carol to Bob using 3 of Bob's payment hashes
// generated above.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, carol, bobPayReqs[:numInvoices/2],
true)
err = completePaymentRequests(
ctxt, carol, carol.RouterClient, bobPayReqs[:numInvoices/2],
true,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -7496,8 +7534,10 @@ func testRevokedCloseRetribution(net *lntest.NetworkHarness, t *harnessTest) {
// Finally, send payments from Carol to Bob, consuming Bob's remaining
// payment hashes.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, carol, bobPayReqs[numInvoices/2:],
true)
err = completePaymentRequests(
ctxt, carol, carol.RouterClient, bobPayReqs[numInvoices/2:],
true,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -7749,7 +7789,9 @@ func testRevokedCloseRetributionZeroValueRemoteOutput(net *lntest.NetworkHarness
// Finally, send payments from Dave to Carol, consuming Carol's remaining
// payment hashes.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, dave, carolPayReqs, false)
err = completePaymentRequests(
ctxt, dave, dave.RouterClient, carolPayReqs, false,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -8002,7 +8044,8 @@ func testRevokedCloseRetributionRemoteHodl(net *lntest.NetworkHarness,
// generated above.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(
ctxt, dave, carolPayReqs[:numInvoices/2], false,
ctxt, dave, dave.RouterClient, carolPayReqs[:numInvoices/2],
false,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
@ -8022,7 +8065,8 @@ func testRevokedCloseRetributionRemoteHodl(net *lntest.NetworkHarness,
// generated above.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(
ctxt, carol, davePayReqs[:numInvoices/2], false,
ctxt, carol, carol.RouterClient, davePayReqs[:numInvoices/2],
false,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
@ -8070,7 +8114,8 @@ func testRevokedCloseRetributionRemoteHodl(net *lntest.NetworkHarness,
// remaining payment hashes.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(
ctxt, dave, carolPayReqs[numInvoices/2:], false,
ctxt, dave, dave.RouterClient, carolPayReqs[numInvoices/2:],
false,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
@ -8469,7 +8514,9 @@ func testRevokedCloseRetributionAltruistWatchtower(net *lntest.NetworkHarness,
// Finally, send payments from Dave to Carol, consuming Carol's remaining
// payment hashes.
err = completePaymentRequests(ctxb, dave, carolPayReqs, false)
err = completePaymentRequests(
ctxb, dave, dave.RouterClient, carolPayReqs, false,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -8930,8 +8977,10 @@ func testDataLossProtection(net *lntest.NetworkHarness, t *harnessTest) {
// Send payments from Carol using 3 of the payment hashes
// generated above.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, carol,
payReqs[:numInvoices/2], true)
err = completePaymentRequests(
ctxt, carol, carol.RouterClient,
payReqs[:numInvoices/2], true,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -8985,8 +9034,10 @@ func testDataLossProtection(net *lntest.NetworkHarness, t *harnessTest) {
// Finally, send more payments from , using the remaining
// payment hashes.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, carol,
payReqs[numInvoices/2:], true)
err = completePaymentRequests(
ctxt, carol, carol.RouterClient,
payReqs[numInvoices/2:], true,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -9290,7 +9341,8 @@ func testRejectHTLC(net *lntest.NetworkHarness, t *harnessTest) {
// Alice pays Carols invoice.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(
ctxt, net.Alice, []string{resp.PaymentRequest}, true,
ctxt, net.Alice, net.Alice.RouterClient,
[]string{resp.PaymentRequest}, true,
)
if err != nil {
t.Fatalf("unable to send payments from alice to carol: %v", err)
@ -9315,7 +9367,8 @@ func testRejectHTLC(net *lntest.NetworkHarness, t *harnessTest) {
// Carol pays Bobs invoice.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(
ctxt, carol, []string{resp.PaymentRequest}, true,
ctxt, carol, carol.RouterClient,
[]string{resp.PaymentRequest}, true,
)
if err != nil {
t.Fatalf("unable to send payments from carol to bob: %v", err)
@ -9343,7 +9396,8 @@ func testRejectHTLC(net *lntest.NetworkHarness, t *harnessTest) {
// --rejecthtlc.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(
ctxt, net.Alice, []string{resp.PaymentRequest}, true,
ctxt, net.Alice, net.Alice.RouterClient,
[]string{resp.PaymentRequest}, true,
)
if err == nil {
t.Fatalf(
@ -9887,33 +9941,45 @@ func testAsyncPayments(net *lntest.NetworkHarness, t *harnessTest) {
"timeout: %v", err)
}
// Open up a payment stream to Alice that we'll use to send payment to
// Bob. We also create a small helper function to send payments to Bob,
// consuming the payment hashes we generated above.
ctxt, _ = context.WithTimeout(ctxb, lntest.AsyncBenchmarkTimeout)
alicePayStream, err := net.Alice.SendPayment(ctxt)
if err != nil {
t.Fatalf("unable to create payment stream for alice: %v", err)
}
// Send payments from Alice to Bob using of Bob's payment hashes
// generated above.
// Simultaneously send payments from Alice to Bob using of Bob's payment
// hashes generated above.
now := time.Now()
errChan := make(chan error)
statusChan := make(chan *lnrpc.Payment)
for i := 0; i < numInvoices; i++ {
sendReq := &lnrpc.SendRequest{
PaymentRequest: bobPayReqs[i],
}
payReq := bobPayReqs[i]
go func() {
ctxt, _ = context.WithTimeout(ctxb, lntest.AsyncBenchmarkTimeout)
stream, err := net.Alice.RouterClient.SendPaymentV2(
ctxt,
&routerrpc.SendPaymentRequest{
PaymentRequest: payReq,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
if err != nil {
errChan <- err
}
result, err := getPaymentResult(stream)
if err != nil {
errChan <- err
}
if err := alicePayStream.Send(sendReq); err != nil {
t.Fatalf("unable to send payment: "+
"stream has been closed: %v", err)
}
statusChan <- result
}()
}
// Wait until all the payments have settled.
for i := 0; i < numInvoices; i++ {
if _, err := alicePayStream.Recv(); err != nil {
t.Fatalf("payment stream have been closed: %v", err)
select {
case result := <-statusChan:
if result.Status == lnrpc.Payment_SUCCEEDED {
continue
}
case err := <-errChan:
t.Fatalf("payment error: %v", err)
}
}
@ -10058,90 +10124,51 @@ func testBidirectionalAsyncPayments(net *lntest.NetworkHarness, t *harnessTest)
t.Fatalf("unable to reset mc for alice: %v", err)
}
// Open up a payment streams to Alice and to Bob, that we'll use to
// send payment between nodes.
ctx, cancel := context.WithTimeout(ctxb, lntest.AsyncBenchmarkTimeout)
defer cancel()
alicePayStream, err := net.Alice.SendPayment(ctx)
if err != nil {
t.Fatalf("unable to create payment stream for alice: %v", err)
}
ctx, cancel = context.WithTimeout(ctxb, lntest.AsyncBenchmarkTimeout)
defer cancel()
bobPayStream, err := net.Bob.SendPayment(ctx)
if err != nil {
t.Fatalf("unable to create payment stream for bob: %v", err)
}
// Send payments from Alice to Bob and from Bob to Alice in async
// manner.
for i := 0; i < numInvoices; i++ {
aliceSendReq := &lnrpc.SendRequest{
PaymentRequest: bobPayReqs[i],
}
errChan := make(chan error)
statusChan := make(chan *lnrpc.Payment)
bobSendReq := &lnrpc.SendRequest{
PaymentRequest: alicePayReqs[i],
}
send := func(node *lntest.HarnessNode, payReq string) {
go func() {
ctxt, _ = context.WithTimeout(
ctxb, lntest.AsyncBenchmarkTimeout,
)
stream, err := node.RouterClient.SendPaymentV2(
ctxt,
&routerrpc.SendPaymentRequest{
PaymentRequest: payReq,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
if err != nil {
errChan <- err
}
result, err := getPaymentResult(stream)
if err != nil {
errChan <- err
}
if err := alicePayStream.Send(aliceSendReq); err != nil {
t.Fatalf("unable to send payment: "+
"%v", err)
}
if err := bobPayStream.Send(bobSendReq); err != nil {
t.Fatalf("unable to send payment: "+
"%v", err)
}
statusChan <- result
}()
}
errChan := make(chan error)
go func() {
for i := 0; i < numInvoices; i++ {
if resp, err := alicePayStream.Recv(); err != nil {
errChan <- errors.Errorf("payment stream has"+
" been closed: %v", err)
return
} else if resp.PaymentError != "" {
errChan <- errors.Errorf("unable to send "+
"payment from alice to bob: %v",
resp.PaymentError)
return
}
}
errChan <- nil
}()
for i := 0; i < numInvoices; i++ {
send(net.Bob, alicePayReqs[i])
send(net.Alice, bobPayReqs[i])
}
go func() {
for i := 0; i < numInvoices; i++ {
if resp, err := bobPayStream.Recv(); err != nil {
errChan <- errors.Errorf("payment stream has"+
" been closed: %v", err)
return
} else if resp.PaymentError != "" {
errChan <- errors.Errorf("unable to send "+
"payment from bob to alice: %v",
resp.PaymentError)
return
}
}
errChan <- nil
}()
// Wait for Alice and Bob receive their payments, and throw and error
// if something goes wrong.
for i := 0; i < 2; i++ {
// Expect all payments to succeed.
for i := 0; i < 2*numInvoices; i++ {
select {
case err := <-errChan:
if err != nil {
t.Fatalf(err.Error())
case result := <-statusChan:
if result.Status != lnrpc.Payment_SUCCEEDED {
t.Fatalf("payment error: %v", result.Status)
}
case <-time.After(lntest.AsyncBenchmarkTimeout):
t.Fatalf("waiting for payments to finish too long "+
"(%v)", lntest.AsyncBenchmarkTimeout)
case err := <-errChan:
t.Fatalf("payment error: %v", err)
}
}
@ -10504,7 +10531,9 @@ func testSwitchCircuitPersistence(net *lntest.NetworkHarness, t *harnessTest) {
// Using Carol as the source, pay to the 5 invoices from Bob created
// above.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, net.Bob, payReqs, false)
err = completePaymentRequests(
ctxt, net.Bob, net.Bob.RouterClient, payReqs, false,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -10630,7 +10659,9 @@ func testSwitchCircuitPersistence(net *lntest.NetworkHarness, t *harnessTest) {
// Using Carol as the source, pay to the 5 invoices from Bob created
// above.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, net.Bob, payReqs, true)
err = completePaymentRequests(
ctxt, net.Bob, net.Bob.RouterClient, payReqs, true,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -10827,7 +10858,9 @@ func testSwitchOfflineDelivery(net *lntest.NetworkHarness, t *harnessTest) {
// Using Carol as the source, pay to the 5 invoices from Bob created
// above.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, net.Bob, payReqs, false)
err = completePaymentRequests(
ctxt, net.Bob, net.Bob.RouterClient, payReqs, false,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -10959,7 +10992,9 @@ func testSwitchOfflineDelivery(net *lntest.NetworkHarness, t *harnessTest) {
// Using Carol as the source, pay to the 5 invoices from Bob created
// above.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, net.Bob, payReqs, true)
err = completePaymentRequests(
ctxt, net.Bob, net.Bob.RouterClient, payReqs, true,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -11156,7 +11191,9 @@ func testSwitchOfflineDeliveryPersistence(net *lntest.NetworkHarness, t *harness
// Using Carol as the source, pay to the 5 invoices from Bob created
// above.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, net.Bob, payReqs, false)
err = completePaymentRequests(
ctxt, net.Bob, net.Bob.RouterClient, payReqs, false,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -11295,7 +11332,9 @@ func testSwitchOfflineDeliveryPersistence(net *lntest.NetworkHarness, t *harness
// Using Carol as the source, pay to the 5 invoices from Bob created
// above.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, net.Bob, payReqs, true)
err = completePaymentRequests(
ctxt, net.Bob, net.Bob.RouterClient, payReqs, true,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -11490,7 +11529,9 @@ func testSwitchOfflineDeliveryOutgoingOffline(
// Using Carol as the source, pay to the 5 invoices from Bob created
// above.
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(ctxt, net.Bob, payReqs, false)
err = completePaymentRequests(
ctxt, net.Bob, net.Bob.RouterClient, payReqs, false,
)
if err != nil {
t.Fatalf("unable to send payments: %v", err)
}
@ -12038,21 +12079,21 @@ func testRouteFeeCutoff(net *lntest.NetworkHarness, t *harnessTest) {
t.Fatalf("unable to create invoice: %v", err)
}
sendReq := &lnrpc.SendRequest{
sendReq := &routerrpc.SendPaymentRequest{
PaymentRequest: invoiceResp.PaymentRequest,
FeeLimit: feeLimit,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
paymentResp, err := net.Alice.SendPaymentSync(ctxt, sendReq)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
if paymentResp.PaymentError != "" {
t.Fatalf("unable to send payment: %v",
paymentResp.PaymentError)
switch limit := feeLimit.Limit.(type) {
case *lnrpc.FeeLimit_Fixed:
sendReq.FeeLimitMsat = 1000 * limit.Fixed
case *lnrpc.FeeLimit_Percent:
sendReq.FeeLimitMsat = 1000 * paymentAmt * limit.Percent / 100
}
checkRoute(paymentResp.PaymentRoute)
result := sendAndAssertSuccess(t, net.Alice, sendReq)
checkRoute(result.Htlcs[0].Route)
}
// We'll start off using percentages first. Since the fee along the
@ -13179,8 +13220,8 @@ func testChanRestoreScenario(t *harnessTest, net *lntest.NetworkHarness,
ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(
ctxt, from, []string{invoiceResp.PaymentRequest},
true,
ctxt, from, from.RouterClient,
[]string{invoiceResp.PaymentRequest}, true,
)
if err != nil {
t.Fatalf("unable to complete payments: %v", err)
@ -14208,7 +14249,8 @@ func testExternalFundingChanPoint(net *lntest.NetworkHarness, t *harnessTest) {
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(
ctxt, carol, []string{resp.PaymentRequest}, true,
ctxt, carol, carol.RouterClient, []string{resp.PaymentRequest},
true,
)
if err != nil {
t.Fatalf("unable to make payments between Carol and Dave")
@ -14259,6 +14301,37 @@ func sendAndAssertSuccess(t *harnessTest, node *lntest.HarnessNode,
return result
}
// sendAndAssertFailure sends the given payment requests and asserts that the
// payment fails with the expected reason.
func sendAndAssertFailure(t *harnessTest, node *lntest.HarnessNode,
req *routerrpc.SendPaymentRequest,
failureReason lnrpc.PaymentFailureReason) *lnrpc.Payment {
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
stream, err := node.RouterClient.SendPaymentV2(ctx, req)
if err != nil {
t.Fatalf("unable to send payment: %v", err)
}
result, err := getPaymentResult(stream)
if err != nil {
t.Fatalf("unable to get payment result: %v", err)
}
if result.Status != lnrpc.Payment_FAILED {
t.Fatalf("payment was expected to fail, but succeeded")
}
if result.FailureReason != failureReason {
t.Fatalf("payment should have been rejected due to "+
"%v, but got %v", failureReason, result.Status)
}
return result
}
// getPaymentResult reads a final result from the stream and returns it.
func getPaymentResult(stream routerrpc.Router_SendPaymentV2Client) (
*lnrpc.Payment, error) {

@ -31,6 +31,7 @@
<time> [ERR] CRTR: Payment with hash <hex> failed: error
<time> [ERR] CRTR: Payment with hash <hex> failed: incorrect_payment_details
<time> [ERR] CRTR: Payment with hash <hex> failed: insufficient_balance
<time> [ERR] CRTR: Payment with hash <hex> failed: no_route
<time> [ERR] CRTR: Payment with hash <hex> failed: router shutting down
<time> [ERR] CRTR: Resuming payment with hash <hex> failed: error.
<time> [ERR] CRTR: Resuming payment with hash <hex> failed: incorrect_payment_details.

@ -7,6 +7,7 @@ import (
"context"
"crypto/rand"
"fmt"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
"github.com/btcsuite/btcutil/psbt"
@ -219,7 +220,8 @@ func testPsbtChanFunding(net *lntest.NetworkHarness, t *harnessTest) {
}
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = completePaymentRequests(
ctxt, carol, []string{resp.PaymentRequest}, true,
ctxt, carol, carol.RouterClient, []string{resp.PaymentRequest},
true,
)
if err != nil {
t.Fatalf("unable to make payments between Carol and Dave")