mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-06 18:37:11 +01:00
Merge pull request #1088 from Roasbeef/chan-close-fix
contractcourt: fix co-op chan close issue by not closing over loop iterator variable
This commit is contained in:
commit
cc08baec63
3 changed files with 38 additions and 6 deletions
|
@ -327,19 +327,22 @@ func (c *ChainArbitrator) Start() error {
|
||||||
// For each open channel, we'll configure then launch a corresponding
|
// For each open channel, we'll configure then launch a corresponding
|
||||||
// ChannelArbitrator.
|
// ChannelArbitrator.
|
||||||
for _, channel := range openChannels {
|
for _, channel := range openChannels {
|
||||||
|
chanPoint := channel.FundingOutpoint
|
||||||
|
|
||||||
// First, we'll create an active chainWatcher for this channel
|
// First, we'll create an active chainWatcher for this channel
|
||||||
// to ensure that we detect any relevant on chain events.
|
// to ensure that we detect any relevant on chain events.
|
||||||
chainWatcher, err := newChainWatcher(
|
chainWatcher, err := newChainWatcher(
|
||||||
channel, c.cfg.Notifier, c.cfg.PreimageDB, c.cfg.Signer,
|
channel, c.cfg.Notifier, c.cfg.PreimageDB, c.cfg.Signer,
|
||||||
c.cfg.IsOurAddress, func() error {
|
c.cfg.IsOurAddress, func() error {
|
||||||
return c.resolveContract(channel.FundingOutpoint, nil)
|
// TODO(roasbeef): also need to pass in log?
|
||||||
|
return c.resolveContract(chanPoint, nil)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.activeWatchers[channel.FundingOutpoint] = chainWatcher
|
c.activeWatchers[chanPoint] = chainWatcher
|
||||||
channelArb, err := newActiveChannelArbitrator(
|
channelArb, err := newActiveChannelArbitrator(
|
||||||
channel, c, chainWatcher.SubscribeChannelEvents(false),
|
channel, c, chainWatcher.SubscribeChannelEvents(false),
|
||||||
)
|
)
|
||||||
|
@ -347,7 +350,7 @@ func (c *ChainArbitrator) Start() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.activeChannels[channel.FundingOutpoint] = channelArb
|
c.activeChannels[chanPoint] = channelArb
|
||||||
}
|
}
|
||||||
|
|
||||||
// In addition to the channels that we know to be open, we'll also
|
// In addition to the channels that we know to be open, we'll also
|
||||||
|
|
|
@ -782,11 +782,14 @@ func (c *CooperativeCloseCtx) LogPotentialClose(potentialClose *channeldb.Channe
|
||||||
// pending closed in the database, then launch a goroutine to mark the channel
|
// pending closed in the database, then launch a goroutine to mark the channel
|
||||||
// fully closed upon confirmation.
|
// fully closed upon confirmation.
|
||||||
func (c *CooperativeCloseCtx) Finalize(preferredClose *channeldb.ChannelCloseSummary) error {
|
func (c *CooperativeCloseCtx) Finalize(preferredClose *channeldb.ChannelCloseSummary) error {
|
||||||
log.Infof("Finalizing chan close for ChannelPoint(%v)",
|
chanPoint := c.watcher.chanState.FundingOutpoint
|
||||||
c.watcher.chanState.FundingOutpoint)
|
|
||||||
|
log.Infof("Finalizing chan close for ChannelPoint(%v)", chanPoint)
|
||||||
|
|
||||||
err := c.watcher.chanState.CloseChannel(preferredClose)
|
err := c.watcher.chanState.CloseChannel(preferredClose)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Errorf("closeCtx: unable to close ChannelPoint(%v): %v",
|
||||||
|
chanPoint, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
28
lnd_test.go
28
lnd_test.go
|
@ -234,7 +234,7 @@ func closeChannelAndAssert(ctx context.Context, t *harnessTest,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, generate a single block, wait for the final close status
|
// We'll now, generate a single block, wait for the final close status
|
||||||
// update, then ensure that the closing transaction was included in the
|
// update, then ensure that the closing transaction was included in the
|
||||||
// block.
|
// block.
|
||||||
block := mineBlocks(t, net, 1)[0]
|
block := mineBlocks(t, net, 1)[0]
|
||||||
|
@ -246,6 +246,32 @@ func closeChannelAndAssert(ctx context.Context, t *harnessTest,
|
||||||
|
|
||||||
assertTxInBlock(t, block, closingTxid)
|
assertTxInBlock(t, block, closingTxid)
|
||||||
|
|
||||||
|
// Finally, the transaction should no longer be in the pending close
|
||||||
|
// state as we've just mined a block that should include the closing
|
||||||
|
// transaction. This only applies for co-op close channels though.
|
||||||
|
if !force {
|
||||||
|
err = lntest.WaitPredicate(func() bool {
|
||||||
|
pendingChansRequest := &lnrpc.PendingChannelsRequest{}
|
||||||
|
pendingChanResp, err := node.PendingChannels(
|
||||||
|
ctx, pendingChansRequest,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pendingClose := range pendingChanResp.PendingClosingChannels {
|
||||||
|
if pendingClose.Channel.ChannelPoint == chanPointStr {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}, time.Second*15)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("closing transaction not marked as fully closed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return closingTxid
|
return closingTxid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue