htlcswicth.test: add 'future' payment response
Add js-like future object which might be used to wait for the response to be received or return the error otherwise.
This commit is contained in:
parent
e170b43615
commit
25efbb61a4
@ -14,6 +14,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
"github.com/go-errors/errors"
|
||||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
@ -189,7 +190,8 @@ func TestChannelLinkSingleHopPayment(t *testing.T) {
|
|||||||
// * alice<->bob commitment state to be updated.
|
// * alice<->bob commitment state to be updated.
|
||||||
// * user notification to be sent.
|
// * user notification to be sent.
|
||||||
invoice, err := n.makePayment(n.aliceServer, n.bobServer,
|
invoice, err := n.makePayment(n.aliceServer, n.bobServer,
|
||||||
n.bobServer.PubKey(), hops, amount, htlcAmt, totalTimelock)
|
n.bobServer.PubKey(), hops, amount, htlcAmt,
|
||||||
|
totalTimelock).Wait(10 * time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to make the payment: %v", err)
|
t.Fatalf("unable to make the payment: %v", err)
|
||||||
}
|
}
|
||||||
@ -275,7 +277,7 @@ func TestChannelLinkBidirectionalOneHopPayments(t *testing.T) {
|
|||||||
|
|
||||||
_, r.err = n.makePayment(n.aliceServer, n.bobServer,
|
_, r.err = n.makePayment(n.aliceServer, n.bobServer,
|
||||||
n.bobServer.PubKey(), hopsForwards, amt, htlcAmt,
|
n.bobServer.PubKey(), hopsForwards, amt, htlcAmt,
|
||||||
totalTimelock)
|
totalTimelock).Wait(30 * time.Second)
|
||||||
resultChan <- r
|
resultChan <- r
|
||||||
}(i)
|
}(i)
|
||||||
}
|
}
|
||||||
@ -290,7 +292,7 @@ func TestChannelLinkBidirectionalOneHopPayments(t *testing.T) {
|
|||||||
|
|
||||||
_, r.err = n.makePayment(n.bobServer, n.aliceServer,
|
_, r.err = n.makePayment(n.bobServer, n.aliceServer,
|
||||||
n.aliceServer.PubKey(), hopsBackwards, amt, htlcAmt,
|
n.aliceServer.PubKey(), hopsBackwards, amt, htlcAmt,
|
||||||
totalTimelock)
|
totalTimelock).Wait(30 * time.Second)
|
||||||
resultChan <- r
|
resultChan <- r
|
||||||
}(i)
|
}(i)
|
||||||
}
|
}
|
||||||
@ -398,7 +400,7 @@ func TestChannelLinkMultiHopPayment(t *testing.T) {
|
|||||||
// * user notification to be sent.
|
// * user notification to be sent.
|
||||||
invoice, err := n.makePayment(n.aliceServer, n.carolServer,
|
invoice, err := n.makePayment(n.aliceServer, n.carolServer,
|
||||||
n.bobServer.PubKey(), hops, amount, htlcAmt,
|
n.bobServer.PubKey(), hops, amount, htlcAmt,
|
||||||
totalTimelock)
|
totalTimelock).Wait(10 * time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to send payment: %v", err)
|
t.Fatalf("unable to send payment: %v", err)
|
||||||
}
|
}
|
||||||
@ -467,7 +469,8 @@ func TestExitNodeTimelockPayloadMismatch(t *testing.T) {
|
|||||||
hops[0].OutgoingCTLV = 500
|
hops[0].OutgoingCTLV = 500
|
||||||
|
|
||||||
_, err := n.makePayment(n.aliceServer, n.bobServer,
|
_, err := n.makePayment(n.aliceServer, n.bobServer,
|
||||||
n.bobServer.PubKey(), hops, amount, htlcAmt, htlcExpiry)
|
n.bobServer.PubKey(), hops, amount, htlcAmt,
|
||||||
|
htlcExpiry).Wait(10 * time.Second)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("payment should have failed but didn't")
|
t.Fatalf("payment should have failed but didn't")
|
||||||
}
|
}
|
||||||
@ -515,7 +518,8 @@ func TestExitNodeAmountPayloadMismatch(t *testing.T) {
|
|||||||
hops[0].AmountToForward = 1
|
hops[0].AmountToForward = 1
|
||||||
|
|
||||||
_, err := n.makePayment(n.aliceServer, n.bobServer,
|
_, err := n.makePayment(n.aliceServer, n.bobServer,
|
||||||
n.bobServer.PubKey(), hops, amount, htlcAmt, htlcExpiry)
|
n.bobServer.PubKey(), hops, amount, htlcAmt,
|
||||||
|
htlcExpiry).Wait(10 * time.Second)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("payment should have failed but didn't")
|
t.Fatalf("payment should have failed but didn't")
|
||||||
} else if err.Error() != lnwire.CodeIncorrectPaymentAmount.String() {
|
} else if err.Error() != lnwire.CodeIncorrectPaymentAmount.String() {
|
||||||
@ -557,8 +561,8 @@ func TestLinkForwardTimelockPolicyMismatch(t *testing.T) {
|
|||||||
// Next, we'll make the payment which'll send an HTLC with our
|
// Next, we'll make the payment which'll send an HTLC with our
|
||||||
// specified parameters to the first hop in the route.
|
// specified parameters to the first hop in the route.
|
||||||
_, err := n.makePayment(n.aliceServer, n.carolServer,
|
_, err := n.makePayment(n.aliceServer, n.carolServer,
|
||||||
n.bobServer.PubKey(), hops, amount, htlcAmt, htlcExpiry)
|
n.bobServer.PubKey(), hops, amount, htlcAmt,
|
||||||
|
htlcExpiry).Wait(10 * time.Second)
|
||||||
// We should get an error, and that error should indicate that the HTLC
|
// We should get an error, and that error should indicate that the HTLC
|
||||||
// should be rejected due to a policy violation.
|
// should be rejected due to a policy violation.
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -610,7 +614,7 @@ func TestLinkForwardFeePolicyMismatch(t *testing.T) {
|
|||||||
// specified parameters to the first hop in the route.
|
// specified parameters to the first hop in the route.
|
||||||
_, err := n.makePayment(n.aliceServer, n.bobServer,
|
_, err := n.makePayment(n.aliceServer, n.bobServer,
|
||||||
n.bobServer.PubKey(), hops, amountNoFee, amountNoFee,
|
n.bobServer.PubKey(), hops, amountNoFee, amountNoFee,
|
||||||
htlcExpiry)
|
htlcExpiry).Wait(10 * time.Second)
|
||||||
|
|
||||||
// We should get an error, and that error should indicate that the HTLC
|
// We should get an error, and that error should indicate that the HTLC
|
||||||
// should be rejected due to a policy violation.
|
// should be rejected due to a policy violation.
|
||||||
@ -663,7 +667,7 @@ func TestLinkForwardMinHTLCPolicyMismatch(t *testing.T) {
|
|||||||
// specified parameters to the first hop in the route.
|
// specified parameters to the first hop in the route.
|
||||||
_, err := n.makePayment(n.aliceServer, n.bobServer,
|
_, err := n.makePayment(n.aliceServer, n.bobServer,
|
||||||
n.bobServer.PubKey(), hops, amountNoFee, htlcAmt,
|
n.bobServer.PubKey(), hops, amountNoFee, htlcAmt,
|
||||||
htlcExpiry)
|
htlcExpiry).Wait(10 * time.Second)
|
||||||
|
|
||||||
// We should get an error, and that error should indicate that the HTLC
|
// We should get an error, and that error should indicate that the HTLC
|
||||||
// should be rejected due to a policy violation (below min HTLC).
|
// should be rejected due to a policy violation (below min HTLC).
|
||||||
@ -717,7 +721,7 @@ func TestUpdateForwardingPolicy(t *testing.T) {
|
|||||||
// should succeed, and all balances should be updated accordingly.
|
// should succeed, and all balances should be updated accordingly.
|
||||||
invoice, err := n.makePayment(n.aliceServer, n.carolServer,
|
invoice, err := n.makePayment(n.aliceServer, n.carolServer,
|
||||||
n.bobServer.PubKey(), hops, amountNoFee, htlcAmt,
|
n.bobServer.PubKey(), hops, amountNoFee, htlcAmt,
|
||||||
htlcExpiry)
|
htlcExpiry).Wait(10 * time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to send payment: %v", err)
|
t.Fatalf("unable to send payment: %v", err)
|
||||||
}
|
}
|
||||||
@ -813,8 +817,9 @@ func TestChannelLinkMultiHopInsufficientPayment(t *testing.T) {
|
|||||||
// * Bob trying to add HTLC add request in Bob<->Carol channel.
|
// * Bob trying to add HTLC add request in Bob<->Carol channel.
|
||||||
// * Cancel HTLC request to be sent back from Bob to Alice.
|
// * Cancel HTLC request to be sent back from Bob to Alice.
|
||||||
// * user notification to be sent.
|
// * user notification to be sent.
|
||||||
invoice, err := n.makePayment(n.aliceServer, n.bobServer,
|
invoice, err := n.makePayment(n.aliceServer, n.carolServer,
|
||||||
n.bobServer.PubKey(), hops, amount, htlcAmt, totalTimelock)
|
n.bobServer.PubKey(), hops, amount, htlcAmt,
|
||||||
|
totalTimelock).Wait(10 * time.Second)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("error haven't been received")
|
t.Fatal("error haven't been received")
|
||||||
} else if !strings.Contains(err.Error(), "insufficient capacity") {
|
} else if !strings.Contains(err.Error(), "insufficient capacity") {
|
||||||
@ -966,8 +971,9 @@ func TestChannelLinkMultiHopUnknownNextHop(t *testing.T) {
|
|||||||
n.firstBobChannelLink, n.carolChannelLink)
|
n.firstBobChannelLink, n.carolChannelLink)
|
||||||
|
|
||||||
davePub := newMockServer("save", serverErr).PubKey()
|
davePub := newMockServer("save", serverErr).PubKey()
|
||||||
|
|
||||||
invoice, err := n.makePayment(n.aliceServer, n.bobServer, davePub, hops,
|
invoice, err := n.makePayment(n.aliceServer, n.bobServer, davePub, hops,
|
||||||
amount, htlcAmt, totalTimelock)
|
amount, htlcAmt, totalTimelock).Wait(10 * time.Second)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("error haven't been received")
|
t.Fatal("error haven't been received")
|
||||||
} else if err.Error() != lnwire.CodeUnknownNextPeer.String() {
|
} else if err.Error() != lnwire.CodeUnknownNextPeer.String() {
|
||||||
@ -1039,7 +1045,8 @@ func TestChannelLinkMultiHopDecodeError(t *testing.T) {
|
|||||||
n.firstBobChannelLink, n.carolChannelLink)
|
n.firstBobChannelLink, n.carolChannelLink)
|
||||||
|
|
||||||
invoice, err := n.makePayment(n.aliceServer, n.carolServer,
|
invoice, err := n.makePayment(n.aliceServer, n.carolServer,
|
||||||
n.bobServer.PubKey(), hops, amount, htlcAmt, totalTimelock)
|
n.bobServer.PubKey(), hops, amount, htlcAmt,
|
||||||
|
totalTimelock).Wait(10 * time.Second)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("error haven't been received")
|
t.Fatal("error haven't been received")
|
||||||
}
|
}
|
||||||
@ -1245,12 +1252,14 @@ func TestChannelLinkSingleHopMessageOrdering(t *testing.T) {
|
|||||||
n.firstBobChannelLink)
|
n.firstBobChannelLink)
|
||||||
|
|
||||||
// Wait for:
|
// Wait for:
|
||||||
// * htlc add htlc request to be sent to alice
|
// * HTLC add request to be sent to bob.
|
||||||
// * alice<->bob commitment state to be updated
|
// * alice<->bob commitment state to be updated.
|
||||||
// * settle request to be sent back from alice to bob
|
// * settle request to be sent back from bob to alice.
|
||||||
// * alice<->bob commitment state to be updated
|
// * alice<->bob commitment state to be updated.
|
||||||
_, err := n.makePayment(n.aliceServer, n.bobServer,
|
// * user notification to be sent.
|
||||||
n.bobServer.PubKey(), hops, amount, htlcAmt, totalTimelock)
|
_, err = n.makePayment(n.aliceServer, n.bobServer,
|
||||||
|
n.bobServer.PubKey(), hops, amount, htlcAmt,
|
||||||
|
totalTimelock).Wait(10 * time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to make the payment: %v", err)
|
t.Fatalf("unable to make the payment: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -402,6 +402,21 @@ func generateHops(payAmt lnwire.MilliSatoshi, startingHeight uint32,
|
|||||||
return runningAmt, totalTimelock, hops
|
return runningAmt, totalTimelock, hops
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type paymentResponse struct {
|
||||||
|
invoice *channeldb.Invoice
|
||||||
|
err chan error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *paymentResponse) Wait(d time.Duration) (*channeldb.Invoice, error) {
|
||||||
|
select {
|
||||||
|
case err := <-r.err:
|
||||||
|
close(r.err)
|
||||||
|
return r.invoice, err
|
||||||
|
case <-time.After(d):
|
||||||
|
return r.invoice, errors.New("htlc was no settled in time")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// makePayment takes the destination node and amount as input, sends the
|
// makePayment takes the destination node and amount as input, sends the
|
||||||
// payment and returns the error channel to wait for error to be received and
|
// payment and returns the error channel to wait for error to be received and
|
||||||
// invoice in order to check its status after the payment finished.
|
// invoice in order to check its status after the payment finished.
|
||||||
@ -413,7 +428,9 @@ func generateHops(payAmt lnwire.MilliSatoshi, startingHeight uint32,
|
|||||||
func (n *threeHopNetwork) makePayment(sendingPeer, receivingPeer Peer,
|
func (n *threeHopNetwork) makePayment(sendingPeer, receivingPeer Peer,
|
||||||
firstHopPub [33]byte, hops []ForwardingInfo,
|
firstHopPub [33]byte, hops []ForwardingInfo,
|
||||||
invoiceAmt, htlcAmt lnwire.MilliSatoshi,
|
invoiceAmt, htlcAmt lnwire.MilliSatoshi,
|
||||||
timelock uint32) (*channeldb.Invoice, error) {
|
timelock uint32) *paymentResponse {
|
||||||
|
|
||||||
|
paymentErr := make(chan error, 1)
|
||||||
|
|
||||||
sender := sendingPeer.(*mockServer)
|
sender := sendingPeer.(*mockServer)
|
||||||
receiver := receivingPeer.(*mockServer)
|
receiver := receivingPeer.(*mockServer)
|
||||||
@ -422,19 +439,31 @@ func (n *threeHopNetwork) makePayment(sendingPeer, receivingPeer Peer,
|
|||||||
// htlc add request.
|
// htlc add request.
|
||||||
blob, err := generateRoute(hops...)
|
blob, err := generateRoute(hops...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
paymentErr <- err
|
||||||
|
return &paymentResponse{
|
||||||
|
invoice: nil,
|
||||||
|
err: paymentErr,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate payment: invoice and htlc.
|
// Generate payment: invoice and htlc.
|
||||||
invoice, htlc, err := generatePayment(invoiceAmt, htlcAmt, timelock,
|
invoice, htlc, err := generatePayment(invoiceAmt, htlcAmt, timelock,
|
||||||
blob)
|
blob)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
paymentErr <- err
|
||||||
|
return &paymentResponse{
|
||||||
|
invoice: nil,
|
||||||
|
err: paymentErr,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check who is last in the route and add invoice to server registry.
|
// Check who is last in the route and add invoice to server registry.
|
||||||
if err := receiver.registry.AddInvoice(invoice); err != nil {
|
if err := receiver.registry.AddInvoice(invoice); err != nil {
|
||||||
return nil, err
|
paymentErr <- err
|
||||||
|
return &paymentResponse{
|
||||||
|
invoice: invoice,
|
||||||
|
err: paymentErr,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send payment and expose err channel.
|
// Send payment and expose err channel.
|
||||||
@ -445,11 +474,9 @@ func (n *threeHopNetwork) makePayment(sendingPeer, receivingPeer Peer,
|
|||||||
errChan <- err
|
errChan <- err
|
||||||
}()
|
}()
|
||||||
|
|
||||||
select {
|
return &paymentResponse{
|
||||||
case err := <-errChan:
|
invoice: invoice,
|
||||||
return invoice, err
|
err: errChan,
|
||||||
case <-time.After(5 * time.Minute):
|
|
||||||
return invoice, errors.New("htlc was not settled in time")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user