LCOV - code coverage report
Current view: top level - src - psbt.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 326 380 85.8 %
Date: 2026-06-25 07:23:43 Functions: 53 56 94.6 %

          Line data    Source code
       1             : // Copyright (c) 2009-2021 The Bitcoin Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #ifndef BITCOIN_PSBT_H
       6             : #define BITCOIN_PSBT_H
       7             : 
       8             : #include <node/transaction.h>
       9             : #include <policy/feerate.h>
      10             : #include <primitives/transaction.h>
      11             : #include <pubkey.h>
      12             : #include <script/keyorigin.h>
      13             : #include <script/sign.h>
      14             : #include <script/signingprovider.h>
      15             : #include <span.h>
      16             : #include <streams.h>
      17             : 
      18             : #include <optional>
      19             : 
      20             : // Magic bytes
      21             : static constexpr uint8_t PSBT_MAGIC_BYTES[5] = {'p', 's', 'b', 't', 0xff};
      22             : 
      23             : // Global types
      24             : static constexpr uint8_t PSBT_GLOBAL_UNSIGNED_TX = 0x00;
      25             : static constexpr uint8_t PSBT_GLOBAL_XPUB = 0x01;
      26             : static constexpr uint8_t PSBT_GLOBAL_VERSION = 0xFB;
      27             : static constexpr uint8_t PSBT_GLOBAL_PROPRIETARY = 0xFC;
      28             : 
      29             : // Input types
      30             : static constexpr uint8_t PSBT_IN_NON_WITNESS_UTXO = 0x00;
      31             : static constexpr uint8_t PSBT_IN_PARTIAL_SIG = 0x02;
      32             : static constexpr uint8_t PSBT_IN_SIGHASH = 0x03;
      33             : static constexpr uint8_t PSBT_IN_REDEEMSCRIPT = 0x04;
      34             : static constexpr uint8_t PSBT_IN_BIP32_DERIVATION = 0x06;
      35             : static constexpr uint8_t PSBT_IN_SCRIPTSIG = 0x07;
      36             : static constexpr uint8_t PSBT_IN_RIPEMD160 = 0x0A;
      37             : static constexpr uint8_t PSBT_IN_SHA256 = 0x0B;
      38             : static constexpr uint8_t PSBT_IN_HASH160 = 0x0C;
      39             : static constexpr uint8_t PSBT_IN_HASH256 = 0x0D;
      40             : static constexpr uint8_t PSBT_IN_PROPRIETARY = 0xFC;
      41             : 
      42             : // Output types
      43             : static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT = 0x00;
      44             : static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION = 0x02;
      45             : static constexpr uint8_t PSBT_OUT_PROPRIETARY = 0xFC;
      46             : 
      47             : // The separator is 0x00. Reading this in means that the unserializer can interpret it
      48             : // as a 0 length key which indicates that this is the separator. The separator has no value.
      49             : static constexpr uint8_t PSBT_SEPARATOR = 0x00;
      50             : 
      51             : // BIP 174 does not specify a maximum file size, but we set a limit anyway
      52             : // to prevent reading a stream indefinitely and running out of memory.
      53             : const std::streamsize MAX_FILE_SIZE_PSBT = 100000000; // 100 MB
      54             : 
      55             : // PSBT version number
      56             : static constexpr uint32_t PSBT_HIGHEST_VERSION = 0;
      57             : 
      58             : /** A structure for PSBT proprietary types */
      59          24 : struct PSBTProprietary
      60             : {
      61             :     uint64_t subtype;
      62             :     std::vector<unsigned char> identifier;
      63             :     std::vector<unsigned char> key;
      64             :     std::vector<unsigned char> value;
      65             : 
      66          16 :     bool operator<(const PSBTProprietary &b) const {
      67          16 :         return key < b.key;
      68             :     }
      69             :     bool operator==(const PSBTProprietary &b) const {
      70             :         return key == b.key;
      71             :     }
      72             : };
      73             : 
      74             : // Takes a stream and multiple arguments and serializes them as if first serialized into a vector and then into the stream
      75             : // The resulting output into the stream has the total serialized length of all of the objects followed by all objects concatenated with each other.
      76             : template<typename Stream, typename... X>
      77        4287 : void SerializeToVector(Stream& s, const X&... args)
      78             : {
      79        4287 :     WriteCompactSize(s, GetSerializeSizeMany(s.GetVersion(), args...));
      80        4287 :     SerializeMany(s, args...);
      81        4287 : }
      82             : 
      83             : // Takes a stream and multiple arguments and unserializes them first as a vector then each object individually in the order provided in the arguments
      84             : template<typename Stream, typename... X>
      85        1259 : void UnserializeFromVector(Stream& s, X&... args)
      86             : {
      87        1259 :     size_t expected_size = ReadCompactSize(s);
      88        1259 :     size_t remaining_before = s.size();
      89        1259 :     UnserializeMany(s, args...);
      90        1259 :     size_t remaining_after = s.size();
      91        1259 :     if (remaining_after + expected_size != remaining_before) {
      92          16 :         throw std::ios_base::failure("Size of value was not the stated size");
      93             :     }
      94        1243 : }
      95             : 
      96             : // Deserialize an individual HD keypath to a stream
      97             : template<typename Stream>
      98         883 : void DeserializeHDKeypath(Stream& s, KeyOriginInfo& hd_keypath)
      99             : {
     100             :     // Read in key path
     101         883 :     uint64_t value_len = ReadCompactSize(s);
     102         883 :     if (value_len % 4 || value_len == 0) {
     103           0 :         throw std::ios_base::failure("Invalid length for HD key path");
     104             :     }
     105             : 
     106         883 :     s >> hd_keypath.fingerprint;
     107        3674 :     for (unsigned int i = 4; i < value_len; i += sizeof(uint32_t)) {
     108             :         uint32_t index;
     109        2791 :         s >> index;
     110        2791 :         hd_keypath.path.push_back(index);
     111        2791 :     }
     112         883 : }
     113             : 
     114             : // Deserialize HD keypaths into a map
     115             : template<typename Stream>
     116         879 : void DeserializeHDKeypaths(Stream& s, const std::vector<unsigned char>& key, std::map<CPubKey, KeyOriginInfo>& hd_keypaths)
     117             : {
     118             :     // Make sure that the key is the size of pubkey + 1
     119         879 :     if (key.size() != CPubKey::SIZE + 1 && key.size() != CPubKey::COMPRESSED_SIZE + 1) {
     120           8 :         throw std::ios_base::failure("Size of key was not the expected size for the type BIP32 keypath");
     121             :     }
     122             :     // Read in the pubkey from key
     123         871 :     CPubKey pubkey(key.begin() + 1, key.end());
     124         871 :     if (!pubkey.IsFullyValid()) {
     125           0 :        throw std::ios_base::failure("Invalid pubkey");
     126             :     }
     127         871 :     if (hd_keypaths.count(pubkey) > 0) {
     128           0 :         throw std::ios_base::failure("Duplicate Key, pubkey derivation path already provided");
     129             :     }
     130             : 
     131         871 :     KeyOriginInfo keypath;
     132         871 :     DeserializeHDKeypath(s, keypath);
     133             : 
     134             :     // Add to map
     135         871 :     hd_keypaths.emplace(pubkey, std::move(keypath));
     136         871 : }
     137             : 
     138             : // Serialize an individual HD keypath to a stream
     139             : template<typename Stream>
     140        1115 : void SerializeHDKeypath(Stream& s, KeyOriginInfo hd_keypath)
     141             : {
     142        1115 :     WriteCompactSize(s, (hd_keypath.path.size() + 1) * sizeof(uint32_t));
     143        1115 :     s << hd_keypath.fingerprint;
     144        5026 :     for (const auto& path : hd_keypath.path) {
     145        3911 :         s << path;
     146             :     }
     147        1115 : }
     148             : 
     149             : // Serialize HD keypaths to a stream from a map
     150             : template<typename Stream>
     151        1649 : void SerializeHDKeypaths(Stream& s, const std::map<CPubKey, KeyOriginInfo>& hd_keypaths, CompactSizeWriter type)
     152             : {
     153        2764 :     for (const auto& keypath_pair : hd_keypaths) {
     154        1115 :         if (!keypath_pair.first.IsValid()) {
     155           0 :             throw std::ios_base::failure("Invalid CPubKey being serialized");
     156             :         }
     157        1115 :         SerializeToVector(s, type, Span{keypath_pair.first});
     158        1115 :         SerializeHDKeypath(s, keypath_pair.second);
     159             :     }
     160        1649 : }
     161             : 
     162             : /** A structure for PSBTs which contain per-input information */
     163        1044 : struct PSBTInput
     164             : {
     165             :     CTransactionRef non_witness_utxo;
     166             :     CScript redeem_script;
     167             :     CScript final_script_sig;
     168             :     std::map<CPubKey, KeyOriginInfo> hd_keypaths;
     169             :     std::map<CKeyID, SigPair> partial_sigs;
     170             :     std::map<uint160, std::vector<unsigned char>> ripemd160_preimages;
     171             :     std::map<uint256, std::vector<unsigned char>> sha256_preimages;
     172             :     std::map<uint160, std::vector<unsigned char>> hash160_preimages;
     173             :     std::map<uint256, std::vector<unsigned char>> hash256_preimages;
     174             :     std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
     175             :     std::set<PSBTProprietary> m_proprietary;
     176             :     std::optional<int> sighash_type;
     177             : 
     178             :     bool IsNull() const;
     179             :     void FillSignatureData(SignatureData& sigdata) const;
     180             :     void FromSignatureData(const SignatureData& sigdata);
     181             :     void Merge(const PSBTInput& input);
     182        3686 :     PSBTInput() {}
     183             : 
     184             :     template <typename Stream>
     185         891 :     inline void Serialize(Stream& s) const {
     186             :         // Write the utxo
     187         891 :         if (non_witness_utxo) {
     188         706 :             SerializeToVector(s, CompactSizeWriter(PSBT_IN_NON_WITNESS_UTXO));
     189         706 :             SerializeToVector(s, non_witness_utxo);
     190         706 :         }
     191             : 
     192         891 :         if (final_script_sig.empty()) {
     193             :             // Write any partial signatures
     194         661 :             for (const auto& sig_pair : partial_sigs) {
     195          78 :                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_PARTIAL_SIG), Span{sig_pair.second.first});
     196          78 :                 s << sig_pair.second.second;
     197             :             }
     198             : 
     199             :             // Write the sighash type
     200         583 :             if (sighash_type != std::nullopt) {
     201          52 :                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_SIGHASH));
     202          52 :                 SerializeToVector(s, *sighash_type);
     203          52 :             }
     204             : 
     205             :             // Write the redeem script
     206         583 :             if (!redeem_script.empty()) {
     207          90 :                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_REDEEMSCRIPT));
     208          90 :                 s << redeem_script;
     209          90 :             }
     210             : 
     211             :             // Write any hd keypaths
     212         583 :             SerializeHDKeypaths(s, hd_keypaths, CompactSizeWriter(PSBT_IN_BIP32_DERIVATION));
     213             : 
     214             :             // Write any ripemd160 preimage
     215         583 :             for (const auto& [hash, preimage] : ripemd160_preimages) {
     216           0 :                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_RIPEMD160), Span{hash});
     217           0 :                 s << preimage;
     218             :             }
     219             : 
     220             :             // Write any sha256 preimage
     221         583 :             for (const auto& [hash, preimage] : sha256_preimages) {
     222           0 :                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_SHA256), Span{hash});
     223           0 :                 s << preimage;
     224             :             }
     225             : 
     226             :             // Write any hash160 preimage
     227         583 :             for (const auto& [hash, preimage] : hash160_preimages) {
     228           0 :                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_HASH160), Span{hash});
     229           0 :                 s << preimage;
     230             :             }
     231             : 
     232             :             // Write any hash256 preimage
     233         583 :             for (const auto& [hash, preimage] : hash256_preimages) {
     234           0 :                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_HASH256), Span{hash});
     235           0 :                 s << preimage;
     236             :             }
     237         583 :         }
     238             : 
     239             :         // Write script sig
     240         891 :         if (!final_script_sig.empty()) {
     241         308 :             SerializeToVector(s, CompactSizeWriter(PSBT_IN_SCRIPTSIG));
     242         308 :             s << final_script_sig;
     243         308 :         }
     244             : 
     245             :         // Write proprietary things
     246         891 :         for (const auto& entry : m_proprietary) {
     247           0 :             s << entry.key;
     248           0 :             s << entry.value;
     249             :         }
     250             : 
     251             :         // Write unknown things
     252         967 :         for (auto& entry : unknown) {
     253          76 :             s << entry.first;
     254          76 :             s << entry.second;
     255             :         }
     256             : 
     257         891 :         s << PSBT_SEPARATOR;
     258         891 :     }
     259             : 
     260             : 
     261             :     template <typename Stream>
     262         930 :     inline void Unserialize(Stream& s) {
     263             :         // Used for duplicate key detection
     264         930 :         std::set<std::vector<unsigned char>> key_lookup;
     265             : 
     266             :         // Read loop
     267         930 :         bool found_sep = false;
     268        2740 :         while(!s.empty()) {
     269             :             // Read
     270        2740 :             std::vector<unsigned char> key;
     271        2740 :             s >> key;
     272             : 
     273             :             // the key is empty if that was actually a separator byte
     274             :             // This is a special case for key lengths 0 as those are not allowed (except for separator)
     275        2740 :             if (key.empty()) {
     276         866 :                 found_sep = true;
     277         866 :                 break;
     278             :             }
     279             : 
     280             :             // Type is compact size uint at beginning of key
     281        1874 :             SpanReader skey(s.GetType(), s.GetVersion(), key);
     282        1874 :             uint64_t type = ReadCompactSize(skey);
     283             : 
     284             :             // Do stuff based on type
     285        1874 :             switch(type) {
     286             :                 case PSBT_IN_NON_WITNESS_UTXO:
     287         564 :                     if (!key_lookup.emplace(key).second) {
     288           0 :                         throw std::ios_base::failure("Duplicate Key, input non-witness utxo already provided");
     289         564 :                     } else if (key.size() != 1) {
     290           4 :                         throw std::ios_base::failure("Non-witness utxo key is more than one byte type");
     291             :                     }
     292         560 :                     UnserializeFromVector(s, non_witness_utxo);
     293         544 :                     break;
     294             :                 case PSBT_IN_PARTIAL_SIG:
     295             :                 {
     296             :                     // Make sure that the key is the size of pubkey + 1
     297         112 :                     if (key.size() != CPubKey::SIZE + 1 && key.size() != CPubKey::COMPRESSED_SIZE + 1) {
     298           4 :                         throw std::ios_base::failure("Size of key was not the expected size for the type partial signature pubkey");
     299             :                     }
     300             :                     // Read in the pubkey from key
     301         108 :                     CPubKey pubkey(key.begin() + 1, key.end());
     302         108 :                     if (!pubkey.IsFullyValid()) {
     303           0 :                        throw std::ios_base::failure("Invalid pubkey");
     304             :                     }
     305         108 :                     if (partial_sigs.count(pubkey.GetID()) > 0) {
     306           0 :                         throw std::ios_base::failure("Duplicate Key, input partial signature for pubkey already provided");
     307             :                     }
     308             : 
     309             :                     // Read in the signature from value
     310         108 :                     std::vector<unsigned char> sig;
     311         108 :                     s >> sig;
     312             : 
     313             :                     // Add to list
     314         108 :                     partial_sigs.emplace(pubkey.GetID(), SigPair(pubkey, std::move(sig)));
     315             :                     break;
     316         108 :                 }
     317             :                 case PSBT_IN_SIGHASH:
     318          80 :                     if (!key_lookup.emplace(key).second) {
     319           4 :                         throw std::ios_base::failure("Duplicate Key, input sighash type already provided");
     320          76 :                     } else if (key.size() != 1) {
     321           4 :                         throw std::ios_base::failure("Sighash type key is more than one byte type");
     322             :                     }
     323             :                     int sighash;
     324          72 :                     UnserializeFromVector(s, sighash);
     325          72 :                     sighash_type = sighash;
     326          72 :                     break;
     327             :                 case PSBT_IN_REDEEMSCRIPT:
     328             :                 {
     329         147 :                     if (!key_lookup.emplace(key).second) {
     330           4 :                         throw std::ios_base::failure("Duplicate Key, input redeemScript already provided");
     331         143 :                     } else if (key.size() != 1) {
     332           4 :                         throw std::ios_base::failure("Input redeemScript key is more than one byte type");
     333             :                     }
     334         139 :                     s >> redeem_script;
     335         139 :                     break;
     336             :                 }
     337             :                 case PSBT_IN_BIP32_DERIVATION:
     338             :                 {
     339         412 :                     DeserializeHDKeypaths(s, key, hd_keypaths);
     340         408 :                     break;
     341             :                 }
     342             :                 case PSBT_IN_SCRIPTSIG:
     343             :                 {
     344         275 :                     if (!key_lookup.emplace(key).second) {
     345           4 :                         throw std::ios_base::failure("Duplicate Key, input final scriptSig already provided");
     346         271 :                     } else if (key.size() != 1) {
     347           4 :                         throw std::ios_base::failure("Final scriptSig key is more than one byte type");
     348             :                     }
     349         267 :                     s >> final_script_sig;
     350         267 :                     break;
     351             :                 }
     352             :                 case PSBT_IN_RIPEMD160:
     353             :                 {
     354             :                     // Make sure that the key is the size of a ripemd160 hash + 1
     355          12 :                     if (key.size() != CRIPEMD160::OUTPUT_SIZE + 1) {
     356           0 :                         throw std::ios_base::failure("Size of key was not the expected size for the type ripemd160 preimage");
     357             :                     }
     358             :                     // Read in the hash from key
     359          12 :                     std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
     360          12 :                     uint160 hash(hash_vec);
     361          12 :                     if (ripemd160_preimages.count(hash) > 0) {
     362           0 :                         throw std::ios_base::failure("Duplicate Key, input ripemd160 preimage already provided");
     363             :                     }
     364             : 
     365             :                     // Read in the preimage from value
     366          12 :                     std::vector<unsigned char> preimage;
     367          12 :                     s >> preimage;
     368             : 
     369             :                     // Add to preimages list
     370          12 :                     ripemd160_preimages.emplace(hash, std::move(preimage));
     371             :                     break;
     372          12 :                 }
     373             :                 case PSBT_IN_SHA256:
     374             :                 {
     375             :                     // Make sure that the key is the size of a sha256 hash + 1
     376          12 :                     if (key.size() != CSHA256::OUTPUT_SIZE + 1) {
     377           0 :                         throw std::ios_base::failure("Size of key was not the expected size for the type sha256 preimage");
     378             :                     }
     379             :                     // Read in the hash from key
     380          12 :                     std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
     381          12 :                     uint256 hash(hash_vec);
     382          12 :                     if (sha256_preimages.count(hash) > 0) {
     383           0 :                         throw std::ios_base::failure("Duplicate Key, input sha256 preimage already provided");
     384             :                     }
     385             : 
     386             :                     // Read in the preimage from value
     387          12 :                     std::vector<unsigned char> preimage;
     388          12 :                     s >> preimage;
     389             : 
     390             :                     // Add to preimages list
     391          12 :                     sha256_preimages.emplace(hash, std::move(preimage));
     392             :                     break;
     393          12 :                 }
     394             :                 case PSBT_IN_HASH160:
     395             :                 {
     396             :                     // Make sure that the key is the size of a hash160 hash + 1
     397          12 :                     if (key.size() != CHash160::OUTPUT_SIZE + 1) {
     398           0 :                         throw std::ios_base::failure("Size of key was not the expected size for the type hash160 preimage");
     399             :                     }
     400             :                     // Read in the hash from key
     401          12 :                     std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
     402          12 :                     uint160 hash(hash_vec);
     403          12 :                     if (hash160_preimages.count(hash) > 0) {
     404           0 :                         throw std::ios_base::failure("Duplicate Key, input hash160 preimage already provided");
     405             :                     }
     406             : 
     407             :                     // Read in the preimage from value
     408          12 :                     std::vector<unsigned char> preimage;
     409          12 :                     s >> preimage;
     410             : 
     411             :                     // Add to preimages list
     412          12 :                     hash160_preimages.emplace(hash, std::move(preimage));
     413             :                     break;
     414          12 :                 }
     415             :                 case PSBT_IN_HASH256:
     416             :                 {
     417             :                     // Make sure that the key is the size of a hash256 hash + 1
     418          12 :                     if (key.size() != CHash256::OUTPUT_SIZE + 1) {
     419           0 :                         throw std::ios_base::failure("Size of key was not the expected size for the type hash256 preimage");
     420             :                     }
     421             :                     // Read in the hash from key
     422          12 :                     std::vector<unsigned char> hash_vec(key.begin() + 1, key.end());
     423          12 :                     uint256 hash(hash_vec);
     424          12 :                     if (hash256_preimages.count(hash) > 0) {
     425           0 :                         throw std::ios_base::failure("Duplicate Key, input hash256 preimage already provided");
     426             :                     }
     427             : 
     428             :                     // Read in the preimage from value
     429          12 :                     std::vector<unsigned char> preimage;
     430          12 :                     s >> preimage;
     431             : 
     432             :                     // Add to preimages list
     433          12 :                     hash256_preimages.emplace(hash, std::move(preimage));
     434             :                     break;
     435          12 :                 }
     436             :                 case PSBT_IN_PROPRIETARY:
     437             :                 {
     438           4 :                     PSBTProprietary this_prop;
     439           4 :                     skey >> this_prop.identifier;
     440           4 :                     this_prop.subtype = ReadCompactSize(skey);
     441           4 :                     this_prop.key = key;
     442             : 
     443           4 :                     if (m_proprietary.count(this_prop) > 0) {
     444           0 :                         throw std::ios_base::failure("Duplicate Key, proprietary key already found");
     445             :                     }
     446           4 :                     s >> this_prop.value;
     447           4 :                     m_proprietary.insert(this_prop);
     448             :                     break;
     449           4 :                 }
     450             :                 // Unknown stuff
     451             :                 default:
     452         232 :                     if (unknown.count(key) > 0) {
     453          12 :                         throw std::ios_base::failure("Duplicate Key, key for unknown value already provided");
     454             :                     }
     455             :                     // Read in the value
     456         220 :                     std::vector<unsigned char> val_bytes;
     457         220 :                     s >> val_bytes;
     458         220 :                     unknown.emplace(std::move(key), std::move(val_bytes));
     459             :                     break;
     460         220 :             }
     461        2740 :         }
     462             : 
     463         866 :         if (!found_sep) {
     464           0 :             throw std::ios_base::failure("Separator is missing at the end of an input map");
     465             :         }
     466         994 :     }
     467             : 
     468             :     template <typename Stream>
     469             :     PSBTInput(deserialize_type, Stream& s) {
     470             :         Unserialize(s);
     471             :     }
     472             : };
     473             : 
     474             : /** A structure for PSBTs which contains per output information */
     475        1082 : struct PSBTOutput
     476             : {
     477             :     CScript redeem_script;
     478             :     std::map<CPubKey, KeyOriginInfo> hd_keypaths;
     479             :     std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
     480             :     std::set<PSBTProprietary> m_proprietary;
     481             : 
     482             :     bool IsNull() const;
     483             :     void FillSignatureData(SignatureData& sigdata) const;
     484             :     void FromSignatureData(const SignatureData& sigdata);
     485             :     void Merge(const PSBTOutput& output);
     486        3750 :     PSBTOutput() {}
     487             : 
     488             :     template <typename Stream>
     489        1066 :     inline void Serialize(Stream& s) const {
     490             :         // Write the redeem script
     491        1066 :         if (!redeem_script.empty()) {
     492          14 :             SerializeToVector(s, CompactSizeWriter(PSBT_OUT_REDEEMSCRIPT));
     493          14 :             s << redeem_script;
     494          14 :         }
     495             : 
     496             :         // Write any hd keypaths
     497        1066 :         SerializeHDKeypaths(s, hd_keypaths, CompactSizeWriter(PSBT_OUT_BIP32_DERIVATION));
     498             : 
     499             :         // Write proprietary things
     500        1066 :         for (const auto& entry : m_proprietary) {
     501           0 :             s << entry.key;
     502           0 :             s << entry.value;
     503             :         }
     504             : 
     505             :         // Write unknown things
     506        1074 :         for (auto& entry : unknown) {
     507           8 :             s << entry.first;
     508           8 :             s << entry.second;
     509             :         }
     510             : 
     511        1066 :         s << PSBT_SEPARATOR;
     512        1066 :     }
     513             : 
     514             : 
     515             :     template <typename Stream>
     516         938 :     inline void Unserialize(Stream& s) {
     517             :         // Used for duplicate key detection
     518         938 :         std::set<std::vector<unsigned char>> key_lookup;
     519             : 
     520             :         // Read loop
     521         938 :         bool found_sep = false;
     522        1453 :         while(!s.empty()) {
     523             :             // Read
     524        1453 :             std::vector<unsigned char> key;
     525        1453 :             s >> key;
     526             : 
     527             :             // the key is empty if that was actually a separator byte
     528             :             // This is a special case for key lengths 0 as those are not allowed (except for separator)
     529        1453 :             if (key.empty()) {
     530         918 :                 found_sep = true;
     531         918 :                 break;
     532             :             }
     533             : 
     534             :             // Type is compact size uint at beginning of key
     535         535 :             SpanReader skey(s.GetType(), s.GetVersion(), key);
     536         535 :             uint64_t type = ReadCompactSize(skey);
     537             : 
     538             :             // Do stuff based on type
     539         535 :             switch(type) {
     540             :                 case PSBT_OUT_REDEEMSCRIPT:
     541             :                 {
     542          44 :                     if (!key_lookup.emplace(key).second) {
     543           4 :                         throw std::ios_base::failure("Duplicate Key, output redeemScript already provided");
     544          40 :                     } else if (key.size() != 1) {
     545           4 :                         throw std::ios_base::failure("Output redeemScript key is more than one byte type");
     546             :                     }
     547          36 :                     s >> redeem_script;
     548          36 :                     break;
     549             :                 }
     550             :                 case PSBT_OUT_BIP32_DERIVATION:
     551             :                 {
     552         467 :                     DeserializeHDKeypaths(s, key, hd_keypaths);
     553         463 :                     break;
     554             :                 }
     555             :                 case PSBT_OUT_PROPRIETARY:
     556             :                 {
     557           4 :                     PSBTProprietary this_prop;
     558           4 :                     skey >> this_prop.identifier;
     559           4 :                     this_prop.subtype = ReadCompactSize(skey);
     560           4 :                     this_prop.key = key;
     561             : 
     562           4 :                     if (m_proprietary.count(this_prop) > 0) {
     563           0 :                         throw std::ios_base::failure("Duplicate Key, proprietary key already found");
     564             :                     }
     565           4 :                     s >> this_prop.value;
     566           4 :                     m_proprietary.insert(this_prop);
     567             :                     break;
     568           4 :                 }
     569             :                 // Unknown stuff
     570             :                 default: {
     571          20 :                     if (unknown.count(key) > 0) {
     572           4 :                         throw std::ios_base::failure("Duplicate Key, key for unknown value already provided");
     573             :                     }
     574             :                     // Read in the value
     575          16 :                     std::vector<unsigned char> val_bytes;
     576          16 :                     s >> val_bytes;
     577          12 :                     unknown.emplace(std::move(key), std::move(val_bytes));
     578             :                     break;
     579          16 :                 }
     580             :             }
     581        1453 :         }
     582             : 
     583         918 :         if (!found_sep) {
     584           0 :             throw std::ios_base::failure("Separator is missing at the end of an output map");
     585             :         }
     586         958 :     }
     587             : 
     588             :     template <typename Stream>
     589             :     PSBTOutput(deserialize_type, Stream& s) {
     590             :         Unserialize(s);
     591             :     }
     592             : };
     593             : 
     594             : /** A version of CTransaction with the PSBT format*/
     595          92 : struct PartiallySignedTransaction
     596             : {
     597             :     std::optional<CMutableTransaction> tx;
     598             :     // We use a vector of CExtPubKey in the event that there happens to be the same KeyOriginInfos for different CExtPubKeys
     599             :     // Note that this map swaps the key and values from the serialization
     600             :     std::map<KeyOriginInfo, std::set<CExtPubKey>> m_xpubs;
     601             :     std::vector<PSBTInput> inputs;
     602             :     std::vector<PSBTOutput> outputs;
     603             :     std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown;
     604             :     std::optional<uint32_t> m_version;
     605             :     std::set<PSBTProprietary> m_proprietary;
     606             : 
     607             :     bool IsNull() const;
     608             :     uint32_t GetVersion() const;
     609             : 
     610             :     /** Merge psbt into this. The two psbts must have the same underlying CTransaction (i.e. the
     611             :       * same actual Bitcoin transaction.) Returns true if the merge succeeded, false otherwise. */
     612             :     [[nodiscard]] bool Merge(const PartiallySignedTransaction& psbt);
     613             :     bool AddInput(const CTxIn& txin, PSBTInput& psbtin);
     614             :     bool AddOutput(const CTxOut& txout, const PSBTOutput& psbtout);
     615        1426 :     PartiallySignedTransaction() {}
     616             :     explicit PartiallySignedTransaction(const CMutableTransaction& tx);
     617             : 
     618             :     /**
     619             :      * Finds the UTXO for a given input index
     620             :      *
     621             :      * @param[out] utxo The UTXO of the input if found
     622             :      * @param[in] input_index Index of the input to retrieve the UTXO of
     623             :      * @return Whether the UTXO for the specified input was found
     624             :      */
     625             :     bool GetInputUTXO(CTxOut& utxo, int input_index) const;
     626             : 
     627             :     template <typename Stream>
     628         583 :     inline void Serialize(Stream& s) const {
     629             : 
     630             :         // magic bytes
     631         583 :         s << PSBT_MAGIC_BYTES;
     632             : 
     633             :         // unsigned tx flag
     634         583 :         SerializeToVector(s, CompactSizeWriter(PSBT_GLOBAL_UNSIGNED_TX));
     635             : 
     636             :         // Write serialized tx to a stream
     637         583 :         SerializeToVector(s, *tx);
     638             : 
     639             :         // Write xpubs
     640         583 :         for (const auto& xpub_pair : m_xpubs) {
     641           0 :             for (const auto& xpub : xpub_pair.second) {
     642             :                 unsigned char ser_xpub[BIP32_EXTKEY_WITH_VERSION_SIZE];
     643           0 :                 xpub.EncodeWithVersion(ser_xpub);
     644             :                 // Note that the serialization swaps the key and value
     645             :                 // The xpub is the key (for uniqueness) while the path is the value
     646           0 :                 SerializeToVector(s, PSBT_GLOBAL_XPUB, ser_xpub);
     647           0 :                 SerializeHDKeypath(s, xpub_pair.first);
     648             :             }
     649             :         }
     650             : 
     651             :         // PSBT version
     652         583 :         if (GetVersion() > 0) {
     653           0 :             SerializeToVector(s, CompactSizeWriter(PSBT_GLOBAL_VERSION));
     654           0 :             SerializeToVector(s, *m_version);
     655           0 :         }
     656             : 
     657             :         // Write proprietary things
     658         583 :         for (const auto& entry : m_proprietary) {
     659           0 :             s << entry.key;
     660           0 :             s << entry.value;
     661             :         }
     662             : 
     663             :         // Write the unknown things
     664         591 :         for (auto& entry : unknown) {
     665           8 :             s << entry.first;
     666           8 :             s << entry.second;
     667             :         }
     668             : 
     669             :         // Separator
     670         583 :         s << PSBT_SEPARATOR;
     671             : 
     672             :         // Write inputs
     673        1474 :         for (const PSBTInput& input : inputs) {
     674         891 :             s << input;
     675             :         }
     676             :         // Write outputs
     677        1649 :         for (const PSBTOutput& output : outputs) {
     678        1066 :             s << output;
     679             :         }
     680         583 :     }
     681             : 
     682             : 
     683             :     template <typename Stream>
     684         639 :     inline void Unserialize(Stream& s) {
     685             :         // Read the magic bytes
     686             :         uint8_t magic[5];
     687         639 :         s >> magic;
     688         639 :         if (!std::equal(magic, magic + 5, PSBT_MAGIC_BYTES)) {
     689         104 :             throw std::ios_base::failure("Invalid PSBT magic bytes");
     690             :         }
     691             : 
     692             :         // Used for duplicate key detection
     693         635 :         std::set<std::vector<unsigned char>> key_lookup;
     694             : 
     695             :         // Track the global xpubs we have already seen. Just for sanity checking
     696         635 :         std::set<CExtPubKey> global_xpubs;
     697             : 
     698             :         // Read global data
     699         635 :         bool found_sep = false;
     700        1282 :         while(!s.empty()) {
     701             :             // Read
     702        1282 :             std::vector<unsigned char> key;
     703        1282 :             s >> key;
     704             : 
     705             :             // the key is empty if that was actually a separator byte
     706             :             // This is a special case for key lengths 0 as those are not allowed (except for separator)
     707        1282 :             if (key.empty()) {
     708         623 :                 found_sep = true;
     709         623 :                 break;
     710             :             }
     711             : 
     712             :             // Type is compact size uint at beginning of key
     713         659 :             SpanReader skey(s.GetType(), s.GetVersion(), key);
     714         659 :             uint64_t type = ReadCompactSize(skey);
     715             : 
     716             :             // Do stuff based on type
     717         659 :             switch(type) {
     718             :                 case PSBT_GLOBAL_UNSIGNED_TX:
     719             :                 {
     720         627 :                     if (!key_lookup.emplace(key).second) {
     721           0 :                         throw std::ios_base::failure("Duplicate Key, unsigned tx already provided");
     722         627 :                     } else if (key.size() != 1) {
     723           4 :                         throw std::ios_base::failure("Global unsigned tx key is more than one byte type");
     724             :                     }
     725         623 :                     CMutableTransaction mtx;
     726         623 :                     UnserializeFromVector(s, mtx);
     727         623 :                     tx = std::move(mtx);
     728             :                     // Make sure that all scriptSigs are empty
     729        1561 :                     for (const CTxIn& txin : tx->vin) {
     730         942 :                         if (!txin.scriptSig.empty()) {
     731           4 :                             throw std::ios_base::failure("Unsigned tx does not have empty scriptSigs.");
     732             :                         }
     733             :                     }
     734             :                     break;
     735         623 :                 }
     736             :                 case PSBT_GLOBAL_XPUB:
     737             :                 {
     738          12 :                     if (key.size() != BIP32_EXTKEY_WITH_VERSION_SIZE + 1) {
     739           0 :                         throw std::ios_base::failure("Size of key was not the expected size for the type global xpub");
     740             :                     }
     741             :                     // Read in the xpub from key
     742          12 :                     CExtPubKey xpub;
     743          12 :                     xpub.DecodeWithVersion(&key.data()[1]);
     744          12 :                     if (!xpub.pubkey.IsFullyValid()) {
     745           0 :                        throw std::ios_base::failure("Invalid pubkey");
     746             :                     }
     747          12 :                     if (global_xpubs.count(xpub) > 0) {
     748           0 :                        throw std::ios_base::failure("Duplicate key, global xpub already provided");
     749             :                     }
     750          12 :                     global_xpubs.insert(xpub);
     751             :                     // Read in the keypath from stream
     752          12 :                     KeyOriginInfo keypath;
     753          12 :                     DeserializeHDKeypath(s, keypath);
     754             : 
     755             :                     // Note that we store these swapped to make searches faster.
     756             :                     // Serialization uses xpub -> keypath to enqure key uniqueness
     757          12 :                     if (m_xpubs.count(keypath) == 0) {
     758             :                         // Make a new set to put the xpub in
     759          12 :                         m_xpubs[keypath] = {xpub};
     760          12 :                     } else {
     761             :                         // Insert xpub into existing set
     762           0 :                         m_xpubs[keypath].insert(xpub);
     763             :                     }
     764             :                     break;
     765          12 :                 }
     766             :                 case PSBT_GLOBAL_VERSION:
     767             :                 {
     768           4 :                     if (m_version) {
     769           0 :                         throw std::ios_base::failure("Duplicate Key, version already provided");
     770           4 :                     } else if (key.size() != 1) {
     771           0 :                         throw std::ios_base::failure("Global version key is more than one byte type");
     772             :                     }
     773             :                     uint32_t v;
     774           4 :                     UnserializeFromVector(s, v);
     775           4 :                     m_version = v;
     776           4 :                     if (*m_version > PSBT_HIGHEST_VERSION) {
     777           4 :                         throw std::ios_base::failure("Unsupported version number");
     778             :                     }
     779           0 :                     break;
     780             :                 }
     781             :                 case PSBT_GLOBAL_PROPRIETARY:
     782             :                 {
     783           8 :                     PSBTProprietary this_prop;
     784           8 :                     skey >> this_prop.identifier;
     785           8 :                     this_prop.subtype = ReadCompactSize(skey);
     786           8 :                     this_prop.key = key;
     787             : 
     788           8 :                     if (m_proprietary.count(this_prop) > 0) {
     789           0 :                         throw std::ios_base::failure("Duplicate Key, proprietary key already found");
     790             :                     }
     791           8 :                     s >> this_prop.value;
     792           8 :                     m_proprietary.insert(this_prop);
     793             :                     break;
     794           8 :                 }
     795             :                 // Unknown stuff
     796             :                 default: {
     797           8 :                     if (unknown.count(key) > 0) {
     798           0 :                         throw std::ios_base::failure("Duplicate Key, key for unknown value already provided");
     799             :                     }
     800             :                     // Read in the value
     801           8 :                     std::vector<unsigned char> val_bytes;
     802           8 :                     s >> val_bytes;
     803           8 :                     unknown.emplace(std::move(key), std::move(val_bytes));
     804           8 :                 }
     805           8 :             }
     806        1282 :         }
     807             : 
     808         623 :         if (!found_sep) {
     809           0 :             throw std::ios_base::failure("Separator is missing at the end of the global map");
     810             :         }
     811             : 
     812             :         // Make sure that we got an unsigned tx
     813         623 :         if (!tx) {
     814           4 :             throw std::ios_base::failure("No unsigned transaction was provided");
     815             :         }
     816             : 
     817             :         // Read input data
     818         619 :         unsigned int i = 0;
     819        1485 :         while (!s.empty() && i < tx->vin.size()) {
     820         930 :             PSBTInput input;
     821         930 :             s >> input;
     822         866 :             inputs.push_back(input);
     823             : 
     824             :             // Make sure the non-witness utxo matches the outpoint
     825         866 :             if (input.non_witness_utxo && input.non_witness_utxo->GetHash() != tx->vin[i].prevout.hash) {
     826           0 :                 throw std::ios_base::failure("Non-witness UTXO does not match outpoint hash");
     827             :             }
     828         866 :             ++i;
     829         930 :         }
     830             :         // Make sure that the number of inputs matches the number of inputs in the transaction
     831         555 :         if (inputs.size() != tx->vin.size()) {
     832           0 :             throw std::ios_base::failure("Inputs provided does not match the number of inputs in transaction.");
     833             :         }
     834             : 
     835             :         // Read output data
     836         555 :         i = 0;
     837        1473 :         while (!s.empty() && i < tx->vout.size()) {
     838         938 :             PSBTOutput output;
     839         938 :             s >> output;
     840         918 :             outputs.push_back(output);
     841         918 :             ++i;
     842         938 :         }
     843             :         // Make sure that the number of outputs matches the number of outputs in the transaction
     844         535 :         if (outputs.size() != tx->vout.size()) {
     845           0 :             throw std::ios_base::failure("Outputs provided does not match the number of outputs in transaction.");
     846             :         }
     847         711 :     }
     848             : 
     849             :     template <typename Stream>
     850             :     PartiallySignedTransaction(deserialize_type, Stream& s) {
     851             :         Unserialize(s);
     852             :     }
     853             : };
     854             : 
     855             : enum class PSBTRole {
     856             :     CREATOR,
     857             :     UPDATER,
     858             :     SIGNER,
     859             :     FINALIZER,
     860             :     EXTRACTOR
     861             : };
     862             : 
     863             : std::string PSBTRoleName(PSBTRole role);
     864             : 
     865             : /** Compute a PrecomputedTransactionData object from a psbt. */
     866             : PrecomputedTransactionData PrecomputePSBTData(const PartiallySignedTransaction& psbt);
     867             : 
     868             : /** Checks whether a PSBTInput is already signed. */
     869             : bool PSBTInputSigned(const PSBTInput& input);
     870             : 
     871             : /** Signs a PSBTInput, verifying that all provided data matches what is being signed.
     872             :  *
     873             :  * txdata should be the output of PrecomputePSBTData (which can be shared across
     874             :  * multiple SignPSBTInput calls). If it is nullptr, a dummy signature will be created.
     875             :  **/
     876             : bool SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, const PrecomputedTransactionData* txdata, int sighash = SIGHASH_ALL, SignatureData* out_sigdata = nullptr, bool finalize = true);
     877             : 
     878             : /**  Reduces the size of the PSBT by dropping unnecessary `non_witness_utxos` (i.e. complete previous transactions) from a psbt when all inputs are segwit v1. */
     879             : void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx, const int& sighash_type);
     880             : 
     881             : /** Counts the unsigned inputs of a PSBT. */
     882             : size_t CountPSBTUnsignedInputs(const PartiallySignedTransaction& psbt);
     883             : 
     884             : /** Updates a PSBTOutput with information from provider.
     885             :  *
     886             :  * This fills in the redeem_script, and hd_keypaths where possible.
     887             :  */
     888             : void UpdatePSBTOutput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index);
     889             : 
     890             : /**
     891             :  * Finalizes a PSBT if possible, combining partial signatures.
     892             :  *
     893             :  * @param[in,out] psbtx PartiallySignedTransaction to finalize
     894             :  * return True if the PSBT is now complete, false otherwise
     895             :  */
     896             : bool FinalizePSBT(PartiallySignedTransaction& psbtx);
     897             : 
     898             : /**
     899             :  * Finalizes a PSBT if possible, and extracts it to a CMutableTransaction if it could be finalized.
     900             :  *
     901             :  * @param[in]  psbtx PartiallySignedTransaction
     902             :  * @param[out] result CMutableTransaction representing the complete transaction, if successful
     903             :  * @return True if we successfully extracted the transaction, false otherwise
     904             :  */
     905             : bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransaction& result);
     906             : 
     907             : /**
     908             :  * Combines PSBTs with the same underlying transaction, resulting in a single PSBT with all partial signatures from each input.
     909             :  *
     910             :  * @param[out] out   the combined PSBT, if successful
     911             :  * @param[in]  psbtxs the PSBTs to combine
     912             :  * @return error (OK if we successfully combined the transactions, other error if they were not compatible)
     913             :  */
     914             : [[nodiscard]] TransactionError CombinePSBTs(PartiallySignedTransaction& out, const std::vector<PartiallySignedTransaction>& psbtxs);
     915             : 
     916             : //! Decode a base64ed PSBT into a PartiallySignedTransaction
     917             : [[nodiscard]] bool DecodeBase64PSBT(PartiallySignedTransaction& decoded_psbt, const std::string& base64_psbt, std::string& error);
     918             : //! Decode a raw (binary blob) PSBT into a PartiallySignedTransaction
     919             : [[nodiscard]] bool DecodeRawPSBT(PartiallySignedTransaction& decoded_psbt, Span<const std::byte> raw_psbt, std::string& error);
     920             : 
     921             : #endif // BITCOIN_PSBT_H

Generated by: LCOV version 1.16