aboutsummaryrefslogtreecommitdiff
path: root/src/psbt.h
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2019-10-02 16:11:34 -0400
committerAndrew Chow <achow101-github@achow101.com>2021-12-10 08:29:26 -0500
commitc3eb416b882522dffa4254b52d2da5b53c970efe (patch)
treebfafcaa8d650fb540209b5010897769575d6a126 /src/psbt.h
parent3235847473e36070cbe9b0e9deacdd8d8d9428fe (diff)
Implement PSBT versions
Diffstat (limited to 'src/psbt.h')
-rw-r--r--src/psbt.h26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/psbt.h b/src/psbt.h
index a752e99e74..834af26219 100644
--- a/src/psbt.h
+++ b/src/psbt.h
@@ -20,6 +20,7 @@ static constexpr uint8_t PSBT_MAGIC_BYTES[5] = {'p', 's', 'b', 't', 0xff};
// Global types
static constexpr uint8_t PSBT_GLOBAL_UNSIGNED_TX = 0x00;
+static constexpr uint8_t PSBT_GLOBAL_VERSION = 0xFB;
// Input types
static constexpr uint8_t PSBT_IN_NON_WITNESS_UTXO = 0x00;
@@ -45,6 +46,9 @@ static constexpr uint8_t PSBT_SEPARATOR = 0x00;
// to prevent reading a stream indefinitely and running out of memory.
const std::streamsize MAX_FILE_SIZE_PSBT = 100000000; // 100 MiB
+// PSBT version number
+static constexpr uint32_t PSBT_HIGHEST_VERSION = 0;
+
/** A structure for PSBTs which contain per-input information */
struct PSBTInput
{
@@ -398,6 +402,7 @@ struct PartiallySignedTransaction
std::vector<PSBTInput> inputs;
std::vector<PSBTOutput> outputs;
std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
+ std::optional<uint32_t> m_version;
bool IsNull() const;
@@ -430,6 +435,12 @@ struct PartiallySignedTransaction
OverrideStream<Stream> os(&s, s.GetType(), s.GetVersion() | SERIALIZE_TRANSACTION_NO_WITNESS);
SerializeToVector(os, *tx);
+ // PSBT version
+ if (m_version != std::nullopt && *m_version > 0) {
+ SerializeToVector(s, CompactSizeWriter(PSBT_GLOBAL_VERSION));
+ SerializeToVector(s, *m_version);
+ }
+
// Write the unknown things
for (auto& entry : unknown) {
s << entry.first;
@@ -502,6 +513,21 @@ struct PartiallySignedTransaction
}
break;
}
+ case PSBT_GLOBAL_VERSION:
+ {
+ if (m_version) {
+ throw std::ios_base::failure("Duplicate Key, version already provided");
+ } else if (key.size() != 1) {
+ throw std::ios_base::failure("Global version key is more than one byte type");
+ }
+ uint32_t v;
+ UnserializeFromVector(s, v);
+ m_version = v;
+ if (*m_version > PSBT_HIGHEST_VERSION) {
+ throw std::ios_base::failure("Unsupported version number");
+ }
+ break;
+ }
// Unknown stuff
default: {
if (unknown.count(key) > 0) {