diff --git a/funding/manager.go b/funding/manager.go index cb948a4b6..681183487 100644 --- a/funding/manager.go +++ b/funding/manager.go @@ -131,7 +131,7 @@ var ( // via a local signal such as RPC. // // TODO(roasbeef): actually use the context package -// * deadlines, etc. +// - deadlines, etc. type reservationWithCtx struct { reservation *lnwallet.ChannelReservation peer lnpeer.Peer @@ -1486,16 +1486,7 @@ func (f *Manager) handleFundingOpen(peer lnpeer.Peer, // (if any) in lieu of user input. shutdown, err := getUpfrontShutdownScript( f.cfg.EnableUpfrontShutdown, peer, acceptorResp.UpfrontShutdown, - func() (lnwire.DeliveryAddress, error) { - addr, err := f.cfg.Wallet.NewAddress( - lnwallet.WitnessPubKey, false, - lnwallet.DefaultAccountName, - ) - if err != nil { - return nil, err - } - return txscript.PayToAddrScript(addr) - }, + f.selectShutdownScript, ) if err != nil { f.failFundingFlow( @@ -3689,7 +3680,7 @@ func (f *Manager) InitFundingWorkflow(msg *InitFundingMsg) { // upfront shutdown scripts automatically. func getUpfrontShutdownScript(enableUpfrontShutdown bool, peer lnpeer.Peer, script lnwire.DeliveryAddress, - getScript func() (lnwire.DeliveryAddress, error)) (lnwire.DeliveryAddress, + getScript func(bool) (lnwire.DeliveryAddress, error)) (lnwire.DeliveryAddress, error) { // Check whether the remote peer supports upfront shutdown scripts. @@ -3721,7 +3712,12 @@ func getUpfrontShutdownScript(enableUpfrontShutdown bool, peer lnpeer.Peer, return nil, nil } - return getScript() + // We can safely send a taproot address iff, both sides have negotiated + // the shutdown-any-segwit feature. + taprootOK := peer.RemoteFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional) && + peer.LocalFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional) + + return getScript(taprootOK) } // handleInitFundingMsg creates a channel reservation within the daemon's @@ -3780,18 +3776,8 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) { // address from the wallet if our node is configured to set shutdown // address by default). shutdown, err := getUpfrontShutdownScript( - f.cfg.EnableUpfrontShutdown, msg.Peer, - msg.ShutdownScript, - func() (lnwire.DeliveryAddress, error) { - addr, err := f.cfg.Wallet.NewAddress( - lnwallet.WitnessPubKey, false, - lnwallet.DefaultAccountName, - ) - if err != nil { - return nil, err - } - return txscript.PayToAddrScript(addr) - }, + f.cfg.EnableUpfrontShutdown, msg.Peer, msg.ShutdownScript, + f.selectShutdownScript, ) if err != nil { msg.Err <- err @@ -4270,3 +4256,24 @@ func (f *Manager) deleteChannelOpeningState(chanPoint *wire.OutPoint) error { outpointBytes.Bytes(), ) } + +// selectShutdownScript selects the shutdown script we should send to the peer. +// If we can use taproot, then we prefer that, otherwise we'll use a p2wkh +// script. +func (f *Manager) selectShutdownScript(taprootOK bool, +) (lnwire.DeliveryAddress, error) { + + addrType := lnwallet.WitnessPubKey + if taprootOK { + addrType = lnwallet.TaprootPubkey + } + + addr, err := f.cfg.Wallet.NewAddress( + addrType, false, lnwallet.DefaultAccountName, + ) + if err != nil { + return nil, err + } + + return txscript.PayToAddrScript(addr) +} diff --git a/funding/manager_test.go b/funding/manager_test.go index 93b450a73..0b353d531 100644 --- a/funding/manager_test.go +++ b/funding/manager_test.go @@ -3331,13 +3331,13 @@ func TestGetUpfrontShutdownScript(t *testing.T) { upfrontScript := []byte("upfront script") generatedScript := []byte("generated script") - getScript := func() (lnwire.DeliveryAddress, error) { + getScript := func(_ bool) (lnwire.DeliveryAddress, error) { return generatedScript, nil } tests := []struct { name string - getScript func() (lnwire.DeliveryAddress, error) + getScript func(bool) (lnwire.DeliveryAddress, error) upfrontScript lnwire.DeliveryAddress peerEnabled bool localEnabled bool @@ -3628,14 +3628,14 @@ func TestFundingManagerUpfrontShutdown(t *testing.T) { pkscript: []byte("\xa9\x14\xfe\x44\x10\x65\xb6\x53" + "\x22\x31\xde\x2f\xac\x56\x31\x52\x20\x5e" + "\xc4\xf5\x9c\x74\x87"), - expectErr: false, + expectErr: true, }, { name: "p2pkh script", pkscript: []byte("\x76\xa9\x14\x64\x1a\xd5\x05\x1e" + "\xdd\x97\x02\x9a\x00\x3f\xe9\xef\xb2\x93" + "\x59\xfc\xee\x40\x9d\x88\xac"), - expectErr: false, + expectErr: true, }, { name: "p2wpkh script",