psbt: add tx input and output fields in PSBTInput and PSBTOutput

PSBTInput should be aware of the previous txid, output index, and
sequence numbers for inputs, extracting them from the global
unsigned tx.

PSBTOutput should be aware of the output amount and script, extracting
them from the global unsigned tx.

This prepares for PSBTv2 where these fields are serialized.
This commit is contained in:
Ava Chow
2026-03-16 14:05:39 -07:00
parent 990b084f11
commit 9671aa08c2
4 changed files with 30 additions and 26 deletions

View File

@@ -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

View File

@@ -280,6 +280,10 @@ public:
std::map<uint160, std::vector<unsigned char>> hash160_preimages;
std::map<uint256, std::vector<unsigned char>> hash256_preimages;
Txid prev_txid;
uint32_t prev_out;
std::optional<uint32_t> sequence;
// Taproot fields
std::vector<unsigned char> m_tap_key_sig;
std::map<std::pair<XOnlyPubKey, uint256>, std::vector<unsigned char>> 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<uint32_t> 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<unsigned char>, std::vector<unsigned char>> unknown;
std::set<PSBTProprietary> 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;

View File

@@ -1649,14 +1649,7 @@ static RPCMethod createpsbt()
CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf, self.Arg<uint32_t>("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{};

View File

@@ -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, {