What changed, and why it matters
This commit adds two missing data fields to Bitcoin's PSBTv2 format support: the transaction version and the locktime. These values are now stored in the correct global fields when a transaction is converted into a PSBTv2. It appears to be a correctness/completeness fix for the newer PSBT standard rather than a fix for an active security vulnerability.
Review as a normal correctness fix. No urgent security action is indicated by the diff alone. If PSBTv2 handling is security-critical for downstream wallets, verify that serialization round-trips and upgrade paths are covered by tests.
Security signals we found
Missing required fields in a protocol data structure (PSBTv2)
Potential serialization/deserialization inconsistency between PSBT versions
No input validation, bounds checking, or memory safety changes present
Evidence from the diff
The change populates PSBT_GLOBAL_TX_VERSION and PSBT_GLOBAL_FALLBACK_LOCKTIME when constructing a PartiallySignedTransaction from a CMutableTransaction or when deserializing a PSBTv0 that is being upgraded. Previously these fields were declared elsewhere but not assigned, which could lead to incomplete PSBTv2 serialization. The patch is additive and aligns the implementation with BIP370 semantics.
Changed components
src/psbt.cppsrc/psbt.hPartiallySignedTransaction constructorPSBT deserialization/upgrading pathInspect captured patch +7 / −0
diff --git a/src/psbt.cpp b/src/psbt.cpp
index 1a49d01a..3f5e2cde 100644
--- a/src/psbt.cpp
+++ b/src/psbt.cpp
@@ -16,6 +16,8 @@ using common::PSBTError;
PartiallySignedTransaction::PartiallySignedTransaction(const CMutableTransaction& tx) : tx(tx)
{
+ tx_version = tx.version;
+ fallback_locktime = tx.nLockTime;
inputs.reserve(tx.vin.size());
for (const CTxIn& input : tx.vin) {
inputs.emplace_back(GetVersion(), input.prevout.hash, input.prevout.n, input.nSequence);
diff --git a/src/psbt.h b/src/psbt.h
index 3d893194..2325ca97 100644
--- a/src/psbt.h
+++ b/src/psbt.h
@@ -1073,6 +1073,9 @@ public:
std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
std::set<PSBTProprietary> m_proprietary;
+ uint32_t tx_version;
+ std::optional<uint32_t> fallback_locktime;
+
bool IsNull() const;
uint32_t GetVersion() const;
@@ -1203,6 +1206,8 @@ public:
throw std::ios_base::failure("Unsigned tx does not have empty scriptSigs and scriptWitnesses.");
}
}
+ tx_version = tx->version;
+ fallback_locktime = tx->nLockTime;
break;
}
case PSBT_GLOBAL_XPUB:
Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.