itest/test: test hold invoice cancel before force close

This commit is contained in:
carla 2021-05-11 08:45:31 +02:00
parent 85e56dbfb7
commit b7d1ed0cbb
No known key found for this signature in database
GPG Key ID: 4CA7FE54A6213C91

@ -14,9 +14,8 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
// testHoldInvoiceForceClose demonstrates that recipients of hold invoices // testHoldInvoiceForceClose tests cancelation of accepted hold invoices which
// will not release active htlcs for their own invoices when they expire, // would otherwise trigger force closes when they expire.
// resulting in a force close of their channel.
func testHoldInvoiceForceClose(net *lntest.NetworkHarness, t *harnessTest) { func testHoldInvoiceForceClose(net *lntest.NetworkHarness, t *harnessTest) {
ctxb, cancel := context.WithCancel(context.Background()) ctxb, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
@ -94,38 +93,43 @@ func testHoldInvoiceForceClose(net *lntest.NetworkHarness, t *harnessTest) {
require.NoError(t.t, net.Alice.WaitForBlockchainSync(ctxb)) require.NoError(t.t, net.Alice.WaitForBlockchainSync(ctxb))
require.NoError(t.t, net.Bob.WaitForBlockchainSync(ctxb)) require.NoError(t.t, net.Bob.WaitForBlockchainSync(ctxb))
// Alice should have a waiting-close channel because she has force // Our channel should not have been force closed, instead we expect our
// closed to time out the htlc. // channel to still be open and our invoice to have been canceled before
assertNumPendingChannels(t, net.Alice, 1, 0) // expiry.
// We should have our force close tx in the mempool.
mineBlocks(t, net, 1, 1)
// Ensure alice and bob are synced to chain after we've mined our force
// close.
require.NoError(t.t, net.Alice.WaitForBlockchainSync(ctxb))
require.NoError(t.t, net.Bob.WaitForBlockchainSync(ctxb))
// At this point, Bob's channel should be resolved because his htlc is
// expired, so no further action is required. Alice will still have a
// pending force close channel because she needs to resolve the htlc.
assertNumPendingChannels(t, net.Alice, 0, 1)
assertNumPendingChannels(t, net.Bob, 0, 0)
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout) ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
err = waitForNumChannelPendingForceClose(ctxt, net.Alice, 1, chanInfo, err := getChanInfo(ctxt, net.Alice)
func(channel *lnrpcForceCloseChannel) error { require.NoError(t.t, err)
numHtlcs := len(channel.PendingHtlcs)
if numHtlcs != 1 { fundingTxID, err := lnrpc.GetChanPointFundingTxid(chanPoint)
return fmt.Errorf("expected 1 htlc, got: "+ require.NoError(t.t, err)
"%v", numHtlcs) chanStr := fmt.Sprintf("%v:%v", fundingTxID, chanPoint.OutputIndex)
require.Equal(t.t, chanStr, chanInfo.ChannelPoint)
err = wait.NoError(func() error {
inv, err := net.Bob.LookupInvoice(ctxt, &lnrpc.PaymentHash{
RHash: payHash[:],
})
if err != nil {
return err
}
if inv.State != lnrpc.Invoice_CANCELED {
return fmt.Errorf("expected canceled invoice, got: %v",
inv.State)
}
for _, htlc := range inv.Htlcs {
if htlc.State != lnrpc.InvoiceHTLCState_CANCELED {
return fmt.Errorf("expected htlc canceled, "+
"got: %v", htlc.State)
}
} }
return nil return nil
}, }, defaultTimeout)
) require.NoError(t.t, err, "expected canceled invoice")
require.NoError(t.t, err)
// Cleanup Alice's force close. // Clean up the channel.
cleanupForceClose(t, net, net.Alice, chanPoint) ctxt, _ = context.WithTimeout(ctxb, channelCloseTimeout)
closeChannelAndAssert(ctxt, t, net, net.Alice, chanPoint, false)
} }