itest: switch over to routerrpc.SendPaymentV2
This commit is contained in:
parent
ca9c58aec9
commit
e201ed8106
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user