From d1c12202caa366fe4d970ae140196e78b42e3261 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Thu, 8 Feb 2018 19:43:03 -0800 Subject: [PATCH] chancloser: initiator always sends the first CloseSigned msg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this commit, we update the chan closer state machine to be fully spec compliant. A recent change was made to the spec to enforce a strict ordering such that, the negotiation is well formed. To enact this change, we’ll ensure that before the closeFeeNegotiation phase, the *initiator* is always the one that sends the CloseSigned message first. --- chancloser.go | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/chancloser.go b/chancloser.go index 15f8e9b4..46cafe91 100644 --- a/chancloser.go +++ b/chancloser.go @@ -302,8 +302,8 @@ func (c *channelCloser) ProcessCloseMsg(msg lnwire.Message) ([]lnwire.Message, b peerLog.Infof("ChannelPoint(%v): Responding to shutdown", c.chanPoint) - msgsToSend := make([]lnwire.Message, 2) - msgsToSend[0] = localShutdown + msgsToSend := make([]lnwire.Message, 0, 2) + msgsToSend = append(msgsToSend, localShutdown) // After the other party receives this message, we'll actually // start the final stage of the closure process: fee @@ -312,12 +312,14 @@ func (c *channelCloser) ProcessCloseMsg(msg lnwire.Message) ([]lnwire.Message, b c.state = closeFeeNegotiation // We'll also craft our initial close proposal in order to keep - // the negotiation moving. - closeSigned, err := c.proposeCloseSigned(c.idealFeeSat) - if err != nil { - return nil, false, err + // the negotiation moving, but only if we're the negotiator. + if c.cfg.channel.IsInitiator() { + closeSigned, err := c.proposeCloseSigned(c.idealFeeSat) + if err != nil { + return nil, false, err + } + msgsToSend = append(msgsToSend, closeSigned) } - msgsToSend[1] = closeSigned // We'll return both sent of messages to sent to the remote // party to kick off the fee negotiation process. @@ -348,13 +350,19 @@ func (c *channelCloser) ProcessCloseMsg(msg lnwire.Message) ([]lnwire.Message, b "entering fee negotiation", c.chanPoint) // Starting with our ideal fee rate, we'll create an initial - // closing proposal. - closeSigned, err := c.proposeCloseSigned(c.idealFeeSat) - if err != nil { - return nil, false, err + // closing proposal, but only if we're the initiator, as + // otherwise, the other party will send their first proposal + // first. + if c.cfg.channel.IsInitiator() { + closeSigned, err := c.proposeCloseSigned(c.idealFeeSat) + if err != nil { + return nil, false, err + } + + return []lnwire.Message{closeSigned}, false, nil } - return []lnwire.Message{closeSigned}, false, nil + return nil, false, nil // If we're receiving a message while we're in the fee negotiation // phase, then this indicates the remote party is responding a closed