Merge pull request #5165 from Crypt-iQ/psbt_funding_04022021

lnwallet/chanfunding: check all PSBT inputs have witness stack
This commit is contained in:
Olaoluwa Osuntokun 2021-04-23 12:04:27 -07:00 committed by GitHub
commit 260ea9b842
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 5 deletions

@ -8,6 +8,10 @@ See [BIP174](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki) for
a full description of the PSBT format and the different _roles_ that a
participant in a PSBT can have.
To avoid possible malleability, all inputs to a funding transaction must be segwit
spends, meaning that P2PKH and normal P2SH cannot be used. An error will be
returned if any inputs are not segwit spends.
## Creating/funding a PSBT
The first step for every transaction that is constructed using a PSBT flow is to

@ -249,6 +249,15 @@ func (i *PsbtIntent) Verify(packet *psbt.Packet) error {
"output amount sum")
}
// SumUtxoInputValues checks that packet.Inputs is non-empty. Here we
// check that each Input has a WitnessUtxo field, to avoid possible
// malleability.
for _, in := range packet.Inputs {
if in.WitnessUtxo == nil {
return fmt.Errorf("not all inputs are segwit spends")
}
}
i.PendingPsbt = packet
i.State = PsbtVerified
return nil

@ -340,8 +340,8 @@ func TestPsbtVerify(t *testing.T) {
},
},
{
name: "input correct",
expectedErr: "",
name: "missing witness-utxo field",
expectedErr: "not all inputs are segwit spends",
doVerify: func(amt int64, p *psbt.Packet,
i *PsbtIntent) error {
@ -370,6 +370,33 @@ func TestPsbtVerify(t *testing.T) {
return i.Verify(p)
},
},
{
name: "input correct",
expectedErr: "",
doVerify: func(amt int64, p *psbt.Packet,
i *PsbtIntent) error {
txOut := &wire.TxOut{
Value: int64(chanCapacity/2) + 1,
}
p.UnsignedTx.TxIn = []*wire.TxIn{
{},
{
PreviousOutPoint: wire.OutPoint{
Index: 0,
},
},
}
p.Inputs = []psbt.PInput{
{
WitnessUtxo: txOut,
},
{
WitnessUtxo: txOut,
}}
return i.Verify(p)
},
},
}
// Create a simple assembler and ask it to provision a channel to get
@ -401,9 +428,11 @@ func TestPsbtVerify(t *testing.T) {
}
err = tc.doVerify(amt, pendingPsbt, psbtIntent)
if err != nil && tc.expectedErr != "" &&
err.Error() != tc.expectedErr {
if err != nil && tc.expectedErr == "" {
t.Fatalf("unexpected error, got '%v' wanted "+
"'%v'", err, tc.expectedErr)
}
if err != nil && err.Error() != tc.expectedErr {
t.Fatalf("unexpected error, got '%v' wanted "+
"'%v'", err, tc.expectedErr)
}