peer+contractcourt: delegate watching for co-op closes to the chainWatcher

In this commit, we modify the interaction between the chanCloser
sub-system and the chain notifier all together. This fixes a series of
bugs as before this commit, we wouldn’t be able to detect if the remote
party actually broadcasted *any* of the transactions that we signed off
upon. This would be rejected to the user by having a “zombie” channel
close that would never actually be resolved.

Rather than the chanCloser watching for on-chain closes, we’ll now open
up a co-op close context to the chainWatcher (via a layer of
indirection via the ChainArbitrator), and report to it all possible
closes that we’ve signed. The chainWatcher will then be able to launch
a goroutine to properly update the database state once any of the
possible closure transactions confirms.
This commit is contained in:
Olaoluwa Osuntokun committed 2018-01-22 19:19:53 -08:00
1 parent 1604c75a9c
commit 3ec83cc82f
5 files changed
+201 -32

No files matched your search

+28 -13
View File
@@ -1425,6 +1425,18 @@ func (p *peer) fetchActiveChanCloser(chanID lnwire.ChannelID) (*channelCloser, e
return nil, err
}
// Before we create the chan closer, we'll start a new
// cooperative channel closure transaction from the chain arb.
// Wtih this context, we'll ensure that we're able to respond
// if *any* of the transactions we sign off on are ever
// braodacast.
closeCtx, err := p.server.chainArb.BeginCoopChanClose(
*channel.ChannelPoint(),
)
if err != nil {
return nil, err
}
chanCloser = newChannelCloser(
chanCloseCfg{
channel: channel,
@@ -1437,6 +1449,7 @@ func (p *peer) fetchActiveChanCloser(chanID lnwire.ChannelID) (*channelCloser, e
targetFeePerKw,
uint32(startingHeight),
nil,
closeCtx,
)
p.activeChanCloses[chanID] = chanCloser
}
@@ -1479,7 +1492,14 @@ func (p *peer) handleLocalCloseReq(req *htlcswitch.ChanClose) {
return
}
_, startingHeight, err := p.server.cc.chainIO.GetBestBlock()
// Before we create the chan closer, we'll start a new
// cooperative channel closure transaction from the chain arb.
// Wtih this context, we'll ensure that we're able to respond
// if *any* of the transactions we sign off on are ever
// braodacast.
closeCtx, err := p.server.chainArb.BeginCoopChanClose(
*channel.ChannelPoint(),
)
if err != nil {
peerLog.Errorf(err.Error())
req.Err <- err
@@ -1488,6 +1508,12 @@ func (p *peer) handleLocalCloseReq(req *htlcswitch.ChanClose) {
// Next, we'll create a new channel closer state machine to
// handle the close negotiation.
_, startingHeight, err := p.server.cc.chainIO.GetBestBlock()
if err != nil {
peerLog.Errorf(err.Error())
req.Err <- err
return
}
chanCloser := newChannelCloser(
chanCloseCfg{
channel: channel,
@@ -1500,6 +1526,7 @@ func (p *peer) handleLocalCloseReq(req *htlcswitch.ChanClose) {
req.TargetFeePerKw,
uint32(startingHeight),
req,
closeCtx,
)
p.activeChanCloses[chanID] = chanCloser
@@ -1591,18 +1618,6 @@ func (p *peer) finalizeChanClosure(chanCloser *channelCloser) {
go waitForChanToClose(chanCloser.negotiationHeight, notifier, errChan,
chanPoint, &closingTxid, func() {
// First, we'll mark the database as being fully closed
// so we'll no longer watch for its ultimate closure
// upon startup.
err := p.server.chanDB.MarkChanFullyClosed(chanPoint)
if err != nil {
if closeReq != nil {
closeReq.Err <- err
}
return
}
// Respond to the local subsystem which requested the
// channel closure.
if closeReq != nil {