contractcourt/chain_watcher: create chainWatcherConfig

This commit is contained in:
Johan T. Halseth 2018-04-19 13:05:05 +02:00
parent 7c945b42fe
commit 0697510884
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26

@ -66,27 +66,14 @@ type ChainEventSubscription struct {
Cancel func() Cancel func()
} }
// chainWatcher is a system that's assigned to every active channel. The duty // chainWatcherConfig encapsulates all the necessary functions and interfaces
// of this system is to watch the chain for spends of the channels chan point. // needed to watch and act on on-chain events for a particular channel.
// If a spend is detected then with chain watcher will notify all subscribers type chainWatcherConfig struct {
// that the channel has been closed, and also give them the materials necessary
// to sweep the funds of the channel on chain eventually.
type chainWatcher struct {
started int32
stopped int32
quit chan struct{}
wg sync.WaitGroup
// chanState is a snapshot of the persistent state of the channel that // chanState is a snapshot of the persistent state of the channel that
// we're watching. In the event of an on-chain event, we'll query the // we're watching. In the event of an on-chain event, we'll query the
// database to ensure that we act using the most up to date state. // database to ensure that we act using the most up to date state.
chanState *channeldb.OpenChannel chanState *channeldb.OpenChannel
// stateHintObfuscator is a 48-bit state hint that's used to obfuscate
// the current state number on the commitment transactions.
stateHintObfuscator [lnwallet.StateHintSize]byte
// notifier is a reference to the channel notifier that we'll use to be // notifier is a reference to the channel notifier that we'll use to be
// notified of output spends and when transactions are confirmed. // notified of output spends and when transactions are confirmed.
notifier chainntnfs.ChainNotifier notifier chainntnfs.ChainNotifier
@ -101,6 +88,34 @@ type chainWatcher struct {
// machine. // machine.
signer lnwallet.Signer signer lnwallet.Signer
// markChanClosed is a method that will be called by the watcher if it
// detects that a cooperative closure transaction has successfully been
// confirmed.
markChanClosed func() error
// isOurAddr is a function that returns true if the passed address is
// known to us.
isOurAddr func(btcutil.Address) bool
}
// chainWatcher is a system that's assigned to every active channel. The duty
// of this system is to watch the chain for spends of the channels chan point.
// If a spend is detected then with chain watcher will notify all subscribers
// that the channel has been closed, and also give them the materials necessary
// to sweep the funds of the channel on chain eventually.
type chainWatcher struct {
started int32
stopped int32
quit chan struct{}
wg sync.WaitGroup
cfg chainWatcherConfig
// stateHintObfuscator is a 48-bit state hint that's used to obfuscate
// the current state number on the commitment transactions.
stateHintObfuscator [lnwallet.StateHintSize]byte
// All the fields below are protected by this mutex. // All the fields below are protected by this mutex.
sync.Mutex sync.Mutex
@ -117,30 +132,18 @@ type chainWatcher struct {
// We'll use this map to keep track of all possible channel closures to // We'll use this map to keep track of all possible channel closures to
// ensure out db state is correct in the end. // ensure out db state is correct in the end.
possibleCloses map[chainhash.Hash]*channeldb.ChannelCloseSummary possibleCloses map[chainhash.Hash]*channeldb.ChannelCloseSummary
// markChanClosed is a method that will be called by the watcher if it
// detects that a cooperative closure transaction has successfully been
// confirmed.
markChanClosed func() error
// isOurAddr is a function that returns true if the passed address is
// known to us.
isOurAddr func(btcutil.Address) bool
} }
// newChainWatcher returns a new instance of a chainWatcher for a channel given // newChainWatcher returns a new instance of a chainWatcher for a channel given
// the chan point to watch, and also a notifier instance that will allow us to // the chan point to watch, and also a notifier instance that will allow us to
// detect on chain events. // detect on chain events.
func newChainWatcher(chanState *channeldb.OpenChannel, func newChainWatcher(cfg chainWatcherConfig) (*chainWatcher, error) {
notifier chainntnfs.ChainNotifier, pCache WitnessBeacon,
signer lnwallet.Signer, isOurAddr func(btcutil.Address) bool,
markChanClosed func() error) (*chainWatcher, error) {
// In order to be able to detect the nature of a potential channel // In order to be able to detect the nature of a potential channel
// closure we'll need to reconstruct the state hint bytes used to // closure we'll need to reconstruct the state hint bytes used to
// obfuscate the commitment state number encoded in the lock time and // obfuscate the commitment state number encoded in the lock time and
// sequence fields. // sequence fields.
var stateHint [lnwallet.StateHintSize]byte var stateHint [lnwallet.StateHintSize]byte
chanState := cfg.chanState
if chanState.IsInitiator { if chanState.IsInitiator {
stateHint = lnwallet.DeriveStateHintObfuscator( stateHint = lnwallet.DeriveStateHintObfuscator(
chanState.LocalChanCfg.PaymentBasePoint.PubKey, chanState.LocalChanCfg.PaymentBasePoint.PubKey,
@ -154,15 +157,10 @@ func newChainWatcher(chanState *channeldb.OpenChannel,
} }
return &chainWatcher{ return &chainWatcher{
chanState: chanState, cfg: cfg,
stateHintObfuscator: stateHint, stateHintObfuscator: stateHint,
notifier: notifier,
pCache: pCache,
markChanClosed: markChanClosed,
signer: signer,
quit: make(chan struct{}), quit: make(chan struct{}),
clientSubscriptions: make(map[uint64]*ChainEventSubscription), clientSubscriptions: make(map[uint64]*ChainEventSubscription),
isOurAddr: isOurAddr,
possibleCloses: make(map[chainhash.Hash]*channeldb.ChannelCloseSummary), possibleCloses: make(map[chainhash.Hash]*channeldb.ChannelCloseSummary),
}, nil }, nil
} }
@ -174,22 +172,23 @@ func (c *chainWatcher) Start() error {
return nil return nil
} }
chanState := c.cfg.chanState
log.Debugf("Starting chain watcher for ChannelPoint(%v)", log.Debugf("Starting chain watcher for ChannelPoint(%v)",
c.chanState.FundingOutpoint) chanState.FundingOutpoint)
// First, we'll register for a notification to be dispatched if the // First, we'll register for a notification to be dispatched if the
// funding output is spent. // funding output is spent.
fundingOut := &c.chanState.FundingOutpoint fundingOut := &chanState.FundingOutpoint
// As a height hint, we'll try to use the opening height, but if the // As a height hint, we'll try to use the opening height, but if the
// channel isn't yet open, then we'll use the height it was broadcast // channel isn't yet open, then we'll use the height it was broadcast
// at. // at.
heightHint := c.chanState.ShortChanID.BlockHeight heightHint := chanState.ShortChanID.BlockHeight
if heightHint == 0 { if heightHint == 0 {
heightHint = c.chanState.FundingBroadcastHeight heightHint = chanState.FundingBroadcastHeight
} }
spendNtfn, err := c.notifier.RegisterSpendNtfn( spendNtfn, err := c.cfg.notifier.RegisterSpendNtfn(
fundingOut, heightHint, false, fundingOut, heightHint, false,
) )
if err != nil { if err != nil {
@ -233,10 +232,10 @@ func (c *chainWatcher) SubscribeChannelEvents(syncDispatch bool) *ChainEventSubs
c.Unlock() c.Unlock()
log.Debugf("New ChainEventSubscription(id=%v) for ChannelPoint(%v)", log.Debugf("New ChainEventSubscription(id=%v) for ChannelPoint(%v)",
clientID, c.chanState.FundingOutpoint) clientID, c.cfg.chanState.FundingOutpoint)
sub := &ChainEventSubscription{ sub := &ChainEventSubscription{
ChanPoint: c.chanState.FundingOutpoint, ChanPoint: c.cfg.chanState.FundingOutpoint,
RemoteUnilateralClosure: make(chan *lnwallet.UnilateralCloseSummary, 1), RemoteUnilateralClosure: make(chan *lnwallet.UnilateralCloseSummary, 1),
LocalUnilateralClosure: make(chan *LocalUnilateralCloseInfo, 1), LocalUnilateralClosure: make(chan *LocalUnilateralCloseInfo, 1),
CooperativeClosure: make(chan struct{}, 1), CooperativeClosure: make(chan struct{}, 1),
@ -293,7 +292,7 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) {
defer c.wg.Done() defer c.wg.Done()
log.Infof("Close observer for ChannelPoint(%v) active", log.Infof("Close observer for ChannelPoint(%v) active",
c.chanState.FundingOutpoint) c.cfg.chanState.FundingOutpoint)
select { select {
// We've detected a spend of the channel onchain! Depending on // We've detected a spend of the channel onchain! Depending on
@ -314,10 +313,10 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) {
// prior revoked state...!!! // prior revoked state...!!!
commitTxBroadcast := commitSpend.SpendingTx commitTxBroadcast := commitSpend.SpendingTx
localCommit, remoteCommit, err := c.chanState.LatestCommitments() localCommit, remoteCommit, err := c.cfg.chanState.LatestCommitments()
if err != nil { if err != nil {
log.Errorf("Unable to fetch channel state for "+ log.Errorf("Unable to fetch channel state for "+
"chan_point=%v", c.chanState.FundingOutpoint) "chan_point=%v", c.cfg.chanState.FundingOutpoint)
return return
} }
@ -326,10 +325,10 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) {
// channel state object that we have. // channel state object that we have.
// //
// TODO(roasbeef): mutation is bad mkay // TODO(roasbeef): mutation is bad mkay
_, err = c.chanState.RemoteRevocationStore() _, err = c.cfg.chanState.RemoteRevocationStore()
if err != nil { if err != nil {
log.Errorf("Unable to fetch revocation state for "+ log.Errorf("Unable to fetch revocation state for "+
"chan_point=%v", c.chanState.FundingOutpoint) "chan_point=%v", c.cfg.chanState.FundingOutpoint)
return return
} }
@ -346,7 +345,7 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) {
); err != nil { ); err != nil {
log.Errorf("unable to handle local"+ log.Errorf("unable to handle local"+
"close for chan_point=%v: %v", "close for chan_point=%v: %v",
c.chanState.FundingOutpoint, err) c.cfg.chanState.FundingOutpoint, err)
} }
return return
} }
@ -365,7 +364,7 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) {
} }
log.Warnf("Unprompted commitment broadcast for "+ log.Warnf("Unprompted commitment broadcast for "+
"ChannelPoint(%v) ", c.chanState.FundingOutpoint) "ChannelPoint(%v) ", c.cfg.chanState.FundingOutpoint)
// Decode the state hint encoded within the commitment // Decode the state hint encoded within the commitment
// transaction to determine if this is a revoked state // transaction to determine if this is a revoked state
@ -395,7 +394,7 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) {
); err != nil { ); err != nil {
log.Errorf("unable to handle remote "+ log.Errorf("unable to handle remote "+
"close for chan_point=%v: %v", "close for chan_point=%v: %v",
c.chanState.FundingOutpoint, err) c.cfg.chanState.FundingOutpoint, err)
} }
// If the state number broadcast is lower than the // If the state number broadcast is lower than the
@ -412,7 +411,7 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) {
); err != nil { ); err != nil {
log.Errorf("unable to handle channel "+ log.Errorf("unable to handle channel "+
"breach for chan_point=%v: %v", "breach for chan_point=%v: %v",
c.chanState.FundingOutpoint, err) c.cfg.chanState.FundingOutpoint, err)
} }
} }
@ -442,7 +441,7 @@ func (c *chainWatcher) toSelfAmount(tx *wire.MsgTx) btcutil.Amount {
} }
for _, addr := range addrs { for _, addr := range addrs {
if c.isOurAddr(addr) { if c.cfg.isOurAddr(addr) {
selfAmt += btcutil.Amount(txOut.Value) selfAmt += btcutil.Amount(txOut.Value)
} }
} }
@ -460,7 +459,7 @@ func (c *chainWatcher) dispatchCooperativeClose(commitSpend *chainntnfs.SpendDet
broadcastTx := commitSpend.SpendingTx broadcastTx := commitSpend.SpendingTx
log.Infof("Cooperative closure for ChannelPoint(%v): %v", log.Infof("Cooperative closure for ChannelPoint(%v): %v",
c.chanState.FundingOutpoint, spew.Sdump(broadcastTx)) c.cfg.chanState.FundingOutpoint, spew.Sdump(broadcastTx))
// If the input *is* final, then we'll check to see which output is // If the input *is* final, then we'll check to see which output is
// ours. // ours.
@ -469,18 +468,18 @@ func (c *chainWatcher) dispatchCooperativeClose(commitSpend *chainntnfs.SpendDet
// Once this is known, we'll mark the state as pending close in the // Once this is known, we'll mark the state as pending close in the
// database. // database.
closeSummary := &channeldb.ChannelCloseSummary{ closeSummary := &channeldb.ChannelCloseSummary{
ChanPoint: c.chanState.FundingOutpoint, ChanPoint: c.cfg.chanState.FundingOutpoint,
ChainHash: c.chanState.ChainHash, ChainHash: c.cfg.chanState.ChainHash,
ClosingTXID: *commitSpend.SpenderTxHash, ClosingTXID: *commitSpend.SpenderTxHash,
RemotePub: c.chanState.IdentityPub, RemotePub: c.cfg.chanState.IdentityPub,
Capacity: c.chanState.Capacity, Capacity: c.cfg.chanState.Capacity,
CloseHeight: uint32(commitSpend.SpendingHeight), CloseHeight: uint32(commitSpend.SpendingHeight),
SettledBalance: localAmt, SettledBalance: localAmt,
CloseType: channeldb.CooperativeClose, CloseType: channeldb.CooperativeClose,
ShortChanID: c.chanState.ShortChanID, ShortChanID: c.cfg.chanState.ShortChanID,
IsPending: true, IsPending: true,
} }
err := c.chanState.CloseChannel(closeSummary) err := c.cfg.chanState.CloseChannel(closeSummary)
if err != nil && err != channeldb.ErrNoActiveChannels && if err != nil && err != channeldb.ErrNoActiveChannels &&
err != channeldb.ErrNoChanDBExists { err != channeldb.ErrNoChanDBExists {
return fmt.Errorf("unable to close chan state: %v", err) return fmt.Errorf("unable to close chan state: %v", err)
@ -489,7 +488,7 @@ func (c *chainWatcher) dispatchCooperativeClose(commitSpend *chainntnfs.SpendDet
// Finally, we'll launch a goroutine to mark the channel as fully // Finally, we'll launch a goroutine to mark the channel as fully
// closed once the transaction confirmed. // closed once the transaction confirmed.
go func() { go func() {
confNtfn, err := c.notifier.RegisterConfirmationsNtfn( confNtfn, err := c.cfg.notifier.RegisterConfirmationsNtfn(
commitSpend.SpenderTxHash, 1, commitSpend.SpenderTxHash, 1,
uint32(commitSpend.SpendingHeight), uint32(commitSpend.SpendingHeight),
) )
@ -500,7 +499,7 @@ func (c *chainWatcher) dispatchCooperativeClose(commitSpend *chainntnfs.SpendDet
log.Infof("closeObserver: waiting for txid=%v to close "+ log.Infof("closeObserver: waiting for txid=%v to close "+
"ChannelPoint(%v) on chain", commitSpend.SpenderTxHash, "ChannelPoint(%v) on chain", commitSpend.SpenderTxHash,
c.chanState.FundingOutpoint) c.cfg.chanState.FundingOutpoint)
select { select {
case confInfo, ok := <-confNtfn.Confirmed: case confInfo, ok := <-confNtfn.Confirmed:
@ -510,10 +509,11 @@ func (c *chainWatcher) dispatchCooperativeClose(commitSpend *chainntnfs.SpendDet
} }
log.Infof("closeObserver: ChannelPoint(%v) is fully "+ log.Infof("closeObserver: ChannelPoint(%v) is fully "+
"closed, at height: %v", c.chanState.FundingOutpoint, "closed, at height: %v",
c.cfg.chanState.FundingOutpoint,
confInfo.BlockHeight) confInfo.BlockHeight)
err := c.markChanClosed() err := c.cfg.markChanClosed()
if err != nil { if err != nil {
log.Errorf("unable to mark chan fully "+ log.Errorf("unable to mark chan fully "+
"closed: %v", err) "closed: %v", err)
@ -546,11 +546,11 @@ func (c *chainWatcher) dispatchLocalForceClose(
localCommit channeldb.ChannelCommitment) error { localCommit channeldb.ChannelCommitment) error {
log.Infof("Local unilateral close of ChannelPoint(%v) "+ log.Infof("Local unilateral close of ChannelPoint(%v) "+
"detected", c.chanState.FundingOutpoint) "detected", c.cfg.chanState.FundingOutpoint)
forceClose, err := lnwallet.NewLocalForceCloseSummary( forceClose, err := lnwallet.NewLocalForceCloseSummary(
c.chanState, c.signer, c.pCache, commitSpend.SpendingTx, c.cfg.chanState, c.cfg.signer, c.cfg.pCache,
localCommit, commitSpend.SpendingTx, localCommit,
) )
if err != nil { if err != nil {
return err return err
@ -568,7 +568,7 @@ func (c *chainWatcher) dispatchLocalForceClose(
Capacity: chanSnapshot.Capacity, Capacity: chanSnapshot.Capacity,
CloseType: channeldb.LocalForceClose, CloseType: channeldb.LocalForceClose,
IsPending: true, IsPending: true,
ShortChanID: c.chanState.ShortChanID, ShortChanID: c.cfg.chanState.ShortChanID,
CloseHeight: uint32(commitSpend.SpendingHeight), CloseHeight: uint32(commitSpend.SpendingHeight),
} }
@ -583,7 +583,7 @@ func (c *chainWatcher) dispatchLocalForceClose(
htlcValue := btcutil.Amount(htlc.SweepSignDesc.Output.Value) htlcValue := btcutil.Amount(htlc.SweepSignDesc.Output.Value)
closeSummary.TimeLockedBalance += htlcValue closeSummary.TimeLockedBalance += htlcValue
} }
err = c.chanState.CloseChannel(closeSummary) err = c.cfg.chanState.CloseChannel(closeSummary)
if err != nil { if err != nil {
return fmt.Errorf("unable to delete channel state: %v", err) return fmt.Errorf("unable to delete channel state: %v", err)
} }
@ -614,13 +614,13 @@ func (c *chainWatcher) dispatchRemoteForceClose(commitSpend *chainntnfs.SpendDet
remoteCommit channeldb.ChannelCommitment) error { remoteCommit channeldb.ChannelCommitment) error {
log.Infof("Unilateral close of ChannelPoint(%v) "+ log.Infof("Unilateral close of ChannelPoint(%v) "+
"detected", c.chanState.FundingOutpoint) "detected", c.cfg.chanState.FundingOutpoint)
// First, we'll create a closure summary that contains all the // First, we'll create a closure summary that contains all the
// materials required to let each subscriber sweep the funds in the // materials required to let each subscriber sweep the funds in the
// channel on-chain. // channel on-chain.
uniClose, err := lnwallet.NewUnilateralCloseSummary(c.chanState, uniClose, err := lnwallet.NewUnilateralCloseSummary(c.cfg.chanState,
c.signer, c.pCache, commitSpend, remoteCommit, c.cfg.signer, c.cfg.pCache, commitSpend, remoteCommit,
) )
if err != nil { if err != nil {
return err return err
@ -629,7 +629,7 @@ func (c *chainWatcher) dispatchRemoteForceClose(commitSpend *chainntnfs.SpendDet
// As we've detected that the channel has been closed, immediately // As we've detected that the channel has been closed, immediately
// delete the state from disk, creating a close summary for future // delete the state from disk, creating a close summary for future
// usage by related sub-systems. // usage by related sub-systems.
err = c.chanState.CloseChannel(&uniClose.ChannelCloseSummary) err = c.cfg.chanState.CloseChannel(&uniClose.ChannelCloseSummary)
if err != nil { if err != nil {
return fmt.Errorf("unable to delete channel state: %v", err) return fmt.Errorf("unable to delete channel state: %v", err)
} }
@ -665,9 +665,9 @@ func (c *chainWatcher) dispatchContractBreach(spendEvent *chainntnfs.SpendDetail
log.Warnf("Remote peer has breached the channel contract for "+ log.Warnf("Remote peer has breached the channel contract for "+
"ChannelPoint(%v). Revoked state #%v was broadcast!!!", "ChannelPoint(%v). Revoked state #%v was broadcast!!!",
c.chanState.FundingOutpoint, broadcastStateNum) c.cfg.chanState.FundingOutpoint, broadcastStateNum)
if err := c.chanState.MarkBorked(); err != nil { if err := c.cfg.chanState.MarkBorked(); err != nil {
return fmt.Errorf("unable to mark channel as borked: %v", err) return fmt.Errorf("unable to mark channel as borked: %v", err)
} }
@ -681,7 +681,7 @@ func (c *chainWatcher) dispatchContractBreach(spendEvent *chainntnfs.SpendDetail
// //
// TODO(roasbeef): move to same package // TODO(roasbeef): move to same package
retribution, err := lnwallet.NewBreachRetribution( retribution, err := lnwallet.NewBreachRetribution(
c.chanState, broadcastStateNum, commitTxBroadcast, c.cfg.chanState, broadcastStateNum, commitTxBroadcast,
spendHeight, spendHeight,
) )
if err != nil { if err != nil {
@ -742,24 +742,24 @@ func (c *chainWatcher) dispatchContractBreach(spendEvent *chainntnfs.SpendDetail
// TODO(roasbeef): instead mark we got all the monies? // TODO(roasbeef): instead mark we got all the monies?
settledBalance := remoteCommit.LocalBalance.ToSatoshis() settledBalance := remoteCommit.LocalBalance.ToSatoshis()
closeSummary := channeldb.ChannelCloseSummary{ closeSummary := channeldb.ChannelCloseSummary{
ChanPoint: c.chanState.FundingOutpoint, ChanPoint: c.cfg.chanState.FundingOutpoint,
ChainHash: c.chanState.ChainHash, ChainHash: c.cfg.chanState.ChainHash,
ClosingTXID: *spendEvent.SpenderTxHash, ClosingTXID: *spendEvent.SpenderTxHash,
CloseHeight: spendHeight, CloseHeight: spendHeight,
RemotePub: c.chanState.IdentityPub, RemotePub: c.cfg.chanState.IdentityPub,
Capacity: c.chanState.Capacity, Capacity: c.cfg.chanState.Capacity,
SettledBalance: settledBalance, SettledBalance: settledBalance,
CloseType: channeldb.BreachClose, CloseType: channeldb.BreachClose,
IsPending: true, IsPending: true,
ShortChanID: c.chanState.ShortChanID, ShortChanID: c.cfg.chanState.ShortChanID,
} }
if err := c.chanState.CloseChannel(&closeSummary); err != nil { if err := c.cfg.chanState.CloseChannel(&closeSummary); err != nil {
return err return err
} }
log.Infof("Breached channel=%v marked pending-closed", log.Infof("Breached channel=%v marked pending-closed",
c.chanState.FundingOutpoint) c.cfg.chanState.FundingOutpoint)
return nil return nil
} }
@ -827,7 +827,7 @@ func (c *CooperativeCloseCtx) LogPotentialClose(potentialClose *channeldb.Channe
// potential close gets confirmed, we'll cancel out all other launched // potential close gets confirmed, we'll cancel out all other launched
// goroutines. // goroutines.
go func() { go func() {
confNtfn, err := c.watcher.notifier.RegisterConfirmationsNtfn( confNtfn, err := c.watcher.cfg.notifier.RegisterConfirmationsNtfn(
&potentialClose.ClosingTXID, 1, &potentialClose.ClosingTXID, 1,
uint32(potentialClose.CloseHeight), uint32(potentialClose.CloseHeight),
) )
@ -838,7 +838,7 @@ func (c *CooperativeCloseCtx) LogPotentialClose(potentialClose *channeldb.Channe
log.Infof("closeCtx: waiting for txid=%v to close "+ log.Infof("closeCtx: waiting for txid=%v to close "+
"ChannelPoint(%v) on chain", potentialClose.ClosingTXID, "ChannelPoint(%v) on chain", potentialClose.ClosingTXID,
c.watcher.chanState.FundingOutpoint) c.watcher.cfg.chanState.FundingOutpoint)
select { select {
case confInfo, ok := <-confNtfn.Confirmed: case confInfo, ok := <-confNtfn.Confirmed:
@ -848,7 +848,7 @@ func (c *CooperativeCloseCtx) LogPotentialClose(potentialClose *channeldb.Channe
} }
log.Infof("closeCtx: ChannelPoint(%v) is fully closed, at "+ log.Infof("closeCtx: ChannelPoint(%v) is fully closed, at "+
"height: %v", c.watcher.chanState.FundingOutpoint, "height: %v", c.watcher.cfg.chanState.FundingOutpoint,
confInfo.BlockHeight) confInfo.BlockHeight)
close(c.watchCancel) close(c.watchCancel)
@ -862,14 +862,14 @@ func (c *CooperativeCloseCtx) LogPotentialClose(potentialClose *channeldb.Channe
} }
c.watcher.Unlock() c.watcher.Unlock()
err := c.watcher.chanState.CloseChannel(potentialClose) err := c.watcher.cfg.chanState.CloseChannel(potentialClose)
if err != nil { if err != nil {
log.Warnf("closeCtx: unable to update latest "+ log.Warnf("closeCtx: unable to update latest "+
"close for ChannelPoint(%v): %v", "close for ChannelPoint(%v): %v",
c.watcher.chanState.FundingOutpoint, err) c.watcher.cfg.chanState.FundingOutpoint, err)
} }
err = c.watcher.markChanClosed() err = c.watcher.cfg.markChanClosed()
if err != nil { if err != nil {
log.Errorf("closeCtx: unable to mark chan fully "+ log.Errorf("closeCtx: unable to mark chan fully "+
"closed: %v", err) "closed: %v", err)
@ -879,7 +879,7 @@ func (c *CooperativeCloseCtx) LogPotentialClose(potentialClose *channeldb.Channe
case <-c.watchCancel: case <-c.watchCancel:
log.Debugf("Exiting watch for close of txid=%v for "+ log.Debugf("Exiting watch for close of txid=%v for "+
"ChannelPoint(%v)", potentialClose.ClosingTXID, "ChannelPoint(%v)", potentialClose.ClosingTXID,
c.watcher.chanState.FundingOutpoint) c.watcher.cfg.chanState.FundingOutpoint)
case <-c.watcher.quit: case <-c.watcher.quit:
return return
@ -892,11 +892,11 @@ func (c *CooperativeCloseCtx) LogPotentialClose(potentialClose *channeldb.Channe
// pending closed in the database, then launch a goroutine to mark the channel // pending closed in the database, then launch a goroutine to mark the channel
// fully closed upon confirmation. // fully closed upon confirmation.
func (c *CooperativeCloseCtx) Finalize(preferredClose *channeldb.ChannelCloseSummary) error { func (c *CooperativeCloseCtx) Finalize(preferredClose *channeldb.ChannelCloseSummary) error {
chanPoint := c.watcher.chanState.FundingOutpoint chanPoint := c.watcher.cfg.chanState.FundingOutpoint
log.Infof("Finalizing chan close for ChannelPoint(%v)", chanPoint) log.Infof("Finalizing chan close for ChannelPoint(%v)", chanPoint)
err := c.watcher.chanState.CloseChannel(preferredClose) err := c.watcher.cfg.chanState.CloseChannel(preferredClose)
if err != nil { if err != nil {
log.Errorf("closeCtx: unable to close ChannelPoint(%v): %v", log.Errorf("closeCtx: unable to close ChannelPoint(%v): %v",
chanPoint, err) chanPoint, err)