rpc: disallow attempting a co-op close of a channel with active HTLCs
In this commit, we fix a bug that at times could cause any dangling HTLC's to be sent to miner's fees if a user attempted to close out a channel cooperatively that still had pending HTLC's. We'll first prevent this at the RPC level by rejecting any attempts to trigger a co-op channel closure while a channel still have dangling HTLC's.
This commit is contained in:
parent
a0fe4fb716
commit
ecbeca5f29
25
rpcserver.go
25
rpcserver.go
@ -996,20 +996,19 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
|
|||||||
|
|
||||||
// TODO(roasbeef): if force and peer online then don't force?
|
// TODO(roasbeef): if force and peer online then don't force?
|
||||||
|
|
||||||
|
// First, we'll fetch the channel as is, as we'll need to examine it
|
||||||
|
// regardless of if this is a force close or not.
|
||||||
|
channel, err := r.fetchActiveChannel(*chanPoint)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
channel.Stop()
|
||||||
|
|
||||||
// If a force closure was requested, then we'll handle all the details
|
// If a force closure was requested, then we'll handle all the details
|
||||||
// around the creation and broadcast of the unilateral closure
|
// around the creation and broadcast of the unilateral closure
|
||||||
// transaction here rather than going to the switch as we don't require
|
// transaction here rather than going to the switch as we don't require
|
||||||
// interaction from the peer.
|
// interaction from the peer.
|
||||||
if force {
|
if force {
|
||||||
// As the first part of the force closure, we first fetch the
|
|
||||||
// channel from the database, then execute a direct force
|
|
||||||
// closure broadcasting our current commitment transaction.
|
|
||||||
channel, err := r.fetchActiveChannel(*chanPoint)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
channel.Stop()
|
|
||||||
|
|
||||||
_, bestHeight, err := r.server.cc.chainIO.GetBestBlock()
|
_, bestHeight, err := r.server.cc.chainIO.GetBestBlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -1092,6 +1091,14 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Before we attempt the cooperative channel closure, we'll
|
||||||
|
// examine the channel to ensure that it doesn't have a
|
||||||
|
// lingering HTLC.
|
||||||
|
if len(channel.localCommit.Htlcs) != 0 {
|
||||||
|
return nil, fmt.Errorf("cannot co-op close channel " +
|
||||||
|
"with active htlcs")
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise, the caller has requested a regular interactive
|
// Otherwise, the caller has requested a regular interactive
|
||||||
// cooperative channel closure. So we'll forward the request to
|
// cooperative channel closure. So we'll forward the request to
|
||||||
// the htlc switch which will handle the negotiation and
|
// the htlc switch which will handle the negotiation and
|
||||||
|
Loading…
Reference in New Issue
Block a user