From 3e1c98f2f72f83ac99b04e8207acfa4e3d89f62b Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 27 Dec 2016 15:54:57 -0800 Subject: [PATCH] breacharbiter: accept handoff for live channel on peer connect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit modifies the interaction between the breachArbiter and the peer struct such that the breachArbiter _always_ has the latest version of a contract. Prior to this commit once we connected out to a peer which we had an active contract with and the breachArbiter was watching, we’d have two copies of the channel in memory, instead of just a single one. This was wasteful and caused some duplicated log messages due to two instances of the channel being active. --- breacharbiter.go | 24 +++++++++++++++++++----- peer.go | 2 +- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/breacharbiter.go b/breacharbiter.go index 5344e8f8..0ea690e4 100644 --- a/breacharbiter.go +++ b/breacharbiter.go @@ -146,9 +146,6 @@ func (b *breachArbiter) contractObserver() { chanPoint := channel.ChannelPoint() b.breachObservers[*chanPoint] = settleSignal - // TODO(roasbeef): possibility of state divergence if updates - // conducted after re-connect, need to ensure only one instance - // is watched at all times b.wg.Add(1) go b.breachObserver(channel, settleSignal) } @@ -188,14 +185,30 @@ out: // the detection of attempted contract breaches. settleSignal := make(chan struct{}) chanPoint := contract.ChannelPoint() + + // If the contract is already being watched, then an + // additional send indicates we have a stale version of + // the contract. So we'll cancel active watcher + // goroutine to create a new instance with the latest + // contract reference. + if _, ok := b.breachObservers[*chanPoint]; ok { + brarLog.Infof("ChannelPoint(%v) is now live, "+ + "abandoning state contract for live "+ + "version", chanPoint) + close(settleSignal) + } + b.breachObservers[*chanPoint] = settleSignal - brarLog.Tracef("New contract detected, launching " + + brarLog.Debugf("New contract detected, launching " + "breachObserver") b.wg.Add(1) go b.breachObserver(contract, settleSignal) + // TODO(roasbeef): add doneChan to signal to peer continue + // * peer send over to us on loadActiveChanenls, sync + // until we're aware so no state transitions case chanPoint := <-b.settledContracts: // A new channel has been closed either unilaterally or // cooperatively, as a result we no longer need a @@ -387,7 +400,7 @@ func (b *breachArbiter) breachObserver(contract *lnwallet.LightningChannel, // Finally, with the two witness generation funcs created, we // send the retribution information to the utxo nursery. - // TODO(roasbeef): populate htlc breacches + // TODO(roasbeef): populate htlc breaches b.breachedContracts <- &retributionInfo{ commitHash: breachInfo.BreachTransaction.TxSha(), chanPoint: *chanPoint, @@ -406,6 +419,7 @@ func (b *breachArbiter) breachObserver(contract *lnwallet.LightningChannel, doneChan: make(chan struct{}), } + // TODO(roasbeef): delete chan state on unilateral close also? case <-b.quit: return } diff --git a/peer.go b/peer.go index f9f7ccb1..01bde9e6 100644 --- a/peer.go +++ b/peer.go @@ -232,7 +232,7 @@ func (p *peer) loadActiveChannels(chans []*channeldb.OpenChannel) error { peerLog.Infof("peerID(%v) loaded ChannelPoint(%v)", p.id, chanPoint) - // TODO(roasbeef): register active channel with breach observer + p.server.breachArbiter.newContracts <- lnChan // Register this new channel link with the HTLC Switch. This is // necessary to properly route multi-hop payments, and forward