Implement PSBT versions

This commit is contained in:
Andrew Chow
2019-10-02 16:11:34 -04:00
parent 3235847473
commit c3eb416b88
2 changed files with 29 additions and 1 deletions

View File

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