contractcourt/chain_watcher: remove CooperativeCloseCtx
Removes CooperativeCloseCtx and methods.
This commit is contained in:
parent
21d1cc3fe8
commit
af14a2fc57
@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/roasbeef/btcd/chaincfg"
|
"github.com/roasbeef/btcd/chaincfg"
|
||||||
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
|
||||||
"github.com/roasbeef/btcd/txscript"
|
"github.com/roasbeef/btcd/txscript"
|
||||||
"github.com/roasbeef/btcd/wire"
|
"github.com/roasbeef/btcd/wire"
|
||||||
"github.com/roasbeef/btcutil"
|
"github.com/roasbeef/btcutil"
|
||||||
@ -123,12 +122,6 @@ type chainWatcher struct {
|
|||||||
// clientSubscriptions is a map that keeps track of all the active
|
// clientSubscriptions is a map that keeps track of all the active
|
||||||
// client subscriptions for events related to this channel.
|
// client subscriptions for events related to this channel.
|
||||||
clientSubscriptions map[uint64]*ChainEventSubscription
|
clientSubscriptions map[uint64]*ChainEventSubscription
|
||||||
|
|
||||||
// possibleCloses is a map from cooperative closing transaction txid to
|
|
||||||
// a close summary that describes the nature of the channel closure.
|
|
||||||
// We'll use this map to keep track of all possible channel closures to
|
|
||||||
// ensure out db state is correct in the end.
|
|
||||||
possibleCloses map[chainhash.Hash]*channeldb.ChannelCloseSummary
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// newChainWatcher returns a new instance of a chainWatcher for a channel given
|
// newChainWatcher returns a new instance of a chainWatcher for a channel given
|
||||||
@ -158,7 +151,6 @@ func newChainWatcher(cfg chainWatcherConfig) (*chainWatcher, error) {
|
|||||||
stateHintObfuscator: stateHint,
|
stateHintObfuscator: stateHint,
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
clientSubscriptions: make(map[uint64]*ChainEventSubscription),
|
clientSubscriptions: make(map[uint64]*ChainEventSubscription),
|
||||||
possibleCloses: make(map[chainhash.Hash]*channeldb.ChannelCloseSummary),
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,147 +743,3 @@ func (c *chainWatcher) dispatchContractBreach(spendEvent *chainntnfs.SpendDetail
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CooperativeCloseCtx is a transactional object that's used by external
|
|
||||||
// parties to initiate a cooperative closure negotiation. During the
|
|
||||||
// negotiation, we sign multiple versions of a closing transaction, either of
|
|
||||||
// which may be counter signed and broadcast by the remote party at any time.
|
|
||||||
// As a result, we'll need to watch the chain to see if any of these confirm,
|
|
||||||
// only afterwards will we mark the channel as fully closed.
|
|
||||||
type CooperativeCloseCtx struct {
|
|
||||||
// potentialCloses is a channel will be used by the party negotiating
|
|
||||||
// the cooperative closure to send possible closing states to the chain
|
|
||||||
// watcher to ensure we detect all on-chain spends.
|
|
||||||
potentialCloses chan *channeldb.ChannelCloseSummary
|
|
||||||
|
|
||||||
// activeCloses keeps track of all the txid's that we're currently
|
|
||||||
// watching for.
|
|
||||||
activeCloses map[chainhash.Hash]struct{}
|
|
||||||
|
|
||||||
// watchCancel will be closed once *one* of the txid's in the map above
|
|
||||||
// is confirmed. This will cause all the lingering goroutines to exit.
|
|
||||||
watchCancel chan struct{}
|
|
||||||
|
|
||||||
watcher *chainWatcher
|
|
||||||
|
|
||||||
sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// BeginCooperativeClose should be called by the party negotiating the
|
|
||||||
// cooperative closure before the first signature is sent to the remote party.
|
|
||||||
// This will return a context that should be used to communicate possible
|
|
||||||
// closing states so we can act on them.
|
|
||||||
func (c *chainWatcher) BeginCooperativeClose() *CooperativeCloseCtx {
|
|
||||||
// We'll simply return a new close context that will be used be the
|
|
||||||
// caller to notify us of potential closes.
|
|
||||||
return &CooperativeCloseCtx{
|
|
||||||
potentialCloses: make(chan *channeldb.ChannelCloseSummary),
|
|
||||||
watchCancel: make(chan struct{}),
|
|
||||||
activeCloses: make(map[chainhash.Hash]struct{}),
|
|
||||||
watcher: c,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogPotentialClose should be called by the party negotiating the cooperative
|
|
||||||
// closure once they signed a new state, but *before* they transmit it to the
|
|
||||||
// remote party. This will ensure that the chain watcher is able to log the new
|
|
||||||
// state it should watch the chain for.
|
|
||||||
func (c *CooperativeCloseCtx) LogPotentialClose(potentialClose *channeldb.ChannelCloseSummary) {
|
|
||||||
c.Lock()
|
|
||||||
defer c.Unlock()
|
|
||||||
|
|
||||||
// We'll check to see if we're already watching for a close of this
|
|
||||||
// channel, if so, then we'll exit early to avoid launching a duplicate
|
|
||||||
// goroutine.
|
|
||||||
if _, ok := c.activeCloses[potentialClose.ClosingTXID]; ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, we'll mark this txid as currently being watched.
|
|
||||||
c.activeCloses[potentialClose.ClosingTXID] = struct{}{}
|
|
||||||
|
|
||||||
// We'll take this potential close, and launch a goroutine which will
|
|
||||||
// wait until it's confirmed, then update the database state. When a
|
|
||||||
// potential close gets confirmed, we'll cancel out all other launched
|
|
||||||
// goroutines.
|
|
||||||
go func() {
|
|
||||||
confNtfn, err := c.watcher.cfg.notifier.RegisterConfirmationsNtfn(
|
|
||||||
&potentialClose.ClosingTXID, 1,
|
|
||||||
uint32(potentialClose.CloseHeight),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("unable to register for conf: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Infof("closeCtx: waiting for txid=%v to close "+
|
|
||||||
"ChannelPoint(%v) on chain", potentialClose.ClosingTXID,
|
|
||||||
c.watcher.cfg.chanState.FundingOutpoint)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case confInfo, ok := <-confNtfn.Confirmed:
|
|
||||||
if !ok {
|
|
||||||
log.Errorf("notifier exiting")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Infof("closeCtx: ChannelPoint(%v) is fully closed, at "+
|
|
||||||
"height: %v", c.watcher.cfg.chanState.FundingOutpoint,
|
|
||||||
confInfo.BlockHeight)
|
|
||||||
|
|
||||||
close(c.watchCancel)
|
|
||||||
|
|
||||||
c.watcher.Lock()
|
|
||||||
for _, sub := range c.watcher.clientSubscriptions {
|
|
||||||
select {
|
|
||||||
case sub.CooperativeClosure <- struct{}{}:
|
|
||||||
case <-c.watcher.quit:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.watcher.Unlock()
|
|
||||||
|
|
||||||
err := c.watcher.cfg.chanState.CloseChannel(potentialClose)
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("closeCtx: unable to update latest "+
|
|
||||||
"close for ChannelPoint(%v): %v",
|
|
||||||
c.watcher.cfg.chanState.FundingOutpoint, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = c.watcher.cfg.markChanClosed()
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("closeCtx: unable to mark chan fully "+
|
|
||||||
"closed: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
case <-c.watchCancel:
|
|
||||||
log.Debugf("Exiting watch for close of txid=%v for "+
|
|
||||||
"ChannelPoint(%v)", potentialClose.ClosingTXID,
|
|
||||||
c.watcher.cfg.chanState.FundingOutpoint)
|
|
||||||
|
|
||||||
case <-c.watcher.quit:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finalize should be called once both parties agree on a final transaction to
|
|
||||||
// close out the channel. This method will immediately mark the channel as
|
|
||||||
// pending closed in the database, then launch a goroutine to mark the channel
|
|
||||||
// fully closed upon confirmation.
|
|
||||||
func (c *CooperativeCloseCtx) Finalize(preferredClose *channeldb.ChannelCloseSummary) error {
|
|
||||||
chanPoint := c.watcher.cfg.chanState.FundingOutpoint
|
|
||||||
|
|
||||||
log.Infof("Finalizing chan close for ChannelPoint(%v)", chanPoint)
|
|
||||||
|
|
||||||
err := c.watcher.cfg.chanState.CloseChannel(preferredClose)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("closeCtx: unable to close ChannelPoint(%v): %v",
|
|
||||||
chanPoint, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
go c.LogPotentialClose(preferredClose)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user