Merge pull request #7827 from carlaKC/cleanup-invoicetests
invoices/test: Cleanup Invoice Registry Tests
This commit is contained in:
2 files changed
+161
-123
No files matched your search
@@ -19,6 +19,8 @@ import (
|
|||||||
|
|
||||||
// TestSettleInvoice tests settling of an invoice and related notifications.
|
// TestSettleInvoice tests settling of an invoice and related notifications.
|
||||||
func TestSettleInvoice(t *testing.T) {
|
func TestSettleInvoice(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
ctx := newTestContext(t, nil)
|
ctx := newTestContext(t, nil)
|
||||||
|
|
||||||
allSubscriptions, err := ctx.registry.SubscribeNotifications(0, 0)
|
allSubscriptions, err := ctx.registry.SubscribeNotifications(0, 0)
|
||||||
@@ -37,6 +39,7 @@ func TestSettleInvoice(t *testing.T) {
|
|||||||
require.Equal(t, subscription.PayHash(), &testInvoicePaymentHash)
|
require.Equal(t, subscription.PayHash(), &testInvoicePaymentHash)
|
||||||
|
|
||||||
// Add the invoice.
|
// Add the invoice.
|
||||||
|
testInvoice := newInvoice(t, false)
|
||||||
addIdx, err := ctx.registry.AddInvoice(
|
addIdx, err := ctx.registry.AddInvoice(
|
||||||
testInvoice, testInvoicePaymentHash,
|
testInvoice, testInvoicePaymentHash,
|
||||||
)
|
)
|
||||||
@@ -193,6 +196,8 @@ func TestSettleInvoice(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func testCancelInvoice(t *testing.T, gc bool) {
|
func testCancelInvoice(t *testing.T, gc bool) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
cfg := defaultRegistryConfig()
|
cfg := defaultRegistryConfig()
|
||||||
|
|
||||||
// If set to true, then also delete the invoice from the DB after
|
// If set to true, then also delete the invoice from the DB after
|
||||||
@@ -220,7 +225,7 @@ func testCancelInvoice(t *testing.T, gc bool) {
|
|||||||
require.Equal(t, subscription.PayHash(), &testInvoicePaymentHash)
|
require.Equal(t, subscription.PayHash(), &testInvoicePaymentHash)
|
||||||
|
|
||||||
// Add the invoice.
|
// Add the invoice.
|
||||||
amt := lnwire.MilliSatoshi(100000)
|
testInvoice := newInvoice(t, false)
|
||||||
_, err = ctx.registry.AddInvoice(testInvoice, testInvoicePaymentHash)
|
_, err = ctx.registry.AddInvoice(testInvoice, testInvoicePaymentHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@@ -298,8 +303,8 @@ func testCancelInvoice(t *testing.T, gc bool) {
|
|||||||
// result in a cancel resolution.
|
// result in a cancel resolution.
|
||||||
hodlChan := make(chan interface{})
|
hodlChan := make(chan interface{})
|
||||||
resolution, err := ctx.registry.NotifyExitHopHtlc(
|
resolution, err := ctx.registry.NotifyExitHopHtlc(
|
||||||
testInvoicePaymentHash, amt, testHtlcExpiry, testCurrentHeight,
|
testInvoicePaymentHash, testInvoiceAmount, testHtlcExpiry,
|
||||||
getCircuitKey(0), hodlChan, testPayload,
|
testCurrentHeight, getCircuitKey(0), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("expected settlement of a canceled invoice to succeed")
|
t.Fatal("expected settlement of a canceled invoice to succeed")
|
||||||
@@ -325,6 +330,8 @@ func testCancelInvoice(t *testing.T, gc bool) {
|
|||||||
|
|
||||||
// TestCancelInvoice tests cancellation of an invoice and related notifications.
|
// TestCancelInvoice tests cancellation of an invoice and related notifications.
|
||||||
func TestCancelInvoice(t *testing.T) {
|
func TestCancelInvoice(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
// Test cancellation both with garbage collection (meaning that canceled
|
// Test cancellation both with garbage collection (meaning that canceled
|
||||||
// invoice will be deleted) and without (meaning it'll be kept).
|
// invoice will be deleted) and without (meaning it'll be kept).
|
||||||
t.Run("garbage collect", func(t *testing.T) {
|
t.Run("garbage collect", func(t *testing.T) {
|
||||||
@@ -339,6 +346,7 @@ func TestCancelInvoice(t *testing.T) {
|
|||||||
// TestSettleHoldInvoice tests settling of a hold invoice and related
|
// TestSettleHoldInvoice tests settling of a hold invoice and related
|
||||||
// notifications.
|
// notifications.
|
||||||
func TestSettleHoldInvoice(t *testing.T) {
|
func TestSettleHoldInvoice(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
defer timeout()()
|
defer timeout()()
|
||||||
|
|
||||||
idb, err := newTestChannelDB(t, clock.NewTestClock(time.Time{}))
|
idb, err := newTestChannelDB(t, clock.NewTestClock(time.Time{}))
|
||||||
@@ -379,7 +387,8 @@ func TestSettleHoldInvoice(t *testing.T) {
|
|||||||
require.Equal(t, subscription.PayHash(), &testInvoicePaymentHash)
|
require.Equal(t, subscription.PayHash(), &testInvoicePaymentHash)
|
||||||
|
|
||||||
// Add the invoice.
|
// Add the invoice.
|
||||||
_, err = registry.AddInvoice(testHodlInvoice, testInvoicePaymentHash)
|
invoice := newInvoice(t, true)
|
||||||
|
_, err = registry.AddInvoice(invoice, testInvoicePaymentHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -511,6 +520,7 @@ func TestSettleHoldInvoice(t *testing.T) {
|
|||||||
// TestCancelHoldInvoice tests canceling of a hold invoice and related
|
// TestCancelHoldInvoice tests canceling of a hold invoice and related
|
||||||
// notifications.
|
// notifications.
|
||||||
func TestCancelHoldInvoice(t *testing.T) {
|
func TestCancelHoldInvoice(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
defer timeout()()
|
defer timeout()()
|
||||||
|
|
||||||
testClock := clock.NewTestClock(testTime)
|
testClock := clock.NewTestClock(testTime)
|
||||||
@@ -536,7 +546,8 @@ func TestCancelHoldInvoice(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Add the invoice.
|
// Add the invoice.
|
||||||
_, err = registry.AddInvoice(testHodlInvoice, testInvoicePaymentHash)
|
invoice := newInvoice(t, true)
|
||||||
|
_, err = registry.AddInvoice(invoice, testInvoicePaymentHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@@ -590,6 +601,7 @@ func TestCancelHoldInvoice(t *testing.T) {
|
|||||||
// if we are the exit hop, but in htlcIncomingContestResolver it is called with
|
// if we are the exit hop, but in htlcIncomingContestResolver it is called with
|
||||||
// forwarded htlc hashes as well.
|
// forwarded htlc hashes as well.
|
||||||
func TestUnknownInvoice(t *testing.T) {
|
func TestUnknownInvoice(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
ctx := newTestContext(t, nil)
|
ctx := newTestContext(t, nil)
|
||||||
|
|
||||||
// Notify arrival of a new htlc paying to this invoice. This should
|
// Notify arrival of a new htlc paying to this invoice. This should
|
||||||
@@ -610,6 +622,8 @@ func TestUnknownInvoice(t *testing.T) {
|
|||||||
// TestKeySend tests receiving a spontaneous payment with and without keysend
|
// TestKeySend tests receiving a spontaneous payment with and without keysend
|
||||||
// enabled.
|
// enabled.
|
||||||
func TestKeySend(t *testing.T) {
|
func TestKeySend(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("enabled", func(t *testing.T) {
|
t.Run("enabled", func(t *testing.T) {
|
||||||
testKeySend(t, true)
|
testKeySend(t, true)
|
||||||
})
|
})
|
||||||
@@ -621,6 +635,7 @@ func TestKeySend(t *testing.T) {
|
|||||||
// testKeySend is the inner test function that tests keysend for a particular
|
// testKeySend is the inner test function that tests keysend for a particular
|
||||||
// enabled state on the receiver end.
|
// enabled state on the receiver end.
|
||||||
func testKeySend(t *testing.T, keySendEnabled bool) {
|
func testKeySend(t *testing.T, keySendEnabled bool) {
|
||||||
|
t.Parallel()
|
||||||
defer timeout()()
|
defer timeout()()
|
||||||
|
|
||||||
cfg := defaultRegistryConfig()
|
cfg := defaultRegistryConfig()
|
||||||
@@ -735,6 +750,8 @@ func testKeySend(t *testing.T, keySendEnabled bool) {
|
|||||||
|
|
||||||
// TestHoldKeysend tests receiving a spontaneous payment that is held.
|
// TestHoldKeysend tests receiving a spontaneous payment that is held.
|
||||||
func TestHoldKeysend(t *testing.T) {
|
func TestHoldKeysend(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("settle", func(t *testing.T) {
|
t.Run("settle", func(t *testing.T) {
|
||||||
testHoldKeysend(t, false)
|
testHoldKeysend(t, false)
|
||||||
})
|
})
|
||||||
@@ -745,6 +762,7 @@ func TestHoldKeysend(t *testing.T) {
|
|||||||
|
|
||||||
// testHoldKeysend is the inner test function that tests hold-keysend.
|
// testHoldKeysend is the inner test function that tests hold-keysend.
|
||||||
func testHoldKeysend(t *testing.T, timeoutKeysend bool) {
|
func testHoldKeysend(t *testing.T, timeoutKeysend bool) {
|
||||||
|
t.Parallel()
|
||||||
defer timeout()()
|
defer timeout()()
|
||||||
|
|
||||||
const holdDuration = time.Minute
|
const holdDuration = time.Minute
|
||||||
@@ -835,18 +853,20 @@ func testHoldKeysend(t *testing.T, timeoutKeysend bool) {
|
|||||||
// It covers the case where there is a mpp timeout before the whole invoice is
|
// It covers the case where there is a mpp timeout before the whole invoice is
|
||||||
// paid and the case where the invoice is settled in time.
|
// paid and the case where the invoice is settled in time.
|
||||||
func TestMppPayment(t *testing.T) {
|
func TestMppPayment(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
defer timeout()()
|
defer timeout()()
|
||||||
|
|
||||||
ctx := newTestContext(t, nil)
|
ctx := newTestContext(t, nil)
|
||||||
|
|
||||||
// Add the invoice.
|
// Add the invoice.
|
||||||
|
testInvoice := newInvoice(t, false)
|
||||||
_, err := ctx.registry.AddInvoice(testInvoice, testInvoicePaymentHash)
|
_, err := ctx.registry.AddInvoice(testInvoice, testInvoicePaymentHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mppPayload := &mockPayload{
|
mppPayload := &mockPayload{
|
||||||
mpp: record.NewMPP(testInvoiceAmt, [32]byte{}),
|
mpp: record.NewMPP(testInvoiceAmount, [32]byte{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send htlc 1.
|
// Send htlc 1.
|
||||||
@@ -936,16 +956,16 @@ func TestMppPaymentWithOverpayment(t *testing.T) {
|
|||||||
ctx := newTestContext(t, nil)
|
ctx := newTestContext(t, nil)
|
||||||
|
|
||||||
// Add the invoice.
|
// Add the invoice.
|
||||||
invoice := *testInvoice
|
testInvoice := newInvoice(t, false)
|
||||||
_, err := ctx.registry.AddInvoice(
|
_, err := ctx.registry.AddInvoice(
|
||||||
&invoice, testInvoicePaymentHash,
|
testInvoice, testInvoicePaymentHash,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mppPayload := &mockPayload{
|
mppPayload := &mockPayload{
|
||||||
mpp: record.NewMPP(testInvoiceAmt, [32]byte{}),
|
mpp: record.NewMPP(testInvoiceAmount, [32]byte{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
// We constrain overpayment amount to be [1,1000].
|
// We constrain overpayment amount to be [1,1000].
|
||||||
@@ -954,7 +974,7 @@ func TestMppPaymentWithOverpayment(t *testing.T) {
|
|||||||
// Send htlc 1.
|
// Send htlc 1.
|
||||||
hodlChan1 := make(chan interface{}, 1)
|
hodlChan1 := make(chan interface{}, 1)
|
||||||
resolution, err := ctx.registry.NotifyExitHopHtlc(
|
resolution, err := ctx.registry.NotifyExitHopHtlc(
|
||||||
testInvoicePaymentHash, invoice.Terms.Value/2,
|
testInvoicePaymentHash, testInvoice.Terms.Value/2,
|
||||||
testHtlcExpiry, testCurrentHeight, getCircuitKey(11),
|
testHtlcExpiry, testCurrentHeight, getCircuitKey(11),
|
||||||
hodlChan1, mppPayload,
|
hodlChan1, mppPayload,
|
||||||
)
|
)
|
||||||
@@ -969,7 +989,7 @@ func TestMppPaymentWithOverpayment(t *testing.T) {
|
|||||||
hodlChan2 := make(chan interface{}, 1)
|
hodlChan2 := make(chan interface{}, 1)
|
||||||
resolution, err = ctx.registry.NotifyExitHopHtlc(
|
resolution, err = ctx.registry.NotifyExitHopHtlc(
|
||||||
testInvoicePaymentHash,
|
testInvoicePaymentHash,
|
||||||
invoice.Terms.Value/2+overpayment, testHtlcExpiry,
|
testInvoice.Terms.Value/2+overpayment, testHtlcExpiry,
|
||||||
testCurrentHeight, getCircuitKey(12), hodlChan2,
|
testCurrentHeight, getCircuitKey(12), hodlChan2,
|
||||||
mppPayload,
|
mppPayload,
|
||||||
)
|
)
|
||||||
@@ -997,7 +1017,7 @@ func TestMppPaymentWithOverpayment(t *testing.T) {
|
|||||||
t.Fatal("expected invoice to be settled")
|
t.Fatal("expected invoice to be settled")
|
||||||
}
|
}
|
||||||
|
|
||||||
return inv.AmtPaid == invoice.Terms.Value+overpayment
|
return inv.AmtPaid == testInvoice.Terms.Value+overpayment
|
||||||
}
|
}
|
||||||
if err := quick.Check(f, nil); err != nil {
|
if err := quick.Check(f, nil); err != nil {
|
||||||
t.Fatalf("amount incorrect: %v", err)
|
t.Fatalf("amount incorrect: %v", err)
|
||||||
@@ -1195,6 +1215,8 @@ func TestOldInvoiceRemovalOnStart(t *testing.T) {
|
|||||||
// invoice is settled before expiry (and thus not canceled), and the case
|
// invoice is settled before expiry (and thus not canceled), and the case
|
||||||
// where the invoice is expired.
|
// where the invoice is expired.
|
||||||
func TestHeightExpiryWithRegistry(t *testing.T) {
|
func TestHeightExpiryWithRegistry(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("single shot settled before expiry", func(t *testing.T) {
|
t.Run("single shot settled before expiry", func(t *testing.T) {
|
||||||
testHeightExpiryWithRegistry(t, 1, true)
|
testHeightExpiryWithRegistry(t, 1, true)
|
||||||
})
|
})
|
||||||
@@ -1222,21 +1244,21 @@ func testHeightExpiryWithRegistry(t *testing.T, numParts int, settle bool) {
|
|||||||
|
|
||||||
// Add a hold invoice, we set a non-nil payment request so that this
|
// Add a hold invoice, we set a non-nil payment request so that this
|
||||||
// invoice is not considered a keysend by the expiry watcher.
|
// invoice is not considered a keysend by the expiry watcher.
|
||||||
invoice := *testInvoice
|
testInvoice := newInvoice(t, false)
|
||||||
invoice.HodlInvoice = true
|
testInvoice.HodlInvoice = true
|
||||||
invoice.PaymentRequest = []byte{1, 2, 3}
|
testInvoice.PaymentRequest = []byte{1, 2, 3}
|
||||||
|
|
||||||
_, err := ctx.registry.AddInvoice(&invoice, testInvoicePaymentHash)
|
_, err := ctx.registry.AddInvoice(testInvoice, testInvoicePaymentHash)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
payLoad := testPayload
|
payLoad := testPayload
|
||||||
if numParts > 1 {
|
if numParts > 1 {
|
||||||
payLoad = &mockPayload{
|
payLoad = &mockPayload{
|
||||||
mpp: record.NewMPP(testInvoiceAmt, [32]byte{}),
|
mpp: record.NewMPP(testInvoiceAmount, [32]byte{}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
htlcAmt := invoice.Terms.Value / lnwire.MilliSatoshi(numParts)
|
htlcAmt := testInvoice.Terms.Value / lnwire.MilliSatoshi(numParts)
|
||||||
hodlChan := make(chan interface{}, numParts)
|
hodlChan := make(chan interface{}, numParts)
|
||||||
for i := 0; i < numParts; i++ {
|
for i := 0; i < numParts; i++ {
|
||||||
// We bump our expiry height for each htlc so that we can test
|
// We bump our expiry height for each htlc so that we can test
|
||||||
@@ -1262,7 +1284,9 @@ func testHeightExpiryWithRegistry(t *testing.T, numParts int, settle bool) {
|
|||||||
// Now that we've added our htlc(s), we tick our test clock to our
|
// Now that we've added our htlc(s), we tick our test clock to our
|
||||||
// invoice expiry time. We don't expect the invoice to be canceled
|
// invoice expiry time. We don't expect the invoice to be canceled
|
||||||
// based on its expiry time now that we have active htlcs.
|
// based on its expiry time now that we have active htlcs.
|
||||||
ctx.clock.SetTime(invoice.CreationDate.Add(invoice.Terms.Expiry + 1))
|
ctx.clock.SetTime(
|
||||||
|
testInvoice.CreationDate.Add(testInvoice.Terms.Expiry + 1),
|
||||||
|
)
|
||||||
|
|
||||||
// The expiry watcher loop takes some time to process the new clock
|
// The expiry watcher loop takes some time to process the new clock
|
||||||
// time. We mine the block before our expiry height, our mock will block
|
// time. We mine the block before our expiry height, our mock will block
|
||||||
@@ -1326,20 +1350,19 @@ func TestMultipleSetHeightExpiry(t *testing.T) {
|
|||||||
ctx := newTestContext(t, nil)
|
ctx := newTestContext(t, nil)
|
||||||
|
|
||||||
// Add a hold invoice.
|
// Add a hold invoice.
|
||||||
invoice := *testInvoice
|
testInvoice := newInvoice(t, true)
|
||||||
invoice.HodlInvoice = true
|
|
||||||
|
|
||||||
_, err := ctx.registry.AddInvoice(&invoice, testInvoicePaymentHash)
|
_, err := ctx.registry.AddInvoice(testInvoice, testInvoicePaymentHash)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
mppPayload := &mockPayload{
|
mppPayload := &mockPayload{
|
||||||
mpp: record.NewMPP(testInvoiceAmt, [32]byte{}),
|
mpp: record.NewMPP(testInvoiceAmount, [32]byte{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send htlc 1.
|
// Send htlc 1.
|
||||||
hodlChan1 := make(chan interface{}, 1)
|
hodlChan1 := make(chan interface{}, 1)
|
||||||
resolution, err := ctx.registry.NotifyExitHopHtlc(
|
resolution, err := ctx.registry.NotifyExitHopHtlc(
|
||||||
testInvoicePaymentHash, invoice.Terms.Value/2,
|
testInvoicePaymentHash, testInvoice.Terms.Value/2,
|
||||||
testHtlcExpiry,
|
testHtlcExpiry,
|
||||||
testCurrentHeight, getCircuitKey(10), hodlChan1, mppPayload,
|
testCurrentHeight, getCircuitKey(10), hodlChan1, mppPayload,
|
||||||
)
|
)
|
||||||
@@ -1369,7 +1392,7 @@ func TestMultipleSetHeightExpiry(t *testing.T) {
|
|||||||
// Send htlc 2.
|
// Send htlc 2.
|
||||||
hodlChan2 := make(chan interface{}, 1)
|
hodlChan2 := make(chan interface{}, 1)
|
||||||
resolution, err = ctx.registry.NotifyExitHopHtlc(
|
resolution, err = ctx.registry.NotifyExitHopHtlc(
|
||||||
testInvoicePaymentHash, invoice.Terms.Value/2, expiry,
|
testInvoicePaymentHash, testInvoice.Terms.Value/2, expiry,
|
||||||
testCurrentHeight, getCircuitKey(11), hodlChan2, mppPayload,
|
testCurrentHeight, getCircuitKey(11), hodlChan2, mppPayload,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -1378,7 +1401,7 @@ func TestMultipleSetHeightExpiry(t *testing.T) {
|
|||||||
// Send htlc 3.
|
// Send htlc 3.
|
||||||
hodlChan3 := make(chan interface{}, 1)
|
hodlChan3 := make(chan interface{}, 1)
|
||||||
resolution, err = ctx.registry.NotifyExitHopHtlc(
|
resolution, err = ctx.registry.NotifyExitHopHtlc(
|
||||||
testInvoicePaymentHash, invoice.Terms.Value/2, expiry,
|
testInvoicePaymentHash, testInvoice.Terms.Value/2, expiry,
|
||||||
testCurrentHeight, getCircuitKey(12), hodlChan3, mppPayload,
|
testCurrentHeight, getCircuitKey(12), hodlChan3, mppPayload,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -1426,10 +1449,25 @@ func TestSettleInvoicePaymentAddrRequired(t *testing.T) {
|
|||||||
|
|
||||||
require.Equal(t, subscription.PayHash(), &testInvoicePaymentHash)
|
require.Equal(t, subscription.PayHash(), &testInvoicePaymentHash)
|
||||||
|
|
||||||
|
invoice := &invpkg.Invoice{
|
||||||
|
Terms: invpkg.ContractTerm{
|
||||||
|
PaymentPreimage: &testInvoicePreimage,
|
||||||
|
Value: testInvoiceAmount,
|
||||||
|
Expiry: time.Hour,
|
||||||
|
Features: lnwire.NewFeatureVector(
|
||||||
|
lnwire.NewRawFeatureVector(
|
||||||
|
lnwire.TLVOnionPayloadOptional,
|
||||||
|
lnwire.PaymentAddrRequired,
|
||||||
|
),
|
||||||
|
lnwire.Features,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
CreationDate: testInvoiceCreationDate,
|
||||||
|
}
|
||||||
// Add the invoice, which requires the MPP payload to always be
|
// Add the invoice, which requires the MPP payload to always be
|
||||||
// included due to its set of feature bits.
|
// included due to its set of feature bits.
|
||||||
addIdx, err := ctx.registry.AddInvoice(
|
addIdx, err := ctx.registry.AddInvoice(
|
||||||
testPayAddrReqInvoice, testInvoicePaymentHash,
|
invoice, testInvoicePaymentHash,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, int(addIdx), 1)
|
require.Equal(t, int(addIdx), 1)
|
||||||
@@ -1462,7 +1500,7 @@ func TestSettleInvoicePaymentAddrRequired(t *testing.T) {
|
|||||||
// information, so it should be forced to the updateLegacy path then
|
// information, so it should be forced to the updateLegacy path then
|
||||||
// fail as a required feature bit exists.
|
// fail as a required feature bit exists.
|
||||||
resolution, err := ctx.registry.NotifyExitHopHtlc(
|
resolution, err := ctx.registry.NotifyExitHopHtlc(
|
||||||
testInvoicePaymentHash, testInvoice.Terms.Value,
|
testInvoicePaymentHash, invoice.Terms.Value,
|
||||||
uint32(testCurrentHeight)+testInvoiceCltvDelta-1,
|
uint32(testCurrentHeight)+testInvoiceCltvDelta-1,
|
||||||
testCurrentHeight, getCircuitKey(10), hodlChan, testPayload,
|
testCurrentHeight, getCircuitKey(10), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
@@ -1499,10 +1537,26 @@ func TestSettleInvoicePaymentAddrRequiredOptionalGrace(t *testing.T) {
|
|||||||
|
|
||||||
require.Equal(t, subscription.PayHash(), &testInvoicePaymentHash)
|
require.Equal(t, subscription.PayHash(), &testInvoicePaymentHash)
|
||||||
|
|
||||||
// Add the invoice, which requires the MPP payload to always be
|
invoice := &invpkg.Invoice{
|
||||||
|
Terms: invpkg.ContractTerm{
|
||||||
|
PaymentPreimage: &testInvoicePreimage,
|
||||||
|
Value: testInvoiceAmount,
|
||||||
|
Expiry: time.Hour,
|
||||||
|
Features: lnwire.NewFeatureVector(
|
||||||
|
lnwire.NewRawFeatureVector(
|
||||||
|
lnwire.TLVOnionPayloadOptional,
|
||||||
|
lnwire.PaymentAddrOptional,
|
||||||
|
),
|
||||||
|
lnwire.Features,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
CreationDate: testInvoiceCreationDate,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the invoice, which does not require the MPP payload to always be
|
||||||
// included due to its set of feature bits.
|
// included due to its set of feature bits.
|
||||||
addIdx, err := ctx.registry.AddInvoice(
|
addIdx, err := ctx.registry.AddInvoice(
|
||||||
testPayAddrOptionalInvoice, testInvoicePaymentHash,
|
invoice, testInvoicePaymentHash,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, int(addIdx), 1)
|
require.Equal(t, int(addIdx), 1)
|
||||||
@@ -1534,7 +1588,7 @@ func TestSettleInvoicePaymentAddrRequiredOptionalGrace(t *testing.T) {
|
|||||||
// no problem as we should allow these existing invoices to be settled.
|
// no problem as we should allow these existing invoices to be settled.
|
||||||
hodlChan := make(chan interface{}, 1)
|
hodlChan := make(chan interface{}, 1)
|
||||||
resolution, err := ctx.registry.NotifyExitHopHtlc(
|
resolution, err := ctx.registry.NotifyExitHopHtlc(
|
||||||
testInvoicePaymentHash, testInvoiceAmt,
|
testInvoicePaymentHash, testInvoiceAmount,
|
||||||
testHtlcExpiry, testCurrentHeight,
|
testHtlcExpiry, testCurrentHeight,
|
||||||
getCircuitKey(10), hodlChan, testPayload,
|
getCircuitKey(10), hodlChan, testPayload,
|
||||||
)
|
)
|
||||||
@@ -1555,7 +1609,7 @@ func TestSettleInvoicePaymentAddrRequiredOptionalGrace(t *testing.T) {
|
|||||||
t.Fatalf("expected state ContractOpen, but got %v",
|
t.Fatalf("expected state ContractOpen, but got %v",
|
||||||
update.State)
|
update.State)
|
||||||
}
|
}
|
||||||
if update.AmtPaid != testInvoice.Terms.Value {
|
if update.AmtPaid != invoice.Terms.Value {
|
||||||
t.Fatal("invoice AmtPaid incorrect")
|
t.Fatal("invoice AmtPaid incorrect")
|
||||||
}
|
}
|
||||||
case <-time.After(testTimeout):
|
case <-time.After(testTimeout):
|
||||||
@@ -1577,6 +1631,7 @@ func TestSettleInvoicePaymentAddrRequiredOptionalGrace(t *testing.T) {
|
|||||||
// TestAMPWithoutMPPPayload asserts that we correctly reject an AMP HTLC that
|
// TestAMPWithoutMPPPayload asserts that we correctly reject an AMP HTLC that
|
||||||
// does not include an MPP record.
|
// does not include an MPP record.
|
||||||
func TestAMPWithoutMPPPayload(t *testing.T) {
|
func TestAMPWithoutMPPPayload(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
defer timeout()()
|
defer timeout()()
|
||||||
|
|
||||||
cfg := defaultRegistryConfig()
|
cfg := defaultRegistryConfig()
|
||||||
@@ -1609,6 +1664,8 @@ func TestAMPWithoutMPPPayload(t *testing.T) {
|
|||||||
// TestSpontaneousAmpPayment tests receiving a spontaneous AMP payment with both
|
// TestSpontaneousAmpPayment tests receiving a spontaneous AMP payment with both
|
||||||
// valid and invalid reconstructions.
|
// valid and invalid reconstructions.
|
||||||
func TestSpontaneousAmpPayment(t *testing.T) {
|
func TestSpontaneousAmpPayment(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
ampEnabled bool
|
ampEnabled bool
|
||||||
@@ -1662,6 +1719,7 @@ func TestSpontaneousAmpPayment(t *testing.T) {
|
|||||||
func testSpontaneousAmpPayment(
|
func testSpontaneousAmpPayment(
|
||||||
t *testing.T, ampEnabled, failReconstruction bool, numShards int) {
|
t *testing.T, ampEnabled, failReconstruction bool, numShards int) {
|
||||||
|
|
||||||
|
t.Parallel()
|
||||||
defer timeout()()
|
defer timeout()()
|
||||||
|
|
||||||
cfg := defaultRegistryConfig()
|
cfg := defaultRegistryConfig()
|
||||||
|
|||||||
+71
-91
@@ -131,61 +131,6 @@ var (
|
|||||||
testInvoiceCreationDate = testTime
|
testInvoiceCreationDate = testTime
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
testInvoiceAmt = lnwire.MilliSatoshi(100000)
|
|
||||||
testInvoice = &invpkg.Invoice{
|
|
||||||
Terms: invpkg.ContractTerm{
|
|
||||||
PaymentPreimage: &testInvoicePreimage,
|
|
||||||
Value: testInvoiceAmt,
|
|
||||||
Expiry: time.Hour,
|
|
||||||
Features: testFeatures,
|
|
||||||
},
|
|
||||||
CreationDate: testInvoiceCreationDate,
|
|
||||||
}
|
|
||||||
|
|
||||||
testPayAddrReqInvoice = &invpkg.Invoice{
|
|
||||||
Terms: invpkg.ContractTerm{
|
|
||||||
PaymentPreimage: &testInvoicePreimage,
|
|
||||||
Value: testInvoiceAmt,
|
|
||||||
Expiry: time.Hour,
|
|
||||||
Features: lnwire.NewFeatureVector(
|
|
||||||
lnwire.NewRawFeatureVector(
|
|
||||||
lnwire.TLVOnionPayloadOptional,
|
|
||||||
lnwire.PaymentAddrRequired,
|
|
||||||
),
|
|
||||||
lnwire.Features,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
CreationDate: testInvoiceCreationDate,
|
|
||||||
}
|
|
||||||
|
|
||||||
testPayAddrOptionalInvoice = &invpkg.Invoice{
|
|
||||||
Terms: invpkg.ContractTerm{
|
|
||||||
PaymentPreimage: &testInvoicePreimage,
|
|
||||||
Value: testInvoiceAmt,
|
|
||||||
Expiry: time.Hour,
|
|
||||||
Features: lnwire.NewFeatureVector(
|
|
||||||
lnwire.NewRawFeatureVector(
|
|
||||||
lnwire.TLVOnionPayloadOptional,
|
|
||||||
lnwire.PaymentAddrOptional,
|
|
||||||
),
|
|
||||||
lnwire.Features,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
CreationDate: testInvoiceCreationDate,
|
|
||||||
}
|
|
||||||
|
|
||||||
testHodlInvoice = &invpkg.Invoice{
|
|
||||||
Terms: invpkg.ContractTerm{
|
|
||||||
Value: testInvoiceAmt,
|
|
||||||
Expiry: time.Hour,
|
|
||||||
Features: testFeatures,
|
|
||||||
},
|
|
||||||
CreationDate: testInvoiceCreationDate,
|
|
||||||
HodlInvoice: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func newTestChannelDB(t *testing.T, clock clock.Clock) (*channeldb.DB, error) {
|
func newTestChannelDB(t *testing.T, clock clock.Clock) (*channeldb.DB, error) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
@@ -275,44 +220,35 @@ func getCircuitKey(htlcID uint64) invpkg.CircuitKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestInvoice(t *testing.T, preimage lntypes.Preimage,
|
// newInvoice returns an invoice that can be used for testing, using the
|
||||||
timestamp time.Time, expiry time.Duration) *invpkg.Invoice {
|
// constant values defined above (deep copied if necessary).
|
||||||
|
//
|
||||||
if expiry == 0 {
|
// Note that this invoice *does not* have a payment address set. It will
|
||||||
expiry = time.Hour
|
// create a regular invoice with a preimage is hodl is false, and a hodl
|
||||||
}
|
// invoice with no preimage otherwise.
|
||||||
|
func newInvoice(t *testing.T, hodl bool) *invpkg.Invoice {
|
||||||
var payAddr [32]byte
|
invoice := &invpkg.Invoice{
|
||||||
if _, err := rand.Read(payAddr[:]); err != nil {
|
|
||||||
t.Fatalf("unable to generate payment addr: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rawInvoice, err := zpay32.NewInvoice(
|
|
||||||
testNetParams,
|
|
||||||
preimage.Hash(),
|
|
||||||
timestamp,
|
|
||||||
zpay32.Amount(testInvoiceAmount),
|
|
||||||
zpay32.Description(testInvoiceDescription),
|
|
||||||
zpay32.Expiry(expiry),
|
|
||||||
zpay32.PaymentAddr(payAddr),
|
|
||||||
)
|
|
||||||
require.NoError(t, err, "Error while creating new invoice")
|
|
||||||
|
|
||||||
paymentRequest, err := rawInvoice.Encode(testMessageSigner)
|
|
||||||
|
|
||||||
require.NoError(t, err, "Error while encoding payment request")
|
|
||||||
|
|
||||||
return &invpkg.Invoice{
|
|
||||||
Terms: invpkg.ContractTerm{
|
Terms: invpkg.ContractTerm{
|
||||||
PaymentPreimage: &preimage,
|
|
||||||
PaymentAddr: payAddr,
|
|
||||||
Value: testInvoiceAmount,
|
Value: testInvoiceAmount,
|
||||||
Expiry: expiry,
|
Expiry: time.Hour,
|
||||||
Features: testFeatures,
|
Features: testFeatures.Clone(),
|
||||||
},
|
},
|
||||||
PaymentRequest: []byte(paymentRequest),
|
CreationDate: testInvoiceCreationDate,
|
||||||
CreationDate: timestamp,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If creating a hodl invoice, we don't include a preimage.
|
||||||
|
if hodl {
|
||||||
|
invoice.HodlInvoice = true
|
||||||
|
return invoice
|
||||||
|
}
|
||||||
|
|
||||||
|
preimage, err := lntypes.MakePreimage(
|
||||||
|
testInvoicePreimage[:],
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
invoice.Terms.PaymentPreimage = &preimage
|
||||||
|
|
||||||
|
return invoice
|
||||||
}
|
}
|
||||||
|
|
||||||
// timeout implements a test level timeout.
|
// timeout implements a test level timeout.
|
||||||
@@ -360,7 +296,7 @@ func generateInvoiceExpiryTestData(
|
|||||||
var preimage lntypes.Preimage
|
var preimage lntypes.Preimage
|
||||||
binary.BigEndian.PutUint32(preimage[:4], uint32(offset+i))
|
binary.BigEndian.PutUint32(preimage[:4], uint32(offset+i))
|
||||||
expiry := time.Duration((i+offset)%24) * time.Hour
|
expiry := time.Duration((i+offset)%24) * time.Hour
|
||||||
invoice := newTestInvoice(
|
invoice := newInvoiceExpiryTestInvoice(
|
||||||
t, preimage, expiredCreationDate, expiry,
|
t, preimage, expiredCreationDate, expiry,
|
||||||
)
|
)
|
||||||
testData.expiredInvoices[preimage.Hash()] = invoice
|
testData.expiredInvoices[preimage.Hash()] = invoice
|
||||||
@@ -370,13 +306,57 @@ func generateInvoiceExpiryTestData(
|
|||||||
var preimage lntypes.Preimage
|
var preimage lntypes.Preimage
|
||||||
binary.BigEndian.PutUint32(preimage[4:], uint32(offset+i))
|
binary.BigEndian.PutUint32(preimage[4:], uint32(offset+i))
|
||||||
expiry := time.Duration((i+offset)%24) * time.Hour
|
expiry := time.Duration((i+offset)%24) * time.Hour
|
||||||
invoice := newTestInvoice(t, preimage, now, expiry)
|
invoice := newInvoiceExpiryTestInvoice(t, preimage, now, expiry)
|
||||||
testData.pendingInvoices[preimage.Hash()] = invoice
|
testData.pendingInvoices[preimage.Hash()] = invoice
|
||||||
}
|
}
|
||||||
|
|
||||||
return testData
|
return testData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// newInvoiceExpiryTestInvoice creates a test invoice with a randomly generated
|
||||||
|
// payment address and custom preimage and expiry details. It should be used in
|
||||||
|
// the case where tests require custom invoice expiry and unique payment
|
||||||
|
// hashes.
|
||||||
|
func newInvoiceExpiryTestInvoice(t *testing.T, preimage lntypes.Preimage,
|
||||||
|
timestamp time.Time, expiry time.Duration) *invpkg.Invoice {
|
||||||
|
|
||||||
|
if expiry == 0 {
|
||||||
|
expiry = time.Hour
|
||||||
|
}
|
||||||
|
|
||||||
|
var payAddr [32]byte
|
||||||
|
if _, err := rand.Read(payAddr[:]); err != nil {
|
||||||
|
t.Fatalf("unable to generate payment addr: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rawInvoice, err := zpay32.NewInvoice(
|
||||||
|
testNetParams,
|
||||||
|
preimage.Hash(),
|
||||||
|
timestamp,
|
||||||
|
zpay32.Amount(testInvoiceAmount),
|
||||||
|
zpay32.Description(testInvoiceDescription),
|
||||||
|
zpay32.Expiry(expiry),
|
||||||
|
zpay32.PaymentAddr(payAddr),
|
||||||
|
)
|
||||||
|
require.NoError(t, err, "Error while creating new invoice")
|
||||||
|
|
||||||
|
paymentRequest, err := rawInvoice.Encode(testMessageSigner)
|
||||||
|
|
||||||
|
require.NoError(t, err, "Error while encoding payment request")
|
||||||
|
|
||||||
|
return &invpkg.Invoice{
|
||||||
|
Terms: invpkg.ContractTerm{
|
||||||
|
PaymentPreimage: &preimage,
|
||||||
|
PaymentAddr: payAddr,
|
||||||
|
Value: testInvoiceAmount,
|
||||||
|
Expiry: expiry,
|
||||||
|
Features: testFeatures,
|
||||||
|
},
|
||||||
|
PaymentRequest: []byte(paymentRequest),
|
||||||
|
CreationDate: timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// checkSettleResolution asserts the resolution is a settle with the correct
|
// checkSettleResolution asserts the resolution is a settle with the correct
|
||||||
// preimage. If successful, the HtlcSettleResolution is returned in case further
|
// preimage. If successful, the HtlcSettleResolution is returned in case further
|
||||||
// checks are desired.
|
// checks are desired.
|
||||||
|
|||||||
Reference in new issue
Block a user