fuzz coverage

Coverage Report

Created: 2025-06-01 19:34

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