Skip to content

Commit e4c4d94

Browse files
multi: add new config option upfront-shutdown-address
Introduced a new config value `upfront-shutdown-address` in the `lnd.conf` file. This ensures that channel close funds are transferred to the specified shutdown address. The value applies to both the funder and the fundee but can be overridden by the value specified during `openchannel` or by the `channel acceptor`. NOTE: If this field is set when opening a channel with a peer that does not advertise support for upfront shutdown feature, the channel open will fail. Signed-off-by: Nishant Bansal <[email protected]>
1 parent af6816b commit e4c4d94

File tree

5 files changed

+62
-6
lines changed

5 files changed

+62
-6
lines changed

config.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,15 @@ type Config struct {
537537
// NoDisconnectOnPongFailure controls if we'll disconnect if a peer
538538
// doesn't respond to a pong in time.
539539
NoDisconnectOnPongFailure bool `long:"no-disconnect-on-pong-failure" description:"If true, a peer will *not* be disconnected if a pong is not received in time or is mismatched. Defaults to false, meaning peers *will* be disconnected on pong failure."`
540+
541+
// UpfrontShutdownAddr specifies an address that our funds will be paid
542+
// out to on cooperative channel close. This applies to all new channel
543+
// opens unless overridden by an option in openchannel or by a channel
544+
// acceptor.
545+
// Note: If this field is set when opening a channel with a peer that
546+
// does not advertise support for the upfront shutdown feature, the
547+
// channel open will fail.
548+
UpfrontShutdownAddr string `long:"upfront-shutdown-address" description:"The address to which funds will be paid out during a cooperative channel close. This applies to all channels opened after this option is set, unless overridden for a specific channel opening. Note: If this option is set, any channel opening will fail if the peer does not explicitly advertise support for the upfront-shutdown feature bit."`
540549
}
541550

542551
// GRPCConfig holds the configuration options for the gRPC server.

funding/manager.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,10 @@ type Config struct {
573573
// implementations to inject and process custom records over channel
574574
// related wire messages.
575575
AuxChannelNegotiator fn.Option[lnwallet.AuxChannelNegotiator]
576+
577+
// ShutdownScript is an optional upfront-shutdown script to which our
578+
// funds should be paid on a cooperative close.
579+
ShutdownScript fn.Option[lnwire.DeliveryAddress]
576580
}
577581

578582
// Manager acts as an orchestrator/bridge between the wallet's
@@ -1760,12 +1764,24 @@ func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
17601764
return
17611765
}
17621766

1767+
// If the fundee didn't provide an upfront-shutdown address via
1768+
// the channel acceptor, fall back to the configured shutdown
1769+
// script (if any).
1770+
shutdownScript := acceptorResp.UpfrontShutdown
1771+
if len(shutdownScript) == 0 {
1772+
f.cfg.ShutdownScript.WhenSome(
1773+
func(script lnwire.DeliveryAddress) {
1774+
shutdownScript = script
1775+
},
1776+
)
1777+
}
1778+
17631779
// Check whether the peer supports upfront shutdown, and get a new
17641780
// wallet address if our node is configured to set shutdown addresses by
17651781
// default. We use the upfront shutdown script provided by our channel
17661782
// acceptor (if any) in lieu of user input.
17671783
shutdown, err := getUpfrontShutdownScript(
1768-
f.cfg.EnableUpfrontShutdown, peer, acceptorResp.UpfrontShutdown,
1784+
f.cfg.EnableUpfrontShutdown, peer, shutdownScript,
17691785
f.selectShutdownScript,
17701786
)
17711787
if err != nil {
@@ -4849,12 +4865,23 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
48494865
}
48504866
}
48514867

4868+
// If the funder did not provide an upfront-shutdown address, fall back
4869+
// to the configured shutdown script (if any).
4870+
shutdownScript := msg.ShutdownScript
4871+
if len(shutdownScript) == 0 {
4872+
f.cfg.ShutdownScript.WhenSome(
4873+
func(script lnwire.DeliveryAddress) {
4874+
shutdownScript = script
4875+
},
4876+
)
4877+
}
4878+
48524879
// Check whether the peer supports upfront shutdown, and get an address
48534880
// which should be used (either a user specified address or a new
48544881
// address from the wallet if our node is configured to set shutdown
48554882
// address by default).
48564883
shutdown, err := getUpfrontShutdownScript(
4857-
f.cfg.EnableUpfrontShutdown, msg.Peer, msg.ShutdownScript,
4884+
f.cfg.EnableUpfrontShutdown, msg.Peer, shutdownScript,
48584885
f.selectShutdownScript,
48594886
)
48604887
if err != nil {

peer/brontide.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3589,9 +3589,9 @@ func (p *Brontide) initNegotiateChanCloser(req *htlcswitch.ChanClose,
35893589
return nil
35903590
}
35913591

3592-
// chooseAddr returns the provided address if it is non-zero length, otherwise
3592+
// ChooseAddr returns the provided address if it is non-zero length, otherwise
35933593
// None.
3594-
func chooseAddr(addr lnwire.DeliveryAddress) fn.Option[lnwire.DeliveryAddress] {
3594+
func ChooseAddr(addr lnwire.DeliveryAddress) fn.Option[lnwire.DeliveryAddress] {
35953595
if len(addr) == 0 {
35963596
return fn.None[lnwire.DeliveryAddress]()
35973597
}
@@ -3930,10 +3930,10 @@ func (p *Brontide) initRbfChanCloser(
39303930
ChanType: channel.ChanType(),
39313931
DefaultFeeRate: defaultFeePerKw.FeePerVByte(),
39323932
ThawHeight: fn.Some(thawHeight),
3933-
RemoteUpfrontShutdown: chooseAddr(
3933+
RemoteUpfrontShutdown: ChooseAddr(
39343934
channel.RemoteUpfrontShutdownScript(),
39353935
),
3936-
LocalUpfrontShutdown: chooseAddr(
3936+
LocalUpfrontShutdown: ChooseAddr(
39373937
channel.LocalUpfrontShutdownScript(),
39383938
),
39393939
NewDeliveryScript: func() (lnwire.DeliveryAddress, error) {

sample-lnd.conf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,15 @@
589589
; pong failure.
590590
; no-disconnect-on-pong-failure=false
591591

592+
; The address to which funds will be paid out during a cooperative channel
593+
; close. This applies to all channels opened after this option is set, unless
594+
; overridden for a specific channel opening.
595+
;
596+
; Note: If this option is set, any channel opening will fail if the peer does
597+
; not explicitly advertise support for the upfront-shutdown feature bit.
598+
; upfront-shutdown-address=
599+
600+
592601
[fee]
593602

594603
; Optional URL for external fee estimation. If no URL is specified, the method

server.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import (
6161
"github.com/lightningnetwork/lnd/lnutils"
6262
"github.com/lightningnetwork/lnd/lnwallet"
6363
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
64+
"github.com/lightningnetwork/lnd/lnwallet/chancloser"
6465
"github.com/lightningnetwork/lnd/lnwallet/chanfunding"
6566
"github.com/lightningnetwork/lnd/lnwallet/rpcwallet"
6667
"github.com/lightningnetwork/lnd/lnwire"
@@ -1445,6 +1446,15 @@ func newServer(ctx context.Context, cfg *Config, listenAddrs []net.Addr,
14451446
devCfg, reservationTimeout, zombieSweeperInterval)
14461447
}
14471448

1449+
// Attempt to parse the provided upfront-shutdown address (if any).
1450+
script, err := chancloser.ParseUpfrontShutdownAddress(
1451+
cfg.UpfrontShutdownAddr, cfg.ActiveNetParams.Params,
1452+
)
1453+
if err != nil {
1454+
return nil, fmt.Errorf("error parsing upfront shutdown: %w",
1455+
err)
1456+
}
1457+
14481458
//nolint:ll
14491459
s.fundingMgr, err = funding.NewFundingManager(funding.Config{
14501460
Dev: devCfg,
@@ -1623,6 +1633,7 @@ func newServer(ctx context.Context, cfg *Config, listenAddrs []net.Addr,
16231633
AuxSigner: implCfg.AuxSigner,
16241634
AuxResolver: implCfg.AuxContractResolver,
16251635
AuxChannelNegotiator: implCfg.AuxChannelNegotiator,
1636+
ShutdownScript: peer.ChooseAddr(script),
16261637
})
16271638
if err != nil {
16281639
return nil, err

0 commit comments

Comments
 (0)