@@ -207,6 +207,13 @@ type chainWatcher struct {
207207 // the current state number on the commitment transactions.
208208 stateHintObfuscator [lnwallet .StateHintSize ]byte
209209
210+ // fundingPkScript is the pkScript of the funding output.
211+ fundingPkScript []byte
212+
213+ // heightHint is the height hint used to checkpoint scans on chain for
214+ // conf/spend events.
215+ heightHint uint32
216+
210217 // All the fields below are protected by this mutex.
211218 sync.Mutex
212219
@@ -267,9 +274,9 @@ func (c *chainWatcher) Start() error {
267274 // As a height hint, we'll try to use the opening height, but if the
268275 // channel isn't yet open, then we'll use the height it was broadcast
269276 // at. This may be an unconfirmed zero-conf channel.
270- heightHint : = c .cfg .chanState .ShortChanID ().BlockHeight
271- if heightHint == 0 {
272- heightHint = chanState .BroadcastHeight ()
277+ c . heightHint = c .cfg .chanState .ShortChanID ().BlockHeight
278+ if c . heightHint == 0 {
279+ c . heightHint = chanState .BroadcastHeight ()
273280 }
274281
275282 // Since no zero-conf state is stored in a channel backup, the below
@@ -279,29 +286,43 @@ func (c *chainWatcher) Start() error {
279286 if chanState .ZeroConfConfirmed () {
280287 // If the zero-conf channel is confirmed, we'll use the
281288 // confirmed SCID's block height.
282- heightHint = chanState .ZeroConfRealScid ().BlockHeight
289+ c . heightHint = chanState .ZeroConfRealScid ().BlockHeight
283290 } else {
284291 // The zero-conf channel is unconfirmed. We'll need to
285292 // use the FundingBroadcastHeight.
286- heightHint = chanState .BroadcastHeight ()
293+ c . heightHint = chanState .BroadcastHeight ()
287294 }
288295 }
289296
290- localKey := chanState .LocalChanCfg .MultiSigKey .PubKey .SerializeCompressed ()
291- remoteKey := chanState .RemoteChanCfg .MultiSigKey .PubKey .SerializeCompressed ()
292- multiSigScript , err := input .GenMultiSigScript (
293- localKey , remoteKey ,
297+ localKey := chanState .LocalChanCfg .MultiSigKey .PubKey
298+ remoteKey := chanState .RemoteChanCfg .MultiSigKey .PubKey
299+
300+ var (
301+ err error
294302 )
295- if err != nil {
296- return err
297- }
298- pkScript , err := input .WitnessScriptHash (multiSigScript )
299- if err != nil {
300- return err
303+ if chanState .ChanType .IsTaproot () {
304+ c .fundingPkScript , _ , err = input .GenTaprootFundingScript (
305+ localKey , remoteKey , 0 ,
306+ )
307+ if err != nil {
308+ return err
309+ }
310+ } else {
311+ multiSigScript , err := input .GenMultiSigScript (
312+ localKey .SerializeCompressed (),
313+ remoteKey .SerializeCompressed (),
314+ )
315+ if err != nil {
316+ return err
317+ }
318+ c .fundingPkScript , err = input .WitnessScriptHash (multiSigScript )
319+ if err != nil {
320+ return err
321+ }
301322 }
302323
303324 spendNtfn , err := c .cfg .notifier .RegisterSpendNtfn (
304- fundingOut , pkScript , heightHint ,
325+ fundingOut , c . fundingPkScript , c . heightHint ,
305326 )
306327 if err != nil {
307328 return err
@@ -567,6 +588,33 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) {
567588 log .Infof ("Close observer for ChannelPoint(%v) active" ,
568589 c .cfg .chanState .FundingOutpoint )
569590
591+ // If this is a taproot channel, before we proceed, we want to ensure
592+ // that the expected funding output has confirmed on chain.
593+ if c .cfg .chanState .ChanType .IsTaproot () {
594+ fundingPoint := c .cfg .chanState .FundingOutpoint
595+
596+ confNtfn , err := c .cfg .notifier .RegisterConfirmationsNtfn (
597+ & fundingPoint .Hash , c .fundingPkScript , 1 , c .heightHint ,
598+ )
599+ if err != nil {
600+ log .Warnf ("unable to register for conf: %v" , err )
601+ }
602+
603+ log .Infof ("Waiting for taproot ChannelPoint(%v) to confirm..." ,
604+ c .cfg .chanState .FundingOutpoint )
605+
606+ select {
607+ case _ , ok := <- confNtfn .Confirmed :
608+ // If the channel was closed, then this means that the
609+ // notifier exited, so we will as well.
610+ if ! ok {
611+ return
612+ }
613+ case <- c .quit :
614+ return
615+ }
616+ }
617+
570618 select {
571619 // We've detected a spend of the channel onchain! Depending on the type
572620 // of spend, we'll act accordingly, so we'll examine the spending
@@ -833,6 +881,9 @@ func (c *chainWatcher) handlePossibleBreach(commitSpend *chainntnfs.SpendDetail,
833881 }
834882
835883 // Create an AnchorResolution for the breached state.
884+ //
885+ // TODO(roasbeef): make keyring for taproot chans to pass in instead of
886+ // nil
836887 anchorRes , err := lnwallet .NewAnchorResolution (
837888 c .cfg .chanState , commitSpend .SpendingTx , nil ,
838889 )
0 commit comments