lnwallet: fix bug in SignPsbt with np2wkh addresses
Fixes #6626. If either of the two fields FinalScriptSig or FinalScriptWitness is set on an input of a PSBT then that results in most of the fields of that input not to be serialized in the packet anymore, since the input is considered to be complete. But because a signer isn't supposed to set any of the Final* fields, this was wrong from the beginning. Only the finalizer will set those fields.
This commit is contained in:
2 files changed
+13
-27
No files matched your search
@@ -330,14 +330,7 @@ func signSegWitV0(in *psbt.PInput, tx *wire.MsgTx,
|
|||||||
// requirement that the PkScript of a P2PKH must be given as the witness
|
// requirement that the PkScript of a P2PKH must be given as the witness
|
||||||
// script in order for it to arrive at the correct sighash. That's why
|
// script in order for it to arrive at the correct sighash. That's why
|
||||||
// we call it subScript here instead of witness script.
|
// we call it subScript here instead of witness script.
|
||||||
subScript, scriptSig, err := prepareScriptsV0(in)
|
subScript := prepareScriptsV0(in)
|
||||||
if err != nil {
|
|
||||||
// We derived the correct key so we _are_ expected to sign this.
|
|
||||||
// Not being able to sign at this point means there's something
|
|
||||||
// wrong.
|
|
||||||
return fmt.Errorf("error deriving script for input %d: %v", idx,
|
|
||||||
err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have everything we need for signing the input now.
|
// We have everything we need for signing the input now.
|
||||||
sig, err := txscript.RawTxInWitnessSignature(
|
sig, err := txscript.RawTxInWitnessSignature(
|
||||||
@@ -347,7 +340,6 @@ func signSegWitV0(in *psbt.PInput, tx *wire.MsgTx,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error signing input %d: %v", idx, err)
|
return fmt.Errorf("error signing input %d: %v", idx, err)
|
||||||
}
|
}
|
||||||
in.FinalScriptSig = scriptSig
|
|
||||||
in.PartialSigs = append(in.PartialSigs, &psbt.PartialSig{
|
in.PartialSigs = append(in.PartialSigs, &psbt.PartialSig{
|
||||||
PubKey: pubKeyBytes,
|
PubKey: pubKeyBytes,
|
||||||
Signature: sig,
|
Signature: sig,
|
||||||
@@ -409,27 +401,19 @@ func signSegWitV1ScriptSpend(in *psbt.PInput, tx *wire.MsgTx,
|
|||||||
|
|
||||||
// prepareScriptsV0 returns the appropriate witness v0 and/or legacy scripts,
|
// prepareScriptsV0 returns the appropriate witness v0 and/or legacy scripts,
|
||||||
// depending on the type of input that should be signed.
|
// depending on the type of input that should be signed.
|
||||||
func prepareScriptsV0(in *psbt.PInput) ([]byte, []byte, error) {
|
func prepareScriptsV0(in *psbt.PInput) []byte {
|
||||||
switch {
|
switch {
|
||||||
// It's a NP2WKH input:
|
// It's a NP2WKH input:
|
||||||
case len(in.RedeemScript) > 0:
|
case len(in.RedeemScript) > 0:
|
||||||
builder := txscript.NewScriptBuilder()
|
return in.RedeemScript
|
||||||
builder.AddData(in.RedeemScript)
|
|
||||||
sigScript, err := builder.Script()
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("error building np2wkh "+
|
|
||||||
"script: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return in.RedeemScript, sigScript, nil
|
|
||||||
|
|
||||||
// It's a P2WSH input:
|
// It's a P2WSH input:
|
||||||
case len(in.WitnessScript) > 0:
|
case len(in.WitnessScript) > 0:
|
||||||
return in.WitnessScript, nil, nil
|
return in.WitnessScript
|
||||||
|
|
||||||
// It's a P2WKH input:
|
// It's a P2WKH input:
|
||||||
default:
|
default:
|
||||||
return in.WitnessUtxo.PkScript, nil, nil
|
return in.WitnessUtxo.PkScript
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -205,10 +205,9 @@ func (i testInputType) decorateInput(t *testing.T, privKey *btcec.PrivateKey,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i testInputType) beforeFinalize(t *testing.T, packet *psbt.Packet) {
|
func (i testInputType) finalize(t *testing.T, packet *psbt.Packet) {
|
||||||
in := &packet.Inputs[0]
|
in := &packet.Inputs[0]
|
||||||
sigBytes := in.PartialSigs[0].Signature
|
sigBytes := in.PartialSigs[0].Signature
|
||||||
pubKeyBytes := in.PartialSigs[0].PubKey
|
|
||||||
|
|
||||||
var witnessStack wire.TxWitness
|
var witnessStack wire.TxWitness
|
||||||
switch i {
|
switch i {
|
||||||
@@ -227,9 +226,12 @@ func (i testInputType) beforeFinalize(t *testing.T, packet *psbt.Packet) {
|
|||||||
witnessStack[2] = in.WitnessScript
|
witnessStack[2] = in.WitnessScript
|
||||||
|
|
||||||
default:
|
default:
|
||||||
witnessStack = make([][]byte, 2)
|
// The PSBT finalizer knows what to do if we're not using a
|
||||||
witnessStack[0] = sigBytes
|
// custom script.
|
||||||
witnessStack[1] = pubKeyBytes
|
err := psbt.MaybeFinalizeAll(packet)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
@@ -321,7 +323,7 @@ func TestSignPsbt(t *testing.T) {
|
|||||||
|
|
||||||
// If the witness stack needs to be assembled, give the caller
|
// If the witness stack needs to be assembled, give the caller
|
||||||
// the option to do that now.
|
// the option to do that now.
|
||||||
tc.inputType.beforeFinalize(t, packet)
|
tc.inputType.finalize(t, packet)
|
||||||
|
|
||||||
finalTx, err := psbt.Extract(packet)
|
finalTx, err := psbt.Extract(packet)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
Reference in new issue
Block a user