diff --git a/src/psbt.cpp b/src/psbt.cpp index 416eae11d1f..29f16e73c87 100644 --- a/src/psbt.cpp +++ b/src/psbt.cpp @@ -15,8 +15,14 @@ using common::PSBTError; PartiallySignedTransaction::PartiallySignedTransaction(const CMutableTransaction& tx) : tx(tx) { - inputs.resize(tx.vin.size(), PSBTInput(GetVersion())); - outputs.resize(tx.vout.size(), PSBTOutput(GetVersion())); + inputs.reserve(tx.vin.size()); + for (const CTxIn& input : tx.vin) { + inputs.emplace_back(GetVersion(), input.prevout.hash, input.prevout.n, input.nSequence); + } + outputs.reserve(tx.vout.size()); + for (const CTxOut& output : tx.vout) { + outputs.emplace_back(GetVersion(), output.nValue, output.scriptPubKey); + } } bool PartiallySignedTransaction::IsNull() const diff --git a/src/psbt.h b/src/psbt.h index 4272cd3a807..dcf0d6bd1a5 100644 --- a/src/psbt.h +++ b/src/psbt.h @@ -280,6 +280,10 @@ public: std::map> hash160_preimages; std::map> hash256_preimages; + Txid prev_txid; + uint32_t prev_out; + std::optional sequence; + // Taproot fields std::vector m_tap_key_sig; std::map, std::vector> m_tap_script_sigs; @@ -304,8 +308,11 @@ public: void FromSignatureData(const SignatureData& sigdata); void Merge(const PSBTInput& input); uint32_t GetVersion() const { return m_psbt_version; } - explicit PSBTInput(uint32_t psbt_version) - : m_psbt_version(psbt_version) + explicit PSBTInput(uint32_t psbt_version, const Txid& prev_txid, uint32_t prev_out, std::optional sequence = std::nullopt) + : m_psbt_version(psbt_version), + prev_txid(prev_txid), + prev_out(prev_out), + sequence(sequence) { assert(m_psbt_version == 0); } @@ -816,13 +823,18 @@ public: std::map, std::vector> unknown; std::set m_proprietary; + CAmount amount; + CScript script; + bool IsNull() const; void FillSignatureData(SignatureData& sigdata) const; void FromSignatureData(const SignatureData& sigdata); void Merge(const PSBTOutput& output); uint32_t GetVersion() const { return m_psbt_version; } - explicit PSBTOutput(uint32_t psbt_version) - : m_psbt_version(psbt_version) + explicit PSBTOutput(uint32_t psbt_version, CAmount amount, const CScript& script) + : m_psbt_version(psbt_version), + amount(amount), + script(script) { assert(m_psbt_version == 0); } @@ -1264,7 +1276,7 @@ public: // Read input data unsigned int i = 0; while (!s.empty() && i < tx->vin.size()) { - PSBTInput input(psbt_ver); + PSBTInput input(psbt_ver, tx->vin[i].prevout.hash, tx->vin[i].prevout.n, tx->vin[i].nSequence); s >> input; inputs.push_back(input); @@ -1287,7 +1299,7 @@ public: // Read output data i = 0; while (!s.empty() && i < tx->vout.size()) { - PSBTOutput output(psbt_ver); + PSBTOutput output(psbt_ver, tx->vout[i].nValue, tx->vout[i].scriptPubKey); s >> output; outputs.push_back(output); ++i; diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 67067110648..517a02bf39d 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1649,14 +1649,7 @@ static RPCMethod createpsbt() CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf, self.Arg("version")); // Make a blank psbt - PartiallySignedTransaction psbtx; - psbtx.tx = rawTx; - for (unsigned int i = 0; i < rawTx.vin.size(); ++i) { - psbtx.inputs.emplace_back(0); - } - for (unsigned int i = 0; i < rawTx.vout.size(); ++i) { - psbtx.outputs.emplace_back(0); - } + PartiallySignedTransaction psbtx(rawTx); // Serialize the PSBT DataStream ssTx{}; @@ -1717,14 +1710,7 @@ static RPCMethod converttopsbt() } // Make a blank psbt - PartiallySignedTransaction psbtx; - psbtx.tx = tx; - for (unsigned int i = 0; i < tx.vin.size(); ++i) { - psbtx.inputs.emplace_back(0); - } - for (unsigned int i = 0; i < tx.vout.size(); ++i) { - psbtx.outputs.emplace_back(0); - } + PartiallySignedTransaction psbtx(tx); // Serialize the PSBT DataStream ssTx{}; diff --git a/src/test/fuzz/deserialize.cpp b/src/test/fuzz/deserialize.cpp index b3f35baa0fc..15150c4a444 100644 --- a/src/test/fuzz/deserialize.cpp +++ b/src/test/fuzz/deserialize.cpp @@ -192,11 +192,11 @@ FUZZ_TARGET_DESERIALIZE(prefilled_transaction_deserialize, { DeserializeFromFuzzingInput(buffer, prefilled_transaction); }) FUZZ_TARGET_DESERIALIZE(psbt_input_deserialize, { - PSBTInput psbt_input(0); + PSBTInput psbt_input(0, Txid{}, 0); DeserializeFromFuzzingInput(buffer, psbt_input); }) FUZZ_TARGET_DESERIALIZE(psbt_output_deserialize, { - PSBTOutput psbt_output(0); + PSBTOutput psbt_output(0, 0, CScript()); DeserializeFromFuzzingInput(buffer, psbt_output); }) FUZZ_TARGET_DESERIALIZE(block_deserialize, {