Skip to content

Commit 2b7682c

Browse files
committed
psbt: use sighash type field to determine whether to remove non-witness utxos
Since the sighash type field is written for atypical sighash types, we can look at that field to figure out whether the psbt contains unnecessary transactions.
1 parent 28781b5 commit 2b7682c

File tree

4 files changed

+33
-29
lines changed

4 files changed

+33
-29
lines changed

src/psbt.cpp

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -487,37 +487,41 @@ PSBTError SignPSBTInput(const SigningProvider& provider, PartiallySignedTransact
487487
return sig_complete ? PSBTError::OK : PSBTError::INCOMPLETE;
488488
}
489489

490-
void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx, std::optional<int> sighash_type)
490+
void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx)
491491
{
492-
if (!sighash_type) sighash_type = SIGHASH_DEFAULT;
493-
// Only drop non_witness_utxos if sighash_type != SIGHASH_ANYONECANPAY
494-
if ((*sighash_type & 0x80) != SIGHASH_ANYONECANPAY) {
495-
// Figure out if any non_witness_utxos should be dropped
496-
std::vector<unsigned int> to_drop;
497-
for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {
498-
const auto& input = psbtx.inputs.at(i);
499-
int wit_ver;
500-
std::vector<unsigned char> wit_prog;
501-
if (input.witness_utxo.IsNull() || !input.witness_utxo.scriptPubKey.IsWitnessProgram(wit_ver, wit_prog)) {
502-
// There's a non-segwit input or Segwit v0, so we cannot drop any witness_utxos
503-
to_drop.clear();
504-
break;
505-
}
506-
if (wit_ver == 0) {
507-
// Segwit v0, so we cannot drop any non_witness_utxos
508-
to_drop.clear();
509-
break;
510-
}
511-
if (input.non_witness_utxo) {
512-
to_drop.push_back(i);
513-
}
492+
// Figure out if any non_witness_utxos should be dropped
493+
std::vector<unsigned int> to_drop;
494+
for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {
495+
const auto& input = psbtx.inputs.at(i);
496+
int wit_ver;
497+
std::vector<unsigned char> wit_prog;
498+
if (input.witness_utxo.IsNull() || !input.witness_utxo.scriptPubKey.IsWitnessProgram(wit_ver, wit_prog)) {
499+
// There's a non-segwit input, so we cannot drop any non_witness_utxos
500+
to_drop.clear();
501+
break;
502+
}
503+
if (wit_ver == 0) {
504+
// Segwit v0, so we cannot drop any non_witness_utxos
505+
to_drop.clear();
506+
break;
507+
}
508+
// non_witness_utxos cannot be dropped if the sighash type includes SIGHASH_ANYONECANPAY
509+
// Since callers should have called SignPSBTInput which updates the sighash type in the PSBT, we only
510+
// need to look at that field. If it is not present, then we can assume SIGHASH_DEFAULT or SIGHASH_ALL.
511+
if (input.sighash_type != std::nullopt && (*input.sighash_type & 0x80) == SIGHASH_ANYONECANPAY) {
512+
to_drop.clear();
513+
break;
514514
}
515515

516-
// Drop the non_witness_utxos that we can drop
517-
for (unsigned int i : to_drop) {
518-
psbtx.inputs.at(i).non_witness_utxo = nullptr;
516+
if (input.non_witness_utxo) {
517+
to_drop.push_back(i);
519518
}
520519
}
520+
521+
// Drop the non_witness_utxos that we can drop
522+
for (unsigned int i : to_drop) {
523+
psbtx.inputs.at(i).non_witness_utxo = nullptr;
524+
}
521525
}
522526

523527
bool FinalizePSBT(PartiallySignedTransaction& psbtx)

src/psbt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1407,7 +1407,7 @@ bool PSBTInputSignedAndVerified(const PartiallySignedTransaction psbt, unsigned
14071407
[[nodiscard]] PSBTError SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, const PrecomputedTransactionData* txdata, std::optional<int> sighash = std::nullopt, SignatureData* out_sigdata = nullptr, bool finalize = true);
14081408

14091409
/** Reduces the size of the PSBT by dropping unnecessary `non_witness_utxos` (i.e. complete previous transactions) from a psbt when all inputs are segwit v1. */
1410-
void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx, std::optional<int> sighash_type);
1410+
void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx);
14111411

14121412
/** Counts the unsigned inputs of a PSBT. */
14131413
size_t CountPSBTUnsignedInputs(const PartiallySignedTransaction& psbt);

src/rpc/rawtransaction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ PartiallySignedTransaction ProcessPSBT(const std::string& psbt_string, const std
244244
UpdatePSBTOutput(provider, psbtx, i);
245245
}
246246

247-
RemoveUnnecessaryTransactions(psbtx, /*sighash_type=*/std::nullopt);
247+
RemoveUnnecessaryTransactions(psbtx);
248248

249249
return psbtx;
250250
}

src/wallet/wallet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2144,7 +2144,7 @@ std::optional<PSBTError> CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bo
21442144
}
21452145
}
21462146

2147-
RemoveUnnecessaryTransactions(psbtx, sighash_type);
2147+
RemoveUnnecessaryTransactions(psbtx);
21482148

21492149
// Complete if every input is now signed
21502150
complete = true;

0 commit comments

Comments
 (0)