Merge pull request #9432 from NishantBansal2003/close-addr-conf
multi: add upfront-shutdown-address to lnd.conf.
This commit is contained in:
8 files changed
+146
-6
No files matched your search
@@ -537,6 +537,15 @@ type Config struct {
|
||||
// NoDisconnectOnPongFailure controls if we'll disconnect if a peer
|
||||
// doesn't respond to a pong in time.
|
||||
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."`
|
||||
|
||||
// UpfrontShutdownAddr specifies an address that our funds will be paid
|
||||
// out to on cooperative channel close. This applies to all new channel
|
||||
// opens unless overridden by an option in openchannel or by a channel
|
||||
// acceptor.
|
||||
// Note: If this field is set when opening a channel with a peer that
|
||||
// does not advertise support for the upfront shutdown feature, the
|
||||
// channel open will fail.
|
||||
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."`
|
||||
}
|
||||
|
||||
// GRPCConfig holds the configuration options for the gRPC server.
|
||||
|
||||
@@ -42,6 +42,12 @@
|
||||
# Improvements
|
||||
## Functional Updates
|
||||
|
||||
* [Added support](https://github.com/lightningnetwork/lnd/pull/9432) for the
|
||||
`upfront-shutdown-address` configuration in `lnd.conf`, allowing users to
|
||||
specify an address for cooperative channel closures where funds will be sent.
|
||||
This applies to both funders and fundees, with the ability to override the
|
||||
value during channel opening or acceptance.
|
||||
|
||||
## RPC Updates
|
||||
|
||||
## lncli Updates
|
||||
@@ -71,3 +77,4 @@
|
||||
|
||||
* Boris Nagaev
|
||||
* Elle Mouton
|
||||
* Nishant Bansal
|
||||
+29
-2
@@ -573,6 +573,10 @@ type Config struct {
|
||||
// implementations to inject and process custom records over channel
|
||||
// related wire messages.
|
||||
AuxChannelNegotiator fn.Option[lnwallet.AuxChannelNegotiator]
|
||||
|
||||
// ShutdownScript is an optional upfront-shutdown script to which our
|
||||
// funds should be paid on a cooperative close.
|
||||
ShutdownScript fn.Option[lnwire.DeliveryAddress]
|
||||
}
|
||||
|
||||
// Manager acts as an orchestrator/bridge between the wallet's
|
||||
@@ -1760,12 +1764,24 @@ func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
|
||||
return
|
||||
}
|
||||
|
||||
// If the fundee didn't provide an upfront-shutdown address via
|
||||
// the channel acceptor, fall back to the configured shutdown
|
||||
// script (if any).
|
||||
shutdownScript := acceptorResp.UpfrontShutdown
|
||||
if len(shutdownScript) == 0 {
|
||||
f.cfg.ShutdownScript.WhenSome(
|
||||
func(script lnwire.DeliveryAddress) {
|
||||
shutdownScript = script
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Check whether the peer supports upfront shutdown, and get a new
|
||||
// wallet address if our node is configured to set shutdown addresses by
|
||||
// default. We use the upfront shutdown script provided by our channel
|
||||
// acceptor (if any) in lieu of user input.
|
||||
shutdown, err := getUpfrontShutdownScript(
|
||||
f.cfg.EnableUpfrontShutdown, peer, acceptorResp.UpfrontShutdown,
|
||||
f.cfg.EnableUpfrontShutdown, peer, shutdownScript,
|
||||
f.selectShutdownScript,
|
||||
)
|
||||
if err != nil {
|
||||
@@ -4849,12 +4865,23 @@ func (f *Manager) handleInitFundingMsg(msg *InitFundingMsg) {
|
||||
}
|
||||
}
|
||||
|
||||
// If the funder did not provide an upfront-shutdown address, fall back
|
||||
// to the configured shutdown script (if any).
|
||||
shutdownScript := msg.ShutdownScript
|
||||
if len(shutdownScript) == 0 {
|
||||
f.cfg.ShutdownScript.WhenSome(
|
||||
func(script lnwire.DeliveryAddress) {
|
||||
shutdownScript = script
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Check whether the peer supports upfront shutdown, and get an address
|
||||
// which should be used (either a user specified address or a new
|
||||
// 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,
|
||||
f.cfg.EnableUpfrontShutdown, msg.Peer, shutdownScript,
|
||||
f.selectShutdownScript,
|
||||
)
|
||||
if err != nil {
|
||||
|
||||
@@ -286,6 +286,10 @@ var allTestCases = []*lntest.TestCase{
|
||||
Name: "open channel reorg test",
|
||||
TestFunc: testOpenChannelAfterReorg,
|
||||
},
|
||||
{
|
||||
Name: "open channel with shutdown address",
|
||||
TestFunc: testOpenChannelWithShutdownAddr,
|
||||
},
|
||||
{
|
||||
Name: "sign psbt",
|
||||
TestFunc: testSignPsbt,
|
||||
|
||||
@@ -1269,3 +1269,76 @@ func testFundingManagerFundingTimeout(ht *lntest.HarnessTest) {
|
||||
// Cleanup the mempool by mining blocks.
|
||||
ht.MineBlocksAndAssertNumTxes(6, 1)
|
||||
}
|
||||
|
||||
// testOpenChannelWithShutdownAddr verifies that if the funder or fundee
|
||||
// specifies an upfront shutdown address in the config, the funds are correctly
|
||||
// transferred to the specified address during channel closure.
|
||||
func testOpenChannelWithShutdownAddr(ht *lntest.HarnessTest) {
|
||||
const (
|
||||
// Channel funding amount in sat.
|
||||
channelAmount int64 = 100000
|
||||
|
||||
// Payment amount in sat.
|
||||
paymentAmount int64 = 50000
|
||||
)
|
||||
|
||||
// Create nodes for testing, ensuring Alice has sufficient initial
|
||||
// funds.
|
||||
alice := ht.NewNodeWithCoins("Alice", nil)
|
||||
bob := ht.NewNode("Bob", nil)
|
||||
|
||||
// Generate upfront shutdown addresses for both nodes.
|
||||
aliceShutdownAddr := alice.RPC.NewAddress(&lnrpc.NewAddressRequest{
|
||||
Type: lnrpc.AddressType_UNUSED_WITNESS_PUBKEY_HASH,
|
||||
})
|
||||
bobShutdownAddr := bob.RPC.NewAddress(&lnrpc.NewAddressRequest{
|
||||
Type: lnrpc.AddressType_UNUSED_WITNESS_PUBKEY_HASH,
|
||||
})
|
||||
|
||||
// Update nodes with upfront shutdown addresses and restart them.
|
||||
aliceNodeArgs := []string{
|
||||
fmt.Sprintf(
|
||||
"--upfront-shutdown-address=%s",
|
||||
aliceShutdownAddr.Address,
|
||||
),
|
||||
}
|
||||
ht.RestartNodeWithExtraArgs(alice, aliceNodeArgs)
|
||||
|
||||
bobNodeArgs := []string{
|
||||
fmt.Sprintf(
|
||||
"--upfront-shutdown-address=%s",
|
||||
bobShutdownAddr.Address,
|
||||
),
|
||||
}
|
||||
ht.RestartNodeWithExtraArgs(bob, bobNodeArgs)
|
||||
|
||||
// Connect Alice and Bob.
|
||||
ht.ConnectNodes(alice, bob)
|
||||
|
||||
// Open a channel between Alice and Bob.
|
||||
openChannelParams := lntest.OpenChannelParams{
|
||||
Amt: btcutil.Amount(channelAmount),
|
||||
PushAmt: btcutil.Amount(paymentAmount),
|
||||
}
|
||||
channelPoint := ht.OpenChannel(alice, bob, openChannelParams)
|
||||
|
||||
// Now close out the channel and obtain the raw closing TX.
|
||||
closingTxid := ht.CloseChannel(alice, channelPoint)
|
||||
closingTx := ht.GetRawTransaction(closingTxid).MsgTx()
|
||||
|
||||
// Calculate Alice's updated balance.
|
||||
aliceFee := ht.CalculateTxFee(closingTx)
|
||||
aliceExpectedBalance := channelAmount - paymentAmount - int64(aliceFee)
|
||||
|
||||
// Ensure Alice sees the change output in the list of unspent outputs.
|
||||
// We expect 6 confirmed UTXOs, as 5 UTXOs of 1 BTC each were sent to
|
||||
// the node during NewNodeWithCoins.
|
||||
aliceUTXOConfirmed := ht.AssertNumUTXOsConfirmed(alice, 6)[0]
|
||||
require.Equal(ht, aliceShutdownAddr.Address, aliceUTXOConfirmed.Address)
|
||||
require.Equal(ht, aliceExpectedBalance, aliceUTXOConfirmed.AmountSat)
|
||||
|
||||
// Ensure Bob see the change output in the list of unspent outputs.
|
||||
bobUTXOConfirmed := ht.AssertNumUTXOsConfirmed(bob, 1)[0]
|
||||
require.Equal(ht, bobShutdownAddr.Address, bobUTXOConfirmed.Address)
|
||||
require.Equal(ht, paymentAmount, bobUTXOConfirmed.AmountSat)
|
||||
}
|
||||
+4
-4
@@ -3589,9 +3589,9 @@ func (p *Brontide) initNegotiateChanCloser(req *htlcswitch.ChanClose,
|
||||
return nil
|
||||
}
|
||||
|
||||
// chooseAddr returns the provided address if it is non-zero length, otherwise
|
||||
// ChooseAddr returns the provided address if it is non-zero length, otherwise
|
||||
// None.
|
||||
func chooseAddr(addr lnwire.DeliveryAddress) fn.Option[lnwire.DeliveryAddress] {
|
||||
func ChooseAddr(addr lnwire.DeliveryAddress) fn.Option[lnwire.DeliveryAddress] {
|
||||
if len(addr) == 0 {
|
||||
return fn.None[lnwire.DeliveryAddress]()
|
||||
}
|
||||
@@ -3930,10 +3930,10 @@ func (p *Brontide) initRbfChanCloser(
|
||||
ChanType: channel.ChanType(),
|
||||
DefaultFeeRate: defaultFeePerKw.FeePerVByte(),
|
||||
ThawHeight: fn.Some(thawHeight),
|
||||
RemoteUpfrontShutdown: chooseAddr(
|
||||
RemoteUpfrontShutdown: ChooseAddr(
|
||||
channel.RemoteUpfrontShutdownScript(),
|
||||
),
|
||||
LocalUpfrontShutdown: chooseAddr(
|
||||
LocalUpfrontShutdown: ChooseAddr(
|
||||
channel.LocalUpfrontShutdownScript(),
|
||||
),
|
||||
NewDeliveryScript: func() (lnwire.DeliveryAddress, error) {
|
||||
|
||||
@@ -589,6 +589,15 @@
|
||||
; pong failure.
|
||||
; no-disconnect-on-pong-failure=false
|
||||
|
||||
; 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.
|
||||
; upfront-shutdown-address=
|
||||
|
||||
|
||||
[fee]
|
||||
|
||||
; Optional URL for external fee estimation. If no URL is specified, the method
|
||||
|
||||
@@ -61,6 +61,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lnutils"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chancloser"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chanfunding"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/rpcwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
@@ -1445,6 +1446,15 @@ func newServer(ctx context.Context, cfg *Config, listenAddrs []net.Addr,
|
||||
devCfg, reservationTimeout, zombieSweeperInterval)
|
||||
}
|
||||
|
||||
// Attempt to parse the provided upfront-shutdown address (if any).
|
||||
script, err := chancloser.ParseUpfrontShutdownAddress(
|
||||
cfg.UpfrontShutdownAddr, cfg.ActiveNetParams.Params,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing upfront shutdown: %w",
|
||||
err)
|
||||
}
|
||||
|
||||
//nolint:ll
|
||||
s.fundingMgr, err = funding.NewFundingManager(funding.Config{
|
||||
Dev: devCfg,
|
||||
@@ -1623,6 +1633,7 @@ func newServer(ctx context.Context, cfg *Config, listenAddrs []net.Addr,
|
||||
AuxSigner: implCfg.AuxSigner,
|
||||
AuxResolver: implCfg.AuxContractResolver,
|
||||
AuxChannelNegotiator: implCfg.AuxChannelNegotiator,
|
||||
ShutdownScript: peer.ChooseAddr(script),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in new issue
Block a user