peer: add createChanCloser function to de-dupe NewChanCloser sites
This commit is contained in:
1 file changed
+97
-92
+97
-92
@@ -2408,6 +2408,15 @@ func (p *Brontide) reenableActiveChannels() {
|
|||||||
func (p *Brontide) fetchActiveChanCloser(chanID lnwire.ChannelID) (
|
func (p *Brontide) fetchActiveChanCloser(chanID lnwire.ChannelID) (
|
||||||
*chancloser.ChanCloser, error) {
|
*chancloser.ChanCloser, error) {
|
||||||
|
|
||||||
|
chanCloser, found := p.activeChanCloses[chanID]
|
||||||
|
if found {
|
||||||
|
// An entry will only be found if the closer has already been
|
||||||
|
// created for a non-pending channel or for a channel that had
|
||||||
|
// previously started the shutdown process but the connection
|
||||||
|
// was restarted.
|
||||||
|
return chanCloser, nil
|
||||||
|
}
|
||||||
|
|
||||||
// First, we'll ensure that we actually know of the target channel. If
|
// First, we'll ensure that we actually know of the target channel. If
|
||||||
// not, we'll ignore this message.
|
// not, we'll ignore this message.
|
||||||
p.activeChanMtx.RLock()
|
p.activeChanMtx.RLock()
|
||||||
@@ -2420,74 +2429,51 @@ func (p *Brontide) fetchActiveChanCloser(chanID lnwire.ChannelID) (
|
|||||||
return nil, ErrChannelNotFound
|
return nil, ErrChannelNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// We'll attempt to look up the matching state machine, if we can't
|
// Optimistically try a link shutdown, erroring out if it failed.
|
||||||
// find one then this means that the remote party is initiating a
|
if err := p.tryLinkShutdown(chanID); err != nil {
|
||||||
// cooperative channel closure.
|
peerLog.Errorf("failed link shutdown: %v", err)
|
||||||
chanCloser, ok := p.activeChanCloses[chanID]
|
return nil, err
|
||||||
if !ok {
|
|
||||||
// Optimistically try a link shutdown, erroring out if it
|
|
||||||
// failed.
|
|
||||||
if err := p.tryLinkShutdown(chanID); err != nil {
|
|
||||||
peerLog.Errorf("failed link shutdown: %v", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// We'll create a valid closing state machine in order to
|
|
||||||
// respond to the initiated cooperative channel closure. First,
|
|
||||||
// we set the delivery script that our funds will be paid out
|
|
||||||
// to. If an upfront shutdown script was set, we will use it.
|
|
||||||
// Otherwise, we get a fresh delivery script.
|
|
||||||
//
|
|
||||||
// TODO: Expose option to allow upfront shutdown script from
|
|
||||||
// watch-only accounts.
|
|
||||||
deliveryScript := channel.LocalUpfrontShutdownScript()
|
|
||||||
if len(deliveryScript) == 0 {
|
|
||||||
var err error
|
|
||||||
deliveryScript, err = p.genDeliveryScript()
|
|
||||||
if err != nil {
|
|
||||||
peerLog.Errorf("unable to gen delivery script: %v", err)
|
|
||||||
return nil, fmt.Errorf("close addr unavailable")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// In order to begin fee negotiations, we'll first compute our
|
|
||||||
// target ideal fee-per-kw.
|
|
||||||
feePerKw, err := p.cfg.FeeEstimator.EstimateFeePerKW(
|
|
||||||
p.cfg.CoopCloseTargetConfs,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
peerLog.Errorf("unable to query fee estimator: %v", err)
|
|
||||||
|
|
||||||
return nil, fmt.Errorf("unable to estimate fee")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, startingHeight, err := p.cfg.ChainIO.GetBestBlock()
|
|
||||||
if err != nil {
|
|
||||||
peerLog.Errorf("unable to obtain best block: %v", err)
|
|
||||||
return nil, fmt.Errorf("cannot obtain best block")
|
|
||||||
}
|
|
||||||
|
|
||||||
chanCloser = chancloser.NewChanCloser(
|
|
||||||
chancloser.ChanCloseCfg{
|
|
||||||
Channel: channel,
|
|
||||||
BroadcastTx: p.cfg.Wallet.PublishTransaction,
|
|
||||||
DisableChannel: func(chanPoint wire.OutPoint) error {
|
|
||||||
return p.cfg.ChanStatusMgr.RequestDisable(chanPoint, false)
|
|
||||||
},
|
|
||||||
Disconnect: func() error {
|
|
||||||
return p.cfg.DisconnectPeer(p.IdentityKey())
|
|
||||||
},
|
|
||||||
Quit: p.quit,
|
|
||||||
},
|
|
||||||
deliveryScript,
|
|
||||||
feePerKw,
|
|
||||||
uint32(startingHeight),
|
|
||||||
nil,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
p.activeChanCloses[chanID] = chanCloser
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We'll create a valid closing state machine in order to respond to
|
||||||
|
// the initiated cooperative channel closure. First, we set the
|
||||||
|
// delivery script that our funds will be paid out to. If an upfront
|
||||||
|
// shutdown script was set, we will use it. Otherwise, we get a fresh
|
||||||
|
// delivery script.
|
||||||
|
//
|
||||||
|
// TODO: Expose option to allow upfront shutdown script from watch-only
|
||||||
|
// accounts.
|
||||||
|
deliveryScript := channel.LocalUpfrontShutdownScript()
|
||||||
|
if len(deliveryScript) == 0 {
|
||||||
|
var err error
|
||||||
|
deliveryScript, err = p.genDeliveryScript()
|
||||||
|
if err != nil {
|
||||||
|
peerLog.Errorf("unable to gen delivery script: %v",
|
||||||
|
err)
|
||||||
|
return nil, fmt.Errorf("close addr unavailable")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// In order to begin fee negotiations, we'll first compute our target
|
||||||
|
// ideal fee-per-kw.
|
||||||
|
feePerKw, err := p.cfg.FeeEstimator.EstimateFeePerKW(
|
||||||
|
p.cfg.CoopCloseTargetConfs,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
peerLog.Errorf("unable to query fee estimator: %v", err)
|
||||||
|
return nil, fmt.Errorf("unable to estimate fee")
|
||||||
|
}
|
||||||
|
|
||||||
|
chanCloser, err = p.createChanCloser(
|
||||||
|
channel, deliveryScript, feePerKw, nil, false,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
peerLog.Errorf("unable to create chan closer: %v", err)
|
||||||
|
return nil, fmt.Errorf("unable to create chan closer")
|
||||||
|
}
|
||||||
|
|
||||||
|
p.activeChanCloses[chanID] = chanCloser
|
||||||
|
|
||||||
return chanCloser, nil
|
return chanCloser, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2522,6 +2508,43 @@ func chooseDeliveryScript(upfront,
|
|||||||
return upfront, nil
|
return upfront, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// createChanCloser constructs a ChanCloser from the passed parameters and is
|
||||||
|
// used to de-duplicate code.
|
||||||
|
func (p *Brontide) createChanCloser(channel *lnwallet.LightningChannel,
|
||||||
|
deliveryScript lnwire.DeliveryAddress, fee chainfee.SatPerKWeight,
|
||||||
|
req *htlcswitch.ChanClose,
|
||||||
|
locallyInitiated bool) (*chancloser.ChanCloser, error) {
|
||||||
|
|
||||||
|
_, startingHeight, err := p.cfg.ChainIO.GetBestBlock()
|
||||||
|
if err != nil {
|
||||||
|
peerLog.Errorf("unable to obtain best block: %v", err)
|
||||||
|
return nil, fmt.Errorf("cannot obtain best block")
|
||||||
|
}
|
||||||
|
|
||||||
|
chanCloser := chancloser.NewChanCloser(
|
||||||
|
chancloser.ChanCloseCfg{
|
||||||
|
Channel: channel,
|
||||||
|
BroadcastTx: p.cfg.Wallet.PublishTransaction,
|
||||||
|
DisableChannel: func(op wire.OutPoint) error {
|
||||||
|
return p.cfg.ChanStatusMgr.RequestDisable(
|
||||||
|
op, false,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
Disconnect: func() error {
|
||||||
|
return p.cfg.DisconnectPeer(p.IdentityKey())
|
||||||
|
},
|
||||||
|
Quit: p.quit,
|
||||||
|
},
|
||||||
|
deliveryScript,
|
||||||
|
fee,
|
||||||
|
uint32(startingHeight),
|
||||||
|
req,
|
||||||
|
locallyInitiated,
|
||||||
|
)
|
||||||
|
|
||||||
|
return chanCloser, nil
|
||||||
|
}
|
||||||
|
|
||||||
// handleLocalCloseReq kicks-off the workflow to execute a cooperative or
|
// handleLocalCloseReq kicks-off the workflow to execute a cooperative or
|
||||||
// forced unilateral closure of the channel initiated by a local subsystem.
|
// forced unilateral closure of the channel initiated by a local subsystem.
|
||||||
func (p *Brontide) handleLocalCloseReq(req *htlcswitch.ChanClose) {
|
func (p *Brontide) handleLocalCloseReq(req *htlcswitch.ChanClose) {
|
||||||
@@ -2575,15 +2598,6 @@ func (p *Brontide) handleLocalCloseReq(req *htlcswitch.ChanClose) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next, we'll create a new channel closer state machine to
|
|
||||||
// handle the close negotiation.
|
|
||||||
_, startingHeight, err := p.cfg.ChainIO.GetBestBlock()
|
|
||||||
if err != nil {
|
|
||||||
peerLog.Errorf(err.Error())
|
|
||||||
req.Err <- err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optimistically try a link shutdown, erroring out if it
|
// Optimistically try a link shutdown, erroring out if it
|
||||||
// failed.
|
// failed.
|
||||||
if err := p.tryLinkShutdown(chanID); err != nil {
|
if err := p.tryLinkShutdown(chanID); err != nil {
|
||||||
@@ -2592,24 +2606,15 @@ func (p *Brontide) handleLocalCloseReq(req *htlcswitch.ChanClose) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
chanCloser := chancloser.NewChanCloser(
|
chanCloser, err := p.createChanCloser(
|
||||||
chancloser.ChanCloseCfg{
|
channel, deliveryScript, req.TargetFeePerKw, req, true,
|
||||||
Channel: channel,
|
|
||||||
BroadcastTx: p.cfg.Wallet.PublishTransaction,
|
|
||||||
DisableChannel: func(chanPoint wire.OutPoint) error {
|
|
||||||
return p.cfg.ChanStatusMgr.RequestDisable(chanPoint, false)
|
|
||||||
},
|
|
||||||
Disconnect: func() error {
|
|
||||||
return p.cfg.DisconnectPeer(p.IdentityKey())
|
|
||||||
},
|
|
||||||
Quit: p.quit,
|
|
||||||
},
|
|
||||||
deliveryScript,
|
|
||||||
req.TargetFeePerKw,
|
|
||||||
uint32(startingHeight),
|
|
||||||
req,
|
|
||||||
true,
|
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
peerLog.Errorf(err.Error())
|
||||||
|
req.Err <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
p.activeChanCloses[chanID] = chanCloser
|
p.activeChanCloses[chanID] = chanCloser
|
||||||
|
|
||||||
// Finally, we'll initiate the channel shutdown within the
|
// Finally, we'll initiate the channel shutdown within the
|
||||||
|
|||||||
Reference in new issue
Block a user