@@ -27,6 +27,7 @@ import (
2727 "github.com/lightningnetwork/lnd/contractcourt"
2828 "github.com/lightningnetwork/lnd/discovery"
2929 "github.com/lightningnetwork/lnd/feature"
30+ "github.com/lightningnetwork/lnd/fn"
3031 "github.com/lightningnetwork/lnd/funding"
3132 "github.com/lightningnetwork/lnd/htlcswitch"
3233 "github.com/lightningnetwork/lnd/htlcswitch/hodl"
@@ -986,6 +987,59 @@ func (p *Brontide) loadActiveChannels(chans []*channeldb.OpenChannel) (
986987 continue
987988 }
988989
990+ shutdownInfo , err := lnChan .State ().ShutdownInfo ()
991+ if err != nil && ! errors .Is (err , channeldb .ErrNoShutdownInfo ) {
992+ return nil , err
993+ }
994+
995+ var (
996+ shutdownMsg fn.Option [lnwire.Shutdown ]
997+ shutdownInfoErr error
998+ )
999+ shutdownInfo .WhenSome (func (info channeldb.ShutdownInfo ) {
1000+ // Compute an ideal fee.
1001+ feePerKw , err := p .cfg .FeeEstimator .EstimateFeePerKW (
1002+ p .cfg .CoopCloseTargetConfs ,
1003+ )
1004+ if err != nil {
1005+ shutdownInfoErr = fmt .Errorf ("unable to " +
1006+ "estimate fee: %w" , err )
1007+
1008+ return
1009+ }
1010+
1011+ chanCloser , err := p .createChanCloser (
1012+ lnChan , info .DeliveryScript .Val , feePerKw , nil ,
1013+ info .LocalInitiator .Val ,
1014+ )
1015+ if err != nil {
1016+ shutdownInfoErr = fmt .Errorf ("unable to " +
1017+ "create chan closer: %w" , err )
1018+
1019+ return
1020+ }
1021+
1022+ chanID := lnwire .NewChanIDFromOutPoint (
1023+ & lnChan .State ().FundingOutpoint ,
1024+ )
1025+
1026+ p .activeChanCloses [chanID ] = chanCloser
1027+
1028+ // Create the Shutdown message.
1029+ shutdown , err := chanCloser .ShutdownChan ()
1030+ if err != nil {
1031+ delete (p .activeChanCloses , chanID )
1032+ shutdownInfoErr = err
1033+
1034+ return
1035+ }
1036+
1037+ shutdownMsg = fn.Some [lnwire.Shutdown ](* shutdown )
1038+ })
1039+ if shutdownInfoErr != nil {
1040+ return nil , shutdownInfoErr
1041+ }
1042+
9891043 // Subscribe to the set of on-chain events for this channel.
9901044 chainEvents , err := p .cfg .ChainArb .SubscribeChannelEvents (
9911045 * chanPoint ,
@@ -996,7 +1050,7 @@ func (p *Brontide) loadActiveChannels(chans []*channeldb.OpenChannel) (
9961050
9971051 err = p .addLink (
9981052 chanPoint , lnChan , forwardingPolicy , chainEvents ,
999- true ,
1053+ true , shutdownMsg ,
10001054 )
10011055 if err != nil {
10021056 return nil , fmt .Errorf ("unable to add link %v to " +
@@ -1014,7 +1068,7 @@ func (p *Brontide) addLink(chanPoint *wire.OutPoint,
10141068 lnChan * lnwallet.LightningChannel ,
10151069 forwardingPolicy * models.ForwardingPolicy ,
10161070 chainEvents * contractcourt.ChainEventSubscription ,
1017- syncStates bool ) error {
1071+ syncStates bool , shutdownMsg fn. Option [lnwire. Shutdown ] ) error {
10181072
10191073 // onChannelFailure will be called by the link in case the channel
10201074 // fails for some reason.
@@ -1083,6 +1137,7 @@ func (p *Brontide) addLink(chanPoint *wire.OutPoint,
10831137 NotifyInactiveLinkEvent : p .cfg .ChannelNotifier .NotifyInactiveLinkEvent ,
10841138 HtlcNotifier : p .cfg .HtlcNotifier ,
10851139 GetAliases : p .cfg .GetAliases ,
1140+ PreviouslySentShutdown : shutdownMsg ,
10861141 }
10871142
10881143 // Before adding our new link, purge the switch of any pending or live
@@ -2802,15 +2857,32 @@ func (p *Brontide) restartCoopClose(lnChan *lnwallet.LightningChannel) (
28022857 return nil , nil
28032858 }
28042859
2805- // As mentioned above, we don't re-create the delivery script.
2806- deliveryScript := c .LocalShutdownScript
2807- if len (deliveryScript ) == 0 {
2808- var err error
2809- deliveryScript , err = p .genDeliveryScript ()
2810- if err != nil {
2811- p .log .Errorf ("unable to gen delivery script: %v" ,
2812- err )
2813- return nil , fmt .Errorf ("close addr unavailable" )
2860+ var deliveryScript []byte
2861+
2862+ shutdownInfo , err := c .ShutdownInfo ()
2863+ switch {
2864+ // We have previously stored the delivery script that we need to use
2865+ // in the shutdown message. Re-use this script.
2866+ case err == nil :
2867+ shutdownInfo .WhenSome (func (info channeldb.ShutdownInfo ) {
2868+ deliveryScript = info .DeliveryScript .Val
2869+ })
2870+
2871+ // An error other than ErrNoShutdownInfo was returned
2872+ case err != nil && ! errors .Is (err , channeldb .ErrNoShutdownInfo ):
2873+ return nil , err
2874+
2875+ case errors .Is (err , channeldb .ErrNoShutdownInfo ):
2876+ deliveryScript = c .LocalShutdownScript
2877+ if len (deliveryScript ) == 0 {
2878+ var err error
2879+ deliveryScript , err = p .genDeliveryScript ()
2880+ if err != nil {
2881+ p .log .Errorf ("unable to gen delivery script: " +
2882+ "%v" , err )
2883+
2884+ return nil , fmt .Errorf ("close addr unavailable" )
2885+ }
28142886 }
28152887 }
28162888
@@ -3905,7 +3977,7 @@ func (p *Brontide) addActiveChannel(c *lnpeer.NewChannel) error {
39053977 // Create the link and add it to the switch.
39063978 err = p .addLink (
39073979 chanPoint , lnChan , initialPolicy , chainEvents ,
3908- shouldReestablish ,
3980+ shouldReestablish , fn . None [lnwire. Shutdown ](),
39093981 )
39103982 if err != nil {
39113983 return fmt .Errorf ("can't register new channel link(%v) with " +
0 commit comments