Skip to content

Commit 71eb88b

Browse files
authored
Merge pull request #396 from carlaKC/subscribesingle-eof
loopin: handle SubscribeSingleInvoice termination
2 parents 087066b + 0e72c2b commit 71eb88b

File tree

5 files changed

+65
-33
lines changed

5 files changed

+65
-33
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ require (
1111
github.com/grpc-ecosystem/grpc-gateway v1.14.3
1212
github.com/jessevdk/go-flags v1.4.0
1313
github.com/lightninglabs/aperture v0.1.6-beta
14-
github.com/lightninglabs/lndclient v0.11.1-6
14+
github.com/lightninglabs/lndclient v0.11.1-9
1515
github.com/lightninglabs/protobuf-hex-display v1.4.3-hex-display
1616
github.com/lightningnetwork/lnd v0.13.0-beta.rc2
1717
github.com/lightningnetwork/lnd/cert v1.0.3

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,8 @@ github.com/lightninglabs/aperture v0.1.6-beta/go.mod h1:9xl4mx778ZAzrB87nLHMqk+X
230230
github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf h1:HZKvJUHlcXI/f/O0Avg7t8sqkPo78HFzjmeYFl6DPnc=
231231
github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf/go.mod h1:vxmQPeIQxPf6Jf9rM8R+B4rKBqLA2AjttNxkFBL2Plk=
232232
github.com/lightninglabs/lndclient v0.11.0-4/go.mod h1:8/cTKNwgL87NX123gmlv3Xh6p1a7pvzu+40Un3PhHiI=
233-
github.com/lightninglabs/lndclient v0.11.1-6 h1:2L+0GIjAShSWsxEsRQ/ZbK+62SF4DBiCpnWBx8HSwyA=
234-
github.com/lightninglabs/lndclient v0.11.1-6/go.mod h1:qVFcrIXxsagpu3RC0SSSdVEs3QVxuv5YiHUYwDauUnc=
233+
github.com/lightninglabs/lndclient v0.11.1-9 h1:KTrCkOnqqP1gCsou0D7k7TOOC7HLboKDS35YREN7a3s=
234+
github.com/lightninglabs/lndclient v0.11.1-9/go.mod h1:qVFcrIXxsagpu3RC0SSSdVEs3QVxuv5YiHUYwDauUnc=
235235
github.com/lightninglabs/neutrino v0.11.0/go.mod h1:CuhF0iuzg9Sp2HO6ZgXgayviFTn1QHdSTJlMncK80wg=
236236
github.com/lightninglabs/neutrino v0.11.1-0.20200316235139-bffc52e8f200/go.mod h1:MlZmoKa7CJP3eR1s5yB7Rm5aSyadpKkxqAwLQmog7N0=
237237
github.com/lightninglabs/neutrino v0.12.1 h1:9umzk5kKNc/l3bAyak8ClSRP1qSulnjc6kppLYDnuqk=

loopin.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -779,12 +779,30 @@ func (s *loopInSwap) waitForSwapComplete(ctx context.Context,
779779
htlcSpend = true
780780

781781
// Swap invoice ntfn error.
782-
case err := <-swapInvoiceErr:
782+
case err, ok := <-swapInvoiceErr:
783+
// If the channel has been closed, the server has
784+
// finished sending updates, so we set the channel to
785+
// nil because we don't want to constantly select this
786+
// case.
787+
if !ok {
788+
swapInvoiceErr = nil
789+
continue
790+
}
791+
783792
return err
784793

785794
// An update to the swap invoice occurred. Check the new state
786795
// and update the swap state accordingly.
787-
case update := <-swapInvoiceChan:
796+
case update, ok := <-swapInvoiceChan:
797+
// If the channel has been closed, the server has
798+
// finished sending updates, so we set the channel to
799+
// nil because we don't want to constantly select this
800+
// case.
801+
if !ok {
802+
swapInvoiceChan = nil
803+
continue
804+
}
805+
788806
s.log.Infof("Received swap invoice update: %v",
789807
update.State)
790808

loopin_test.go

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"testing"
66

7-
"github.com/lightninglabs/lndclient"
87
"github.com/lightninglabs/loop/loopdb"
98
"github.com/lightninglabs/loop/swap"
109
"github.com/lightninglabs/loop/test"
@@ -89,17 +88,11 @@ func TestLoopInSuccess(t *testing.T) {
8988
<-ctx.lnd.RegisterSpendChannel
9089

9190
// Client starts listening for swap invoice updates.
92-
subscription := <-ctx.lnd.SingleInvoiceSubcribeChannel
93-
if subscription.Hash != ctx.server.swapHash {
94-
t.Fatal("client subscribing to wrong invoice")
95-
}
91+
ctx.assertSubscribeInvoice(ctx.server.swapHash)
9692

9793
// Server has already paid invoice before spending the htlc. Signal
9894
// settled.
99-
subscription.Update <- lndclient.InvoiceUpdate{
100-
State: channeldb.ContractSettled,
101-
AmtPaid: 49000,
102-
}
95+
ctx.updateInvoiceState(49000, channeldb.ContractSettled)
10396

10497
// Swap is expected to move to the state InvoiceSettled
10598
ctx.assertState(loopdb.StateInvoiceSettled)
@@ -257,10 +250,7 @@ func testLoopInTimeout(t *testing.T,
257250
<-ctx.lnd.RegisterSpendChannel
258251

259252
// Client starts listening for swap invoice updates.
260-
subscription := <-ctx.lnd.SingleInvoiceSubcribeChannel
261-
if subscription.Hash != ctx.server.swapHash {
262-
t.Fatal("client subscribing to wrong invoice")
263-
}
253+
ctx.assertSubscribeInvoice(ctx.server.swapHash)
264254

265255
// Let htlc expire.
266256
ctx.blockEpochChan <- s.LoopInContract.CltvExpiry
@@ -294,10 +284,8 @@ func testLoopInTimeout(t *testing.T,
294284
// safely cancel the swap invoice.
295285
<-ctx.lnd.FailInvoiceChannel
296286

297-
// Signal the the invoice was canceled.
298-
subscription.Update <- lndclient.InvoiceUpdate{
299-
State: channeldb.ContractCanceled,
300-
}
287+
// Signal that the invoice was canceled.
288+
ctx.updateInvoiceState(0, channeldb.ContractCanceled)
301289

302290
ctx.assertState(loopdb.StateFailTimeout)
303291
state := ctx.store.assertLoopInState(loopdb.StateFailTimeout)
@@ -501,18 +489,12 @@ func testLoopInResume(t *testing.T, state loopdb.SwapState, expired bool,
501489
<-ctx.lnd.RegisterSpendChannel
502490

503491
// Client starts listening for swap invoice updates.
504-
subscription := <-ctx.lnd.SingleInvoiceSubcribeChannel
505-
if subscription.Hash != testPreimage.Hash() {
506-
t.Fatal("client subscribing to wrong invoice")
507-
}
492+
ctx.assertSubscribeInvoice(testPreimage.Hash())
508493

509494
// Server has already paid invoice before spending the htlc. Signal
510495
// settled.
511-
invoiceUpdate := lndclient.InvoiceUpdate{
512-
State: channeldb.ContractSettled,
513-
AmtPaid: 49000,
514-
}
515-
subscription.Update <- invoiceUpdate
496+
amtPaid := btcutil.Amount(49000)
497+
ctx.updateInvoiceState(amtPaid, channeldb.ContractSettled)
516498

517499
// Swap is expected to move to the state InvoiceSettled
518500
ctx.assertState(loopdb.StateInvoiceSettled)
@@ -537,7 +519,6 @@ func testLoopInResume(t *testing.T, state loopdb.SwapState, expired bool,
537519
// We expect our server fee to reflect as the difference between htlc
538520
// value and invoice amount paid. We use our original on-chain cost, set
539521
// earlier in the test, because we expect this value to be unchanged.
540-
cost.Server = btcutil.Amount(htlcTx.TxOut[0].Value) -
541-
invoiceUpdate.AmtPaid
522+
cost.Server = btcutil.Amount(htlcTx.TxOut[0].Value) - amtPaid
542523
require.Equal(t, cost, finalState.Cost)
543524
}

loopin_testcontext_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@ import (
44
"testing"
55
"time"
66

7+
"github.com/btcsuite/btcutil"
8+
"github.com/lightninglabs/lndclient"
79
"github.com/lightninglabs/loop/loopdb"
810
"github.com/lightninglabs/loop/sweep"
911
"github.com/lightninglabs/loop/test"
12+
"github.com/lightningnetwork/lnd/channeldb"
13+
"github.com/lightningnetwork/lnd/lntypes"
14+
"github.com/stretchr/testify/require"
1015
)
1116

1217
type loopInTestContext struct {
@@ -18,6 +23,8 @@ type loopInTestContext struct {
1823
cfg *executeConfig
1924
statusChan chan SwapInfo
2025
blockEpochChan chan interface{}
26+
27+
swapInvoiceSubscription *test.SingleInvoiceSubscription
2128
}
2229

2330
func newLoopInTestContext(t *testing.T) *loopInTestContext {
@@ -61,3 +68,29 @@ func (c *loopInTestContext) assertState(expectedState loopdb.SwapState) {
6168
state.State)
6269
}
6370
}
71+
72+
// assertSubscribeInvoice asserts that the client subscribes to invoice updates
73+
// for our swap invoice.
74+
func (c *loopInTestContext) assertSubscribeInvoice(hash lntypes.Hash) {
75+
c.swapInvoiceSubscription = <-c.lnd.SingleInvoiceSubcribeChannel
76+
require.Equal(c.t, hash, c.swapInvoiceSubscription.Hash)
77+
}
78+
79+
// updateInvoiceState mocks an update to our swap invoice state.
80+
func (c *loopInTestContext) updateInvoiceState(amount btcutil.Amount,
81+
state channeldb.ContractState) {
82+
83+
c.swapInvoiceSubscription.Update <- lndclient.InvoiceUpdate{
84+
AmtPaid: amount,
85+
State: state,
86+
}
87+
88+
// If we're in a final state, close our update channels as lndclient
89+
// would.
90+
if state == channeldb.ContractCanceled ||
91+
state == channeldb.ContractSettled {
92+
93+
close(c.swapInvoiceSubscription.Update)
94+
close(c.swapInvoiceSubscription.Err)
95+
}
96+
}

0 commit comments

Comments
 (0)