/Users/eugenesiegel/btc/bitcoin/src/psbt.h
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | // Copyright (c) 2009-present 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 <common/types.h> | 
| 9 |  | #include <node/transaction.h> | 
| 10 |  | #include <policy/feerate.h> | 
| 11 |  | #include <primitives/transaction.h> | 
| 12 |  | #include <pubkey.h> | 
| 13 |  | #include <script/keyorigin.h> | 
| 14 |  | #include <script/sign.h> | 
| 15 |  | #include <script/signingprovider.h> | 
| 16 |  | #include <span.h> | 
| 17 |  | #include <streams.h> | 
| 18 |  |  | 
| 19 |  | #include <optional> | 
| 20 |  |  | 
| 21 |  | namespace node { | 
| 22 |  | enum class TransactionError; | 
| 23 |  | } // namespace node | 
| 24 |  |  | 
| 25 |  | using common::PSBTError; | 
| 26 |  |  | 
| 27 |  | // Magic bytes | 
| 28 |  | static constexpr uint8_t PSBT_MAGIC_BYTES[5] = {'p', 's', 'b', 't', 0xff}; | 
| 29 |  |  | 
| 30 |  | // Global types | 
| 31 |  | static constexpr uint8_t PSBT_GLOBAL_UNSIGNED_TX = 0x00; | 
| 32 |  | static constexpr uint8_t PSBT_GLOBAL_XPUB = 0x01; | 
| 33 |  | static constexpr uint8_t PSBT_GLOBAL_VERSION = 0xFB; | 
| 34 |  | static constexpr uint8_t PSBT_GLOBAL_PROPRIETARY = 0xFC; | 
| 35 |  |  | 
| 36 |  | // Input types | 
| 37 |  | static constexpr uint8_t PSBT_IN_NON_WITNESS_UTXO = 0x00; | 
| 38 |  | static constexpr uint8_t PSBT_IN_WITNESS_UTXO = 0x01; | 
| 39 |  | static constexpr uint8_t PSBT_IN_PARTIAL_SIG = 0x02; | 
| 40 |  | static constexpr uint8_t PSBT_IN_SIGHASH = 0x03; | 
| 41 |  | static constexpr uint8_t PSBT_IN_REDEEMSCRIPT = 0x04; | 
| 42 |  | static constexpr uint8_t PSBT_IN_WITNESSSCRIPT = 0x05; | 
| 43 |  | static constexpr uint8_t PSBT_IN_BIP32_DERIVATION = 0x06; | 
| 44 |  | static constexpr uint8_t PSBT_IN_SCRIPTSIG = 0x07; | 
| 45 |  | static constexpr uint8_t PSBT_IN_SCRIPTWITNESS = 0x08; | 
| 46 |  | static constexpr uint8_t PSBT_IN_RIPEMD160 = 0x0A; | 
| 47 |  | static constexpr uint8_t PSBT_IN_SHA256 = 0x0B; | 
| 48 |  | static constexpr uint8_t PSBT_IN_HASH160 = 0x0C; | 
| 49 |  | static constexpr uint8_t PSBT_IN_HASH256 = 0x0D; | 
| 50 |  | static constexpr uint8_t PSBT_IN_TAP_KEY_SIG = 0x13; | 
| 51 |  | static constexpr uint8_t PSBT_IN_TAP_SCRIPT_SIG = 0x14; | 
| 52 |  | static constexpr uint8_t PSBT_IN_TAP_LEAF_SCRIPT = 0x15; | 
| 53 |  | static constexpr uint8_t PSBT_IN_TAP_BIP32_DERIVATION = 0x16; | 
| 54 |  | static constexpr uint8_t PSBT_IN_TAP_INTERNAL_KEY = 0x17; | 
| 55 |  | static constexpr uint8_t PSBT_IN_TAP_MERKLE_ROOT = 0x18; | 
| 56 |  | static constexpr uint8_t PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS = 0x1a; | 
| 57 |  | static constexpr uint8_t PSBT_IN_MUSIG2_PUB_NONCE = 0x1b; | 
| 58 |  | static constexpr uint8_t PSBT_IN_MUSIG2_PARTIAL_SIG = 0x1c; | 
| 59 |  | static constexpr uint8_t PSBT_IN_PROPRIETARY = 0xFC; | 
| 60 |  |  | 
| 61 |  | // Output types | 
| 62 |  | static constexpr uint8_t PSBT_OUT_REDEEMSCRIPT = 0x00; | 
| 63 |  | static constexpr uint8_t PSBT_OUT_WITNESSSCRIPT = 0x01; | 
| 64 |  | static constexpr uint8_t PSBT_OUT_BIP32_DERIVATION = 0x02; | 
| 65 |  | static constexpr uint8_t PSBT_OUT_TAP_INTERNAL_KEY = 0x05; | 
| 66 |  | static constexpr uint8_t PSBT_OUT_TAP_TREE = 0x06; | 
| 67 |  | static constexpr uint8_t PSBT_OUT_TAP_BIP32_DERIVATION = 0x07; | 
| 68 |  | static constexpr uint8_t PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS = 0x08; | 
| 69 |  | static constexpr uint8_t PSBT_OUT_PROPRIETARY = 0xFC; | 
| 70 |  |  | 
| 71 |  | // The separator is 0x00. Reading this in means that the unserializer can interpret it | 
| 72 |  | // as a 0 length key which indicates that this is the separator. The separator has no value. | 
| 73 |  | static constexpr uint8_t PSBT_SEPARATOR = 0x00; | 
| 74 |  |  | 
| 75 |  | // BIP 174 does not specify a maximum file size, but we set a limit anyway | 
| 76 |  | // to prevent reading a stream indefinitely and running out of memory. | 
| 77 |  | const std::streamsize MAX_FILE_SIZE_PSBT = 100000000; // 100 MB | 
| 78 |  |  | 
| 79 |  | // PSBT version number | 
| 80 |  | static constexpr uint32_t PSBT_HIGHEST_VERSION = 0; | 
| 81 |  |  | 
| 82 |  | /** A structure for PSBT proprietary types */ | 
| 83 |  | struct PSBTProprietary | 
| 84 |  | { | 
| 85 |  |     uint64_t subtype; | 
| 86 |  |     std::vector<unsigned char> identifier; | 
| 87 |  |     std::vector<unsigned char> key; | 
| 88 |  |     std::vector<unsigned char> value; | 
| 89 |  |  | 
| 90 | 0 |     bool operator<(const PSBTProprietary &b) const { | 
| 91 | 0 |         return key < b.key; | 
| 92 | 0 |     } | 
| 93 | 0 |     bool operator==(const PSBTProprietary &b) const { | 
| 94 | 0 |         return key == b.key; | 
| 95 | 0 |     } | 
| 96 |  | }; | 
| 97 |  |  | 
| 98 |  | // Takes a stream and multiple arguments and serializes them as if first serialized into a vector and then into the stream | 
| 99 |  | // The resulting output into the stream has the total serialized length of all of the objects followed by all objects concatenated with each other. | 
| 100 |  | template<typename Stream, typename... X> | 
| 101 |  | void SerializeToVector(Stream& s, const X&... args) | 
| 102 | 0 | { | 
| 103 | 0 |     SizeComputer sizecomp; | 
| 104 | 0 |     SerializeMany(sizecomp, args...); | 
| 105 | 0 |     WriteCompactSize(s, sizecomp.size()); | 
| 106 | 0 |     SerializeMany(s, args...); | 
| 107 | 0 | } Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJ17CompactSizeWriterEEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJ13ParamsWrapperI20TransactionSerParamsK19CMutableTransactionEEEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJhA78_hEEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJjEEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJ13ParamsWrapperI20TransactionSerParamsKNSt3__110shared_ptrIK12CTransactionEEEEEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJ6CTxOutEEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJ17CompactSizeWriterNSt3__14spanIKhLm18446744073709551615EEEEEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJiEEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJhEEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJh11XOnlyPubKey7uint256EEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJhNSt3__14spanIKhLm18446744073709551615EEEEEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJh11XOnlyPubKeyEEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJ7uint256EEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJ17CompactSizeWriterNSt3__14spanIKhLm18446744073709551615EEES5_EEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJ17CompactSizeWriterNSt3__14spanIKhLm18446744073709551615EEES5_7uint256EEvRT_DpRKT0_Unexecuted instantiation: _Z17SerializeToVectorI10DataStreamJNSt3__16vectorINS2_IhNS1_9allocatorIhEEEENS3_IS5_EEEEEEvRT_DpRKT0_ | 
| 108 |  |  | 
| 109 |  | // Takes a stream and multiple arguments and unserializes them first as a vector then each object individually in the order provided in the arguments | 
| 110 |  | template<typename Stream, typename... X> | 
| 111 |  | void UnserializeFromVector(Stream& s, X&&... args) | 
| 112 | 0 | { | 
| 113 | 0 |     size_t expected_size = ReadCompactSize(s); | 
| 114 | 0 |     size_t remaining_before = s.size(); | 
| 115 | 0 |     UnserializeMany(s, args...); | 
| 116 | 0 |     size_t remaining_after = s.size(); | 
| 117 | 0 |     if (remaining_after + expected_size != remaining_before) { | 
| 118 | 0 |         throw std::ios_base::failure("Size of value was not the stated size"); | 
| 119 | 0 |     } | 
| 120 | 0 | } Unexecuted instantiation: _Z21UnserializeFromVectorI10DataStreamJ13ParamsWrapperI20TransactionSerParams19CMutableTransactionEEEvRT_DpOT0_Unexecuted instantiation: _Z21UnserializeFromVectorI10DataStreamJRjEEvRT_DpOT0_Unexecuted instantiation: _Z21UnserializeFromVectorI10DataStreamJ13ParamsWrapperI20TransactionSerParamsNSt3__110shared_ptrIK12CTransactionEEEEEvRT_DpOT0_Unexecuted instantiation: _Z21UnserializeFromVectorI10DataStreamJR6CTxOutEEvRT_DpOT0_Unexecuted instantiation: _Z21UnserializeFromVectorI10DataStreamJRiEEvRT_DpOT0_Unexecuted instantiation: _Z21UnserializeFromVectorI10DataStreamJRNSt3__16vectorINS2_IhNS1_9allocatorIhEEEENS3_IS5_EEEEEEvRT_DpOT0_Unexecuted instantiation: _Z21UnserializeFromVectorI10DataStreamJR11XOnlyPubKeyEEvRT_DpOT0_Unexecuted instantiation: _Z21UnserializeFromVectorI10DataStreamJR7uint256EEvRT_DpOT0_ | 
| 121 |  |  | 
| 122 |  | // Deserialize bytes of given length from the stream as a KeyOriginInfo | 
| 123 |  | template<typename Stream> | 
| 124 |  | KeyOriginInfo DeserializeKeyOrigin(Stream& s, uint64_t length) | 
| 125 | 0 | { | 
| 126 |  |     // Read in key path | 
| 127 | 0 |     if (length % 4 || length == 0) { | 
| 128 | 0 |         throw std::ios_base::failure("Invalid length for HD key path"); | 
| 129 | 0 |     } | 
| 130 |  |  | 
| 131 | 0 |     KeyOriginInfo hd_keypath; | 
| 132 | 0 |     s >> hd_keypath.fingerprint; | 
| 133 | 0 |     for (unsigned int i = 4; i < length; i += sizeof(uint32_t)) { | 
| 134 | 0 |         uint32_t index; | 
| 135 | 0 |         s >> index; | 
| 136 | 0 |         hd_keypath.path.push_back(index); | 
| 137 | 0 |     } | 
| 138 | 0 |     return hd_keypath; | 
| 139 | 0 | } | 
| 140 |  |  | 
| 141 |  | // Deserialize a length prefixed KeyOriginInfo from a stream | 
| 142 |  | template<typename Stream> | 
| 143 |  | void DeserializeHDKeypath(Stream& s, KeyOriginInfo& hd_keypath) | 
| 144 | 0 | { | 
| 145 | 0 |     hd_keypath = DeserializeKeyOrigin(s, ReadCompactSize(s)); | 
| 146 | 0 | } | 
| 147 |  |  | 
| 148 |  | // Deserialize HD keypaths into a map | 
| 149 |  | template<typename Stream> | 
| 150 |  | void DeserializeHDKeypaths(Stream& s, const std::vector<unsigned char>& key, std::map<CPubKey, KeyOriginInfo>& hd_keypaths) | 
| 151 | 0 | { | 
| 152 |  |     // Make sure that the key is the size of pubkey + 1 | 
| 153 | 0 |     if (key.size() != CPubKey::SIZE + 1 && key.size() != CPubKey::COMPRESSED_SIZE + 1) { | 
| 154 | 0 |         throw std::ios_base::failure("Size of key was not the expected size for the type BIP32 keypath"); | 
| 155 | 0 |     } | 
| 156 |  |     // Read in the pubkey from key | 
| 157 | 0 |     CPubKey pubkey(key.begin() + 1, key.end()); | 
| 158 | 0 |     if (!pubkey.IsFullyValid()) { | 
| 159 | 0 |        throw std::ios_base::failure("Invalid pubkey"); | 
| 160 | 0 |     } | 
| 161 | 0 |     if (hd_keypaths.count(pubkey) > 0) { | 
| 162 | 0 |         throw std::ios_base::failure("Duplicate Key, pubkey derivation path already provided"); | 
| 163 | 0 |     } | 
| 164 |  |  | 
| 165 | 0 |     KeyOriginInfo keypath; | 
| 166 | 0 |     DeserializeHDKeypath(s, keypath); | 
| 167 |  |  | 
| 168 |  |     // Add to map | 
| 169 | 0 |     hd_keypaths.emplace(pubkey, std::move(keypath)); | 
| 170 | 0 | } | 
| 171 |  |  | 
| 172 |  | // Serialize a KeyOriginInfo to a stream | 
| 173 |  | template<typename Stream> | 
| 174 |  | void SerializeKeyOrigin(Stream& s, KeyOriginInfo hd_keypath) | 
| 175 | 0 | { | 
| 176 | 0 |     s << hd_keypath.fingerprint; | 
| 177 | 0 |     for (const auto& path : hd_keypath.path) { | 
| 178 | 0 |         s << path; | 
| 179 | 0 |     } | 
| 180 | 0 | } Unexecuted instantiation: _Z18SerializeKeyOriginI10DataStreamEvRT_13KeyOriginInfoUnexecuted instantiation: _Z18SerializeKeyOriginI12VectorWriterEvRT_13KeyOriginInfo | 
| 181 |  |  | 
| 182 |  | // Serialize a length prefixed KeyOriginInfo to a stream | 
| 183 |  | template<typename Stream> | 
| 184 |  | void SerializeHDKeypath(Stream& s, KeyOriginInfo hd_keypath) | 
| 185 | 0 | { | 
| 186 | 0 |     WriteCompactSize(s, (hd_keypath.path.size() + 1) * sizeof(uint32_t)); | 
| 187 | 0 |     SerializeKeyOrigin(s, hd_keypath); | 
| 188 | 0 | } | 
| 189 |  |  | 
| 190 |  | // Serialize HD keypaths to a stream from a map | 
| 191 |  | template<typename Stream> | 
| 192 |  | void SerializeHDKeypaths(Stream& s, const std::map<CPubKey, KeyOriginInfo>& hd_keypaths, CompactSizeWriter type) | 
| 193 | 0 | { | 
| 194 | 0 |     for (const auto& keypath_pair : hd_keypaths) { | 
| 195 | 0 |         if (!keypath_pair.first.IsValid()) { | 
| 196 | 0 |             throw std::ios_base::failure("Invalid CPubKey being serialized"); | 
| 197 | 0 |         } | 
| 198 | 0 |         SerializeToVector(s, type, std::span{keypath_pair.first}); | 
| 199 | 0 |         SerializeHDKeypath(s, keypath_pair.second); | 
| 200 | 0 |     } | 
| 201 | 0 | } | 
| 202 |  |  | 
| 203 |  | // Deserialize a PSBT_{IN/OUT}_MUSIG2_PARTICIPANT_PUBKEYS field | 
| 204 |  | template<typename Stream> | 
| 205 |  | void DeserializeMuSig2ParticipantPubkeys(Stream& s, SpanReader& skey, std::map<CPubKey, std::vector<CPubKey>>& out, std::string context) | 
| 206 | 0 | { | 
| 207 | 0 |     std::array<unsigned char, CPubKey::COMPRESSED_SIZE> agg_pubkey_bytes; | 
| 208 | 0 |     skey >> std::as_writable_bytes(std::span{agg_pubkey_bytes}); | 
| 209 | 0 |     CPubKey agg_pubkey(agg_pubkey_bytes); | 
| 210 |  | 
 | 
| 211 | 0 |     std::vector<CPubKey> participants; | 
| 212 | 0 |     std::vector<unsigned char> val; | 
| 213 | 0 |     s >> val; | 
| 214 | 0 |     SpanReader s_val{val}; | 
| 215 | 0 |     while (s_val.size() >= CPubKey::COMPRESSED_SIZE) { | 
| 216 | 0 |         std::array<unsigned char, CPubKey::COMPRESSED_SIZE> part_pubkey_bytes; | 
| 217 | 0 |         s_val >> std::as_writable_bytes(std::span{part_pubkey_bytes}); | 
| 218 | 0 |         participants.emplace_back(std::span{part_pubkey_bytes}); | 
| 219 | 0 |     } | 
| 220 | 0 |     if (!s_val.empty()) { | 
| 221 | 0 |         throw std::ios_base::failure(context + " musig2 participants pubkeys value size is not a multiple of 33"); | 
| 222 | 0 |     } | 
| 223 |  |  | 
| 224 | 0 |     out.emplace(agg_pubkey, participants); | 
| 225 | 0 | } | 
| 226 |  |  | 
| 227 |  | // Deserialize the MuSig2 participant identifiers from PSBT_MUSIG2_{PUBNONCE/PARTIAL_SIG} fields | 
| 228 |  | // Both fields contain the same data after the type byte - aggregate pubkey | participant pubkey | leaf script hash | 
| 229 |  | template<typename Stream> | 
| 230 |  | void DeserializeMuSig2ParticipantDataIdentifier(Stream& skey, CPubKey& agg_pub, CPubKey& part_pub, uint256& leaf_hash) | 
| 231 | 0 | { | 
| 232 | 0 |     leaf_hash.SetNull(); | 
| 233 |  | 
 | 
| 234 | 0 |     std::array<unsigned char, CPubKey::COMPRESSED_SIZE> part_pubkey_bytes; | 
| 235 | 0 |     std::array<unsigned char, CPubKey::COMPRESSED_SIZE> agg_pubkey_bytes; | 
| 236 |  | 
 | 
| 237 | 0 |     skey >> std::as_writable_bytes(std::span{part_pubkey_bytes}) >> std::as_writable_bytes(std::span{agg_pubkey_bytes}); | 
| 238 | 0 |     agg_pub.Set(agg_pubkey_bytes.begin(), agg_pubkey_bytes.end()); | 
| 239 | 0 |     part_pub.Set(part_pubkey_bytes.begin(), part_pubkey_bytes.end()); | 
| 240 |  | 
 | 
| 241 | 0 |     if (!skey.empty()) { | 
| 242 | 0 |         skey >> leaf_hash; | 
| 243 | 0 |     } | 
| 244 | 0 | } | 
| 245 |  |  | 
| 246 |  | /** A structure for PSBTs which contain per-input information */ | 
| 247 |  | struct PSBTInput | 
| 248 |  | { | 
| 249 |  |     CTransactionRef non_witness_utxo; | 
| 250 |  |     CTxOut witness_utxo; | 
| 251 |  |     CScript redeem_script; | 
| 252 |  |     CScript witness_script; | 
| 253 |  |     CScript final_script_sig; | 
| 254 |  |     CScriptWitness final_script_witness; | 
| 255 |  |     std::map<CPubKey, KeyOriginInfo> hd_keypaths; | 
| 256 |  |     std::map<CKeyID, SigPair> partial_sigs; | 
| 257 |  |     std::map<uint160, std::vector<unsigned char>> ripemd160_preimages; | 
| 258 |  |     std::map<uint256, std::vector<unsigned char>> sha256_preimages; | 
| 259 |  |     std::map<uint160, std::vector<unsigned char>> hash160_preimages; | 
| 260 |  |     std::map<uint256, std::vector<unsigned char>> hash256_preimages; | 
| 261 |  |  | 
| 262 |  |     // Taproot fields | 
| 263 |  |     std::vector<unsigned char> m_tap_key_sig; | 
| 264 |  |     std::map<std::pair<XOnlyPubKey, uint256>, std::vector<unsigned char>> m_tap_script_sigs; | 
| 265 |  |     std::map<std::pair<std::vector<unsigned char>, int>, std::set<std::vector<unsigned char>, ShortestVectorFirstComparator>> m_tap_scripts; | 
| 266 |  |     std::map<XOnlyPubKey, std::pair<std::set<uint256>, KeyOriginInfo>> m_tap_bip32_paths; | 
| 267 |  |     XOnlyPubKey m_tap_internal_key; | 
| 268 |  |     uint256 m_tap_merkle_root; | 
| 269 |  |  | 
| 270 |  |     // MuSig2 fields | 
| 271 |  |     std::map<CPubKey, std::vector<CPubKey>> m_musig2_participants; | 
| 272 |  |     // Key is the aggregate pubkey and the script leaf hash, value is a map of participant pubkey to pubnonce | 
| 273 |  |     std::map<std::pair<CPubKey, uint256>, std::map<CPubKey, std::vector<uint8_t>>> m_musig2_pubnonces; | 
| 274 |  |     // Key is the aggregate pubkey and the script leaf hash, value is a map of participant pubkey to partial_sig | 
| 275 |  |     std::map<std::pair<CPubKey, uint256>, std::map<CPubKey, uint256>> m_musig2_partial_sigs; | 
| 276 |  |  | 
| 277 |  |     std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown; | 
| 278 |  |     std::set<PSBTProprietary> m_proprietary; | 
| 279 |  |     std::optional<int> sighash_type; | 
| 280 |  |  | 
| 281 |  |     bool IsNull() const; | 
| 282 |  |     void FillSignatureData(SignatureData& sigdata) const; | 
| 283 |  |     void FromSignatureData(const SignatureData& sigdata); | 
| 284 |  |     void Merge(const PSBTInput& input); | 
| 285 | 0 |     PSBTInput() = default; | 
| 286 |  |  | 
| 287 |  |     template <typename Stream> | 
| 288 | 0 |     inline void Serialize(Stream& s) const { | 
| 289 |  |         // Write the utxo | 
| 290 | 0 |         if (non_witness_utxo) { | 
| 291 | 0 |             SerializeToVector(s, CompactSizeWriter(PSBT_IN_NON_WITNESS_UTXO)); | 
| 292 | 0 |             SerializeToVector(s, TX_NO_WITNESS(non_witness_utxo)); | 
| 293 | 0 |         } | 
| 294 | 0 |         if (!witness_utxo.IsNull()) { | 
| 295 | 0 |             SerializeToVector(s, CompactSizeWriter(PSBT_IN_WITNESS_UTXO)); | 
| 296 | 0 |             SerializeToVector(s, witness_utxo); | 
| 297 | 0 |         } | 
| 298 |  | 
 | 
| 299 | 0 |         if (final_script_sig.empty() && final_script_witness.IsNull()) { | 
| 300 |  |             // Write any partial signatures | 
| 301 | 0 |             for (const auto& sig_pair : partial_sigs) { | 
| 302 | 0 |                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_PARTIAL_SIG), std::span{sig_pair.second.first}); | 
| 303 | 0 |                 s << sig_pair.second.second; | 
| 304 | 0 |             } | 
| 305 |  |  | 
| 306 |  |             // Write the sighash type | 
| 307 | 0 |             if (sighash_type != std::nullopt) { | 
| 308 | 0 |                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_SIGHASH)); | 
| 309 | 0 |                 SerializeToVector(s, *sighash_type); | 
| 310 | 0 |             } | 
| 311 |  |  | 
| 312 |  |             // Write the redeem script | 
| 313 | 0 |             if (!redeem_script.empty()) { | 
| 314 | 0 |                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_REDEEMSCRIPT)); | 
| 315 | 0 |                 s << redeem_script; | 
| 316 | 0 |             } | 
| 317 |  |  | 
| 318 |  |             // Write the witness script | 
| 319 | 0 |             if (!witness_script.empty()) { | 
| 320 | 0 |                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_WITNESSSCRIPT)); | 
| 321 | 0 |                 s << witness_script; | 
| 322 | 0 |             } | 
| 323 |  |  | 
| 324 |  |             // Write any hd keypaths | 
| 325 | 0 |             SerializeHDKeypaths(s, hd_keypaths, CompactSizeWriter(PSBT_IN_BIP32_DERIVATION)); | 
| 326 |  |  | 
| 327 |  |             // Write any ripemd160 preimage | 
| 328 | 0 |             for (const auto& [hash, preimage] : ripemd160_preimages) { | 
| 329 | 0 |                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_RIPEMD160), std::span{hash}); | 
| 330 | 0 |                 s << preimage; | 
| 331 | 0 |             } | 
| 332 |  |  | 
| 333 |  |             // Write any sha256 preimage | 
| 334 | 0 |             for (const auto& [hash, preimage] : sha256_preimages) { | 
| 335 | 0 |                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_SHA256), std::span{hash}); | 
| 336 | 0 |                 s << preimage; | 
| 337 | 0 |             } | 
| 338 |  |  | 
| 339 |  |             // Write any hash160 preimage | 
| 340 | 0 |             for (const auto& [hash, preimage] : hash160_preimages) { | 
| 341 | 0 |                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_HASH160), std::span{hash}); | 
| 342 | 0 |                 s << preimage; | 
| 343 | 0 |             } | 
| 344 |  |  | 
| 345 |  |             // Write any hash256 preimage | 
| 346 | 0 |             for (const auto& [hash, preimage] : hash256_preimages) { | 
| 347 | 0 |                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_HASH256), std::span{hash}); | 
| 348 | 0 |                 s << preimage; | 
| 349 | 0 |             } | 
| 350 |  |  | 
| 351 |  |             // Write taproot key sig | 
| 352 | 0 |             if (!m_tap_key_sig.empty()) { | 
| 353 | 0 |                 SerializeToVector(s, PSBT_IN_TAP_KEY_SIG); | 
| 354 | 0 |                 s << m_tap_key_sig; | 
| 355 | 0 |             } | 
| 356 |  |  | 
| 357 |  |             // Write taproot script sigs | 
| 358 | 0 |             for (const auto& [pubkey_leaf, sig] : m_tap_script_sigs) { | 
| 359 | 0 |                 const auto& [xonly, leaf_hash] = pubkey_leaf; | 
| 360 | 0 |                 SerializeToVector(s, PSBT_IN_TAP_SCRIPT_SIG, xonly, leaf_hash); | 
| 361 | 0 |                 s << sig; | 
| 362 | 0 |             } | 
| 363 |  |  | 
| 364 |  |             // Write taproot leaf scripts | 
| 365 | 0 |             for (const auto& [leaf, control_blocks] : m_tap_scripts) { | 
| 366 | 0 |                 const auto& [script, leaf_ver] = leaf; | 
| 367 | 0 |                 for (const auto& control_block : control_blocks) { | 
| 368 | 0 |                     SerializeToVector(s, PSBT_IN_TAP_LEAF_SCRIPT, std::span{control_block}); | 
| 369 | 0 |                     std::vector<unsigned char> value_v(script.begin(), script.end()); | 
| 370 | 0 |                     value_v.push_back((uint8_t)leaf_ver); | 
| 371 | 0 |                     s << value_v; | 
| 372 | 0 |                 } | 
| 373 | 0 |             } | 
| 374 |  |  | 
| 375 |  |             // Write taproot bip32 keypaths | 
| 376 | 0 |             for (const auto& [xonly, leaf_origin] : m_tap_bip32_paths) { | 
| 377 | 0 |                 const auto& [leaf_hashes, origin] = leaf_origin; | 
| 378 | 0 |                 SerializeToVector(s, PSBT_IN_TAP_BIP32_DERIVATION, xonly); | 
| 379 | 0 |                 std::vector<unsigned char> value; | 
| 380 | 0 |                 VectorWriter s_value{value, 0}; | 
| 381 | 0 |                 s_value << leaf_hashes; | 
| 382 | 0 |                 SerializeKeyOrigin(s_value, origin); | 
| 383 | 0 |                 s << value; | 
| 384 | 0 |             } | 
| 385 |  |  | 
| 386 |  |             // Write taproot internal key | 
| 387 | 0 |             if (!m_tap_internal_key.IsNull()) { | 
| 388 | 0 |                 SerializeToVector(s, PSBT_IN_TAP_INTERNAL_KEY); | 
| 389 | 0 |                 s << ToByteVector(m_tap_internal_key); | 
| 390 | 0 |             } | 
| 391 |  |  | 
| 392 |  |             // Write taproot merkle root | 
| 393 | 0 |             if (!m_tap_merkle_root.IsNull()) { | 
| 394 | 0 |                 SerializeToVector(s, PSBT_IN_TAP_MERKLE_ROOT); | 
| 395 | 0 |                 SerializeToVector(s, m_tap_merkle_root); | 
| 396 | 0 |             } | 
| 397 |  |  | 
| 398 |  |             // Write MuSig2 Participants | 
| 399 | 0 |             for (const auto& [agg_pubkey, part_pubs] : m_musig2_participants) { | 
| 400 | 0 |                 SerializeToVector(s, CompactSizeWriter(PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS), std::span{agg_pubkey}); | 
| 401 | 0 |                 std::vector<unsigned char> value; | 
| 402 | 0 |                 VectorWriter s_value{value, 0}; | 
| 403 | 0 |                 for (auto& pk : part_pubs) { | 
| 404 | 0 |                     s_value << std::span{pk}; | 
| 405 | 0 |                 } | 
| 406 | 0 |                 s << value; | 
| 407 | 0 |             } | 
| 408 |  |  | 
| 409 |  |             // Write MuSig2 pubnonces | 
| 410 | 0 |             for (const auto& [agg_pubkey_leaf_hash, pubnonces] : m_musig2_pubnonces) { | 
| 411 | 0 |                 const auto& [agg_pubkey, leaf_hash] = agg_pubkey_leaf_hash; | 
| 412 | 0 |                 for (const auto& [part_pubkey, pubnonce] : pubnonces) { | 
| 413 | 0 |                     if (leaf_hash.IsNull()) { | 
| 414 | 0 |                         SerializeToVector(s, CompactSizeWriter(PSBT_IN_MUSIG2_PUB_NONCE), std::span{part_pubkey}, std::span{agg_pubkey}); | 
| 415 | 0 |                     } else { | 
| 416 | 0 |                         SerializeToVector(s, CompactSizeWriter(PSBT_IN_MUSIG2_PUB_NONCE), std::span{part_pubkey}, std::span{agg_pubkey}, leaf_hash); | 
| 417 | 0 |                     } | 
| 418 | 0 |                     s << pubnonce; | 
| 419 | 0 |                 } | 
| 420 | 0 |             } | 
| 421 |  |  | 
| 422 |  |             // Write MuSig2 partial signatures | 
| 423 | 0 |             for (const auto& [agg_pubkey_leaf_hash, psigs] : m_musig2_partial_sigs) { | 
| 424 | 0 |                 const auto& [agg_pubkey, leaf_hash] = agg_pubkey_leaf_hash; | 
| 425 | 0 |                 for (const auto& [pubkey, psig] : psigs) { | 
| 426 | 0 |                     if (leaf_hash.IsNull()) { | 
| 427 | 0 |                         SerializeToVector(s, CompactSizeWriter(PSBT_IN_MUSIG2_PARTIAL_SIG), std::span{pubkey}, std::span{agg_pubkey}); | 
| 428 | 0 |                     } else { | 
| 429 | 0 |                         SerializeToVector(s, CompactSizeWriter(PSBT_IN_MUSIG2_PARTIAL_SIG), std::span{pubkey}, std::span{agg_pubkey}, leaf_hash); | 
| 430 | 0 |                     } | 
| 431 | 0 |                     SerializeToVector(s, psig); | 
| 432 | 0 |                 } | 
| 433 | 0 |             } | 
| 434 | 0 |         } | 
| 435 |  |  | 
| 436 |  |         // Write script sig | 
| 437 | 0 |         if (!final_script_sig.empty()) { | 
| 438 | 0 |             SerializeToVector(s, CompactSizeWriter(PSBT_IN_SCRIPTSIG)); | 
| 439 | 0 |             s << final_script_sig; | 
| 440 | 0 |         } | 
| 441 |  |         // write script witness | 
| 442 | 0 |         if (!final_script_witness.IsNull()) { | 
| 443 | 0 |             SerializeToVector(s, CompactSizeWriter(PSBT_IN_SCRIPTWITNESS)); | 
| 444 | 0 |             SerializeToVector(s, final_script_witness.stack); | 
| 445 | 0 |         } | 
| 446 |  |  | 
| 447 |  |         // Write proprietary things | 
| 448 | 0 |         for (const auto& entry : m_proprietary) { | 
| 449 | 0 |             s << entry.key; | 
| 450 | 0 |             s << entry.value; | 
| 451 | 0 |         } | 
| 452 |  |  | 
| 453 |  |         // Write unknown things | 
| 454 | 0 |         for (auto& entry : unknown) { | 
| 455 | 0 |             s << entry.first; | 
| 456 | 0 |             s << entry.second; | 
| 457 | 0 |         } | 
| 458 |  | 
 | 
| 459 | 0 |         s << PSBT_SEPARATOR; | 
| 460 | 0 |     } | 
| 461 |  |  | 
| 462 |  |  | 
| 463 |  |     template <typename Stream> | 
| 464 | 0 |     inline void Unserialize(Stream& s) { | 
| 465 |  |         // Used for duplicate key detection | 
| 466 | 0 |         std::set<std::vector<unsigned char>> key_lookup; | 
| 467 |  |  | 
| 468 |  |         // Read loop | 
| 469 | 0 |         bool found_sep = false; | 
| 470 | 0 |         while(!s.empty()) { | 
| 471 |  |             // Read | 
| 472 | 0 |             std::vector<unsigned char> key; | 
| 473 | 0 |             s >> key; | 
| 474 |  |  | 
| 475 |  |             // the key is empty if that was actually a separator byte | 
| 476 |  |             // This is a special case for key lengths 0 as those are not allowed (except for separator) | 
| 477 | 0 |             if (key.empty()) { | 
| 478 | 0 |                 found_sep = true; | 
| 479 | 0 |                 break; | 
| 480 | 0 |             } | 
| 481 |  |  | 
| 482 |  |             // Type is compact size uint at beginning of key | 
| 483 | 0 |             SpanReader skey{key}; | 
| 484 | 0 |             uint64_t type = ReadCompactSize(skey); | 
| 485 |  |  | 
| 486 |  |             // Do stuff based on type | 
| 487 | 0 |             switch(type) { | 
| 488 | 0 |                 case PSBT_IN_NON_WITNESS_UTXO: | 
| 489 | 0 |                 { | 
| 490 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 491 | 0 |                         throw std::ios_base::failure("Duplicate Key, input non-witness utxo already provided"); | 
| 492 | 0 |                     } else if (key.size() != 1) { | 
| 493 | 0 |                         throw std::ios_base::failure("Non-witness utxo key is more than one byte type"); | 
| 494 | 0 |                     } | 
| 495 |  |                     // Set the stream to unserialize with witness since this is always a valid network transaction | 
| 496 | 0 |                     UnserializeFromVector(s, TX_WITH_WITNESS(non_witness_utxo)); | 
| 497 | 0 |                     break; | 
| 498 | 0 |                 } | 
| 499 | 0 |                 case PSBT_IN_WITNESS_UTXO: | 
| 500 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 501 | 0 |                         throw std::ios_base::failure("Duplicate Key, input witness utxo already provided"); | 
| 502 | 0 |                     } else if (key.size() != 1) { | 
| 503 | 0 |                         throw std::ios_base::failure("Witness utxo key is more than one byte type"); | 
| 504 | 0 |                     } | 
| 505 | 0 |                     UnserializeFromVector(s, witness_utxo); | 
| 506 | 0 |                     break; | 
| 507 | 0 |                 case PSBT_IN_PARTIAL_SIG: | 
| 508 | 0 |                 { | 
| 509 |  |                     // Make sure that the key is the size of pubkey + 1 | 
| 510 | 0 |                     if (key.size() != CPubKey::SIZE + 1 && key.size() != CPubKey::COMPRESSED_SIZE + 1) { | 
| 511 | 0 |                         throw std::ios_base::failure("Size of key was not the expected size for the type partial signature pubkey"); | 
| 512 | 0 |                     } | 
| 513 |  |                     // Read in the pubkey from key | 
| 514 | 0 |                     CPubKey pubkey(key.begin() + 1, key.end()); | 
| 515 | 0 |                     if (!pubkey.IsFullyValid()) { | 
| 516 | 0 |                        throw std::ios_base::failure("Invalid pubkey"); | 
| 517 | 0 |                     } | 
| 518 | 0 |                     if (partial_sigs.count(pubkey.GetID()) > 0) { | 
| 519 | 0 |                         throw std::ios_base::failure("Duplicate Key, input partial signature for pubkey already provided"); | 
| 520 | 0 |                     } | 
| 521 |  |  | 
| 522 |  |                     // Read in the signature from value | 
| 523 | 0 |                     std::vector<unsigned char> sig; | 
| 524 | 0 |                     s >> sig; | 
| 525 |  |  | 
| 526 |  |                     // Check that the signature is validly encoded | 
| 527 | 0 |                     if (sig.empty() || !CheckSignatureEncoding(sig, SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_STRICTENC, nullptr)) { | 
| 528 | 0 |                         throw std::ios_base::failure("Signature is not a valid encoding"); | 
| 529 | 0 |                     } | 
| 530 |  |  | 
| 531 |  |                     // Add to list | 
| 532 | 0 |                     partial_sigs.emplace(pubkey.GetID(), SigPair(pubkey, std::move(sig))); | 
| 533 | 0 |                     break; | 
| 534 | 0 |                 } | 
| 535 | 0 |                 case PSBT_IN_SIGHASH: | 
| 536 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 537 | 0 |                         throw std::ios_base::failure("Duplicate Key, input sighash type already provided"); | 
| 538 | 0 |                     } else if (key.size() != 1) { | 
| 539 | 0 |                         throw std::ios_base::failure("Sighash type key is more than one byte type"); | 
| 540 | 0 |                     } | 
| 541 | 0 |                     int sighash; | 
| 542 | 0 |                     UnserializeFromVector(s, sighash); | 
| 543 | 0 |                     sighash_type = sighash; | 
| 544 | 0 |                     break; | 
| 545 | 0 |                 case PSBT_IN_REDEEMSCRIPT: | 
| 546 | 0 |                 { | 
| 547 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 548 | 0 |                         throw std::ios_base::failure("Duplicate Key, input redeemScript already provided"); | 
| 549 | 0 |                     } else if (key.size() != 1) { | 
| 550 | 0 |                         throw std::ios_base::failure("Input redeemScript key is more than one byte type"); | 
| 551 | 0 |                     } | 
| 552 | 0 |                     s >> redeem_script; | 
| 553 | 0 |                     break; | 
| 554 | 0 |                 } | 
| 555 | 0 |                 case PSBT_IN_WITNESSSCRIPT: | 
| 556 | 0 |                 { | 
| 557 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 558 | 0 |                         throw std::ios_base::failure("Duplicate Key, input witnessScript already provided"); | 
| 559 | 0 |                     } else if (key.size() != 1) { | 
| 560 | 0 |                         throw std::ios_base::failure("Input witnessScript key is more than one byte type"); | 
| 561 | 0 |                     } | 
| 562 | 0 |                     s >> witness_script; | 
| 563 | 0 |                     break; | 
| 564 | 0 |                 } | 
| 565 | 0 |                 case PSBT_IN_BIP32_DERIVATION: | 
| 566 | 0 |                 { | 
| 567 | 0 |                     DeserializeHDKeypaths(s, key, hd_keypaths); | 
| 568 | 0 |                     break; | 
| 569 | 0 |                 } | 
| 570 | 0 |                 case PSBT_IN_SCRIPTSIG: | 
| 571 | 0 |                 { | 
| 572 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 573 | 0 |                         throw std::ios_base::failure("Duplicate Key, input final scriptSig already provided"); | 
| 574 | 0 |                     } else if (key.size() != 1) { | 
| 575 | 0 |                         throw std::ios_base::failure("Final scriptSig key is more than one byte type"); | 
| 576 | 0 |                     } | 
| 577 | 0 |                     s >> final_script_sig; | 
| 578 | 0 |                     break; | 
| 579 | 0 |                 } | 
| 580 | 0 |                 case PSBT_IN_SCRIPTWITNESS: | 
| 581 | 0 |                 { | 
| 582 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 583 | 0 |                         throw std::ios_base::failure("Duplicate Key, input final scriptWitness already provided"); | 
| 584 | 0 |                     } else if (key.size() != 1) { | 
| 585 | 0 |                         throw std::ios_base::failure("Final scriptWitness key is more than one byte type"); | 
| 586 | 0 |                     } | 
| 587 | 0 |                     UnserializeFromVector(s, final_script_witness.stack); | 
| 588 | 0 |                     break; | 
| 589 | 0 |                 } | 
| 590 | 0 |                 case PSBT_IN_RIPEMD160: | 
| 591 | 0 |                 { | 
| 592 |  |                     // Make sure that the key is the size of a ripemd160 hash + 1 | 
| 593 | 0 |                     if (key.size() != CRIPEMD160::OUTPUT_SIZE + 1) { | 
| 594 | 0 |                         throw std::ios_base::failure("Size of key was not the expected size for the type ripemd160 preimage"); | 
| 595 | 0 |                     } | 
| 596 |  |                     // Read in the hash from key | 
| 597 | 0 |                     std::vector<unsigned char> hash_vec(key.begin() + 1, key.end()); | 
| 598 | 0 |                     uint160 hash(hash_vec); | 
| 599 | 0 |                     if (ripemd160_preimages.count(hash) > 0) { | 
| 600 | 0 |                         throw std::ios_base::failure("Duplicate Key, input ripemd160 preimage already provided"); | 
| 601 | 0 |                     } | 
| 602 |  |  | 
| 603 |  |                     // Read in the preimage from value | 
| 604 | 0 |                     std::vector<unsigned char> preimage; | 
| 605 | 0 |                     s >> preimage; | 
| 606 |  |  | 
| 607 |  |                     // Add to preimages list | 
| 608 | 0 |                     ripemd160_preimages.emplace(hash, std::move(preimage)); | 
| 609 | 0 |                     break; | 
| 610 | 0 |                 } | 
| 611 | 0 |                 case PSBT_IN_SHA256: | 
| 612 | 0 |                 { | 
| 613 |  |                     // Make sure that the key is the size of a sha256 hash + 1 | 
| 614 | 0 |                     if (key.size() != CSHA256::OUTPUT_SIZE + 1) { | 
| 615 | 0 |                         throw std::ios_base::failure("Size of key was not the expected size for the type sha256 preimage"); | 
| 616 | 0 |                     } | 
| 617 |  |                     // Read in the hash from key | 
| 618 | 0 |                     std::vector<unsigned char> hash_vec(key.begin() + 1, key.end()); | 
| 619 | 0 |                     uint256 hash(hash_vec); | 
| 620 | 0 |                     if (sha256_preimages.count(hash) > 0) { | 
| 621 | 0 |                         throw std::ios_base::failure("Duplicate Key, input sha256 preimage already provided"); | 
| 622 | 0 |                     } | 
| 623 |  |  | 
| 624 |  |                     // Read in the preimage from value | 
| 625 | 0 |                     std::vector<unsigned char> preimage; | 
| 626 | 0 |                     s >> preimage; | 
| 627 |  |  | 
| 628 |  |                     // Add to preimages list | 
| 629 | 0 |                     sha256_preimages.emplace(hash, std::move(preimage)); | 
| 630 | 0 |                     break; | 
| 631 | 0 |                 } | 
| 632 | 0 |                 case PSBT_IN_HASH160: | 
| 633 | 0 |                 { | 
| 634 |  |                     // Make sure that the key is the size of a hash160 hash + 1 | 
| 635 | 0 |                     if (key.size() != CHash160::OUTPUT_SIZE + 1) { | 
| 636 | 0 |                         throw std::ios_base::failure("Size of key was not the expected size for the type hash160 preimage"); | 
| 637 | 0 |                     } | 
| 638 |  |                     // Read in the hash from key | 
| 639 | 0 |                     std::vector<unsigned char> hash_vec(key.begin() + 1, key.end()); | 
| 640 | 0 |                     uint160 hash(hash_vec); | 
| 641 | 0 |                     if (hash160_preimages.count(hash) > 0) { | 
| 642 | 0 |                         throw std::ios_base::failure("Duplicate Key, input hash160 preimage already provided"); | 
| 643 | 0 |                     } | 
| 644 |  |  | 
| 645 |  |                     // Read in the preimage from value | 
| 646 | 0 |                     std::vector<unsigned char> preimage; | 
| 647 | 0 |                     s >> preimage; | 
| 648 |  |  | 
| 649 |  |                     // Add to preimages list | 
| 650 | 0 |                     hash160_preimages.emplace(hash, std::move(preimage)); | 
| 651 | 0 |                     break; | 
| 652 | 0 |                 } | 
| 653 | 0 |                 case PSBT_IN_HASH256: | 
| 654 | 0 |                 { | 
| 655 |  |                     // Make sure that the key is the size of a hash256 hash + 1 | 
| 656 | 0 |                     if (key.size() != CHash256::OUTPUT_SIZE + 1) { | 
| 657 | 0 |                         throw std::ios_base::failure("Size of key was not the expected size for the type hash256 preimage"); | 
| 658 | 0 |                     } | 
| 659 |  |                     // Read in the hash from key | 
| 660 | 0 |                     std::vector<unsigned char> hash_vec(key.begin() + 1, key.end()); | 
| 661 | 0 |                     uint256 hash(hash_vec); | 
| 662 | 0 |                     if (hash256_preimages.count(hash) > 0) { | 
| 663 | 0 |                         throw std::ios_base::failure("Duplicate Key, input hash256 preimage already provided"); | 
| 664 | 0 |                     } | 
| 665 |  |  | 
| 666 |  |                     // Read in the preimage from value | 
| 667 | 0 |                     std::vector<unsigned char> preimage; | 
| 668 | 0 |                     s >> preimage; | 
| 669 |  |  | 
| 670 |  |                     // Add to preimages list | 
| 671 | 0 |                     hash256_preimages.emplace(hash, std::move(preimage)); | 
| 672 | 0 |                     break; | 
| 673 | 0 |                 } | 
| 674 | 0 |                 case PSBT_IN_TAP_KEY_SIG: | 
| 675 | 0 |                 { | 
| 676 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 677 | 0 |                         throw std::ios_base::failure("Duplicate Key, input Taproot key signature already provided"); | 
| 678 | 0 |                     } else if (key.size() != 1) { | 
| 679 | 0 |                         throw std::ios_base::failure("Input Taproot key signature key is more than one byte type"); | 
| 680 | 0 |                     } | 
| 681 | 0 |                     s >> m_tap_key_sig; | 
| 682 | 0 |                     if (m_tap_key_sig.size() < 64) { | 
| 683 | 0 |                         throw std::ios_base::failure("Input Taproot key path signature is shorter than 64 bytes"); | 
| 684 | 0 |                     } else if (m_tap_key_sig.size() > 65) { | 
| 685 | 0 |                         throw std::ios_base::failure("Input Taproot key path signature is longer than 65 bytes"); | 
| 686 | 0 |                     } | 
| 687 | 0 |                     break; | 
| 688 | 0 |                 } | 
| 689 | 0 |                 case PSBT_IN_TAP_SCRIPT_SIG: | 
| 690 | 0 |                 { | 
| 691 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 692 | 0 |                         throw std::ios_base::failure("Duplicate Key, input Taproot script signature already provided"); | 
| 693 | 0 |                     } else if (key.size() != 65) { | 
| 694 | 0 |                         throw std::ios_base::failure("Input Taproot script signature key is not 65 bytes"); | 
| 695 | 0 |                     } | 
| 696 | 0 |                     SpanReader s_key{std::span{key}.subspan(1)}; | 
| 697 | 0 |                     XOnlyPubKey xonly; | 
| 698 | 0 |                     uint256 hash; | 
| 699 | 0 |                     s_key >> xonly; | 
| 700 | 0 |                     s_key >> hash; | 
| 701 | 0 |                     std::vector<unsigned char> sig; | 
| 702 | 0 |                     s >> sig; | 
| 703 | 0 |                     if (sig.size() < 64) { | 
| 704 | 0 |                         throw std::ios_base::failure("Input Taproot script path signature is shorter than 64 bytes"); | 
| 705 | 0 |                     } else if (sig.size() > 65) { | 
| 706 | 0 |                         throw std::ios_base::failure("Input Taproot script path signature is longer than 65 bytes"); | 
| 707 | 0 |                     } | 
| 708 | 0 |                     m_tap_script_sigs.emplace(std::make_pair(xonly, hash), sig); | 
| 709 | 0 |                     break; | 
| 710 | 0 |                 } | 
| 711 | 0 |                 case PSBT_IN_TAP_LEAF_SCRIPT: | 
| 712 | 0 |                 { | 
| 713 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 714 | 0 |                         throw std::ios_base::failure("Duplicate Key, input Taproot leaf script already provided"); | 
| 715 | 0 |                     } else if (key.size() < 34) { | 
| 716 | 0 |                         throw std::ios_base::failure("Taproot leaf script key is not at least 34 bytes"); | 
| 717 | 0 |                     } else if ((key.size() - 2) % 32 != 0) { | 
| 718 | 0 |                         throw std::ios_base::failure("Input Taproot leaf script key's control block size is not valid"); | 
| 719 | 0 |                     } | 
| 720 | 0 |                     std::vector<unsigned char> script_v; | 
| 721 | 0 |                     s >> script_v; | 
| 722 | 0 |                     if (script_v.empty()) { | 
| 723 | 0 |                         throw std::ios_base::failure("Input Taproot leaf script must be at least 1 byte"); | 
| 724 | 0 |                     } | 
| 725 | 0 |                     uint8_t leaf_ver = script_v.back(); | 
| 726 | 0 |                     script_v.pop_back(); | 
| 727 | 0 |                     const auto leaf_script = std::make_pair(script_v, (int)leaf_ver); | 
| 728 | 0 |                     m_tap_scripts[leaf_script].insert(std::vector<unsigned char>(key.begin() + 1, key.end())); | 
| 729 | 0 |                     break; | 
| 730 | 0 |                 } | 
| 731 | 0 |                 case PSBT_IN_TAP_BIP32_DERIVATION: | 
| 732 | 0 |                 { | 
| 733 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 734 | 0 |                         throw std::ios_base::failure("Duplicate Key, input Taproot BIP32 keypath already provided"); | 
| 735 | 0 |                     } else if (key.size() != 33) { | 
| 736 | 0 |                         throw std::ios_base::failure("Input Taproot BIP32 keypath key is not at 33 bytes"); | 
| 737 | 0 |                     } | 
| 738 | 0 |                     SpanReader s_key{std::span{key}.subspan(1)}; | 
| 739 | 0 |                     XOnlyPubKey xonly; | 
| 740 | 0 |                     s_key >> xonly; | 
| 741 | 0 |                     std::set<uint256> leaf_hashes; | 
| 742 | 0 |                     uint64_t value_len = ReadCompactSize(s); | 
| 743 | 0 |                     size_t before_hashes = s.size(); | 
| 744 | 0 |                     s >> leaf_hashes; | 
| 745 | 0 |                     size_t after_hashes = s.size(); | 
| 746 | 0 |                     size_t hashes_len = before_hashes - after_hashes; | 
| 747 | 0 |                     if (hashes_len > value_len) { | 
| 748 | 0 |                         throw std::ios_base::failure("Input Taproot BIP32 keypath has an invalid length"); | 
| 749 | 0 |                     } | 
| 750 | 0 |                     size_t origin_len = value_len - hashes_len; | 
| 751 | 0 |                     m_tap_bip32_paths.emplace(xonly, std::make_pair(leaf_hashes, DeserializeKeyOrigin(s, origin_len))); | 
| 752 | 0 |                     break; | 
| 753 | 0 |                 } | 
| 754 | 0 |                 case PSBT_IN_TAP_INTERNAL_KEY: | 
| 755 | 0 |                 { | 
| 756 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 757 | 0 |                         throw std::ios_base::failure("Duplicate Key, input Taproot internal key already provided"); | 
| 758 | 0 |                     } else if (key.size() != 1) { | 
| 759 | 0 |                         throw std::ios_base::failure("Input Taproot internal key key is more than one byte type"); | 
| 760 | 0 |                     } | 
| 761 | 0 |                     UnserializeFromVector(s, m_tap_internal_key); | 
| 762 | 0 |                     break; | 
| 763 | 0 |                 } | 
| 764 | 0 |                 case PSBT_IN_TAP_MERKLE_ROOT: | 
| 765 | 0 |                 { | 
| 766 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 767 | 0 |                         throw std::ios_base::failure("Duplicate Key, input Taproot merkle root already provided"); | 
| 768 | 0 |                     } else if (key.size() != 1) { | 
| 769 | 0 |                         throw std::ios_base::failure("Input Taproot merkle root key is more than one byte type"); | 
| 770 | 0 |                     } | 
| 771 | 0 |                     UnserializeFromVector(s, m_tap_merkle_root); | 
| 772 | 0 |                     break; | 
| 773 | 0 |                 } | 
| 774 | 0 |                 case PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS: | 
| 775 | 0 |                 { | 
| 776 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 777 | 0 |                         throw std::ios_base::failure("Duplicate Key, input participant pubkeys for an aggregate key already provided"); | 
| 778 | 0 |                     } else if (key.size() != CPubKey::COMPRESSED_SIZE + 1) { | 
| 779 | 0 |                         throw std::ios_base::failure("Input musig2 participants pubkeys aggregate key is not 34 bytes"); | 
| 780 | 0 |                     } | 
| 781 | 0 |                     DeserializeMuSig2ParticipantPubkeys(s, skey, m_musig2_participants, std::string{"Input"}); | 
| 782 | 0 |                     break; | 
| 783 | 0 |                 } | 
| 784 | 0 |                 case PSBT_IN_MUSIG2_PUB_NONCE: | 
| 785 | 0 |                 { | 
| 786 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 787 | 0 |                         throw std::ios_base::failure("Duplicate Key, input musig2 pubnonce already provided"); | 
| 788 | 0 |                     } else if (key.size() != 2 * CPubKey::COMPRESSED_SIZE + 1 && key.size() != 2 * CPubKey::COMPRESSED_SIZE + CSHA256::OUTPUT_SIZE + 1) { | 
| 789 | 0 |                         throw std::ios_base::failure("Input musig2 pubnonce key is not expected size of 67 or 99 bytes"); | 
| 790 | 0 |                     } | 
| 791 | 0 |                     CPubKey agg_pub, part_pub; | 
| 792 | 0 |                     uint256 leaf_hash; | 
| 793 | 0 |                     DeserializeMuSig2ParticipantDataIdentifier(skey, agg_pub, part_pub, leaf_hash); | 
| 794 |  | 
 | 
| 795 | 0 |                     std::vector<uint8_t> pubnonce; | 
| 796 | 0 |                     s >> pubnonce; | 
| 797 | 0 |                     if (pubnonce.size() != 66) { | 
| 798 | 0 |                         throw std::ios_base::failure("Input musig2 pubnonce value is not 66 bytes"); | 
| 799 | 0 |                     } | 
| 800 |  |  | 
| 801 | 0 |                     m_musig2_pubnonces[std::make_pair(agg_pub, leaf_hash)].emplace(part_pub, pubnonce); | 
| 802 | 0 |                     break; | 
| 803 | 0 |                 } | 
| 804 | 0 |                 case PSBT_IN_MUSIG2_PARTIAL_SIG: | 
| 805 | 0 |                 { | 
| 806 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 807 | 0 |                         throw std::ios_base::failure("Duplicate Key, input musig2 partial sig already provided"); | 
| 808 | 0 |                     } else if (key.size() != 2 * CPubKey::COMPRESSED_SIZE + 1 && key.size() != 2 * CPubKey::COMPRESSED_SIZE + CSHA256::OUTPUT_SIZE + 1) { | 
| 809 | 0 |                         throw std::ios_base::failure("Input musig2 partial sig key is not expected size of 67 or 99 bytes"); | 
| 810 | 0 |                     } | 
| 811 | 0 |                     CPubKey agg_pub, part_pub; | 
| 812 | 0 |                     uint256 leaf_hash; | 
| 813 | 0 |                     DeserializeMuSig2ParticipantDataIdentifier(skey, agg_pub, part_pub, leaf_hash); | 
| 814 |  | 
 | 
| 815 | 0 |                     uint256 partial_sig; | 
| 816 | 0 |                     UnserializeFromVector(s, partial_sig); | 
| 817 |  | 
 | 
| 818 | 0 |                     m_musig2_partial_sigs[std::make_pair(agg_pub, leaf_hash)].emplace(part_pub, partial_sig); | 
| 819 | 0 |                     break; | 
| 820 | 0 |                 } | 
| 821 | 0 |                 case PSBT_IN_PROPRIETARY: | 
| 822 | 0 |                 { | 
| 823 | 0 |                     PSBTProprietary this_prop; | 
| 824 | 0 |                     skey >> this_prop.identifier; | 
| 825 | 0 |                     this_prop.subtype = ReadCompactSize(skey); | 
| 826 | 0 |                     this_prop.key = key; | 
| 827 |  | 
 | 
| 828 | 0 |                     if (m_proprietary.count(this_prop) > 0) { | 
| 829 | 0 |                         throw std::ios_base::failure("Duplicate Key, proprietary key already found"); | 
| 830 | 0 |                     } | 
| 831 | 0 |                     s >> this_prop.value; | 
| 832 | 0 |                     m_proprietary.insert(this_prop); | 
| 833 | 0 |                     break; | 
| 834 | 0 |                 } | 
| 835 |  |                 // Unknown stuff | 
| 836 | 0 |                 default: | 
| 837 | 0 |                     if (unknown.count(key) > 0) { | 
| 838 | 0 |                         throw std::ios_base::failure("Duplicate Key, key for unknown value already provided"); | 
| 839 | 0 |                     } | 
| 840 |  |                     // Read in the value | 
| 841 | 0 |                     std::vector<unsigned char> val_bytes; | 
| 842 | 0 |                     s >> val_bytes; | 
| 843 | 0 |                     unknown.emplace(std::move(key), std::move(val_bytes)); | 
| 844 | 0 |                     break; | 
| 845 | 0 |             } | 
| 846 | 0 |         } | 
| 847 |  |  | 
| 848 | 0 |         if (!found_sep) { | 
| 849 | 0 |             throw std::ios_base::failure("Separator is missing at the end of an input map"); | 
| 850 | 0 |         } | 
| 851 | 0 |     } | 
| 852 |  |  | 
| 853 |  |     template <typename Stream> | 
| 854 |  |     PSBTInput(deserialize_type, Stream& s) { | 
| 855 |  |         Unserialize(s); | 
| 856 |  |     } | 
| 857 |  | }; | 
| 858 |  |  | 
| 859 |  | /** A structure for PSBTs which contains per output information */ | 
| 860 |  | struct PSBTOutput | 
| 861 |  | { | 
| 862 |  |     CScript redeem_script; | 
| 863 |  |     CScript witness_script; | 
| 864 |  |     std::map<CPubKey, KeyOriginInfo> hd_keypaths; | 
| 865 |  |     XOnlyPubKey m_tap_internal_key; | 
| 866 |  |     std::vector<std::tuple<uint8_t, uint8_t, std::vector<unsigned char>>> m_tap_tree; | 
| 867 |  |     std::map<XOnlyPubKey, std::pair<std::set<uint256>, KeyOriginInfo>> m_tap_bip32_paths; | 
| 868 |  |     std::map<CPubKey, std::vector<CPubKey>> m_musig2_participants; | 
| 869 |  |     std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown; | 
| 870 |  |     std::set<PSBTProprietary> m_proprietary; | 
| 871 |  |  | 
| 872 |  |     bool IsNull() const; | 
| 873 |  |     void FillSignatureData(SignatureData& sigdata) const; | 
| 874 |  |     void FromSignatureData(const SignatureData& sigdata); | 
| 875 |  |     void Merge(const PSBTOutput& output); | 
| 876 | 0 |     PSBTOutput() = default; | 
| 877 |  |  | 
| 878 |  |     template <typename Stream> | 
| 879 | 0 |     inline void Serialize(Stream& s) const { | 
| 880 |  |         // Write the redeem script | 
| 881 | 0 |         if (!redeem_script.empty()) { | 
| 882 | 0 |             SerializeToVector(s, CompactSizeWriter(PSBT_OUT_REDEEMSCRIPT)); | 
| 883 | 0 |             s << redeem_script; | 
| 884 | 0 |         } | 
| 885 |  |  | 
| 886 |  |         // Write the witness script | 
| 887 | 0 |         if (!witness_script.empty()) { | 
| 888 | 0 |             SerializeToVector(s, CompactSizeWriter(PSBT_OUT_WITNESSSCRIPT)); | 
| 889 | 0 |             s << witness_script; | 
| 890 | 0 |         } | 
| 891 |  |  | 
| 892 |  |         // Write any hd keypaths | 
| 893 | 0 |         SerializeHDKeypaths(s, hd_keypaths, CompactSizeWriter(PSBT_OUT_BIP32_DERIVATION)); | 
| 894 |  |  | 
| 895 |  |         // Write proprietary things | 
| 896 | 0 |         for (const auto& entry : m_proprietary) { | 
| 897 | 0 |             s << entry.key; | 
| 898 | 0 |             s << entry.value; | 
| 899 | 0 |         } | 
| 900 |  |  | 
| 901 |  |         // Write taproot internal key | 
| 902 | 0 |         if (!m_tap_internal_key.IsNull()) { | 
| 903 | 0 |             SerializeToVector(s, PSBT_OUT_TAP_INTERNAL_KEY); | 
| 904 | 0 |             s << ToByteVector(m_tap_internal_key); | 
| 905 | 0 |         } | 
| 906 |  |  | 
| 907 |  |         // Write taproot tree | 
| 908 | 0 |         if (!m_tap_tree.empty()) { | 
| 909 | 0 |             SerializeToVector(s, PSBT_OUT_TAP_TREE); | 
| 910 | 0 |             std::vector<unsigned char> value; | 
| 911 | 0 |             VectorWriter s_value{value, 0}; | 
| 912 | 0 |             for (const auto& [depth, leaf_ver, script] : m_tap_tree) { | 
| 913 | 0 |                 s_value << depth; | 
| 914 | 0 |                 s_value << leaf_ver; | 
| 915 | 0 |                 s_value << script; | 
| 916 | 0 |             } | 
| 917 | 0 |             s << value; | 
| 918 | 0 |         } | 
| 919 |  |  | 
| 920 |  |         // Write taproot bip32 keypaths | 
| 921 | 0 |         for (const auto& [xonly, leaf] : m_tap_bip32_paths) { | 
| 922 | 0 |             const auto& [leaf_hashes, origin] = leaf; | 
| 923 | 0 |             SerializeToVector(s, PSBT_OUT_TAP_BIP32_DERIVATION, xonly); | 
| 924 | 0 |             std::vector<unsigned char> value; | 
| 925 | 0 |             VectorWriter s_value{value, 0}; | 
| 926 | 0 |             s_value << leaf_hashes; | 
| 927 | 0 |             SerializeKeyOrigin(s_value, origin); | 
| 928 | 0 |             s << value; | 
| 929 | 0 |         } | 
| 930 |  |  | 
| 931 |  |         // Write MuSig2 Participants | 
| 932 | 0 |         for (const auto& [agg_pubkey, part_pubs] : m_musig2_participants) { | 
| 933 | 0 |             SerializeToVector(s, CompactSizeWriter(PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS), std::span{agg_pubkey}); | 
| 934 | 0 |             std::vector<unsigned char> value; | 
| 935 | 0 |             VectorWriter s_value{value, 0}; | 
| 936 | 0 |             for (auto& pk : part_pubs) { | 
| 937 | 0 |                 s_value << std::span{pk}; | 
| 938 | 0 |             } | 
| 939 | 0 |             s << value; | 
| 940 | 0 |         } | 
| 941 |  |  | 
| 942 |  |         // Write unknown things | 
| 943 | 0 |         for (auto& entry : unknown) { | 
| 944 | 0 |             s << entry.first; | 
| 945 | 0 |             s << entry.second; | 
| 946 | 0 |         } | 
| 947 |  | 
 | 
| 948 | 0 |         s << PSBT_SEPARATOR; | 
| 949 | 0 |     } | 
| 950 |  |  | 
| 951 |  |  | 
| 952 |  |     template <typename Stream> | 
| 953 | 0 |     inline void Unserialize(Stream& s) { | 
| 954 |  |         // Used for duplicate key detection | 
| 955 | 0 |         std::set<std::vector<unsigned char>> key_lookup; | 
| 956 |  |  | 
| 957 |  |         // Read loop | 
| 958 | 0 |         bool found_sep = false; | 
| 959 | 0 |         while(!s.empty()) { | 
| 960 |  |             // Read | 
| 961 | 0 |             std::vector<unsigned char> key; | 
| 962 | 0 |             s >> key; | 
| 963 |  |  | 
| 964 |  |             // the key is empty if that was actually a separator byte | 
| 965 |  |             // This is a special case for key lengths 0 as those are not allowed (except for separator) | 
| 966 | 0 |             if (key.empty()) { | 
| 967 | 0 |                 found_sep = true; | 
| 968 | 0 |                 break; | 
| 969 | 0 |             } | 
| 970 |  |  | 
| 971 |  |             // Type is compact size uint at beginning of key | 
| 972 | 0 |             SpanReader skey{key}; | 
| 973 | 0 |             uint64_t type = ReadCompactSize(skey); | 
| 974 |  |  | 
| 975 |  |             // Do stuff based on type | 
| 976 | 0 |             switch(type) { | 
| 977 | 0 |                 case PSBT_OUT_REDEEMSCRIPT: | 
| 978 | 0 |                 { | 
| 979 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 980 | 0 |                         throw std::ios_base::failure("Duplicate Key, output redeemScript already provided"); | 
| 981 | 0 |                     } else if (key.size() != 1) { | 
| 982 | 0 |                         throw std::ios_base::failure("Output redeemScript key is more than one byte type"); | 
| 983 | 0 |                     } | 
| 984 | 0 |                     s >> redeem_script; | 
| 985 | 0 |                     break; | 
| 986 | 0 |                 } | 
| 987 | 0 |                 case PSBT_OUT_WITNESSSCRIPT: | 
| 988 | 0 |                 { | 
| 989 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 990 | 0 |                         throw std::ios_base::failure("Duplicate Key, output witnessScript already provided"); | 
| 991 | 0 |                     } else if (key.size() != 1) { | 
| 992 | 0 |                         throw std::ios_base::failure("Output witnessScript key is more than one byte type"); | 
| 993 | 0 |                     } | 
| 994 | 0 |                     s >> witness_script; | 
| 995 | 0 |                     break; | 
| 996 | 0 |                 } | 
| 997 | 0 |                 case PSBT_OUT_BIP32_DERIVATION: | 
| 998 | 0 |                 { | 
| 999 | 0 |                     DeserializeHDKeypaths(s, key, hd_keypaths); | 
| 1000 | 0 |                     break; | 
| 1001 | 0 |                 } | 
| 1002 | 0 |                 case PSBT_OUT_TAP_INTERNAL_KEY: | 
| 1003 | 0 |                 { | 
| 1004 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 1005 | 0 |                         throw std::ios_base::failure("Duplicate Key, output Taproot internal key already provided"); | 
| 1006 | 0 |                     } else if (key.size() != 1) { | 
| 1007 | 0 |                         throw std::ios_base::failure("Output Taproot internal key key is more than one byte type"); | 
| 1008 | 0 |                     } | 
| 1009 | 0 |                     UnserializeFromVector(s, m_tap_internal_key); | 
| 1010 | 0 |                     break; | 
| 1011 | 0 |                 } | 
| 1012 | 0 |                 case PSBT_OUT_TAP_TREE: | 
| 1013 | 0 |                 { | 
| 1014 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 1015 | 0 |                         throw std::ios_base::failure("Duplicate Key, output Taproot tree already provided"); | 
| 1016 | 0 |                     } else if (key.size() != 1) { | 
| 1017 | 0 |                         throw std::ios_base::failure("Output Taproot tree key is more than one byte type"); | 
| 1018 | 0 |                     } | 
| 1019 | 0 |                     std::vector<unsigned char> tree_v; | 
| 1020 | 0 |                     s >> tree_v; | 
| 1021 | 0 |                     SpanReader s_tree{tree_v}; | 
| 1022 | 0 |                     if (s_tree.empty()) { | 
| 1023 | 0 |                         throw std::ios_base::failure("Output Taproot tree must not be empty"); | 
| 1024 | 0 |                     } | 
| 1025 | 0 |                     TaprootBuilder builder; | 
| 1026 | 0 |                     while (!s_tree.empty()) { | 
| 1027 | 0 |                         uint8_t depth; | 
| 1028 | 0 |                         uint8_t leaf_ver; | 
| 1029 | 0 |                         std::vector<unsigned char> script; | 
| 1030 | 0 |                         s_tree >> depth; | 
| 1031 | 0 |                         s_tree >> leaf_ver; | 
| 1032 | 0 |                         s_tree >> script; | 
| 1033 | 0 |                         if (depth > TAPROOT_CONTROL_MAX_NODE_COUNT) { | 
| 1034 | 0 |                             throw std::ios_base::failure("Output Taproot tree has as leaf greater than Taproot maximum depth"); | 
| 1035 | 0 |                         } | 
| 1036 | 0 |                         if ((leaf_ver & ~TAPROOT_LEAF_MASK) != 0) { | 
| 1037 | 0 |                             throw std::ios_base::failure("Output Taproot tree has a leaf with an invalid leaf version"); | 
| 1038 | 0 |                         } | 
| 1039 | 0 |                         m_tap_tree.emplace_back(depth, leaf_ver, script); | 
| 1040 | 0 |                         builder.Add((int)depth, script, (int)leaf_ver, /*track=*/true); | 
| 1041 | 0 |                     } | 
| 1042 | 0 |                     if (!builder.IsComplete()) { | 
| 1043 | 0 |                         throw std::ios_base::failure("Output Taproot tree is malformed"); | 
| 1044 | 0 |                     } | 
| 1045 | 0 |                     break; | 
| 1046 | 0 |                 } | 
| 1047 | 0 |                 case PSBT_OUT_TAP_BIP32_DERIVATION: | 
| 1048 | 0 |                 { | 
| 1049 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 1050 | 0 |                         throw std::ios_base::failure("Duplicate Key, output Taproot BIP32 keypath already provided"); | 
| 1051 | 0 |                     } else if (key.size() != 33) { | 
| 1052 | 0 |                         throw std::ios_base::failure("Output Taproot BIP32 keypath key is not at 33 bytes"); | 
| 1053 | 0 |                     } | 
| 1054 | 0 |                     XOnlyPubKey xonly(uint256(std::span<uint8_t>(key).last(32))); | 
| 1055 | 0 |                     std::set<uint256> leaf_hashes; | 
| 1056 | 0 |                     uint64_t value_len = ReadCompactSize(s); | 
| 1057 | 0 |                     size_t before_hashes = s.size(); | 
| 1058 | 0 |                     s >> leaf_hashes; | 
| 1059 | 0 |                     size_t after_hashes = s.size(); | 
| 1060 | 0 |                     size_t hashes_len = before_hashes - after_hashes; | 
| 1061 | 0 |                     if (hashes_len > value_len) { | 
| 1062 | 0 |                         throw std::ios_base::failure("Output Taproot BIP32 keypath has an invalid length"); | 
| 1063 | 0 |                     } | 
| 1064 | 0 |                     size_t origin_len = value_len - hashes_len; | 
| 1065 | 0 |                     m_tap_bip32_paths.emplace(xonly, std::make_pair(leaf_hashes, DeserializeKeyOrigin(s, origin_len))); | 
| 1066 | 0 |                     break; | 
| 1067 | 0 |                 } | 
| 1068 | 0 |                 case PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS: | 
| 1069 | 0 |                 { | 
| 1070 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 1071 | 0 |                         throw std::ios_base::failure("Duplicate Key, output participant pubkeys for an aggregate key already provided"); | 
| 1072 | 0 |                     } else if (key.size() != CPubKey::COMPRESSED_SIZE + 1) { | 
| 1073 | 0 |                         throw std::ios_base::failure("Output musig2 participants pubkeys aggregate key is not 34 bytes"); | 
| 1074 | 0 |                     } | 
| 1075 | 0 |                     DeserializeMuSig2ParticipantPubkeys(s, skey, m_musig2_participants, std::string{"Output"}); | 
| 1076 | 0 |                     break; | 
| 1077 | 0 |                 } | 
| 1078 | 0 |                 case PSBT_OUT_PROPRIETARY: | 
| 1079 | 0 |                 { | 
| 1080 | 0 |                     PSBTProprietary this_prop; | 
| 1081 | 0 |                     skey >> this_prop.identifier; | 
| 1082 | 0 |                     this_prop.subtype = ReadCompactSize(skey); | 
| 1083 | 0 |                     this_prop.key = key; | 
| 1084 |  | 
 | 
| 1085 | 0 |                     if (m_proprietary.count(this_prop) > 0) { | 
| 1086 | 0 |                         throw std::ios_base::failure("Duplicate Key, proprietary key already found"); | 
| 1087 | 0 |                     } | 
| 1088 | 0 |                     s >> this_prop.value; | 
| 1089 | 0 |                     m_proprietary.insert(this_prop); | 
| 1090 | 0 |                     break; | 
| 1091 | 0 |                 } | 
| 1092 |  |                 // Unknown stuff | 
| 1093 | 0 |                 default: { | 
| 1094 | 0 |                     if (unknown.count(key) > 0) { | 
| 1095 | 0 |                         throw std::ios_base::failure("Duplicate Key, key for unknown value already provided"); | 
| 1096 | 0 |                     } | 
| 1097 |  |                     // Read in the value | 
| 1098 | 0 |                     std::vector<unsigned char> val_bytes; | 
| 1099 | 0 |                     s >> val_bytes; | 
| 1100 | 0 |                     unknown.emplace(std::move(key), std::move(val_bytes)); | 
| 1101 | 0 |                     break; | 
| 1102 | 0 |                 } | 
| 1103 | 0 |             } | 
| 1104 | 0 |         } | 
| 1105 |  |  | 
| 1106 | 0 |         if (!found_sep) { | 
| 1107 | 0 |             throw std::ios_base::failure("Separator is missing at the end of an output map"); | 
| 1108 | 0 |         } | 
| 1109 | 0 |     } | 
| 1110 |  |  | 
| 1111 |  |     template <typename Stream> | 
| 1112 |  |     PSBTOutput(deserialize_type, Stream& s) { | 
| 1113 |  |         Unserialize(s); | 
| 1114 |  |     } | 
| 1115 |  | }; | 
| 1116 |  |  | 
| 1117 |  | /** A version of CTransaction with the PSBT format*/ | 
| 1118 |  | struct PartiallySignedTransaction | 
| 1119 |  | { | 
| 1120 |  |     std::optional<CMutableTransaction> tx; | 
| 1121 |  |     // We use a vector of CExtPubKey in the event that there happens to be the same KeyOriginInfos for different CExtPubKeys | 
| 1122 |  |     // Note that this map swaps the key and values from the serialization | 
| 1123 |  |     std::map<KeyOriginInfo, std::set<CExtPubKey>> m_xpubs; | 
| 1124 |  |     std::vector<PSBTInput> inputs; | 
| 1125 |  |     std::vector<PSBTOutput> outputs; | 
| 1126 |  |     std::map<std::vector<unsigned char>, std::vector<unsigned char>> unknown; | 
| 1127 |  |     std::optional<uint32_t> m_version; | 
| 1128 |  |     std::set<PSBTProprietary> m_proprietary; | 
| 1129 |  |  | 
| 1130 |  |     bool IsNull() const; | 
| 1131 |  |     uint32_t GetVersion() const; | 
| 1132 |  |  | 
| 1133 |  |     /** Merge psbt into this. The two psbts must have the same underlying CTransaction (i.e. the | 
| 1134 |  |       * same actual Bitcoin transaction.) Returns true if the merge succeeded, false otherwise. */ | 
| 1135 |  |     [[nodiscard]] bool Merge(const PartiallySignedTransaction& psbt); | 
| 1136 |  |     bool AddInput(const CTxIn& txin, PSBTInput& psbtin); | 
| 1137 |  |     bool AddOutput(const CTxOut& txout, const PSBTOutput& psbtout); | 
| 1138 | 0 |     PartiallySignedTransaction() = default; | 
| 1139 |  |     explicit PartiallySignedTransaction(const CMutableTransaction& tx); | 
| 1140 |  |     /** | 
| 1141 |  |      * Finds the UTXO for a given input index | 
| 1142 |  |      * | 
| 1143 |  |      * @param[out] utxo The UTXO of the input if found | 
| 1144 |  |      * @param[in] input_index Index of the input to retrieve the UTXO of | 
| 1145 |  |      * @return Whether the UTXO for the specified input was found | 
| 1146 |  |      */ | 
| 1147 |  |     bool GetInputUTXO(CTxOut& utxo, int input_index) const; | 
| 1148 |  |  | 
| 1149 |  |     template <typename Stream> | 
| 1150 | 0 |     inline void Serialize(Stream& s) const { | 
| 1151 |  |  | 
| 1152 |  |         // magic bytes | 
| 1153 | 0 |         s << PSBT_MAGIC_BYTES; | 
| 1154 |  |  | 
| 1155 |  |         // unsigned tx flag | 
| 1156 | 0 |         SerializeToVector(s, CompactSizeWriter(PSBT_GLOBAL_UNSIGNED_TX)); | 
| 1157 |  |  | 
| 1158 |  |         // Write serialized tx to a stream | 
| 1159 | 0 |         SerializeToVector(s, TX_NO_WITNESS(*tx)); | 
| 1160 |  |  | 
| 1161 |  |         // Write xpubs | 
| 1162 | 0 |         for (const auto& xpub_pair : m_xpubs) { | 
| 1163 | 0 |             for (const auto& xpub : xpub_pair.second) { | 
| 1164 | 0 |                 unsigned char ser_xpub[BIP32_EXTKEY_WITH_VERSION_SIZE]; | 
| 1165 | 0 |                 xpub.EncodeWithVersion(ser_xpub); | 
| 1166 |  |                 // Note that the serialization swaps the key and value | 
| 1167 |  |                 // The xpub is the key (for uniqueness) while the path is the value | 
| 1168 | 0 |                 SerializeToVector(s, PSBT_GLOBAL_XPUB, ser_xpub); | 
| 1169 | 0 |                 SerializeHDKeypath(s, xpub_pair.first); | 
| 1170 | 0 |             } | 
| 1171 | 0 |         } | 
| 1172 |  |  | 
| 1173 |  |         // PSBT version | 
| 1174 | 0 |         if (GetVersion() > 0) { | 
| 1175 | 0 |             SerializeToVector(s, CompactSizeWriter(PSBT_GLOBAL_VERSION)); | 
| 1176 | 0 |             SerializeToVector(s, *m_version); | 
| 1177 | 0 |         } | 
| 1178 |  |  | 
| 1179 |  |         // Write proprietary things | 
| 1180 | 0 |         for (const auto& entry : m_proprietary) { | 
| 1181 | 0 |             s << entry.key; | 
| 1182 | 0 |             s << entry.value; | 
| 1183 | 0 |         } | 
| 1184 |  |  | 
| 1185 |  |         // Write the unknown things | 
| 1186 | 0 |         for (auto& entry : unknown) { | 
| 1187 | 0 |             s << entry.first; | 
| 1188 | 0 |             s << entry.second; | 
| 1189 | 0 |         } | 
| 1190 |  |  | 
| 1191 |  |         // Separator | 
| 1192 | 0 |         s << PSBT_SEPARATOR; | 
| 1193 |  |  | 
| 1194 |  |         // Write inputs | 
| 1195 | 0 |         for (const PSBTInput& input : inputs) { | 
| 1196 | 0 |             s << input; | 
| 1197 | 0 |         } | 
| 1198 |  |         // Write outputs | 
| 1199 | 0 |         for (const PSBTOutput& output : outputs) { | 
| 1200 | 0 |             s << output; | 
| 1201 | 0 |         } | 
| 1202 | 0 |     } | 
| 1203 |  |  | 
| 1204 |  |  | 
| 1205 |  |     template <typename Stream> | 
| 1206 | 0 |     inline void Unserialize(Stream& s) { | 
| 1207 |  |         // Read the magic bytes | 
| 1208 | 0 |         uint8_t magic[5]; | 
| 1209 | 0 |         s >> magic; | 
| 1210 | 0 |         if (!std::equal(magic, magic + 5, PSBT_MAGIC_BYTES)) { | 
| 1211 | 0 |             throw std::ios_base::failure("Invalid PSBT magic bytes"); | 
| 1212 | 0 |         } | 
| 1213 |  |  | 
| 1214 |  |         // Used for duplicate key detection | 
| 1215 | 0 |         std::set<std::vector<unsigned char>> key_lookup; | 
| 1216 |  |  | 
| 1217 |  |         // Track the global xpubs we have already seen. Just for sanity checking | 
| 1218 | 0 |         std::set<CExtPubKey> global_xpubs; | 
| 1219 |  |  | 
| 1220 |  |         // Read global data | 
| 1221 | 0 |         bool found_sep = false; | 
| 1222 | 0 |         while(!s.empty()) { | 
| 1223 |  |             // Read | 
| 1224 | 0 |             std::vector<unsigned char> key; | 
| 1225 | 0 |             s >> key; | 
| 1226 |  |  | 
| 1227 |  |             // the key is empty if that was actually a separator byte | 
| 1228 |  |             // This is a special case for key lengths 0 as those are not allowed (except for separator) | 
| 1229 | 0 |             if (key.empty()) { | 
| 1230 | 0 |                 found_sep = true; | 
| 1231 | 0 |                 break; | 
| 1232 | 0 |             } | 
| 1233 |  |  | 
| 1234 |  |             // Type is compact size uint at beginning of key | 
| 1235 | 0 |             SpanReader skey{key}; | 
| 1236 | 0 |             uint64_t type = ReadCompactSize(skey); | 
| 1237 |  |  | 
| 1238 |  |             // Do stuff based on type | 
| 1239 | 0 |             switch(type) { | 
| 1240 | 0 |                 case PSBT_GLOBAL_UNSIGNED_TX: | 
| 1241 | 0 |                 { | 
| 1242 | 0 |                     if (!key_lookup.emplace(key).second) { | 
| 1243 | 0 |                         throw std::ios_base::failure("Duplicate Key, unsigned tx already provided"); | 
| 1244 | 0 |                     } else if (key.size() != 1) { | 
| 1245 | 0 |                         throw std::ios_base::failure("Global unsigned tx key is more than one byte type"); | 
| 1246 | 0 |                     } | 
| 1247 | 0 |                     CMutableTransaction mtx; | 
| 1248 |  |                     // Set the stream to serialize with non-witness since this should always be non-witness | 
| 1249 | 0 |                     UnserializeFromVector(s, TX_NO_WITNESS(mtx)); | 
| 1250 | 0 |                     tx = std::move(mtx); | 
| 1251 |  |                     // Make sure that all scriptSigs and scriptWitnesses are empty | 
| 1252 | 0 |                     for (const CTxIn& txin : tx->vin) { | 
| 1253 | 0 |                         if (!txin.scriptSig.empty() || !txin.scriptWitness.IsNull()) { | 
| 1254 | 0 |                             throw std::ios_base::failure("Unsigned tx does not have empty scriptSigs and scriptWitnesses."); | 
| 1255 | 0 |                         } | 
| 1256 | 0 |                     } | 
| 1257 | 0 |                     break; | 
| 1258 | 0 |                 } | 
| 1259 | 0 |                 case PSBT_GLOBAL_XPUB: | 
| 1260 | 0 |                 { | 
| 1261 | 0 |                     if (key.size() != BIP32_EXTKEY_WITH_VERSION_SIZE + 1) { | 
| 1262 | 0 |                         throw std::ios_base::failure("Size of key was not the expected size for the type global xpub"); | 
| 1263 | 0 |                     } | 
| 1264 |  |                     // Read in the xpub from key | 
| 1265 | 0 |                     CExtPubKey xpub; | 
| 1266 | 0 |                     xpub.DecodeWithVersion(&key.data()[1]); | 
| 1267 | 0 |                     if (!xpub.pubkey.IsFullyValid()) { | 
| 1268 | 0 |                        throw std::ios_base::failure("Invalid pubkey"); | 
| 1269 | 0 |                     } | 
| 1270 | 0 |                     if (global_xpubs.count(xpub) > 0) { | 
| 1271 | 0 |                        throw std::ios_base::failure("Duplicate key, global xpub already provided"); | 
| 1272 | 0 |                     } | 
| 1273 | 0 |                     global_xpubs.insert(xpub); | 
| 1274 |  |                     // Read in the keypath from stream | 
| 1275 | 0 |                     KeyOriginInfo keypath; | 
| 1276 | 0 |                     DeserializeHDKeypath(s, keypath); | 
| 1277 |  |  | 
| 1278 |  |                     // Note that we store these swapped to make searches faster. | 
| 1279 |  |                     // Serialization uses xpub -> keypath to enqure key uniqueness | 
| 1280 | 0 |                     if (m_xpubs.count(keypath) == 0) { | 
| 1281 |  |                         // Make a new set to put the xpub in | 
| 1282 | 0 |                         m_xpubs[keypath] = {xpub}; | 
| 1283 | 0 |                     } else { | 
| 1284 |  |                         // Insert xpub into existing set | 
| 1285 | 0 |                         m_xpubs[keypath].insert(xpub); | 
| 1286 | 0 |                     } | 
| 1287 | 0 |                     break; | 
| 1288 | 0 |                 } | 
| 1289 | 0 |                 case PSBT_GLOBAL_VERSION: | 
| 1290 | 0 |                 { | 
| 1291 | 0 |                     if (m_version) { | 
| 1292 | 0 |                         throw std::ios_base::failure("Duplicate Key, version already provided"); | 
| 1293 | 0 |                     } else if (key.size() != 1) { | 
| 1294 | 0 |                         throw std::ios_base::failure("Global version key is more than one byte type"); | 
| 1295 | 0 |                     } | 
| 1296 | 0 |                     uint32_t v; | 
| 1297 | 0 |                     UnserializeFromVector(s, v); | 
| 1298 | 0 |                     m_version = v; | 
| 1299 | 0 |                     if (*m_version > PSBT_HIGHEST_VERSION) { | 
| 1300 | 0 |                         throw std::ios_base::failure("Unsupported version number"); | 
| 1301 | 0 |                     } | 
| 1302 | 0 |                     break; | 
| 1303 | 0 |                 } | 
| 1304 | 0 |                 case PSBT_GLOBAL_PROPRIETARY: | 
| 1305 | 0 |                 { | 
| 1306 | 0 |                     PSBTProprietary this_prop; | 
| 1307 | 0 |                     skey >> this_prop.identifier; | 
| 1308 | 0 |                     this_prop.subtype = ReadCompactSize(skey); | 
| 1309 | 0 |                     this_prop.key = key; | 
| 1310 |  | 
 | 
| 1311 | 0 |                     if (m_proprietary.count(this_prop) > 0) { | 
| 1312 | 0 |                         throw std::ios_base::failure("Duplicate Key, proprietary key already found"); | 
| 1313 | 0 |                     } | 
| 1314 | 0 |                     s >> this_prop.value; | 
| 1315 | 0 |                     m_proprietary.insert(this_prop); | 
| 1316 | 0 |                     break; | 
| 1317 | 0 |                 } | 
| 1318 |  |                 // Unknown stuff | 
| 1319 | 0 |                 default: { | 
| 1320 | 0 |                     if (unknown.count(key) > 0) { | 
| 1321 | 0 |                         throw std::ios_base::failure("Duplicate Key, key for unknown value already provided"); | 
| 1322 | 0 |                     } | 
| 1323 |  |                     // Read in the value | 
| 1324 | 0 |                     std::vector<unsigned char> val_bytes; | 
| 1325 | 0 |                     s >> val_bytes; | 
| 1326 | 0 |                     unknown.emplace(std::move(key), std::move(val_bytes)); | 
| 1327 | 0 |                 } | 
| 1328 | 0 |             } | 
| 1329 | 0 |         } | 
| 1330 |  |  | 
| 1331 | 0 |         if (!found_sep) { | 
| 1332 | 0 |             throw std::ios_base::failure("Separator is missing at the end of the global map"); | 
| 1333 | 0 |         } | 
| 1334 |  |  | 
| 1335 |  |         // Make sure that we got an unsigned tx | 
| 1336 | 0 |         if (!tx) { | 
| 1337 | 0 |             throw std::ios_base::failure("No unsigned transaction was provided"); | 
| 1338 | 0 |         } | 
| 1339 |  |  | 
| 1340 |  |         // Read input data | 
| 1341 | 0 |         unsigned int i = 0; | 
| 1342 | 0 |         while (!s.empty() && i < tx->vin.size()) { | 
| 1343 | 0 |             PSBTInput input; | 
| 1344 | 0 |             s >> input; | 
| 1345 | 0 |             inputs.push_back(input); | 
| 1346 |  |  | 
| 1347 |  |             // Make sure the non-witness utxo matches the outpoint | 
| 1348 | 0 |             if (input.non_witness_utxo) { | 
| 1349 | 0 |                 if (input.non_witness_utxo->GetHash() != tx->vin[i].prevout.hash) { | 
| 1350 | 0 |                     throw std::ios_base::failure("Non-witness UTXO does not match outpoint hash"); | 
| 1351 | 0 |                 } | 
| 1352 | 0 |                 if (tx->vin[i].prevout.n >= input.non_witness_utxo->vout.size()) { | 
| 1353 | 0 |                     throw std::ios_base::failure("Input specifies output index that does not exist"); | 
| 1354 | 0 |                 } | 
| 1355 | 0 |             } | 
| 1356 | 0 |             ++i; | 
| 1357 | 0 |         } | 
| 1358 |  |         // Make sure that the number of inputs matches the number of inputs in the transaction | 
| 1359 | 0 |         if (inputs.size() != tx->vin.size()) { | 
| 1360 | 0 |             throw std::ios_base::failure("Inputs provided does not match the number of inputs in transaction."); | 
| 1361 | 0 |         } | 
| 1362 |  |  | 
| 1363 |  |         // Read output data | 
| 1364 | 0 |         i = 0; | 
| 1365 | 0 |         while (!s.empty() && i < tx->vout.size()) { | 
| 1366 | 0 |             PSBTOutput output; | 
| 1367 | 0 |             s >> output; | 
| 1368 | 0 |             outputs.push_back(output); | 
| 1369 | 0 |             ++i; | 
| 1370 | 0 |         } | 
| 1371 |  |         // Make sure that the number of outputs matches the number of outputs in the transaction | 
| 1372 | 0 |         if (outputs.size() != tx->vout.size()) { | 
| 1373 | 0 |             throw std::ios_base::failure("Outputs provided does not match the number of outputs in transaction."); | 
| 1374 | 0 |         } | 
| 1375 | 0 |     } | 
| 1376 |  |  | 
| 1377 |  |     template <typename Stream> | 
| 1378 |  |     PartiallySignedTransaction(deserialize_type, Stream& s) { | 
| 1379 |  |         Unserialize(s); | 
| 1380 |  |     } | 
| 1381 |  | }; | 
| 1382 |  |  | 
| 1383 |  | enum class PSBTRole { | 
| 1384 |  |     CREATOR, | 
| 1385 |  |     UPDATER, | 
| 1386 |  |     SIGNER, | 
| 1387 |  |     FINALIZER, | 
| 1388 |  |     EXTRACTOR | 
| 1389 |  | }; | 
| 1390 |  |  | 
| 1391 |  | std::string PSBTRoleName(PSBTRole role); | 
| 1392 |  |  | 
| 1393 |  | /** Compute a PrecomputedTransactionData object from a psbt. */ | 
| 1394 |  | PrecomputedTransactionData PrecomputePSBTData(const PartiallySignedTransaction& psbt); | 
| 1395 |  |  | 
| 1396 |  | /** Checks whether a PSBTInput is already signed by checking for non-null finalized fields. */ | 
| 1397 |  | bool PSBTInputSigned(const PSBTInput& input); | 
| 1398 |  |  | 
| 1399 |  | /** Checks whether a PSBTInput is already signed by doing script verification using final fields. */ | 
| 1400 |  | bool PSBTInputSignedAndVerified(const PartiallySignedTransaction psbt, unsigned int input_index, const PrecomputedTransactionData* txdata); | 
| 1401 |  |  | 
| 1402 |  | /** Signs a PSBTInput, verifying that all provided data matches what is being signed. | 
| 1403 |  |  * | 
| 1404 |  |  * txdata should be the output of PrecomputePSBTData (which can be shared across | 
| 1405 |  |  * multiple SignPSBTInput calls). If it is nullptr, a dummy signature will be created. | 
| 1406 |  |  **/ | 
| 1407 |  | [[nodiscard]] PSBTError SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, const PrecomputedTransactionData* txdata, std::optional<int> sighash = std::nullopt, SignatureData* out_sigdata = nullptr, bool finalize = true); | 
| 1408 |  |  | 
| 1409 |  | /**  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. */ | 
| 1410 |  | void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx); | 
| 1411 |  |  | 
| 1412 |  | /** Counts the unsigned inputs of a PSBT. */ | 
| 1413 |  | size_t CountPSBTUnsignedInputs(const PartiallySignedTransaction& psbt); | 
| 1414 |  |  | 
| 1415 |  | /** Updates a PSBTOutput with information from provider. | 
| 1416 |  |  * | 
| 1417 |  |  * This fills in the redeem_script, witness_script, and hd_keypaths where possible. | 
| 1418 |  |  */ | 
| 1419 |  | void UpdatePSBTOutput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index); | 
| 1420 |  |  | 
| 1421 |  | /** | 
| 1422 |  |  * Finalizes a PSBT if possible, combining partial signatures. | 
| 1423 |  |  * | 
| 1424 |  |  * @param[in,out] psbtx PartiallySignedTransaction to finalize | 
| 1425 |  |  * return True if the PSBT is now complete, false otherwise | 
| 1426 |  |  */ | 
| 1427 |  | bool FinalizePSBT(PartiallySignedTransaction& psbtx); | 
| 1428 |  |  | 
| 1429 |  | /** | 
| 1430 |  |  * Finalizes a PSBT if possible, and extracts it to a CMutableTransaction if it could be finalized. | 
| 1431 |  |  * | 
| 1432 |  |  * @param[in]  psbtx PartiallySignedTransaction | 
| 1433 |  |  * @param[out] result CMutableTransaction representing the complete transaction, if successful | 
| 1434 |  |  * @return True if we successfully extracted the transaction, false otherwise | 
| 1435 |  |  */ | 
| 1436 |  | bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransaction& result); | 
| 1437 |  |  | 
| 1438 |  | /** | 
| 1439 |  |  * Combines PSBTs with the same underlying transaction, resulting in a single PSBT with all partial signatures from each input. | 
| 1440 |  |  * | 
| 1441 |  |  * @param[out] out   the combined PSBT, if successful | 
| 1442 |  |  * @param[in]  psbtxs the PSBTs to combine | 
| 1443 |  |  * @return True if we successfully combined the transactions, false if they were not compatible | 
| 1444 |  |  */ | 
| 1445 |  | [[nodiscard]] bool CombinePSBTs(PartiallySignedTransaction& out, const std::vector<PartiallySignedTransaction>& psbtxs); | 
| 1446 |  |  | 
| 1447 |  | //! Decode a base64ed PSBT into a PartiallySignedTransaction | 
| 1448 |  | [[nodiscard]] bool DecodeBase64PSBT(PartiallySignedTransaction& decoded_psbt, const std::string& base64_psbt, std::string& error); | 
| 1449 |  | //! Decode a raw (binary blob) PSBT into a PartiallySignedTransaction | 
| 1450 |  | [[nodiscard]] bool DecodeRawPSBT(PartiallySignedTransaction& decoded_psbt, std::span<const std::byte> raw_psbt, std::string& error); | 
| 1451 |  |  | 
| 1452 |  | #endif // BITCOIN_PSBT_H |