Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5/? ] - lnwallet: add taproot funding support to the internal wallet flow (reservations) #7344

9 changes: 9 additions & 0 deletions channeldb/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ const (
// ScidAliasFeatureBit indicates that the scid-alias feature bit was
// negotiated during the lifetime of this channel.
ScidAliasFeatureBit ChannelType = 1 << 9

// SimpleTaprootFeatureBit indicates that the simple-taproot-channels
// feature bit was negotiated during the lifetime of the channel.
SimpleTaprootFeatureBit ChannelType = 1 << 10
)

// IsSingleFunder returns true if the channel type if one of the known single
Expand Down Expand Up @@ -360,6 +364,11 @@ func (c ChannelType) HasScidAliasFeature() bool {
return c&ScidAliasFeatureBit == ScidAliasFeatureBit
}

// IsTaproot returns true if the channel is using taproot features.
func (c ChannelType) IsTaproot() bool {
return c&SimpleTaprootFeatureBit == SimpleTaprootFeatureBit
}

// ChannelConstraints represents a set of constraints meant to allow a node to
// limit their exposure, enact flow control and ensure that all HTLCs are
// economically relevant. This struct will be mirrored for both sides of the
Expand Down
2 changes: 1 addition & 1 deletion contractcourt/chain_watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,7 @@ func (c *chainWatcher) handlePossibleBreach(commitSpend *chainntnfs.SpendDetail,

// Create an AnchorResolution for the breached state.
anchorRes, err := lnwallet.NewAnchorResolution(
c.cfg.chanState, commitSpend.SpendingTx,
c.cfg.chanState, commitSpend.SpendingTx, nil,
)
if err != nil {
return false, fmt.Errorf("unable to create anchor "+
Expand Down
44 changes: 35 additions & 9 deletions lnwallet/channel.go
Original file line number Diff line number Diff line change
Expand Up @@ -2588,7 +2588,6 @@ func createBreachRetribution(revokedLog *channeldb.RevocationLog,

// Read the amounts from the breach transaction.
theirAmt = spendTx.TxOut[theirOutpoint.Index].Value

} else {
// Otherwise, we check to see if the revocation log
// contains remote parties' output amount. Due to a
Expand Down Expand Up @@ -5945,7 +5944,7 @@ func NewUnilateralCloseSummary(chanState *channeldb.OpenChannel, signer input.Si
}

anchorResolution, err := NewAnchorResolution(
chanState, commitTxBroadcast,
chanState, commitTxBroadcast, keyRing,
)
if err != nil {
return nil, err
Expand Down Expand Up @@ -6642,7 +6641,7 @@ func NewLocalForceCloseSummary(chanState *channeldb.OpenChannel,
}

anchorResolution, err := NewAnchorResolution(
chanState, commitTx,
chanState, commitTx, keyRing,
)
if err != nil {
return nil, err
Expand Down Expand Up @@ -6826,7 +6825,7 @@ type AnchorResolutions struct {

// NewAnchorResolutions returns a set of anchor resolutions wrapped in the
// struct AnchorResolutions. Because we have no view on the mempool, we can
// only blindly anchor all of these txes down. Caller needs to check the
// only blindly anchor all of these txes down. The caller needs to check the
// returned values against nil to decide whether there exists an anchor
// resolution for local/remote/pending remote commitment txes.
func (lc *LightningChannel) NewAnchorResolutions() (*AnchorResolutions,
Expand All @@ -6835,20 +6834,38 @@ func (lc *LightningChannel) NewAnchorResolutions() (*AnchorResolutions,
lc.Lock()
defer lc.Unlock()

resolutions := &AnchorResolutions{}
var resolutions AnchorResolutions

// Add anchor for local commitment tx, if any.
revocation, err := lc.channelState.RevocationProducer.AtIndex(
lc.currentHeight,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving some notes for other reviewers, was wondering if lc.currentHeight is always updated to date here since NewAnchorResolutions makes a separate call to db and creates a new LightningWallet. This is fine as we'd only call it when StateCommitmentBroadcasted, which means the db has the latest view of the local commit, and no other goroutines can update it anymore because it's closed.

)
if err != nil {
return nil, err
}
localCommitPoint := input.ComputeCommitmentPoint(revocation[:])
localKeyRing := DeriveCommitmentKeys(
localCommitPoint, true, lc.channelState.ChanType,
&lc.channelState.LocalChanCfg, &lc.channelState.RemoteChanCfg,
)
localRes, err := NewAnchorResolution(
lc.channelState, lc.channelState.LocalCommitment.CommitTx,
localKeyRing,
)
if err != nil {
return nil, err
}
resolutions.Local = localRes

// Add anchor for remote commitment tx, if any.
remoteKeyRing := DeriveCommitmentKeys(
lc.channelState.RemoteCurrentRevocation, false,
lc.channelState.ChanType, &lc.channelState.LocalChanCfg,
&lc.channelState.RemoteChanCfg,
)
remoteRes, err := NewAnchorResolution(
lc.channelState, lc.channelState.RemoteCommitment.CommitTx,
remoteKeyRing,
)
if err != nil {
return nil, err
Expand All @@ -6862,23 +6879,30 @@ func (lc *LightningChannel) NewAnchorResolutions() (*AnchorResolutions,
}

if remotePendingCommit != nil {
pendingRemoteKeyRing := DeriveCommitmentKeys(
lc.channelState.RemoteNextRevocation, false,
lc.channelState.ChanType, &lc.channelState.LocalChanCfg,
&lc.channelState.RemoteChanCfg,
)
remotePendingRes, err := NewAnchorResolution(
lc.channelState,
remotePendingCommit.Commitment.CommitTx,
pendingRemoteKeyRing,
)
if err != nil {
return nil, err
}
resolutions.RemotePending = remotePendingRes
}

return resolutions, nil
return &resolutions, nil
}

// NewAnchorResolution returns the information that is required to sweep the
// local anchor.
func NewAnchorResolution(chanState *channeldb.OpenChannel,
commitTx *wire.MsgTx) (*AnchorResolution, error) {
commitTx *wire.MsgTx,
keyRing *CommitmentKeyRing) (*AnchorResolution, error) {

// Return nil resolution if the channel has no anchors.
if !chanState.ChanType.HasAnchors() {
Expand All @@ -6887,7 +6911,8 @@ func NewAnchorResolution(chanState *channeldb.OpenChannel,

// Derive our local anchor script.
localAnchor, _, err := CommitScriptAnchors(
&chanState.LocalChanCfg, &chanState.RemoteChanCfg,
chanState.ChanType, &chanState.LocalChanCfg,
&chanState.RemoteChanCfg, keyRing,
)
if err != nil {
return nil, err
Expand Down Expand Up @@ -7239,7 +7264,8 @@ func (lc *LightningChannel) generateRevocation(height uint64) (*lnwire.RevokeAnd

revocationMsg.NextRevocationKey = input.ComputeCommitmentPoint(nextCommitSecret[:])
revocationMsg.ChanID = lnwire.NewChanIDFromOutPoint(
&lc.channelState.FundingOutpoint)
&lc.channelState.FundingOutpoint,
)

return revocationMsg, nil
}
Expand Down
Loading