mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-02-22 22:25:24 +01:00
contractcourt: for taproot channels, wait for conf in closeObserver
This ensures that we end up playing the target output on chain for taproot channels.
This commit is contained in:
parent
638516879f
commit
d4a6be1c9f
1 changed files with 43 additions and 10 deletions
|
@ -207,6 +207,13 @@ type chainWatcher struct {
|
||||||
// the current state number on the commitment transactions.
|
// the current state number on the commitment transactions.
|
||||||
stateHintObfuscator [lnwallet.StateHintSize]byte
|
stateHintObfuscator [lnwallet.StateHintSize]byte
|
||||||
|
|
||||||
|
// fundingPkScript is the pkScript of the funding output.
|
||||||
|
fundingPkScript []byte
|
||||||
|
|
||||||
|
// heightHint is the height hint used to checkpoint scans on chain for
|
||||||
|
// conf/spend events.
|
||||||
|
heightHint uint32
|
||||||
|
|
||||||
// All the fields below are protected by this mutex.
|
// All the fields below are protected by this mutex.
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
|
|
||||||
|
@ -267,9 +274,9 @@ func (c *chainWatcher) Start() error {
|
||||||
// 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. This may be an unconfirmed zero-conf channel.
|
// at. This may be an unconfirmed zero-conf channel.
|
||||||
heightHint := c.cfg.chanState.ShortChanID().BlockHeight
|
c.heightHint = c.cfg.chanState.ShortChanID().BlockHeight
|
||||||
if heightHint == 0 {
|
if c.heightHint == 0 {
|
||||||
heightHint = chanState.BroadcastHeight()
|
c.heightHint = chanState.BroadcastHeight()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since no zero-conf state is stored in a channel backup, the below
|
// Since no zero-conf state is stored in a channel backup, the below
|
||||||
|
@ -279,11 +286,11 @@ func (c *chainWatcher) Start() error {
|
||||||
if chanState.ZeroConfConfirmed() {
|
if chanState.ZeroConfConfirmed() {
|
||||||
// If the zero-conf channel is confirmed, we'll use the
|
// If the zero-conf channel is confirmed, we'll use the
|
||||||
// confirmed SCID's block height.
|
// confirmed SCID's block height.
|
||||||
heightHint = chanState.ZeroConfRealScid().BlockHeight
|
c.heightHint = chanState.ZeroConfRealScid().BlockHeight
|
||||||
} else {
|
} else {
|
||||||
// The zero-conf channel is unconfirmed. We'll need to
|
// The zero-conf channel is unconfirmed. We'll need to
|
||||||
// use the FundingBroadcastHeight.
|
// use the FundingBroadcastHeight.
|
||||||
heightHint = chanState.BroadcastHeight()
|
c.heightHint = chanState.BroadcastHeight()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,11 +298,10 @@ func (c *chainWatcher) Start() error {
|
||||||
remoteKey := chanState.RemoteChanCfg.MultiSigKey.PubKey
|
remoteKey := chanState.RemoteChanCfg.MultiSigKey.PubKey
|
||||||
|
|
||||||
var (
|
var (
|
||||||
pkScript []byte
|
err error
|
||||||
err error
|
|
||||||
)
|
)
|
||||||
if chanState.ChanType.IsTaproot() {
|
if chanState.ChanType.IsTaproot() {
|
||||||
pkScript, _, err = input.GenTaprootFundingScript(
|
c.fundingPkScript, _, err = input.GenTaprootFundingScript(
|
||||||
localKey, remoteKey, 0,
|
localKey, remoteKey, 0,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -309,14 +315,14 @@ func (c *chainWatcher) Start() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pkScript, err = input.WitnessScriptHash(multiSigScript)
|
c.fundingPkScript, err = input.WitnessScriptHash(multiSigScript)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spendNtfn, err := c.cfg.notifier.RegisterSpendNtfn(
|
spendNtfn, err := c.cfg.notifier.RegisterSpendNtfn(
|
||||||
fundingOut, pkScript, heightHint,
|
fundingOut, c.fundingPkScript, c.heightHint,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -582,6 +588,33 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) {
|
||||||
log.Infof("Close observer for ChannelPoint(%v) active",
|
log.Infof("Close observer for ChannelPoint(%v) active",
|
||||||
c.cfg.chanState.FundingOutpoint)
|
c.cfg.chanState.FundingOutpoint)
|
||||||
|
|
||||||
|
// If this is a taproot channel, before we proceed, we want to ensure
|
||||||
|
// that the expected funding output has confirmed on chain.
|
||||||
|
if c.cfg.chanState.ChanType.IsTaproot() {
|
||||||
|
fundingPoint := c.cfg.chanState.FundingOutpoint
|
||||||
|
|
||||||
|
confNtfn, err := c.cfg.notifier.RegisterConfirmationsNtfn(
|
||||||
|
&fundingPoint.Hash, c.fundingPkScript, 1, c.heightHint,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("unable to register for conf: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("Waiting for taproot ChannelPoint(%v) to confirm...",
|
||||||
|
c.cfg.chanState.FundingOutpoint)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case _, ok := <-confNtfn.Confirmed:
|
||||||
|
// If the channel was closed, then this means that the
|
||||||
|
// notifier exited, so we will as well.
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case <-c.quit:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
// We've detected a spend of the channel onchain! Depending on the type
|
// We've detected a spend of the channel onchain! Depending on the type
|
||||||
// of spend, we'll act accordingly, so we'll examine the spending
|
// of spend, we'll act accordingly, so we'll examine the spending
|
||||||
|
|
Loading…
Add table
Reference in a new issue