cnct: clear exclusive group on anchor sweep after confirmation

The sweeper call UpdateParams does not update the exclusive group
property of a pending sweep. This led to anchor outputs being swept
after confirmation with an exclusive group restriction, which is not
necessary.

This commit changes the anchor resolver to not use UpdateParams anymore,
but instead always re-offer the anchor input to the sweeper. The sweeper
is modified so that a re-offering also updates the sweep parameters.
This commit is contained in:
Joost Jager 2020-09-04 11:53:24 +02:00
parent 6df4fa84df
commit 08bb8ec54e
No known key found for this signature in database
GPG Key ID: A61B9D4C393C59C7
3 changed files with 27 additions and 33 deletions

@ -10,7 +10,6 @@ import (
"github.com/btcsuite/btcutil"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/sweep"
)
@ -86,23 +85,15 @@ func (c *anchorResolver) Resolve() (ContractResolver, error) {
// situation. We don't want to force sweep anymore, because the anchor
// lost its special purpose to get the commitment confirmed. It is just
// an output that we want to sweep only if it is economical to do so.
//
// An exclusive group is not necessary anymore, because we know that
// this is the only anchor that can be swept.
//
// After a restart or when the remote force closes, the sweeper is not
// yet aware of the anchor. In that case, it will be added as new input
// to the sweeper.
relayFeeRate := c.Sweeper.RelayFeePerKW()
resultChan, err := c.Sweeper.UpdateParams(
c.anchor,
sweep.ParamsUpdate{
Fee: sweep.FeePreference{
FeeRate: relayFeeRate,
},
Force: false,
},
)
// After a restart or when the remote force closes, the sweeper is not
// yet aware of the anchor. In that case, offer it as a new input to the
// sweeper. An exclusive group is not necessary anymore, because we know
// that this is the only anchor that can be swept.
if err == lnwallet.ErrNotMine {
anchorInput := input.MakeBaseInput(
&c.anchor,
input.CommitmentAnchor,
@ -110,7 +101,7 @@ func (c *anchorResolver) Resolve() (ContractResolver, error) {
c.broadcastHeight,
)
resultChan, err = c.Sweeper.SweepInput(
resultChan, err := c.Sweeper.SweepInput(
&anchorInput,
sweep.Params{
Fee: sweep.FeePreference{
@ -121,7 +112,6 @@ func (c *anchorResolver) Resolve() (ContractResolver, error) {
if err != nil {
return nil, err
}
}
var (
outcome channeldb.ResolverOutcome

@ -2237,9 +2237,9 @@ func TestChannelArbitratorAnchors(t *testing.T) {
t.Fatalf("expected anchor resolver, got %T", resolver)
}
// The anchor resolver is expected to offer the anchor input to the
// The anchor resolver is expected to re-offer the anchor input to the
// sweeper.
<-chanArbCtx.sweeper.updatedInputs
<-chanArbCtx.sweeper.sweptInputs
// The mock sweeper immediately signals success for that input. This
// should transition the channel to the resolved state.

@ -505,6 +505,9 @@ func (s *UtxoSweeper) collector(blockEpochs <-chan *chainntnfs.BlockEpoch) {
log.Debugf("Already pending input %v received",
outpoint)
// Update sweep parameters.
pendInput.params = input.params
// Add additional result channel to signal
// spend of this input.
pendInput.listeners = append(
@ -1131,8 +1134,9 @@ func (s *UtxoSweeper) handlePendingSweepsReq(
// UpdateParams allows updating the sweep parameters of a pending input in the
// UtxoSweeper. This function can be used to provide an updated fee preference
// that will be used for a new sweep transaction of the input that will act as a
// replacement transaction (RBF) of the original sweeping transaction, if any.
// and force flag that will be used for a new sweep transaction of the input
// that will act as a replacement transaction (RBF) of the original sweeping
// transaction, if any. The exclusive group is left unchanged.
//
// NOTE: This currently doesn't do any fee rate validation to ensure that a bump
// is actually successful. The responsibility of doing so should be handled by