From 2010239b631ae3196a20036e03602b464381a96e Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 1 Mar 2023 22:14:12 -0800 Subject: [PATCH] contractcourt: update the anchor resolver for taproot chans --- contractcourt/anchor_resolver.go | 20 ++++++++++++++------ contractcourt/chain_watcher.go | 3 ++- contractcourt/channel_arbitrator.go | 23 +++++++++++++++++++++-- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/contractcourt/anchor_resolver.go b/contractcourt/anchor_resolver.go index 80ac45631..d96960026 100644 --- a/contractcourt/anchor_resolver.go +++ b/contractcourt/anchor_resolver.go @@ -33,6 +33,9 @@ type anchorResolver struct { // chanPoint is the channel point of the original contract. chanPoint wire.OutPoint + // chanType denotes the type of channel the contract belongs to. + chanType channeldb.ChannelType + // currentReport stores the current state of the resolver for reporting // over the rpc interface. currentReport ContractReport @@ -97,12 +100,16 @@ func (c *anchorResolver) Resolve() (ContractResolver, error) { // to the sweeper. relayFeeRate := c.Sweeper.RelayFeePerKW() + witnessType := input.CommitmentAnchor + + // For taproot channels, we need to use the proper witness type. + if c.chanType.IsTaproot() { + witnessType = input.TaprootAnchorSweepSpend + } + anchorInput := input.MakeBaseInput( - &c.anchor, - input.CommitmentAnchor, - &c.anchorSignDescriptor, - c.broadcastHeight, - nil, + &c.anchor, witnessType, &c.anchorSignDescriptor, + c.broadcastHeight, nil, ) resultChan, err := c.Sweeper.SweepInput( @@ -195,7 +202,8 @@ func (c *anchorResolver) IsResolved() bool { // state required for the proper resolution of a contract. // // NOTE: Part of the ContractResolver interface. -func (c *anchorResolver) SupplementState(_ *channeldb.OpenChannel) { +func (c *anchorResolver) SupplementState(state *channeldb.OpenChannel) { + c.chanType = state.ChanType } // report returns a report on the resolution state of the contract. diff --git a/contractcourt/chain_watcher.go b/contractcourt/chain_watcher.go index 9d788fed4..3b0ee9664 100644 --- a/contractcourt/chain_watcher.go +++ b/contractcourt/chain_watcher.go @@ -885,7 +885,8 @@ func (c *chainWatcher) handlePossibleBreach(commitSpend *chainntnfs.SpendDetail, // TODO(roasbeef): make keyring for taproot chans to pass in instead of // nil anchorRes, err := lnwallet.NewAnchorResolution( - c.cfg.chanState, commitSpend.SpendingTx, nil, false, + c.cfg.chanState, commitSpend.SpendingTx, retribution.KeyRing, + false, ) if err != nil { return false, fmt.Errorf("unable to create anchor "+ diff --git a/contractcourt/channel_arbitrator.go b/contractcourt/channel_arbitrator.go index 3eb3ffb87..33b3385d2 100644 --- a/contractcourt/channel_arbitrator.go +++ b/contractcourt/channel_arbitrator.go @@ -11,6 +11,7 @@ import ( "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/channeldb" @@ -728,7 +729,7 @@ func (c *ChannelArbitrator) relaunchResolvers(commitSet *CommitSet, for i := range unresolvedContracts { resolver := unresolvedContracts[i] - if chanState != nil { + if chanState != nil { resolver.SupplementState(chanState) } @@ -766,7 +767,12 @@ func (c *ChannelArbitrator) relaunchResolvers(commitSet *CommitSet, ChannelArbitratorConfig: c.cfg, }, ) + + anchorResolver.SupplementState(chanState) + unresolvedContracts = append(unresolvedContracts, anchorResolver) + + // TODO(roasbeef): this isn't re-launched? } c.launchResolvers(unresolvedContracts) @@ -1292,10 +1298,21 @@ func (c *ChannelArbitrator) sweepAnchors(anchors *lnwallet.AnchorResolutions, "anchor of %s commit tx %v", c.cfg.ChanPoint, anchorPath, anchor.CommitAnchor) + witnessType := input.CommitmentAnchor + + // For taproot channels, we need to use the proper witness + // type. + if txscript.IsPayToTaproot( + anchor.AnchorSignDescriptor.Output.PkScript, + ) { + + witnessType = input.TaprootAnchorSweepSpend + } + // Prepare anchor output for sweeping. anchorInput := input.MakeBaseInput( &anchor.CommitAnchor, - input.CommitmentAnchor, + witnessType, &anchor.AnchorSignDescriptor, heightHint, &input.TxInfo{ @@ -2181,6 +2198,8 @@ func (c *ChannelArbitrator) prepContractResolutions( contractResolutions.AnchorResolution.CommitAnchor, height, c.cfg.ChanPoint, resolverCfg, ) + anchorResolver.SupplementState(chanState) + htlcResolvers = append(htlcResolvers, anchorResolver) }