chancloser: deny co-op close initiated by the chan initiator for frozen chans
This commit is contained in:
parent
c85f6bb364
commit
1ac7550e3f
@ -347,6 +347,21 @@ func (c *channelCloser) ProcessCloseMsg(msg lnwire.Message) ([]lnwire.Message, b
|
||||
"instead have %v", spew.Sdump(msg))
|
||||
}
|
||||
|
||||
// As we're the responder to this shutdown (the other party
|
||||
// wants to close), we'll check if this is a frozen channel or
|
||||
// not. If the channel is frozen as we were also the initiator
|
||||
// of the channel opening, then we'll deny their close attempt.
|
||||
chanInitiator := c.cfg.channel.IsInitiator()
|
||||
if !chanInitiator && c.cfg.channel.State().ChanType.IsFrozen() &&
|
||||
c.negotiationHeight < c.cfg.channel.State().ThawHeight {
|
||||
|
||||
return nil, false, fmt.Errorf("initiator attempting "+
|
||||
"to co-op close frozen ChannelPoint(%v) "+
|
||||
"(current_height=%v, thaw_height=%v)",
|
||||
c.chanPoint, c.negotiationHeight,
|
||||
c.cfg.channel.State().ThawHeight)
|
||||
}
|
||||
|
||||
// If the remote node opened the channel with option upfront shutdown
|
||||
// script, check that the script they provided matches.
|
||||
if err := maybeMatchScript(
|
||||
@ -382,7 +397,7 @@ func (c *channelCloser) ProcessCloseMsg(msg lnwire.Message) ([]lnwire.Message, b
|
||||
|
||||
// We'll also craft our initial close proposal in order to keep
|
||||
// the negotiation moving, but only if we're the negotiator.
|
||||
if c.cfg.channel.IsInitiator() {
|
||||
if chanInitiator {
|
||||
closeSigned, err := c.proposeCloseSigned(c.idealFeeSat)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
|
28
rpcserver.go
28
rpcserver.go
@ -1470,8 +1470,8 @@ func extractOpenChannelMinConfs(in *lnrpc.OpenChannelRequest) (int32, error) {
|
||||
|
||||
// newFundingShimAssembler returns a new fully populated
|
||||
// chanfunding.CannedAssembler using a FundingShim obtained from an RPC caller.
|
||||
func newFundingShimAssembler(chanPointShim *lnrpc.ChanPointShim,
|
||||
initiator bool, keyRing keychain.KeyRing) (chanfunding.Assembler, error) {
|
||||
func newFundingShimAssembler(chanPointShim *lnrpc.ChanPointShim, initiator bool,
|
||||
keyRing keychain.KeyRing) (chanfunding.Assembler, error) {
|
||||
|
||||
// Perform some basic sanity checks to ensure that all the expected
|
||||
// fields are populated.
|
||||
@ -1545,8 +1545,9 @@ func newFundingShimAssembler(chanPointShim *lnrpc.ChanPointShim,
|
||||
// With all the parts assembled, we can now make the canned assembler
|
||||
// to pass into the wallet.
|
||||
return chanfunding.NewCannedAssembler(
|
||||
0, *chanPoint, btcutil.Amount(chanPointShim.Amt),
|
||||
&localKeyDesc, remoteKey, initiator,
|
||||
chanPointShim.ThawHeight, *chanPoint,
|
||||
btcutil.Amount(chanPointShim.Amt), &localKeyDesc,
|
||||
remoteKey, initiator,
|
||||
), nil
|
||||
}
|
||||
|
||||
@ -1956,15 +1957,25 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
|
||||
return err
|
||||
}
|
||||
|
||||
// If this is a frozen channel, then we only allow the close to proceed
|
||||
// if we were the responder to this channel.
|
||||
_, bestHeight, err := r.server.cc.chainIO.GetBestBlock()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if channel.State().ChanType.IsFrozen() && channel.IsInitiator() &&
|
||||
uint32(bestHeight) < channel.State().ThawHeight {
|
||||
|
||||
return fmt.Errorf("cannot co-op close frozen channel as "+
|
||||
"initiator until height=%v, (current_height=%v)",
|
||||
channel.State().ThawHeight, bestHeight)
|
||||
}
|
||||
|
||||
// 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
|
||||
// interaction from the peer.
|
||||
if force {
|
||||
_, bestHeight, err := r.server.cc.chainIO.GetBestBlock()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// As we're force closing this channel, as a precaution, we'll
|
||||
// ensure that the switch doesn't continue to see this channel
|
||||
@ -3179,6 +3190,7 @@ func createRPCOpenChannel(r *rpcServer, graph *channeldb.ChannelGraph,
|
||||
RemoteChanReserveSat: int64(dbChannel.RemoteChanCfg.ChanReserve),
|
||||
StaticRemoteKey: commitmentType == lnrpc.CommitmentType_STATIC_REMOTE_KEY,
|
||||
CommitmentType: commitmentType,
|
||||
ThawHeight: dbChannel.ThawHeight,
|
||||
}
|
||||
|
||||
for i, htlc := range localCommit.Htlcs {
|
||||
|
Loading…
Reference in New Issue
Block a user