mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
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.
This commit is contained in:
parent
1f85f6911d
commit
7515c35f22
4 changed files with 33 additions and 29 deletions
16
src/psbt.cpp
16
src/psbt.cpp
|
@ -487,11 +487,8 @@ PSBTError SignPSBTInput(const SigningProvider& provider, PartiallySignedTransact
|
|||
return sig_complete ? PSBTError::OK : PSBTError::INCOMPLETE;
|
||||
}
|
||||
|
||||
void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx, std::optional<int> sighash_type)
|
||||
void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx)
|
||||
{
|
||||
if (!sighash_type) sighash_type = SIGHASH_DEFAULT;
|
||||
// Only drop non_witness_utxos if sighash_type != SIGHASH_ANYONECANPAY
|
||||
if ((*sighash_type & 0x80) != SIGHASH_ANYONECANPAY) {
|
||||
// Figure out if any non_witness_utxos should be dropped
|
||||
std::vector<unsigned int> to_drop;
|
||||
for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {
|
||||
|
@ -499,7 +496,7 @@ void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx, std::optio
|
|||
int wit_ver;
|
||||
std::vector<unsigned char> wit_prog;
|
||||
if (input.witness_utxo.IsNull() || !input.witness_utxo.scriptPubKey.IsWitnessProgram(wit_ver, wit_prog)) {
|
||||
// There's a non-segwit input or Segwit v0, so we cannot drop any witness_utxos
|
||||
// There's a non-segwit input, so we cannot drop any non_witness_utxos
|
||||
to_drop.clear();
|
||||
break;
|
||||
}
|
||||
|
@ -508,6 +505,14 @@ void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx, std::optio
|
|||
to_drop.clear();
|
||||
break;
|
||||
}
|
||||
// non_witness_utxos cannot be dropped if the sighash type includes SIGHASH_ANYONECANPAY
|
||||
// Since callers should have called SignPSBTInput which updates the sighash type in the PSBT, we only
|
||||
// need to look at that field. If it is not present, then we can assume SIGHASH_DEFAULT or SIGHASH_ALL.
|
||||
if (input.sighash_type != std::nullopt && (*input.sighash_type & 0x80) == SIGHASH_ANYONECANPAY) {
|
||||
to_drop.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
if (input.non_witness_utxo) {
|
||||
to_drop.push_back(i);
|
||||
}
|
||||
|
@ -518,7 +523,6 @@ void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx, std::optio
|
|||
psbtx.inputs.at(i).non_witness_utxo = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FinalizePSBT(PartiallySignedTransaction& psbtx)
|
||||
{
|
||||
|
|
|
@ -1407,7 +1407,7 @@ bool PSBTInputSignedAndVerified(const PartiallySignedTransaction psbt, unsigned
|
|||
[[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);
|
||||
|
||||
/** 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. */
|
||||
void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx, std::optional<int> sighash_type);
|
||||
void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx);
|
||||
|
||||
/** Counts the unsigned inputs of a PSBT. */
|
||||
size_t CountPSBTUnsignedInputs(const PartiallySignedTransaction& psbt);
|
||||
|
|
|
@ -244,7 +244,7 @@ PartiallySignedTransaction ProcessPSBT(const std::string& psbt_string, const std
|
|||
UpdatePSBTOutput(provider, psbtx, i);
|
||||
}
|
||||
|
||||
RemoveUnnecessaryTransactions(psbtx, /*sighash_type=*/std::nullopt);
|
||||
RemoveUnnecessaryTransactions(psbtx);
|
||||
|
||||
return psbtx;
|
||||
}
|
||||
|
|
|
@ -2254,7 +2254,7 @@ std::optional<PSBTError> CWallet::FillPSBT(PartiallySignedTransaction& psbtx, bo
|
|||
}
|
||||
}
|
||||
|
||||
RemoveUnnecessaryTransactions(psbtx, sighash_type);
|
||||
RemoveUnnecessaryTransactions(psbtx);
|
||||
|
||||
// Complete if every input is now signed
|
||||
complete = true;
|
||||
|
|
Loading…
Add table
Reference in a new issue