From 3bc248e01c1ffaeb7be3a5fc057165d468f39445 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 5 Dec 2017 18:00:33 -0800 Subject: [PATCH] peer: properly process retransmitted FundingLocked message we've never processed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this commit, we modify the logic within the channelManager to be able to process any retransmitted FundingLocked messages. Before this commit, we would simply ignore any new channels sent to us, iff, we already had an active channel with the same channel point. With the recent change to the loadActiveChannels method in the peer, this is now incorrect. When a peer retransmits the FundingLocked message, it goes through to the fundingManager. The fundingMgr will then (if we haven’t already processed it), send the channel to the breach arbiter and also to the peer’s channelManager. In order to handle this case properly, if we already have the channel, we’ll check if our current channel *doesn’t* already have the RemoteNextRevocation field set. If it doesn’t, then this means that we haven’t yet processed the FundingLcoked message, so we’ll process it for the first time. This new logic will properly: * ensure that the breachArbiter still has the most up to date channel * allow us to update the state of the link has been added to the switch at this point * this link will now be eligible for forwarding after this sequence --- peer.go | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/peer.go b/peer.go index 2a273a68..f00afccc 100644 --- a/peer.go +++ b/peer.go @@ -1171,13 +1171,46 @@ out: // Make sure this channel is not already active. p.activeChanMtx.Lock() - if _, ok := p.activeChannels[chanID]; ok { + if currentChan, ok := p.activeChannels[chanID]; ok { peerLog.Infof("Already have ChannelPoint(%v), "+ "ignoring.", chanPoint) + p.activeChanMtx.Unlock() close(newChanReq.done) newChanReq.channel.Stop() newChanReq.channel.CancelObserver() + + // We'll re-send our current channel to the + // breachArbiter to ensure that it has the most + // up to date version. + select { + case p.server.breachArbiter.newContracts <- currentChan: + case <-p.server.quit: + return + case <-p.quit: + return + } + + // If we're being sent a new channel, and our + // existing channel doesn't have the next + // revocation, then we need to update the + // current exsiting channel. + if currentChan.RemoteNextRevocation() != nil { + continue + } + + peerLog.Infof("Processing retransmitted "+ + "FundingLocked for ChannelPoint(%v)", + chanPoint) + + nextRevoke := newChan.RemoteNextRevocation() + err := currentChan.InitNextRevocation(nextRevoke) + if err != nil { + peerLog.Errorf("unable to init chan "+ + "revocation: %v", err) + continue + } + continue }