mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 03:47:29 -03:00
Implement PSBT proprietary type
This commit is contained in:
parent
10ba0b593d
commit
aebe758e54
1 changed files with 82 additions and 0 deletions
82
src/psbt.h
82
src/psbt.h
|
@ -21,6 +21,7 @@ static constexpr uint8_t PSBT_MAGIC_BYTES[5] = {'p', 's', 'b', 't', 0xff};
|
||||||
// Global types
|
// Global types
|
||||||
static constexpr uint8_t PSBT_GLOBAL_UNSIGNED_TX = 0x00;
|
static constexpr uint8_t PSBT_GLOBAL_UNSIGNED_TX = 0x00;
|
||||||
static constexpr uint8_t PSBT_GLOBAL_VERSION = 0xFB;
|
static constexpr uint8_t PSBT_GLOBAL_VERSION = 0xFB;
|
||||||
|
static constexpr uint8_t PSBT_GLOBAL_PROPRIETARY = 0xFC;
|
||||||
|
|
||||||
// Input types
|
// Input types
|
||||||
static constexpr uint8_t PSBT_IN_NON_WITNESS_UTXO = 0x00;
|
static constexpr uint8_t PSBT_IN_NON_WITNESS_UTXO = 0x00;
|
||||||
|
@ -32,11 +33,13 @@ static constexpr uint8_t PSBT_IN_WITNESSSCRIPT = 0x05;
|
||||||
static constexpr uint8_t PSBT_IN_BIP32_DERIVATION = 0x06;
|
static constexpr uint8_t PSBT_IN_BIP32_DERIVATION = 0x06;
|
||||||
static constexpr uint8_t PSBT_IN_SCRIPTSIG = 0x07;
|
static constexpr uint8_t PSBT_IN_SCRIPTSIG = 0x07;
|
||||||
static constexpr uint8_t PSBT_IN_SCRIPTWITNESS = 0x08;
|
static constexpr uint8_t PSBT_IN_SCRIPTWITNESS = 0x08;
|
||||||
|
static constexpr uint8_t PSBT_IN_PROPRIETARY = 0xFC;
|
||||||
|
|
||||||
// Output types
|
// Output types
|
||||||
static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT = 0x00;
|
static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT = 0x00;
|
||||||
static constexpr uint8_t PSBT_OUT_WITNESSSCRIPT = 0x01;
|
static constexpr uint8_t PSBT_OUT_WITNESSSCRIPT = 0x01;
|
||||||
static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION = 0x02;
|
static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION = 0x02;
|
||||||
|
static constexpr uint8_t PSBT_OUT_PROPRIETARY = 0xFC;
|
||||||
|
|
||||||
// The separator is 0x00. Reading this in means that the unserializer can interpret it
|
// The separator is 0x00. Reading this in means that the unserializer can interpret it
|
||||||
// as a 0 length key which indicates that this is the separator. The separator has no value.
|
// as a 0 length key which indicates that this is the separator. The separator has no value.
|
||||||
|
@ -49,6 +52,22 @@ const std::streamsize MAX_FILE_SIZE_PSBT = 100000000; // 100 MiB
|
||||||
// PSBT version number
|
// PSBT version number
|
||||||
static constexpr uint32_t PSBT_HIGHEST_VERSION = 0;
|
static constexpr uint32_t PSBT_HIGHEST_VERSION = 0;
|
||||||
|
|
||||||
|
/** A structure for PSBT proprietary types */
|
||||||
|
struct PSBTProprietary
|
||||||
|
{
|
||||||
|
uint64_t subtype;
|
||||||
|
std::vector<unsigned char> identifier;
|
||||||
|
std::vector<unsigned char> key;
|
||||||
|
std::vector<unsigned char> value;
|
||||||
|
|
||||||
|
bool operator<(const PSBTProprietary &b) const {
|
||||||
|
return key < b.key;
|
||||||
|
}
|
||||||
|
bool operator==(const PSBTProprietary &b) const {
|
||||||
|
return key == b.key;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** A structure for PSBTs which contain per-input information */
|
/** A structure for PSBTs which contain per-input information */
|
||||||
struct PSBTInput
|
struct PSBTInput
|
||||||
{
|
{
|
||||||
|
@ -61,6 +80,7 @@ struct PSBTInput
|
||||||
std::map<CPubKey, KeyOriginInfo> hd_keypaths;
|
std::map<CPubKey, KeyOriginInfo> hd_keypaths;
|
||||||
std::map<CKeyID, SigPair> partial_sigs;
|
std::map<CKeyID, SigPair> partial_sigs;
|
||||||
std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
|
std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
|
||||||
|
std::set<PSBTProprietary> m_proprietary;
|
||||||
std::optional<int> sighash_type;
|
std::optional<int> sighash_type;
|
||||||
|
|
||||||
bool IsNull() const;
|
bool IsNull() const;
|
||||||
|
@ -122,6 +142,12 @@ struct PSBTInput
|
||||||
SerializeToVector(s, final_script_witness.stack);
|
SerializeToVector(s, final_script_witness.stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write proprietary things
|
||||||
|
for (const auto& entry : m_proprietary) {
|
||||||
|
s << entry.key;
|
||||||
|
s << entry.value;
|
||||||
|
}
|
||||||
|
|
||||||
// Write unknown things
|
// Write unknown things
|
||||||
for (auto& entry : unknown) {
|
for (auto& entry : unknown) {
|
||||||
s << entry.first;
|
s << entry.first;
|
||||||
|
@ -255,6 +281,20 @@ struct PSBTInput
|
||||||
UnserializeFromVector(s, final_script_witness.stack);
|
UnserializeFromVector(s, final_script_witness.stack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PSBT_IN_PROPRIETARY:
|
||||||
|
{
|
||||||
|
PSBTProprietary this_prop;
|
||||||
|
skey >> this_prop.identifier;
|
||||||
|
this_prop.subtype = ReadCompactSize(skey);
|
||||||
|
this_prop.key = key;
|
||||||
|
|
||||||
|
if (m_proprietary.count(this_prop) > 0) {
|
||||||
|
throw std::ios_base::failure("Duplicate Key, proprietary key already found");
|
||||||
|
}
|
||||||
|
s >> this_prop.value;
|
||||||
|
m_proprietary.insert(this_prop);
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Unknown stuff
|
// Unknown stuff
|
||||||
default:
|
default:
|
||||||
if (unknown.count(key) > 0) {
|
if (unknown.count(key) > 0) {
|
||||||
|
@ -286,6 +326,7 @@ struct PSBTOutput
|
||||||
CScript witness_script;
|
CScript witness_script;
|
||||||
std::map<CPubKey, KeyOriginInfo> hd_keypaths;
|
std::map<CPubKey, KeyOriginInfo> hd_keypaths;
|
||||||
std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
|
std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
|
||||||
|
std::set<PSBTProprietary> m_proprietary;
|
||||||
|
|
||||||
bool IsNull() const;
|
bool IsNull() const;
|
||||||
void FillSignatureData(SignatureData& sigdata) const;
|
void FillSignatureData(SignatureData& sigdata) const;
|
||||||
|
@ -310,6 +351,12 @@ struct PSBTOutput
|
||||||
// Write any hd keypaths
|
// Write any hd keypaths
|
||||||
SerializeHDKeypaths(s, hd_keypaths, CompactSizeWriter(PSBT_OUT_BIP32_DERIVATION));
|
SerializeHDKeypaths(s, hd_keypaths, CompactSizeWriter(PSBT_OUT_BIP32_DERIVATION));
|
||||||
|
|
||||||
|
// Write proprietary things
|
||||||
|
for (const auto& entry : m_proprietary) {
|
||||||
|
s << entry.key;
|
||||||
|
s << entry.value;
|
||||||
|
}
|
||||||
|
|
||||||
// Write unknown things
|
// Write unknown things
|
||||||
for (auto& entry : unknown) {
|
for (auto& entry : unknown) {
|
||||||
s << entry.first;
|
s << entry.first;
|
||||||
|
@ -370,6 +417,20 @@ struct PSBTOutput
|
||||||
DeserializeHDKeypaths(s, key, hd_keypaths);
|
DeserializeHDKeypaths(s, key, hd_keypaths);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PSBT_OUT_PROPRIETARY:
|
||||||
|
{
|
||||||
|
PSBTProprietary this_prop;
|
||||||
|
skey >> this_prop.identifier;
|
||||||
|
this_prop.subtype = ReadCompactSize(skey);
|
||||||
|
this_prop.key = key;
|
||||||
|
|
||||||
|
if (m_proprietary.count(this_prop) > 0) {
|
||||||
|
throw std::ios_base::failure("Duplicate Key, proprietary key already found");
|
||||||
|
}
|
||||||
|
s >> this_prop.value;
|
||||||
|
m_proprietary.insert(this_prop);
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Unknown stuff
|
// Unknown stuff
|
||||||
default: {
|
default: {
|
||||||
if (unknown.count(key) > 0) {
|
if (unknown.count(key) > 0) {
|
||||||
|
@ -403,6 +464,7 @@ struct PartiallySignedTransaction
|
||||||
std::vector<PSBTOutput> outputs;
|
std::vector<PSBTOutput> outputs;
|
||||||
std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
|
std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
|
||||||
std::optional<uint32_t> m_version;
|
std::optional<uint32_t> m_version;
|
||||||
|
std::set<PSBTProprietary> m_proprietary;
|
||||||
|
|
||||||
bool IsNull() const;
|
bool IsNull() const;
|
||||||
uint32_t GetVersion() const;
|
uint32_t GetVersion() const;
|
||||||
|
@ -442,6 +504,12 @@ struct PartiallySignedTransaction
|
||||||
SerializeToVector(s, *m_version);
|
SerializeToVector(s, *m_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write proprietary things
|
||||||
|
for (const auto& entry : m_proprietary) {
|
||||||
|
s << entry.key;
|
||||||
|
s << entry.value;
|
||||||
|
}
|
||||||
|
|
||||||
// Write the unknown things
|
// Write the unknown things
|
||||||
for (auto& entry : unknown) {
|
for (auto& entry : unknown) {
|
||||||
s << entry.first;
|
s << entry.first;
|
||||||
|
@ -529,6 +597,20 @@ struct PartiallySignedTransaction
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PSBT_GLOBAL_PROPRIETARY:
|
||||||
|
{
|
||||||
|
PSBTProprietary this_prop;
|
||||||
|
skey >> this_prop.identifier;
|
||||||
|
this_prop.subtype = ReadCompactSize(skey);
|
||||||
|
this_prop.key = key;
|
||||||
|
|
||||||
|
if (m_proprietary.count(this_prop) > 0) {
|
||||||
|
throw std::ios_base::failure("Duplicate Key, proprietary key already found");
|
||||||
|
}
|
||||||
|
s >> this_prop.value;
|
||||||
|
m_proprietary.insert(this_prop);
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Unknown stuff
|
// Unknown stuff
|
||||||
default: {
|
default: {
|
||||||
if (unknown.count(key) > 0) {
|
if (unknown.count(key) > 0) {
|
||||||
|
|
Loading…
Reference in a new issue