|
|
|
@ -6,6 +6,7 @@ import (
|
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
"github.com/lightningnetwork/lnd/chainntnfs" |
|
|
|
|
"github.com/lightningnetwork/lnd/channeldb" |
|
|
|
|
"github.com/lightningnetwork/lnd/clock" |
|
|
|
|
"github.com/lightningnetwork/lnd/lntypes" |
|
|
|
|
) |
|
|
|
@ -203,3 +204,115 @@ func TestInvoiceExpiryWhenAddingMultipleInvoices(t *testing.T) {
|
|
|
|
|
test.watcher.Stop() |
|
|
|
|
test.checkExpectations() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TestExpiredHodlInv tests expiration of an already-expired hodl invoice
|
|
|
|
|
// which has no htlcs.
|
|
|
|
|
func TestExpiredHodlInv(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
creationDate := testTime.Add(time.Hour * -24) |
|
|
|
|
expiry := time.Hour |
|
|
|
|
|
|
|
|
|
test := setupHodlExpiry( |
|
|
|
|
t, creationDate, expiry, 0, channeldb.ContractOpen, nil, |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
test.assertCanceled(t, test.hash) |
|
|
|
|
test.watcher.Stop() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TestAcceptedHodlNotExpired tests that hodl invoices which are in an accepted
|
|
|
|
|
// state are not expired once their time-based expiry elapses, using a regular
|
|
|
|
|
// invoice that expires at the same time as a control to ensure that invoices
|
|
|
|
|
// with that timestamp would otherwise be expired.
|
|
|
|
|
func TestAcceptedHodlNotExpired(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
creationDate := testTime |
|
|
|
|
expiry := time.Hour |
|
|
|
|
|
|
|
|
|
test := setupHodlExpiry( |
|
|
|
|
t, creationDate, expiry, 0, channeldb.ContractAccepted, nil, |
|
|
|
|
) |
|
|
|
|
defer test.watcher.Stop() |
|
|
|
|
|
|
|
|
|
// Add another invoice that will expire at our expiry time as a control
|
|
|
|
|
// value.
|
|
|
|
|
tsExpires := &invoiceExpiryTs{ |
|
|
|
|
PaymentHash: lntypes.Hash{1, 2, 3}, |
|
|
|
|
Expiry: creationDate.Add(expiry), |
|
|
|
|
Keysend: true, |
|
|
|
|
} |
|
|
|
|
test.watcher.AddInvoices(tsExpires) |
|
|
|
|
|
|
|
|
|
test.mockClock.SetTime(creationDate.Add(expiry + 1)) |
|
|
|
|
|
|
|
|
|
// Assert that only the ts expiry invoice is expired.
|
|
|
|
|
test.assertCanceled(t, tsExpires.PaymentHash) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TestHeightAlreadyExpired tests the case where we add an invoice with htlcs
|
|
|
|
|
// that have already expired to the expiry watcher.
|
|
|
|
|
func TestHeightAlreadyExpired(t *testing.T) { |
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
|
|
expiredHtlc := []*channeldb.InvoiceHTLC{ |
|
|
|
|
{ |
|
|
|
|
State: channeldb.HtlcStateAccepted, |
|
|
|
|
Expiry: uint32(testCurrentHeight), |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
test := setupHodlExpiry( |
|
|
|
|
t, testTime, time.Hour, 0, channeldb.ContractAccepted, |
|
|
|
|
expiredHtlc, |
|
|
|
|
) |
|
|
|
|
defer test.watcher.Stop() |
|
|
|
|
|
|
|
|
|
test.assertCanceled(t, test.hash) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TestExpiryHeightArrives tests the case where we add a hodl invoice to the
|
|
|
|
|
// expiry watcher when it has no htlcs, htlcs are added and then they finally
|
|
|
|
|
// expire. We use a non-zero delta for this test to check that we expire with
|
|
|
|
|
// sufficient buffer.
|
|
|
|
|
func TestExpiryHeightArrives(t *testing.T) { |
|
|
|
|
var ( |
|
|
|
|
creationDate = testTime |
|
|
|
|
expiry = time.Hour * 2 |
|
|
|
|
delta uint32 = 1 |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// Start out with a hodl invoice that is open, and has no htlcs.
|
|
|
|
|
test := setupHodlExpiry( |
|
|
|
|
t, creationDate, expiry, delta, channeldb.ContractOpen, nil, |
|
|
|
|
) |
|
|
|
|
defer test.watcher.Stop() |
|
|
|
|
|
|
|
|
|
htlc1 := uint32(testCurrentHeight + 10) |
|
|
|
|
expiry1 := makeHeightExpiry(test.hash, htlc1) |
|
|
|
|
|
|
|
|
|
// Add htlcs to our invoice and progress its state to accepted.
|
|
|
|
|
test.watcher.AddInvoices(expiry1) |
|
|
|
|
test.setState(channeldb.ContractAccepted) |
|
|
|
|
|
|
|
|
|
// Progress time so that our expiry has elapsed. We no longer expect
|
|
|
|
|
// this invoice to be canceled because it has been accepted.
|
|
|
|
|
test.mockClock.SetTime(creationDate.Add(expiry)) |
|
|
|
|
|
|
|
|
|
// Tick our mock block subscription with the next block, we don't
|
|
|
|
|
// expect anything to happen.
|
|
|
|
|
currentHeight := uint32(testCurrentHeight + 1) |
|
|
|
|
test.announceBlock(t, currentHeight) |
|
|
|
|
|
|
|
|
|
// Now, we add another htlc to the invoice. This one has a lower expiry
|
|
|
|
|
// height than our current ones.
|
|
|
|
|
htlc2 := currentHeight + 5 |
|
|
|
|
expiry2 := makeHeightExpiry(test.hash, htlc2) |
|
|
|
|
test.watcher.AddInvoices(expiry2) |
|
|
|
|
|
|
|
|
|
// Announce our lowest htlc expiry block minus our delta, the invoice
|
|
|
|
|
// should be expired now.
|
|
|
|
|
test.announceBlock(t, htlc2-delta) |
|
|
|
|
test.assertCanceled(t, test.hash) |
|
|
|
|
} |
|
|
|
|