cnct: resolve anchors post-confirmation

Sweeping anchors and being able to bump the fee was already added in a
previous commit. This commit extends anchor sweeping with an anchor
resolver object that becomes active after the commitment tx confirms.
At that point, the anchors do not serve the purpose of getting the
commitment tranaction confirmed anymore. It is however still possible to
reclaim some of their value if using a low fee rate.
This commit is contained in:
Joost Jager
2019-11-25 13:17:44 +01:00
parent d84b596f55
commit ea397c9d6e
5 changed files with 282 additions and 6 deletions

View File

@@ -467,7 +467,7 @@ func (c *ChannelArbitrator) Start() error {
// receive a chain event from the chain watcher than the
// commitment has been confirmed on chain, and before we
// advance our state step, we call InsertConfirmedCommitSet.
if err := c.relaunchResolvers(commitSet); err != nil {
if err := c.relaunchResolvers(commitSet, triggerHeight); err != nil {
c.cfg.BlockEpochs.Cancel()
return err
}
@@ -483,7 +483,9 @@ func (c *ChannelArbitrator) Start() error {
// starting the ChannelArbitrator. This information should ideally be stored in
// the database, so this only serves as a intermediate work-around to prevent a
// migration.
func (c *ChannelArbitrator) relaunchResolvers(commitSet *CommitSet) error {
func (c *ChannelArbitrator) relaunchResolvers(commitSet *CommitSet,
heightHint uint32) error {
// We'll now query our log to see if there are any active unresolved
// contracts. If this is the case, then we'll relaunch all contract
// resolvers.
@@ -558,6 +560,19 @@ func (c *ChannelArbitrator) relaunchResolvers(commitSet *CommitSet) error {
htlcResolver.Supplement(*htlc)
}
// The anchor resolver is stateless and can always be re-instantiated.
if contractResolutions.AnchorResolution != nil {
anchorResolver := newAnchorResolver(
contractResolutions.AnchorResolution.AnchorSignDescriptor,
contractResolutions.AnchorResolution.CommitAnchor,
heightHint, c.cfg.ChanPoint,
ResolverConfig{
ChannelArbitratorConfig: c.cfg,
},
)
unresolvedContracts = append(unresolvedContracts, anchorResolver)
}
c.launchResolvers(unresolvedContracts)
return nil
@@ -1856,8 +1871,8 @@ func (c *ChannelArbitrator) prepContractResolutions(
}
}
// Finally, if this is was a unilateral closure, then we'll also create
// a resolver to sweep our commitment output (but only if it wasn't
// If this is was an unilateral closure, then we'll also create a
// resolver to sweep our commitment output (but only if it wasn't
// trimmed).
if contractResolutions.CommitResolution != nil {
resolver := newCommitSweepResolver(
@@ -1867,6 +1882,17 @@ func (c *ChannelArbitrator) prepContractResolutions(
htlcResolvers = append(htlcResolvers, resolver)
}
// We instantiate an anchor resolver if the commitmentment tx has an
// anchor.
if contractResolutions.AnchorResolution != nil {
anchorResolver := newAnchorResolver(
contractResolutions.AnchorResolution.AnchorSignDescriptor,
contractResolutions.AnchorResolution.CommitAnchor,
height, c.cfg.ChanPoint, resolverCfg,
)
htlcResolvers = append(htlcResolvers, anchorResolver)
}
return htlcResolvers, msgsToSend, nil
}