From fffad49ad15d71e23612705ead3f0675c77d9b24 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Fri, 10 Jun 2022 11:18:33 -0700 Subject: [PATCH] peer: send taproot addrs during co-op close based on new feature bit If the ShutdownAnySegwitOptional option is active, then we can safely send these newer addresses. --- peer/brontide.go | 16 +++++++++++++++- peer/brontide_test.go | 6 ++++++ peer/test_utils.go | 17 +++++++---------- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/peer/brontide.go b/peer/brontide.go index ee8c7907c..b9741fae2 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -657,6 +657,13 @@ func (p *Brontide) initGossipSync() { } } +// taprootShutdownAllowed returns true if both parties have negotiated the +// shutdown-any-segwit feature. +func (p *Brontide) taprootShutdownAllowed() bool { + return p.RemoteFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional) && + p.LocalFeatures().HasFeature(lnwire.ShutdownAnySegwitOptional) +} + // QuitSignal is a method that should return a channel which will be sent upon // or closed once the backing peer exits. This allows callers using the // interface to cancel any processing in the event the backing implementation @@ -2244,8 +2251,15 @@ func (p *Brontide) ChannelSnapshots() []*channeldb.ChannelSnapshot { // genDeliveryScript returns a new script to be used to send our funds to in // the case of a cooperative channel close negotiation. func (p *Brontide) genDeliveryScript() ([]byte, error) { + // We'll send a normal p2wkh address unless we've negotiated the + // shutdown-any-segwit feature. + addrType := lnwallet.WitnessPubKey + if p.taprootShutdownAllowed() { + addrType = lnwallet.TaprootPubkey + } + deliveryAddr, err := p.cfg.Wallet.NewAddress( - lnwallet.WitnessPubKey, false, lnwallet.DefaultAccountName, + addrType, false, lnwallet.DefaultAccountName, ) if err != nil { return nil, err diff --git a/peer/brontide_test.go b/peer/brontide_test.go index 9a657e79f..38ef2e5e7 100644 --- a/peer/brontide_test.go +++ b/peer/brontide_test.go @@ -55,6 +55,8 @@ func TestPeerChannelClosureAcceptFeeResponder(t *testing.T) { mockLink := newMockUpdateHandler(chanID) mockSwitch.links = append(mockSwitch.links, mockLink) + dummyDeliveryScript := genScript(t, p2wshAddress) + // We send a shutdown request to Alice. She will now be the responding // node in this shutdown procedure. We first expect Alice to answer // this shutdown request with a Shutdown message. @@ -156,6 +158,8 @@ func TestPeerChannelClosureAcceptFeeInitiator(t *testing.T) { mockLink := newMockUpdateHandler(chanID) mockSwitch.links = append(mockSwitch.links, mockLink) + dummyDeliveryScript := genScript(t, p2wshAddress) + // We make Alice send a shutdown request. updateChan := make(chan interface{}, 1) errChan := make(chan error, 1) @@ -281,6 +285,7 @@ func TestPeerChannelClosureFeeNegotiationsResponder(t *testing.T) { // Bob sends a shutdown request to Alice. She will now be the responding // node in this shutdown procedure. We first expect Alice to answer this // Shutdown request with a Shutdown message. + dummyDeliveryScript := genScript(t, p2wshAddress) alicePeer.chanCloseMsgs <- &closeMsg{ cid: chanID, msg: lnwire.NewShutdown(chanID, @@ -492,6 +497,7 @@ func TestPeerChannelClosureFeeNegotiationsInitiator(t *testing.T) { aliceDeliveryScript := shutdownMsg.Address // Bob will answer the Shutdown message with his own Shutdown. + dummyDeliveryScript := genScript(t, p2wshAddress) respShutdown := lnwire.NewShutdown(chanID, dummyDeliveryScript) alicePeer.chanCloseMsgs <- &closeMsg{ cid: chanID, diff --git a/peer/test_utils.go b/peer/test_utils.go index f80705d55..abebf5260 100644 --- a/peer/test_utils.go +++ b/peer/test_utils.go @@ -45,9 +45,6 @@ const ( ) var ( - // Just use some arbitrary bytes as delivery script. - dummyDeliveryScript = channels.AlicesPrivKey - testKeyLoc = keychain.KeyLocator{Family: keychain.KeyFamilyNodeKey} ) @@ -368,26 +365,26 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, } cfg := &Config{ - Addr: cfgAddr, - PubKeyBytes: pubKey, - ErrorBuffer: errBuffer, - ChainIO: chainIO, - Switch: mockSwitch, - + Addr: cfgAddr, + PubKeyBytes: pubKey, + ErrorBuffer: errBuffer, + ChainIO: chainIO, + Switch: mockSwitch, ChanActiveTimeout: chanActiveTimeout, InterceptSwitch: htlcswitch.NewInterceptableSwitch( nil, testCltvRejectDelta, false, ), - ChannelDB: dbAlice.ChannelStateDB(), FeeEstimator: estimator, Wallet: wallet, ChainNotifier: notifier, ChanStatusMgr: chanStatusMgr, + Features: lnwire.NewFeatureVector(nil, lnwire.Features), DisconnectPeer: func(b *btcec.PublicKey) error { return nil }, } alicePeer := NewBrontide(*cfg) + alicePeer.remoteFeatures = lnwire.NewFeatureVector(nil, lnwire.Features) chanID := lnwire.NewChanIDFromOutPoint(channelAlice.ChannelPoint()) alicePeer.activeChannels[chanID] = channelAlice