multi: coop close with active HTLCs on the channel
For the lncli cmd we now always initiate the coop close even if there are active HTLCs on the channel. In case HTLCs are on the channel and the coop close is initiated LND handles the closing flow in the background and the lncli cmd will block until the transaction is broadcasted to the mempool. In the background LND disallows any new HTLCs and waits until all HTLCs are resolved before kicking of the negotiation process. Moreover if active HTLCs are present and the no_wait param is not set the error msg is now highlightning it so the user can react accordingly.
This commit is contained in:
6 files changed
+2353
-2273
No files matched your search
+18
-5
@@ -2717,6 +2717,9 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
|
||||
return err
|
||||
}
|
||||
|
||||
// Retrieve the number of active HTLCs on the channel.
|
||||
activeHtlcs := channel.ActiveHtlcs()
|
||||
|
||||
// If a force closure was requested, then we'll handle all the details
|
||||
// around the creation and broadcast of the unilateral closure
|
||||
// transaction here rather than going to the switch as we don't require
|
||||
@@ -2833,9 +2836,12 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
|
||||
// If the user hasn't specified NoWait, then before we attempt
|
||||
// to close the channel we ensure there are no active HTLCs on
|
||||
// the link.
|
||||
if !in.NoWait && len(channel.ActiveHtlcs()) != 0 {
|
||||
return fmt.Errorf("cannot co-op close channel " +
|
||||
"with active htlcs")
|
||||
if !in.NoWait && len(activeHtlcs) != 0 {
|
||||
return fmt.Errorf("cannot coop close channel with "+
|
||||
"active htlcs (number of active htlcs: %d), "+
|
||||
"bypass this check and initiate the coop "+
|
||||
"close by setting no_wait=true",
|
||||
len(activeHtlcs))
|
||||
}
|
||||
|
||||
// Otherwise, the caller has requested a regular interactive
|
||||
@@ -2879,12 +2885,19 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
|
||||
}
|
||||
|
||||
// If the user doesn't want to wait for the txid to come back then we
|
||||
// will send an empty update to kick off the stream.
|
||||
// will send an empty update to kick off the stream. This is also used
|
||||
// when active htlcs are still on the channel to give the client
|
||||
// immediate feedback.
|
||||
if in.NoWait {
|
||||
rpcsLog.Trace("[closechannel] sending instant update")
|
||||
if err := updateStream.Send(
|
||||
//nolint:ll
|
||||
&lnrpc.CloseStatusUpdate{
|
||||
Update: &lnrpc.CloseStatusUpdate_CloseInstant{},
|
||||
Update: &lnrpc.CloseStatusUpdate_CloseInstant{
|
||||
CloseInstant: &lnrpc.InstantUpdate{
|
||||
NumPendingHtlcs: int32(len(activeHtlcs)),
|
||||
},
|
||||
},
|
||||
},
|
||||
); err != nil {
|
||||
return err
|
||||
|
||||
Reference in new issue
Block a user