lnwallet+contractcourt: publicly export DeriveCommitmentKeys use in chain watcher
In this commit, we consolidate the number of areas where we derive our commitment keys. Before this commit, the `isOurCommitment` function in the chain watcher used a custom routine to derive the expected scripts/keys for our commitment at that height. With the recent changes, we now have additional logic in `DeriveCommitmentKeys` that wasn't copied over to this area. As a result, the prior logic would erroneously detect if it was our commitment that had hit the chain or not. In this commit, we remove the old custom code, and use `DeriveCommitmentKeys` wihtin the chain watcher as well. This ensures that we only need to maintain the key derivation code in a single place, preventing future bugs of this nature.
This commit is contained in:
parent
e497a07d64
commit
6d97bcbacd
@ -331,7 +331,7 @@ func (c *chainWatcher) SubscribeChannelEvents() *ChainEventSubscription {
|
|||||||
// based off of only the set of outputs included.
|
// based off of only the set of outputs included.
|
||||||
func isOurCommitment(localChanCfg, remoteChanCfg channeldb.ChannelConfig,
|
func isOurCommitment(localChanCfg, remoteChanCfg channeldb.ChannelConfig,
|
||||||
commitSpend *chainntnfs.SpendDetail, broadcastStateNum uint64,
|
commitSpend *chainntnfs.SpendDetail, broadcastStateNum uint64,
|
||||||
revocationProducer shachain.Producer) (bool, error) {
|
revocationProducer shachain.Producer, tweakless bool) (bool, error) {
|
||||||
|
|
||||||
// First, we'll re-derive our commitment point for this state since
|
// First, we'll re-derive our commitment point for this state since
|
||||||
// this is what we use to randomize each of the keys for this state.
|
// this is what we use to randomize each of the keys for this state.
|
||||||
@ -344,14 +344,15 @@ func isOurCommitment(localChanCfg, remoteChanCfg channeldb.ChannelConfig,
|
|||||||
// Now that we have the commit point, we'll derive the tweaked local
|
// Now that we have the commit point, we'll derive the tweaked local
|
||||||
// and remote keys for this state. We use our point as only we can
|
// and remote keys for this state. We use our point as only we can
|
||||||
// revoke our own commitment.
|
// revoke our own commitment.
|
||||||
localDelayBasePoint := localChanCfg.DelayBasePoint.PubKey
|
commitKeyRing := lnwallet.DeriveCommitmentKeys(
|
||||||
localDelayKey := input.TweakPubKey(localDelayBasePoint, commitPoint)
|
commitPoint, true, tweakless, &localChanCfg, &remoteChanCfg,
|
||||||
remoteNonDelayPoint := remoteChanCfg.PaymentBasePoint.PubKey
|
)
|
||||||
remotePayKey := input.TweakPubKey(remoteNonDelayPoint, commitPoint)
|
|
||||||
|
|
||||||
// With the keys derived, we'll construct the remote script that'll be
|
// With the keys derived, we'll construct the remote script that'll be
|
||||||
// present if they have a non-dust balance on the commitment.
|
// present if they have a non-dust balance on the commitment.
|
||||||
remotePkScript, err := input.CommitScriptUnencumbered(remotePayKey)
|
remotePkScript, err := input.CommitScriptUnencumbered(
|
||||||
|
commitKeyRing.NoDelayKey,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -359,11 +360,9 @@ func isOurCommitment(localChanCfg, remoteChanCfg channeldb.ChannelConfig,
|
|||||||
// Next, we'll derive our script that includes the revocation base for
|
// Next, we'll derive our script that includes the revocation base for
|
||||||
// the remote party allowing them to claim this output before the CSV
|
// the remote party allowing them to claim this output before the CSV
|
||||||
// delay if we breach.
|
// delay if we breach.
|
||||||
revocationKey := input.DeriveRevocationPubkey(
|
|
||||||
remoteChanCfg.RevocationBasePoint.PubKey, commitPoint,
|
|
||||||
)
|
|
||||||
localScript, err := input.CommitScriptToSelf(
|
localScript, err := input.CommitScriptToSelf(
|
||||||
uint32(localChanCfg.CsvDelay), localDelayKey, revocationKey,
|
uint32(localChanCfg.CsvDelay), commitKeyRing.DelayKey,
|
||||||
|
commitKeyRing.RevocationKey,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@ -423,6 +422,11 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) {
|
|||||||
// revoked state...!!!
|
// revoked state...!!!
|
||||||
commitTxBroadcast := commitSpend.SpendingTx
|
commitTxBroadcast := commitSpend.SpendingTx
|
||||||
|
|
||||||
|
// An additional piece of information we need to properly
|
||||||
|
// dispatch a close event if is this channel was using the
|
||||||
|
// tweakless remove key format or not.
|
||||||
|
tweaklessCommit := c.cfg.chanState.ChanType.IsTweakless()
|
||||||
|
|
||||||
localCommit, remoteCommit, err := c.cfg.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 "+
|
||||||
@ -480,6 +484,7 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) {
|
|||||||
c.cfg.chanState.LocalChanCfg,
|
c.cfg.chanState.LocalChanCfg,
|
||||||
c.cfg.chanState.RemoteChanCfg, commitSpend,
|
c.cfg.chanState.RemoteChanCfg, commitSpend,
|
||||||
broadcastStateNum, c.cfg.chanState.RevocationProducer,
|
broadcastStateNum, c.cfg.chanState.RevocationProducer,
|
||||||
|
tweaklessCommit,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("unable to determine self commit for "+
|
log.Errorf("unable to determine self commit for "+
|
||||||
@ -584,9 +589,6 @@ func (c *chainWatcher) closeObserver(spendNtfn *chainntnfs.SpendEvent) {
|
|||||||
"state #%v!!! Attempting recovery...",
|
"state #%v!!! Attempting recovery...",
|
||||||
broadcastStateNum, remoteStateNum)
|
broadcastStateNum, remoteStateNum)
|
||||||
|
|
||||||
tweaklessCommit := (c.cfg.chanState.ChanType ==
|
|
||||||
channeldb.SingleFunderTweakless)
|
|
||||||
|
|
||||||
// If this isn't a tweakless commitment, then we'll
|
// If this isn't a tweakless commitment, then we'll
|
||||||
// need to wait for the remote party's latest unrevoked
|
// need to wait for the remote party's latest unrevoked
|
||||||
// commitment point to be presented to us as we need
|
// commitment point to be presented to us as we need
|
||||||
|
@ -876,13 +876,13 @@ func (lc *LightningChannel) diskCommitToMemCommit(isLocal bool,
|
|||||||
// haven't yet received a responding commitment from the remote party.
|
// haven't yet received a responding commitment from the remote party.
|
||||||
var localCommitKeys, remoteCommitKeys *CommitmentKeyRing
|
var localCommitKeys, remoteCommitKeys *CommitmentKeyRing
|
||||||
if localCommitPoint != nil {
|
if localCommitPoint != nil {
|
||||||
localCommitKeys = deriveCommitmentKeys(
|
localCommitKeys = DeriveCommitmentKeys(
|
||||||
localCommitPoint, true, tweaklessCommit,
|
localCommitPoint, true, tweaklessCommit,
|
||||||
lc.localChanCfg, lc.remoteChanCfg,
|
lc.localChanCfg, lc.remoteChanCfg,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if remoteCommitPoint != nil {
|
if remoteCommitPoint != nil {
|
||||||
remoteCommitKeys = deriveCommitmentKeys(
|
remoteCommitKeys = DeriveCommitmentKeys(
|
||||||
remoteCommitPoint, false, tweaklessCommit,
|
remoteCommitPoint, false, tweaklessCommit,
|
||||||
lc.localChanCfg, lc.remoteChanCfg,
|
lc.localChanCfg, lc.remoteChanCfg,
|
||||||
)
|
)
|
||||||
@ -981,10 +981,10 @@ type CommitmentKeyRing struct {
|
|||||||
RevocationKey *btcec.PublicKey
|
RevocationKey *btcec.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// deriveCommitmentKey generates a new commitment key set using the base points
|
// DeriveCommitmentKey generates a new commitment key set using the base points
|
||||||
// and commitment point. The keys are derived differently depending whether the
|
// and commitment point. The keys are derived differently depending whether the
|
||||||
// commitment transaction is ours or the remote peer's.
|
// commitment transaction is ours or the remote peer's.
|
||||||
func deriveCommitmentKeys(commitPoint *btcec.PublicKey,
|
func DeriveCommitmentKeys(commitPoint *btcec.PublicKey,
|
||||||
isOurCommit, tweaklessCommit bool,
|
isOurCommit, tweaklessCommit bool,
|
||||||
localChanCfg, remoteChanCfg *channeldb.ChannelConfig) *CommitmentKeyRing {
|
localChanCfg, remoteChanCfg *channeldb.ChannelConfig) *CommitmentKeyRing {
|
||||||
|
|
||||||
@ -1711,9 +1711,8 @@ func (lc *LightningChannel) restoreCommitState(
|
|||||||
|
|
||||||
// We'll also re-create the set of commitment keys needed to
|
// We'll also re-create the set of commitment keys needed to
|
||||||
// fully re-derive the state.
|
// fully re-derive the state.
|
||||||
tweaklessCommit := (lc.channelState.ChanType ==
|
tweaklessCommit := lc.channelState.ChanType.IsTweakless()
|
||||||
channeldb.SingleFunderTweakless)
|
pendingRemoteKeyChain = DeriveCommitmentKeys(
|
||||||
pendingRemoteKeyChain = deriveCommitmentKeys(
|
|
||||||
pendingCommitPoint, false, tweaklessCommit,
|
pendingCommitPoint, false, tweaklessCommit,
|
||||||
lc.localChanCfg, lc.remoteChanCfg,
|
lc.localChanCfg, lc.remoteChanCfg,
|
||||||
)
|
)
|
||||||
@ -1999,8 +1998,8 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
|
|||||||
|
|
||||||
// With the commitment point generated, we can now generate the four
|
// With the commitment point generated, we can now generate the four
|
||||||
// keys we'll need to reconstruct the commitment state,
|
// keys we'll need to reconstruct the commitment state,
|
||||||
tweaklessCommit := chanState.ChanType == channeldb.SingleFunderTweakless
|
tweaklessCommit := chanState.ChanType.IsTweakless()
|
||||||
keyRing := deriveCommitmentKeys(
|
keyRing := DeriveCommitmentKeys(
|
||||||
commitmentPoint, false, tweaklessCommit,
|
commitmentPoint, false, tweaklessCommit,
|
||||||
&chanState.LocalChanCfg, &chanState.RemoteChanCfg,
|
&chanState.LocalChanCfg, &chanState.RemoteChanCfg,
|
||||||
)
|
)
|
||||||
@ -3258,11 +3257,9 @@ func (lc *LightningChannel) SignNextCommitment() (lnwire.Sig, []lnwire.Sig, []ch
|
|||||||
// Grab the next commitment point for the remote party. This will be
|
// Grab the next commitment point for the remote party. This will be
|
||||||
// used within fetchCommitmentView to derive all the keys necessary to
|
// used within fetchCommitmentView to derive all the keys necessary to
|
||||||
// construct the commitment state.
|
// construct the commitment state.
|
||||||
tweaklessCommit := (lc.channelState.ChanType ==
|
keyRing := DeriveCommitmentKeys(
|
||||||
channeldb.SingleFunderTweakless)
|
commitPoint, false, lc.channelState.ChanType.IsTweakless(),
|
||||||
keyRing := deriveCommitmentKeys(
|
lc.localChanCfg, lc.remoteChanCfg,
|
||||||
commitPoint, false, tweaklessCommit, lc.localChanCfg,
|
|
||||||
lc.remoteChanCfg,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Create a new commitment view which will calculate the evaluated
|
// Create a new commitment view which will calculate the evaluated
|
||||||
@ -4017,11 +4014,9 @@ func (lc *LightningChannel) ReceiveNewCommitment(commitSig lnwire.Sig,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
commitPoint := input.ComputeCommitmentPoint(commitSecret[:])
|
commitPoint := input.ComputeCommitmentPoint(commitSecret[:])
|
||||||
tweaklessCommit := (lc.channelState.ChanType ==
|
keyRing := DeriveCommitmentKeys(
|
||||||
channeldb.SingleFunderTweakless)
|
commitPoint, true, lc.channelState.ChanType.IsTweakless(),
|
||||||
keyRing := deriveCommitmentKeys(
|
lc.localChanCfg, lc.remoteChanCfg,
|
||||||
commitPoint, true, tweaklessCommit, lc.localChanCfg,
|
|
||||||
lc.remoteChanCfg,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// With the current commitment point re-calculated, construct the new
|
// With the current commitment point re-calculated, construct the new
|
||||||
@ -5050,8 +5045,8 @@ func NewUnilateralCloseSummary(chanState *channeldb.OpenChannel, signer input.Si
|
|||||||
|
|
||||||
// First, we'll generate the commitment point and the revocation point
|
// First, we'll generate the commitment point and the revocation point
|
||||||
// so we can re-construct the HTLC state and also our payment key.
|
// so we can re-construct the HTLC state and also our payment key.
|
||||||
tweaklessCommit := chanState.ChanType == channeldb.SingleFunderTweakless
|
tweaklessCommit := chanState.ChanType.IsTweakless()
|
||||||
keyRing := deriveCommitmentKeys(
|
keyRing := DeriveCommitmentKeys(
|
||||||
commitPoint, false, tweaklessCommit, &chanState.LocalChanCfg,
|
commitPoint, false, tweaklessCommit, &chanState.LocalChanCfg,
|
||||||
&chanState.RemoteChanCfg,
|
&chanState.RemoteChanCfg,
|
||||||
)
|
)
|
||||||
@ -5706,10 +5701,9 @@ func NewLocalForceCloseSummary(chanState *channeldb.OpenChannel, signer input.Si
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
commitPoint := input.ComputeCommitmentPoint(revocation[:])
|
commitPoint := input.ComputeCommitmentPoint(revocation[:])
|
||||||
tweaklessCommit := chanState.ChanType == channeldb.SingleFunderTweakless
|
keyRing := DeriveCommitmentKeys(
|
||||||
keyRing := deriveCommitmentKeys(
|
commitPoint, true, chanState.ChanType.IsTweakless(),
|
||||||
commitPoint, true, tweaklessCommit, &chanState.LocalChanCfg,
|
&chanState.LocalChanCfg, &chanState.RemoteChanCfg,
|
||||||
&chanState.RemoteChanCfg,
|
|
||||||
)
|
)
|
||||||
selfScript, err := input.CommitScriptToSelf(csvTimeout, keyRing.DelayKey,
|
selfScript, err := input.CommitScriptToSelf(csvTimeout, keyRing.DelayKey,
|
||||||
keyRing.RevocationKey)
|
keyRing.RevocationKey)
|
||||||
|
@ -663,11 +663,11 @@ func CreateCommitmentTxns(localBalance, remoteBalance btcutil.Amount,
|
|||||||
fundingTxIn wire.TxIn,
|
fundingTxIn wire.TxIn,
|
||||||
tweaklessCommit bool) (*wire.MsgTx, *wire.MsgTx, error) {
|
tweaklessCommit bool) (*wire.MsgTx, *wire.MsgTx, error) {
|
||||||
|
|
||||||
localCommitmentKeys := deriveCommitmentKeys(
|
localCommitmentKeys := DeriveCommitmentKeys(
|
||||||
localCommitPoint, true, tweaklessCommit, ourChanCfg,
|
localCommitPoint, true, tweaklessCommit, ourChanCfg,
|
||||||
theirChanCfg,
|
theirChanCfg,
|
||||||
)
|
)
|
||||||
remoteCommitmentKeys := deriveCommitmentKeys(
|
remoteCommitmentKeys := DeriveCommitmentKeys(
|
||||||
remoteCommitPoint, false, tweaklessCommit, ourChanCfg,
|
remoteCommitPoint, false, tweaklessCommit, ourChanCfg,
|
||||||
theirChanCfg,
|
theirChanCfg,
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user