mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 09:53:54 +01:00
contractcourt: don't wait for DLP point if commit is tweakless on remote close
In this commit, we update the logic in the `chainWatcher` to no longer wait until the DLP point has been populated in the database before we dispatch the force close summary to any registered clients. Instead, we can sweep immediately, as we have all the information we need to sweep the funds (just our key).
This commit is contained in:
parent
fdec603279
commit
d22f2a1936
@ -584,48 +584,32 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) {
|
||||
"state #%v!!! Attempting recovery...",
|
||||
broadcastStateNum, remoteStateNum)
|
||||
|
||||
// If we are lucky, the remote peer sent us the correct
|
||||
// commitment point during channel sync, such that we
|
||||
// can sweep our funds. If we cannot find the commit
|
||||
// point, there's not much we can do other than wait
|
||||
// for us to retrieve it. We will attempt to retrieve
|
||||
// it from the peer each time we connect to it.
|
||||
//
|
||||
// TODO(halseth): actively initiate re-connection to
|
||||
// the peer?
|
||||
var commitPoint *btcec.PublicKey
|
||||
backoff := minCommitPointPollTimeout
|
||||
for {
|
||||
commitPoint, err = c.cfg.chanState.DataLossCommitPoint()
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
tweaklessCommit := (c.cfg.chanState.ChanType ==
|
||||
channeldb.SingleFunderTweakless)
|
||||
|
||||
log.Errorf("Unable to retrieve commitment "+
|
||||
"point for channel(%v) with lost "+
|
||||
"state: %v. Retrying in %v.",
|
||||
c.cfg.chanState.FundingOutpoint,
|
||||
err, backoff)
|
||||
|
||||
select {
|
||||
// Wait before retrying, with an exponential
|
||||
// backoff.
|
||||
case <-time.After(backoff):
|
||||
backoff = 2 * backoff
|
||||
if backoff > maxCommitPointPollTimeout {
|
||||
backoff = maxCommitPointPollTimeout
|
||||
}
|
||||
|
||||
case <-c.quit:
|
||||
// If this isn't a tweakless commitment, then we'll
|
||||
// need to wait for the remote party's latest unrevoked
|
||||
// commitment point to be presented to us as we need
|
||||
// this to sweep. Otherwise, we can dispatch the remote
|
||||
// close and sweep immediately using a fake commitPoint
|
||||
// as it isn't actually needed for recovery anymore.
|
||||
commitPoint := c.cfg.chanState.RemoteCurrentRevocation
|
||||
if !tweaklessCommit {
|
||||
commitPoint = c.waitForCommitmentPoint()
|
||||
if commitPoint == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("Recovered commit point(%x) for "+
|
||||
"channel(%v)! Now attempting to use it to "+
|
||||
"sweep our funds...",
|
||||
commitPoint.SerializeCompressed(),
|
||||
c.cfg.chanState.FundingOutpoint)
|
||||
log.Infof("Recovered commit point(%x) for "+
|
||||
"channel(%v)! Now attempting to use it to "+
|
||||
"sweep our funds...",
|
||||
commitPoint.SerializeCompressed(),
|
||||
c.cfg.chanState.FundingOutpoint)
|
||||
|
||||
} else {
|
||||
log.Infof("ChannelPoint(%v) is tweakless, " +
|
||||
"moving to sweep directly on chain")
|
||||
}
|
||||
|
||||
// Since we don't have the commitment stored for this
|
||||
// state, we'll just pass an empty commitment within
|
||||
@ -1009,3 +993,39 @@ func (c *chainWatcher) dispatchContractBreach(spendEvent *chainntnfs.SpendDetail
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// waitForCommitmentPoint waits for the commitment point to be inserted into
|
||||
// the local database. We'll use this method in the DLP case, to wait for the
|
||||
// remote party to send us their point, as we can't proceed until we have that.
|
||||
func (c *chainWatcher) waitForCommitmentPoint() *btcec.PublicKey {
|
||||
// If we are lucky, the remote peer sent us the correct commitment
|
||||
// point during channel sync, such that we can sweep our funds. If we
|
||||
// cannot find the commit point, there's not much we can do other than
|
||||
// wait for us to retrieve it. We will attempt to retrieve it from the
|
||||
// peer each time we connect to it.
|
||||
//
|
||||
// TODO(halseth): actively initiate re-connection to the peer?
|
||||
backoff := minCommitPointPollTimeout
|
||||
for {
|
||||
commitPoint, err := c.cfg.chanState.DataLossCommitPoint()
|
||||
if err == nil {
|
||||
return commitPoint
|
||||
}
|
||||
|
||||
log.Errorf("Unable to retrieve commitment point for "+
|
||||
"channel(%v) with lost state: %v. Retrying in %v.",
|
||||
c.cfg.chanState.FundingOutpoint, err, backoff)
|
||||
|
||||
select {
|
||||
// Wait before retrying, with an exponential backoff.
|
||||
case <-time.After(backoff):
|
||||
backoff = 2 * backoff
|
||||
if backoff > maxCommitPointPollTimeout {
|
||||
backoff = maxCommitPointPollTimeout
|
||||
}
|
||||
|
||||
case <-c.quit:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user