Skip to content

Commit 9f23c16

Browse files
committed
Merge #13721: Bugfixes for BIP 174 combining and deserialization
fad231a Fix merging of global unknown data in PSBTs (Andrew Chow) 41df035 Check that PSBT keys are the correct length (Andrew Chow) Pull request description: This PR fixes a few bugs that were found and adds tests checking for these errors. Specifically: - Single byte keys are checked to actually be one byte. - Unknown global data must be merged when combining two PSBTs. Tree-SHA512: c0e7b4bc607d510cc005aaa7c0813ee58c5467ab7ce4adce485522dfeee92b1af3d29fe89df778b0ea812bb3827e085b30e04d4f4ebcefd8364d809573991332
2 parents 94dd89e + fad231a commit 9f23c16

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

src/script/sign.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ void PartiallySignedTransaction::Merge(const PartiallySignedTransaction& psbt)
474474
for (unsigned int i = 0; i < outputs.size(); ++i) {
475475
outputs[i].Merge(psbt.outputs[i]);
476476
}
477+
unknown.insert(psbt.unknown.begin(), psbt.unknown.end());
477478
}
478479

479480
bool PartiallySignedTransaction::IsSane() const

src/script/sign.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,12 +284,16 @@ struct PSBTInput
284284
case PSBT_IN_NON_WITNESS_UTXO:
285285
if (non_witness_utxo) {
286286
throw std::ios_base::failure("Duplicate Key, input non-witness utxo already provided");
287+
} else if (key.size() != 1) {
288+
throw std::ios_base::failure("Non-witness utxo key is more than one byte type");
287289
}
288290
UnserializeFromVector(s, non_witness_utxo);
289291
break;
290292
case PSBT_IN_WITNESS_UTXO:
291293
if (!witness_utxo.IsNull()) {
292294
throw std::ios_base::failure("Duplicate Key, input witness utxo already provided");
295+
} else if (key.size() != 1) {
296+
throw std::ios_base::failure("Witness utxo key is more than one byte type");
293297
}
294298
UnserializeFromVector(s, witness_utxo);
295299
break;
@@ -319,13 +323,17 @@ struct PSBTInput
319323
case PSBT_IN_SIGHASH:
320324
if (sighash_type > 0) {
321325
throw std::ios_base::failure("Duplicate Key, input sighash type already provided");
326+
} else if (key.size() != 1) {
327+
throw std::ios_base::failure("Sighash type key is more than one byte type");
322328
}
323329
UnserializeFromVector(s, sighash_type);
324330
break;
325331
case PSBT_IN_REDEEMSCRIPT:
326332
{
327333
if (!redeem_script.empty()) {
328334
throw std::ios_base::failure("Duplicate Key, input redeemScript already provided");
335+
} else if (key.size() != 1) {
336+
throw std::ios_base::failure("Input redeemScript key is more than one byte type");
329337
}
330338
s >> redeem_script;
331339
break;
@@ -334,6 +342,8 @@ struct PSBTInput
334342
{
335343
if (!witness_script.empty()) {
336344
throw std::ios_base::failure("Duplicate Key, input witnessScript already provided");
345+
} else if (key.size() != 1) {
346+
throw std::ios_base::failure("Input witnessScript key is more than one byte type");
337347
}
338348
s >> witness_script;
339349
break;
@@ -347,6 +357,8 @@ struct PSBTInput
347357
{
348358
if (!final_script_sig.empty()) {
349359
throw std::ios_base::failure("Duplicate Key, input final scriptSig already provided");
360+
} else if (key.size() != 1) {
361+
throw std::ios_base::failure("Final scriptSig key is more than one byte type");
350362
}
351363
s >> final_script_sig;
352364
break;
@@ -355,6 +367,8 @@ struct PSBTInput
355367
{
356368
if (!final_script_witness.IsNull()) {
357369
throw std::ios_base::failure("Duplicate Key, input final scriptWitness already provided");
370+
} else if (key.size() != 1) {
371+
throw std::ios_base::failure("Final scriptWitness key is more than one byte type");
358372
}
359373
UnserializeFromVector(s, final_script_witness.stack);
360374
break;
@@ -442,6 +456,8 @@ struct PSBTOutput
442456
{
443457
if (!redeem_script.empty()) {
444458
throw std::ios_base::failure("Duplicate Key, output redeemScript already provided");
459+
} else if (key.size() != 1) {
460+
throw std::ios_base::failure("Output redeemScript key is more than one byte type");
445461
}
446462
s >> redeem_script;
447463
break;
@@ -450,6 +466,8 @@ struct PSBTOutput
450466
{
451467
if (!witness_script.empty()) {
452468
throw std::ios_base::failure("Duplicate Key, output witnessScript already provided");
469+
} else if (key.size() != 1) {
470+
throw std::ios_base::failure("Output witnessScript key is more than one byte type");
453471
}
454472
s >> witness_script;
455473
break;
@@ -564,6 +582,8 @@ struct PartiallySignedTransaction
564582
{
565583
if (tx) {
566584
throw std::ios_base::failure("Duplicate Key, unsigned tx already provided");
585+
} else if (key.size() != 1) {
586+
throw std::ios_base::failure("Global unsigned tx key is more than one byte type");
567587
}
568588
CMutableTransaction mtx;
569589
UnserializeFromVector(s, mtx);

0 commit comments

Comments
 (0)