lnwallet: update NewBreachRetribution to handle taproot chans

For our local output, we need a valid control block. To sweep the remote
output, we use the taptweak so we can spend the keyspend path.
This commit is contained in:
Olaoluwa Osuntokun 2023-03-01 21:45:27 -08:00
parent 1f887a1b14
commit 995e6cd66b
No known key found for this signature in database
GPG key ID: 3BBD59E99B280306

View file

@ -2475,6 +2475,7 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
// If the returned *RevocationLog is non-nil, use it to derive the info // If the returned *RevocationLog is non-nil, use it to derive the info
// we need. // we need.
isTaproot := chanState.ChanType.IsTaproot()
if revokedLog != nil { if revokedLog != nil {
br, ourAmt, theirAmt, err = createBreachRetribution( br, ourAmt, theirAmt, err = createBreachRetribution(
revokedLog, spendTx, chanState, keyRing, revokedLog, spendTx, chanState, keyRing,
@ -2517,6 +2518,22 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
}, },
HashType: txscript.SigHashAll, HashType: txscript.SigHashAll,
} }
// For taproot channels, we'll make sure to set the script path
// spend (as our output on their revoked tx still needs the
// delay), and set the control block.
if isTaproot {
br.LocalOutputSignDesc.SignMethod = input.TaprootScriptSpendSignMethod
ctrlBlock := input.MakeTaprootCtrlBlock(
br.LocalOutputSignDesc.WitnessScript,
&input.TaprootNUMSKey, ourScript.ScriptTree,
)
br.LocalOutputSignDesc.ControlBlock, err = ctrlBlock.ToBytes()
if err != nil {
return nil, err
}
}
} }
// Similarly, if their balance exceeds the remote party's dust limit, // Similarly, if their balance exceeds the remote party's dust limit,
@ -2533,6 +2550,18 @@ func NewBreachRetribution(chanState *channeldb.OpenChannel, stateNum uint64,
}, },
HashType: txscript.SigHashAll, HashType: txscript.SigHashAll,
} }
// For taproot channels, the remote ouput (the revoked outuput)
// can be spent using a single key spend, now that we know the
// revocation key.
if isTaproot {
br.RemoteOutputSignDesc.SignMethod = input.TaprootKeySpendSignMethod
// We'll also need to set the taptweak as we'll be
// signing with the full output key.
tapscriptRoot := theirScript.ScriptTree.RootNode.TapHash()
br.RemoteOutputSignDesc.TapTweak = tapscriptRoot[:]
}
} }
// Finally, with all the necessary data constructed, we can pad the // Finally, with all the necessary data constructed, we can pad the