Browse Source

loopin: handle EOF case for SubscribeSingleInvoice

From lnd 0.13.0, the SubscribeSingleInvoice rpc will return an EOF
once it has served a final state to the stream. This is handled in
our lndclient wrapper by closing the channels that we send updates/
errors on. When we are exclusively consuming updates from these
streams, we don't need to handle this case because we will receive
our final update and exit. However, in the case where we continue
to listen on the update channels after consuming the final update,
we need to handle this EOF/closed channels case. This is done by
setting the channels to nil after they're closed so that we no
longer select on them but can continue waiting for our other cases
to complete.

We have similar handling in loopout's waitForHtlcSpendConfirmed.
pull/396/head
carla 4 months ago
parent
commit
0e72c2bf92
No known key found for this signature in database GPG Key ID: 4CA7FE54A6213C91
2 changed files with 29 additions and 2 deletions
  1. +20
    -2
      loopin.go
  2. +9
    -0
      loopin_testcontext_test.go

+ 20
- 2
loopin.go View File

@ -779,12 +779,30 @@ func (s *loopInSwap) waitForSwapComplete(ctx context.Context,
htlcSpend = true
// Swap invoice ntfn error.
case err := <-swapInvoiceErr:
case err, ok := <-swapInvoiceErr:
// If the channel has been closed, the server has
// finished sending updates, so we set the channel to
// nil because we don't want to constantly select this
// case.
if !ok {
swapInvoiceErr = nil
continue
}
return err
// An update to the swap invoice occurred. Check the new state
// and update the swap state accordingly.
case update := <-swapInvoiceChan:
case update, ok := <-swapInvoiceChan:
// If the channel has been closed, the server has
// finished sending updates, so we set the channel to
// nil because we don't want to constantly select this
// case.
if !ok {
swapInvoiceChan = nil
continue
}
s.log.Infof("Received swap invoice update: %v",
update.State)

+ 9
- 0
loopin_testcontext_test.go View File

@ -84,4 +84,13 @@ func (c *loopInTestContext) updateInvoiceState(amount btcutil.Amount,
AmtPaid: amount,
State: state,
}
// If we're in a final state, close our update channels as lndclient
// would.
if state == channeldb.ContractCanceled ||
state == channeldb.ContractSettled {
close(c.swapInvoiceSubscription.Update)
close(c.swapInvoiceSubscription.Err)
}
}

Loading…
Cancel
Save