peer: properly process retransmitted FundingLocked message we've never processed

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
This commit is contained in:
Olaoluwa Osuntokun 2017-12-05 18:00:33 -08:00
parent ddc5a0fc85
commit 3bc248e01c
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21

35
peer.go

@ -1171,13 +1171,46 @@ out:
// Make sure this channel is not already active. // Make sure this channel is not already active.
p.activeChanMtx.Lock() p.activeChanMtx.Lock()
if _, ok := p.activeChannels[chanID]; ok { if currentChan, ok := p.activeChannels[chanID]; ok {
peerLog.Infof("Already have ChannelPoint(%v), "+ peerLog.Infof("Already have ChannelPoint(%v), "+
"ignoring.", chanPoint) "ignoring.", chanPoint)
p.activeChanMtx.Unlock() p.activeChanMtx.Unlock()
close(newChanReq.done) close(newChanReq.done)
newChanReq.channel.Stop() newChanReq.channel.Stop()
newChanReq.channel.CancelObserver() 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 continue
} }