Branch data Line data Source code
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 : : #include <psbt.h>
6 : :
7 : : #include <common/types.h>
8 : : #include <node/types.h>
9 : : #include <policy/policy.h>
10 : : #include <primitives/transaction.h>
11 : : #include <script/signingprovider.h>
12 : : #include <util/check.h>
13 : : #include <util/result.h>
14 : : #include <util/strencodings.h>
15 : :
16 : : #include <algorithm>
17 : :
18 : : using common::PSBTError;
19 : :
20 [ + - ]: 16 : PartiallySignedTransaction::PartiallySignedTransaction(const CMutableTransaction& tx, uint32_t version) : m_version(version)
21 : : {
22 [ + - - + ]: 16 : assert(m_version == 0 || m_version == 2);
23 : :
24 : 16 : tx_version = tx.version;
25 [ - + ]: 16 : fallback_locktime = tx.nLockTime;
26 [ - + + - ]: 16 : inputs.reserve(tx.vin.size());
27 [ + + ]: 24 : for (const CTxIn& input : tx.vin) {
28 [ + - + - ]: 8 : inputs.emplace_back(GetVersion(), input.prevout.hash, input.prevout.n, input.nSequence);
29 : : }
30 [ - + + - ]: 16 : outputs.reserve(tx.vout.size());
31 [ + + ]: 30 : for (const CTxOut& output : tx.vout) {
32 [ + - + - ]: 14 : outputs.emplace_back(GetVersion(), output.nValue, output.scriptPubKey);
33 : : }
34 : 16 : }
35 : :
36 : 1 : bool PartiallySignedTransaction::Merge(const PartiallySignedTransaction& psbt)
37 : : {
38 : : // Prohibited to merge two PSBTs over different transactions
39 : 1 : std::optional<Txid> this_id = GetUniqueID();
40 : 1 : std::optional<Txid> psbt_id = psbt.GetUniqueID();
41 [ + - + - : 1 : if (!this_id || !psbt_id || this_id != psbt_id) {
+ - ]
42 : : return false;
43 : : }
44 [ + - ]: 1 : if (GetVersion() != psbt.GetVersion()) {
45 : : return false;
46 : : }
47 : :
48 [ - + + + ]: 2 : for (unsigned int i = 0; i < inputs.size(); ++i) {
49 [ + - ]: 1 : if (!inputs[i].Merge(psbt.inputs[i])) {
50 : : return false;
51 : : }
52 : : }
53 [ - + + + ]: 2 : for (unsigned int i = 0; i < outputs.size(); ++i) {
54 [ + - ]: 1 : if (!outputs[i].Merge(psbt.outputs[i])) {
55 : : return false;
56 : : }
57 : : }
58 : 1 : MergeGlobalXPubs(psbt);
59 [ - + - - ]: 1 : if (fallback_locktime == std::nullopt && psbt.fallback_locktime != std::nullopt) fallback_locktime = psbt.fallback_locktime;
60 : :
61 : : // Set m_tx_modifiable only if either PSBT had it set
62 [ + - - + ]: 1 : if (m_tx_modifiable.has_value() || psbt.m_tx_modifiable.has_value()) {
63 : : // In general, we AND the modifiable flags
64 [ # # ]: 0 : std::bitset<8> this_modifiable = m_tx_modifiable.value_or(0);
65 [ # # ]: 0 : std::bitset<8> psbt_modifiable = psbt.m_tx_modifiable.value_or(0);
66 [ # # ]: 0 : std::bitset<8> final_modifiable = this_modifiable & psbt_modifiable;
67 : : // SIGHASH_SINGLE Modifiable (bit 2) needs to be bitwise OR'd
68 [ # # # # : 0 : final_modifiable.set(2, this_modifiable[2] || psbt_modifiable[2]);
# # ]
69 : :
70 [ # # ]: 0 : m_tx_modifiable = final_modifiable;
71 : : }
72 : :
73 : 1 : m_proprietary.insert(psbt.m_proprietary.begin(), psbt.m_proprietary.end());
74 : 1 : unknown.insert(psbt.unknown.begin(), psbt.unknown.end());
75 : :
76 : 1 : return true;
77 : : }
78 : :
79 : 1 : void PartiallySignedTransaction::MergeGlobalXPubs(const PartiallySignedTransaction& psbt)
80 : : {
81 [ - + ]: 1 : for (const auto& [origin, xpubs] : psbt.m_xpubs) {
82 [ # # ]: 0 : for (const CExtPubKey& xpub : xpubs) {
83 : 0 : const bool known{std::ranges::any_of(m_xpubs, [&](const auto& entry) { return entry.second.contains(xpub); })};
84 [ # # ]: 0 : if (!known) m_xpubs[origin].insert(xpub);
85 : : }
86 : : }
87 : 1 : }
88 : :
89 : 57 : std::optional<uint32_t> PartiallySignedTransaction::ComputeTimeLock() const
90 : : {
91 [ + + ]: 57 : if (GetVersion() >= 2) {
92 : 38 : std::optional<uint32_t> time_lock{0};
93 : 38 : std::optional<uint32_t> height_lock{0};
94 [ + + ]: 96 : for (const PSBTInput& input : inputs) {
95 [ + + + + ]: 60 : if (input.time_locktime.has_value() && !input.height_locktime.has_value()) {
96 [ + - ]: 10 : height_lock.reset(); // Transaction can no longer have a height locktime
97 [ + + ]: 10 : if (!time_lock.has_value()) {
98 : 2 : return std::nullopt;
99 : : }
100 [ + + + + ]: 50 : } else if (!input.time_locktime.has_value() && input.height_locktime.has_value()) {
101 [ + + ]: 10 : time_lock.reset(); // Transaction can no longer have a time locktime
102 [ - + ]: 10 : if (!height_lock.has_value()) {
103 : 0 : return std::nullopt;
104 : : }
105 : : }
106 [ + + + + ]: 58 : if (input.time_locktime && time_lock.has_value()) {
107 : 19 : time_lock = std::max(time_lock, input.time_locktime);
108 : : }
109 [ + + + + ]: 58 : if (input.height_locktime && height_lock.has_value()) {
110 : 21 : height_lock = std::max(height_lock, input.height_locktime);
111 : : }
112 : : }
113 [ + + + + ]: 36 : if (height_lock.has_value() && *height_lock > 0) {
114 : 9 : return *height_lock;
115 : : }
116 [ + - + + ]: 27 : if (time_lock.has_value() && *time_lock > 0) {
117 : 8 : return *time_lock;
118 : : }
119 : : }
120 [ + + ]: 74 : return fallback_locktime.value_or(0);
121 : : }
122 : :
123 : 43 : std::optional<CMutableTransaction> PartiallySignedTransaction::GetUnsignedTx() const
124 : : {
125 : 43 : CMutableTransaction mtx;
126 : 43 : mtx.version = tx_version;
127 [ + - ]: 43 : std::optional<uint32_t> locktime = ComputeTimeLock();
128 [ + + ]: 43 : if (!locktime) {
129 : 1 : return std::nullopt;
130 : : }
131 : 42 : mtx.nLockTime = *locktime;
132 : 42 : uint32_t max_sequence = CTxIn::SEQUENCE_FINAL;
133 [ + + ]: 105 : for (const PSBTInput& input : inputs) {
134 : 63 : CTxIn txin;
135 : 63 : txin.prevout.hash = input.prev_txid;
136 : 63 : txin.prevout.n = input.prev_out;
137 [ + + ]: 63 : txin.nSequence = input.sequence.value_or(max_sequence);
138 [ + - ]: 63 : mtx.vin.push_back(txin);
139 : 63 : }
140 [ + + ]: 104 : for (const PSBTOutput& output : outputs) {
141 : 62 : CTxOut txout;
142 : 62 : txout.nValue = output.amount;
143 : 62 : txout.scriptPubKey = output.script;
144 [ + - ]: 62 : mtx.vout.push_back(txout);
145 : 62 : }
146 : 42 : return mtx;
147 : 43 : }
148 : :
149 : 2 : std::optional<Txid> PartiallySignedTransaction::GetUniqueID() const
150 : : {
151 : : // Get the unsigned transaction
152 : 2 : std::optional<CMutableTransaction> mtx = GetUnsignedTx();
153 [ - + ]: 2 : if (!mtx) {
154 : 0 : return std::nullopt;
155 : : }
156 [ + - + - ]: 2 : if (GetVersion() >= 2) {
157 [ + + ]: 4 : for (CTxIn& txin : mtx->vin) {
158 : 2 : txin.nSequence = 0;
159 : : }
160 : : }
161 [ + - ]: 2 : return mtx->GetHash();
162 : 2 : }
163 : :
164 : 15 : bool PartiallySignedTransaction::AddInput(const PSBTInput& psbtin)
165 : : {
166 : : // The input being added must be for this PSBT's version
167 [ + + ]: 15 : if (psbtin.GetVersion() != GetVersion()) {
168 : : return false;
169 : : }
170 : :
171 : : // Prevent duplicate inputs
172 [ + - ]: 14 : if (std::find_if(inputs.begin(), inputs.end(),
173 [ + - + + ]: 84 : [psbtin](const PSBTInput& psbt) {
174 [ + + - + ]: 47 : return psbt.prev_txid == psbtin.prev_txid && psbt.prev_out == psbtin.prev_out;
175 : : }
176 : 28 : ) != inputs.end()) {
177 : : return false;
178 : : }
179 : :
180 [ - + ]: 8 : if (GetVersion() < 2) {
181 : : // This is a v0 psbt, so do the v0 AddInput
182 : 0 : inputs.push_back(psbtin);
183 : 0 : inputs.back().partial_sigs.clear();
184 : 0 : inputs.back().final_script_sig.clear();
185 : 0 : inputs.back().final_script_witness.SetNull();
186 : 0 : return true;
187 : : }
188 : :
189 : : // Check inputs modifiable flag
190 [ + - + + ]: 8 : if (!m_tx_modifiable.has_value() || !m_tx_modifiable->test(0)) {
191 : : return false;
192 : : }
193 : :
194 : : // Determine if we need to iterate the inputs.
195 : : // For now, we only do this if the new input has a required time lock.
196 : : // BIP 370 states that we should also do this if m_tx_modifiable's bit 2 is set
197 : : // (Has SIGHASH_SINGLE flag) but since we are only adding inputs at the end of the vector,
198 : : // we don't care about that.
199 [ + + + + ]: 7 : bool iterate_inputs = psbtin.time_locktime != std::nullopt || psbtin.height_locktime != std::nullopt;
200 : 4 : if (iterate_inputs) {
201 : 4 : std::optional<uint32_t> old_timelock = ComputeTimeLock();
202 [ + - ]: 4 : if (!old_timelock) {
203 : : return false;
204 : : }
205 : :
206 : 4 : std::optional<uint32_t> time_lock = psbtin.time_locktime;
207 : 4 : std::optional<uint32_t> height_lock = psbtin.height_locktime;
208 : 4 : bool has_sigs = false;
209 [ + + ]: 17 : for (const PSBTInput& input : inputs) {
210 [ + + + + ]: 14 : if (input.time_locktime.has_value() && !input.height_locktime.has_value()) {
211 [ + + ]: 2 : height_lock.reset(); // Transaction can no longer have a height locktime
212 [ + + ]: 2 : if (time_lock == std::nullopt) {
213 : : return false;
214 : : }
215 [ + + - + ]: 12 : } else if (!input.time_locktime.has_value() && input.height_locktime.has_value()) {
216 [ # # ]: 0 : time_lock.reset(); // Transaction can no longer have a time locktime
217 [ # # ]: 0 : if (height_lock == std::nullopt) {
218 : : return false;
219 : : }
220 : : }
221 [ + + + + ]: 13 : if (input.time_locktime && time_lock.has_value()) {
222 : 3 : time_lock = std::max(time_lock, input.time_locktime);
223 : : }
224 [ + + + + ]: 13 : if (input.height_locktime && height_lock.has_value()) {
225 : 1 : height_lock = std::max(height_lock, input.height_locktime);
226 : : }
227 [ + + ]: 13 : if (input.HasSignatures()) {
228 : 1 : has_sigs = true;
229 : : }
230 : : }
231 [ + - ]: 3 : uint32_t new_timelock = fallback_locktime.value_or(0);
232 [ + + - + ]: 3 : if (height_lock.has_value() && *height_lock > 0) {
233 : : new_timelock = *height_lock;
234 [ + - - + ]: 2 : } else if (time_lock.has_value() && *time_lock > 0) {
235 : : new_timelock = *time_lock;
236 : : }
237 [ + + - + ]: 3 : if (has_sigs && *old_timelock != new_timelock) {
238 : : return false;
239 : : }
240 : : }
241 : :
242 : : // Add the input to the end
243 : 5 : inputs.push_back(psbtin);
244 : 5 : return true;
245 : : }
246 : :
247 : 4 : bool PartiallySignedTransaction::AddOutput(const PSBTOutput& psbtout)
248 : : {
249 : : // The output being added must be for this PSBT's version
250 [ + + ]: 4 : if (psbtout.GetVersion() != GetVersion()) {
251 : : return false;
252 : : }
253 : :
254 [ - + ]: 3 : if (GetVersion() < 2) {
255 : : // This is a v0 psbt, do the v0 AddOutput
256 : 0 : outputs.push_back(psbtout);
257 : 0 : return true;
258 : : }
259 : :
260 : : // No global tx, must be PSBTv2
261 : : // Check outputs are modifiable
262 [ + - + + ]: 3 : if (!m_tx_modifiable.has_value() || !m_tx_modifiable->test(1)) {
263 : : return false;
264 : : }
265 : 2 : outputs.push_back(psbtout);
266 : :
267 : 2 : return true;
268 : : }
269 : :
270 : 4 : bool PSBTInput::GetUTXO(CTxOut& utxo) const
271 : : {
272 [ + - ]: 4 : if (non_witness_utxo) {
273 [ - + + + ]: 4 : if (prev_out >= non_witness_utxo->vout.size()) {
274 : : return false;
275 : : }
276 [ + - ]: 3 : if (non_witness_utxo->GetHash() != prev_txid) {
277 : : return false;
278 : : }
279 : 3 : utxo = non_witness_utxo->vout[prev_out];
280 [ # # ]: 0 : } else if (!witness_utxo.IsNull()) {
281 : 0 : utxo = witness_utxo;
282 : : } else {
283 : : return false;
284 : : }
285 : : return true;
286 : : }
287 : :
288 : 14 : COutPoint PSBTInput::GetOutPoint() const
289 : : {
290 : 14 : return COutPoint(prev_txid, prev_out);
291 : : }
292 : :
293 : 6 : void PSBTInput::FillSignatureData(SignatureData& sigdata) const
294 : : {
295 [ - + - + ]: 6 : if (!final_script_sig.empty()) {
296 : 0 : sigdata.scriptSig = final_script_sig;
297 : 0 : sigdata.complete = true;
298 : : }
299 [ - + ]: 6 : if (!final_script_witness.IsNull()) {
300 : 0 : sigdata.scriptWitness = final_script_witness;
301 : 0 : sigdata.complete = true;
302 : : }
303 [ + - ]: 6 : if (sigdata.complete) {
304 : : return;
305 : : }
306 : :
307 : 6 : sigdata.signatures.insert(partial_sigs.begin(), partial_sigs.end());
308 [ + + + + ]: 7 : if (!redeem_script.empty()) {
309 : 1 : sigdata.redeem_script = redeem_script;
310 : : }
311 [ - + - + ]: 6 : if (!witness_script.empty()) {
312 : 0 : sigdata.witness_script = witness_script;
313 : : }
314 [ + + ]: 8 : for (const auto& key_pair : hd_keypaths) {
315 : 2 : sigdata.misc_pubkeys.emplace(key_pair.first.GetID(), key_pair);
316 : : }
317 [ - + ]: 6 : if (!m_tap_key_sig.empty()) {
318 : 0 : sigdata.taproot_key_path_sig = m_tap_key_sig;
319 : : }
320 [ - + ]: 6 : for (const auto& [pubkey_leaf, sig] : m_tap_script_sigs) {
321 : 0 : sigdata.taproot_script_sigs.emplace(pubkey_leaf, sig);
322 : : }
323 [ - + ]: 12 : if (!m_tap_internal_key.IsNull()) {
324 : 0 : sigdata.tr_spenddata.internal_key = m_tap_internal_key;
325 : : }
326 [ - + ]: 12 : if (!m_tap_merkle_root.IsNull()) {
327 : 0 : sigdata.tr_spenddata.merkle_root = m_tap_merkle_root;
328 : : }
329 [ - + ]: 6 : for (const auto& [leaf_script, control_block] : m_tap_scripts) {
330 : 0 : sigdata.tr_spenddata.scripts.emplace(leaf_script, control_block);
331 : : }
332 [ - + ]: 6 : for (const auto& [pubkey, leaf_origin] : m_tap_bip32_paths) {
333 : 0 : sigdata.taproot_misc_pubkeys.emplace(pubkey, leaf_origin);
334 : 0 : sigdata.tap_pubkeys.emplace(Hash160(pubkey), pubkey);
335 : : }
336 [ - + ]: 6 : for (const auto& [hash, preimage] : ripemd160_preimages) {
337 [ # # ]: 0 : sigdata.ripemd160_preimages.emplace(std::vector<unsigned char>(hash.begin(), hash.end()), preimage);
338 : : }
339 [ - + ]: 6 : for (const auto& [hash, preimage] : sha256_preimages) {
340 [ # # ]: 0 : sigdata.sha256_preimages.emplace(std::vector<unsigned char>(hash.begin(), hash.end()), preimage);
341 : : }
342 [ - + ]: 6 : for (const auto& [hash, preimage] : hash160_preimages) {
343 [ # # ]: 0 : sigdata.hash160_preimages.emplace(std::vector<unsigned char>(hash.begin(), hash.end()), preimage);
344 : : }
345 [ - + ]: 6 : for (const auto& [hash, preimage] : hash256_preimages) {
346 [ # # ]: 0 : sigdata.hash256_preimages.emplace(std::vector<unsigned char>(hash.begin(), hash.end()), preimage);
347 : : }
348 : 6 : sigdata.musig2_pubkeys.insert(m_musig2_participants.begin(), m_musig2_participants.end());
349 [ - + ]: 6 : for (const auto& [agg_key_lh, pubnonces] : m_musig2_pubnonces) {
350 : 0 : sigdata.musig2_pubnonces[agg_key_lh].insert(pubnonces.begin(), pubnonces.end());
351 : : }
352 [ - + ]: 6 : for (const auto& [agg_key_lh, psigs] : m_musig2_partial_sigs) {
353 : 0 : sigdata.musig2_partial_sigs[agg_key_lh].insert(psigs.begin(), psigs.end());
354 : : }
355 : : }
356 : :
357 : 6 : void PSBTInput::FromSignatureData(const SignatureData& sigdata)
358 : : {
359 [ - + ]: 6 : if (sigdata.complete) {
360 : 0 : partial_sigs.clear();
361 : 0 : hd_keypaths.clear();
362 : 0 : redeem_script.clear();
363 : 0 : witness_script.clear();
364 : :
365 [ # # # # ]: 0 : if (!sigdata.scriptSig.empty()) {
366 : 0 : final_script_sig = sigdata.scriptSig;
367 : : }
368 [ # # ]: 0 : if (!sigdata.scriptWitness.IsNull()) {
369 : 0 : final_script_witness = sigdata.scriptWitness;
370 : : }
371 : 0 : return;
372 : : }
373 : :
374 : 6 : partial_sigs.insert(sigdata.signatures.begin(), sigdata.signatures.end());
375 [ + + + + : 8 : if (redeem_script.empty() && !sigdata.redeem_script.empty()) {
+ + + + ]
376 : 2 : redeem_script = sigdata.redeem_script;
377 : : }
378 [ - + + - : 7 : if (witness_script.empty() && !sigdata.witness_script.empty()) {
+ + + + ]
379 : 1 : witness_script = sigdata.witness_script;
380 : : }
381 [ + + ]: 12 : for (const auto& entry : sigdata.misc_pubkeys) {
382 : 6 : hd_keypaths.emplace(entry.second);
383 : : }
384 [ - + ]: 6 : if (!sigdata.taproot_key_path_sig.empty()) {
385 : 0 : m_tap_key_sig = sigdata.taproot_key_path_sig;
386 : : }
387 [ - + ]: 6 : for (const auto& [pubkey_leaf, sig] : sigdata.taproot_script_sigs) {
388 : 0 : m_tap_script_sigs.emplace(pubkey_leaf, sig);
389 : : }
390 [ - + ]: 12 : if (!sigdata.tr_spenddata.internal_key.IsNull()) {
391 : 0 : m_tap_internal_key = sigdata.tr_spenddata.internal_key;
392 : : }
393 [ - + ]: 12 : if (!sigdata.tr_spenddata.merkle_root.IsNull()) {
394 : 0 : m_tap_merkle_root = sigdata.tr_spenddata.merkle_root;
395 : : }
396 [ - + ]: 6 : for (const auto& [leaf_script, control_block] : sigdata.tr_spenddata.scripts) {
397 : 0 : m_tap_scripts.emplace(leaf_script, control_block);
398 : : }
399 [ - + ]: 6 : for (const auto& [pubkey, leaf_origin] : sigdata.taproot_misc_pubkeys) {
400 : 0 : m_tap_bip32_paths.emplace(pubkey, leaf_origin);
401 : : }
402 : 6 : m_musig2_participants.insert(sigdata.musig2_pubkeys.begin(), sigdata.musig2_pubkeys.end());
403 [ - + ]: 6 : for (const auto& [agg_key_lh, pubnonces] : sigdata.musig2_pubnonces) {
404 : 0 : m_musig2_pubnonces[agg_key_lh].insert(pubnonces.begin(), pubnonces.end());
405 : : }
406 [ - + ]: 6 : for (const auto& [agg_key_lh, psigs] : sigdata.musig2_partial_sigs) {
407 : 0 : m_musig2_partial_sigs[agg_key_lh].insert(psigs.begin(), psigs.end());
408 : : }
409 [ - + ]: 6 : for (const auto& [hash, preimage] : sigdata.ripemd160_preimages) {
410 : 0 : ripemd160_preimages.emplace(std::vector<unsigned char>(hash.begin(), hash.end()), preimage);
411 : : }
412 [ - + ]: 6 : for (const auto& [hash, preimage] : sigdata.sha256_preimages) {
413 : 0 : sha256_preimages.emplace(std::vector<unsigned char>(hash.begin(), hash.end()), preimage);
414 : : }
415 [ - + ]: 6 : for (const auto& [hash, preimage] : sigdata.hash160_preimages) {
416 : 0 : hash160_preimages.emplace(std::vector<unsigned char>(hash.begin(), hash.end()), preimage);
417 : : }
418 [ - + ]: 6 : for (const auto& [hash, preimage] : sigdata.hash256_preimages) {
419 : 0 : hash256_preimages.emplace(std::vector<unsigned char>(hash.begin(), hash.end()), preimage);
420 : : }
421 : : }
422 : :
423 : 1 : bool PSBTInput::Merge(const PSBTInput& input)
424 : : {
425 [ + - - + ]: 1 : if (!non_witness_utxo && input.non_witness_utxo) non_witness_utxo = input.non_witness_utxo;
426 [ + - - + ]: 1 : if (witness_utxo.IsNull() && !input.witness_utxo.IsNull()) {
427 : 0 : witness_utxo = input.witness_utxo;
428 : : }
429 : :
430 : 1 : partial_sigs.insert(input.partial_sigs.begin(), input.partial_sigs.end());
431 : 1 : ripemd160_preimages.insert(input.ripemd160_preimages.begin(), input.ripemd160_preimages.end());
432 : 1 : sha256_preimages.insert(input.sha256_preimages.begin(), input.sha256_preimages.end());
433 : 1 : hash160_preimages.insert(input.hash160_preimages.begin(), input.hash160_preimages.end());
434 : 1 : hash256_preimages.insert(input.hash256_preimages.begin(), input.hash256_preimages.end());
435 : 1 : hd_keypaths.insert(input.hd_keypaths.begin(), input.hd_keypaths.end());
436 : 1 : m_proprietary.insert(input.m_proprietary.begin(), input.m_proprietary.end());
437 : 1 : unknown.insert(input.unknown.begin(), input.unknown.end());
438 : 1 : m_tap_script_sigs.insert(input.m_tap_script_sigs.begin(), input.m_tap_script_sigs.end());
439 : 1 : m_tap_scripts.insert(input.m_tap_scripts.begin(), input.m_tap_scripts.end());
440 : 1 : m_tap_bip32_paths.insert(input.m_tap_bip32_paths.begin(), input.m_tap_bip32_paths.end());
441 : :
442 [ - + + - : 1 : if (redeem_script.empty() && !input.redeem_script.empty()) redeem_script = input.redeem_script;
- + - + ]
443 [ - + + - : 1 : if (witness_script.empty() && !input.witness_script.empty()) witness_script = input.witness_script;
- + - + ]
444 [ - + + - : 1 : if (final_script_sig.empty() && !input.final_script_sig.empty()) final_script_sig = input.final_script_sig;
- + - + ]
445 [ + - - + ]: 1 : if (final_script_witness.IsNull() && !input.final_script_witness.IsNull()) final_script_witness = input.final_script_witness;
446 [ + - - + ]: 1 : if (m_tap_key_sig.empty() && !input.m_tap_key_sig.empty()) m_tap_key_sig = input.m_tap_key_sig;
447 [ + - - + ]: 3 : if (m_tap_internal_key.IsNull() && !input.m_tap_internal_key.IsNull()) m_tap_internal_key = input.m_tap_internal_key;
448 [ + - - + ]: 3 : if (m_tap_merkle_root.IsNull() && !input.m_tap_merkle_root.IsNull()) m_tap_merkle_root = input.m_tap_merkle_root;
449 : 1 : m_musig2_participants.insert(input.m_musig2_participants.begin(), input.m_musig2_participants.end());
450 [ - + ]: 1 : for (const auto& [agg_key_lh, pubnonces] : input.m_musig2_pubnonces) {
451 : 0 : m_musig2_pubnonces[agg_key_lh].insert(pubnonces.begin(), pubnonces.end());
452 : : }
453 [ - + ]: 1 : for (const auto& [agg_key_lh, psigs] : input.m_musig2_partial_sigs) {
454 : 0 : m_musig2_partial_sigs[agg_key_lh].insert(psigs.begin(), psigs.end());
455 : : }
456 [ - + - - ]: 1 : if (sequence == std::nullopt && input.sequence != std::nullopt) sequence = input.sequence;
457 [ + - - + ]: 1 : if (time_locktime == std::nullopt && input.time_locktime != std::nullopt) time_locktime = input.time_locktime;
458 [ + - - + ]: 1 : if (height_locktime == std::nullopt && input.height_locktime != std::nullopt) height_locktime = input.height_locktime;
459 : :
460 : 1 : return true;
461 : : }
462 : :
463 : 13 : bool PSBTInput::HasSignatures() const
464 : : {
465 [ - + ]: 13 : return !final_script_sig.empty()
466 [ + - ]: 12 : || !final_script_witness.IsNull()
467 [ + - ]: 12 : || !partial_sigs.empty()
468 [ + - ]: 12 : || !m_tap_key_sig.empty()
469 [ + - ]: 12 : || !m_tap_script_sigs.empty()
470 [ + + - + ]: 25 : || !m_musig2_partial_sigs.empty();
471 : : }
472 : :
473 : 14 : void PSBTOutput::FillSignatureData(SignatureData& sigdata) const
474 : : {
475 [ - + - + ]: 14 : if (!redeem_script.empty()) {
476 : 0 : sigdata.redeem_script = redeem_script;
477 : : }
478 [ - + - + ]: 14 : if (!witness_script.empty()) {
479 : 0 : sigdata.witness_script = witness_script;
480 : : }
481 [ - + ]: 14 : for (const auto& key_pair : hd_keypaths) {
482 : 0 : sigdata.misc_pubkeys.emplace(key_pair.first.GetID(), key_pair);
483 : : }
484 [ - + - - ]: 14 : if (!m_tap_tree.empty() && m_tap_internal_key.IsFullyValid()) {
485 : 0 : TaprootBuilder builder;
486 [ # # # # ]: 0 : for (const auto& [depth, leaf_ver, script] : m_tap_tree) {
487 [ # # # # ]: 0 : builder.Add((int)depth, script, (int)leaf_ver, /*track=*/true);
488 : : }
489 [ # # ]: 0 : assert(builder.IsComplete());
490 [ # # ]: 0 : builder.Finalize(m_tap_internal_key);
491 [ # # ]: 0 : TaprootSpendData spenddata = builder.GetSpendData();
492 : :
493 : 0 : sigdata.tr_spenddata.internal_key = m_tap_internal_key;
494 [ # # # # ]: 0 : sigdata.tr_spenddata.Merge(spenddata);
495 [ # # ]: 0 : sigdata.tr_builder = builder;
496 : 0 : }
497 [ - + ]: 14 : for (const auto& [pubkey, leaf_origin] : m_tap_bip32_paths) {
498 : 0 : sigdata.taproot_misc_pubkeys.emplace(pubkey, leaf_origin);
499 : 0 : sigdata.tap_pubkeys.emplace(Hash160(pubkey), pubkey);
500 : : }
501 : 14 : sigdata.musig2_pubkeys.insert(m_musig2_participants.begin(), m_musig2_participants.end());
502 : 14 : }
503 : :
504 : 14 : void PSBTOutput::FromSignatureData(const SignatureData& sigdata)
505 : : {
506 [ - + + - : 14 : if (redeem_script.empty() && !sigdata.redeem_script.empty()) {
- + + + ]
507 : 2 : redeem_script = sigdata.redeem_script;
508 : : }
509 [ - + + - : 16 : if (witness_script.empty() && !sigdata.witness_script.empty()) {
+ + + + ]
510 : 4 : witness_script = sigdata.witness_script;
511 : : }
512 [ + + ]: 26 : for (const auto& entry : sigdata.misc_pubkeys) {
513 : 12 : hd_keypaths.emplace(entry.second);
514 : : }
515 [ - + ]: 28 : if (!sigdata.tr_spenddata.internal_key.IsNull()) {
516 : 0 : m_tap_internal_key = sigdata.tr_spenddata.internal_key;
517 : : }
518 [ - + - - ]: 14 : if (sigdata.tr_builder.has_value() && sigdata.tr_builder->HasScripts()) {
519 : 0 : m_tap_tree = sigdata.tr_builder->GetTreeTuples();
520 : : }
521 [ + + ]: 16 : for (const auto& [pubkey, leaf_origin] : sigdata.taproot_misc_pubkeys) {
522 : 2 : m_tap_bip32_paths.emplace(pubkey, leaf_origin);
523 : : }
524 : 14 : m_musig2_participants.insert(sigdata.musig2_pubkeys.begin(), sigdata.musig2_pubkeys.end());
525 : 14 : }
526 : :
527 : 1 : bool PSBTOutput::Merge(const PSBTOutput& output)
528 : : {
529 : 1 : hd_keypaths.insert(output.hd_keypaths.begin(), output.hd_keypaths.end());
530 : 1 : m_proprietary.insert(output.m_proprietary.begin(), output.m_proprietary.end());
531 : 1 : unknown.insert(output.unknown.begin(), output.unknown.end());
532 : 1 : m_tap_bip32_paths.insert(output.m_tap_bip32_paths.begin(), output.m_tap_bip32_paths.end());
533 : :
534 [ - + + - : 1 : if (redeem_script.empty() && !output.redeem_script.empty()) redeem_script = output.redeem_script;
- + - + ]
535 [ - + + - : 1 : if (witness_script.empty() && !output.witness_script.empty()) witness_script = output.witness_script;
- + - + ]
536 [ + - - + ]: 3 : if (m_tap_internal_key.IsNull() && !output.m_tap_internal_key.IsNull()) m_tap_internal_key = output.m_tap_internal_key;
537 [ + - - + ]: 1 : if (m_tap_tree.empty() && !output.m_tap_tree.empty()) m_tap_tree = output.m_tap_tree;
538 : 1 : m_musig2_participants.insert(output.m_musig2_participants.begin(), output.m_musig2_participants.end());
539 : :
540 : 1 : return true;
541 : : }
542 : :
543 : 17 : bool PSBTInputSigned(const PSBTInput& input)
544 : : {
545 [ - + + - : 17 : return !input.final_script_sig.empty() || !input.final_script_witness.IsNull();
- + ]
546 : : }
547 : :
548 : 8 : bool PSBTInputSignedAndVerified(const PartiallySignedTransaction& psbt, unsigned int input_index, const PrecomputedTransactionData* txdata)
549 : : {
550 : 8 : CTxOut utxo;
551 [ - + - + ]: 8 : assert(input_index < psbt.inputs.size());
552 [ + - ]: 8 : const PSBTInput& input = psbt.inputs[input_index];
553 : :
554 [ + - ]: 8 : if (input.non_witness_utxo) {
555 : : // If we're taking our information from a non-witness UTXO, verify that it matches the prevout.
556 [ + - ]: 8 : COutPoint prevout = input.GetOutPoint();
557 [ - + + - ]: 8 : if (prevout.n >= input.non_witness_utxo->vout.size()) {
558 : : return false;
559 : : }
560 [ + - ]: 16 : if (input.non_witness_utxo->GetHash() != prevout.hash) {
561 : : return false;
562 : : }
563 : 8 : utxo = input.non_witness_utxo->vout[prevout.n];
564 [ # # ]: 0 : } else if (!input.witness_utxo.IsNull()) {
565 : 0 : utxo = input.witness_utxo;
566 : : } else {
567 : : return false;
568 : : }
569 : :
570 [ + - ]: 8 : std::optional<CMutableTransaction> unsigned_tx = psbt.GetUnsignedTx();
571 [ + - ]: 8 : if (!unsigned_tx) {
572 : : return false;
573 : : }
574 [ + - ]: 8 : const CMutableTransaction& tx = *unsigned_tx;
575 [ + - ]: 8 : if (txdata) {
576 [ + - ]: 8 : return VerifyScript(input.final_script_sig, utxo.scriptPubKey, &input.final_script_witness, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker{&tx, input_index, utxo.nValue, *txdata, MissingDataBehavior::FAIL});
577 : : } else {
578 [ # # ]: 0 : return VerifyScript(input.final_script_sig, utxo.scriptPubKey, &input.final_script_witness, STANDARD_SCRIPT_VERIFY_FLAGS, MutableTransactionSignatureChecker{&tx, input_index, utxo.nValue, MissingDataBehavior::FAIL});
579 : : }
580 : 16 : }
581 : :
582 : 0 : size_t CountPSBTUnsignedInputs(const PartiallySignedTransaction& psbt) {
583 : 0 : size_t count = 0;
584 [ # # ]: 0 : for (const auto& input : psbt.inputs) {
585 [ # # ]: 0 : if (!PSBTInputSigned(input)) {
586 : 0 : count++;
587 : : }
588 : : }
589 : :
590 : 0 : return count;
591 : : }
592 : :
593 : 14 : void UpdatePSBTOutput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index)
594 : : {
595 : 14 : std::optional<CMutableTransaction> unsigned_tx = psbt.GetUnsignedTx();
596 [ - + ]: 14 : if (!unsigned_tx) {
597 : 0 : return;
598 : : }
599 [ + - ]: 14 : const CTxOut& out = unsigned_tx->vout.at(index);
600 [ + - ]: 14 : PSBTOutput& psbt_out = psbt.outputs.at(index);
601 : :
602 : : // Fill a SignatureData with output info
603 : 14 : SignatureData sigdata;
604 [ + - ]: 14 : psbt_out.FillSignatureData(sigdata);
605 : :
606 : : // Construct a would-be spend of this output, to update sigdata with.
607 : : // Note that ProduceSignature is used to fill in metadata (not actual signatures),
608 : : // so provider does not need to provide any private keys (it can be a HidingSigningProvider).
609 [ + - ]: 14 : CMutableTransaction tx{};
610 [ + - ]: 14 : tx.vin.emplace_back();
611 [ + - ]: 14 : MutableTransactionSignatureCreator creator(tx, /*input_idx=*/0, out.nValue, {.sighash_type = SIGHASH_ALL});
612 [ + - ]: 14 : ProduceSignature(provider, creator, out.scriptPubKey, sigdata);
613 : :
614 : : // Put redeem_script, witness_script, key paths, into PSBTOutput.
615 [ + - ]: 14 : psbt_out.FromSignatureData(sigdata);
616 [ + - ]: 42 : }
617 : :
618 : 2 : std::optional<PrecomputedTransactionData> PrecomputePSBTData(const PartiallySignedTransaction& psbt)
619 : : {
620 : 2 : std::optional<CMutableTransaction> unsigned_tx = psbt.GetUnsignedTx();
621 [ - + ]: 2 : if (!unsigned_tx) {
622 : 0 : return std::nullopt;
623 : : }
624 : 2 : const CMutableTransaction& tx = *unsigned_tx;
625 : 2 : bool have_all_spent_outputs = true;
626 : 2 : std::vector<CTxOut> utxos;
627 [ + + ]: 6 : for (const PSBTInput& input : psbt.inputs) {
628 [ + - + - : 4 : if (!input.GetUTXO(utxos.emplace_back())) have_all_spent_outputs = false;
+ + ]
629 : : }
630 : 2 : PrecomputedTransactionData txdata;
631 [ + + ]: 2 : if (have_all_spent_outputs) {
632 [ + - ]: 1 : txdata.Init(tx, std::move(utxos), true);
633 : : } else {
634 [ + - ]: 1 : txdata.Init(tx, {}, true);
635 : : }
636 : 2 : return txdata;
637 : 4 : }
638 : :
639 : 6 : util::Expected<void, PSBTError> SignPSBTInput(const SigningProvider& provider, PartiallySignedTransaction& psbt, int index, const PrecomputedTransactionData* txdata, const common::PSBTFillOptions& options, SignatureData* out_sigdata)
640 : : {
641 : 6 : PSBTInput& input = psbt.inputs.at(index);
642 : 6 : std::optional<CMutableTransaction> unsigned_tx = psbt.GetUnsignedTx();
643 [ - + ]: 6 : if (!unsigned_tx) {
644 : 0 : return util::Unexpected{PSBTError::INVALID_TX};
645 : : }
646 [ + - ]: 6 : const CMutableTransaction& tx = *unsigned_tx;
647 : :
648 [ + - - + ]: 6 : if (PSBTInputSignedAndVerified(psbt, index, txdata)) {
649 : 0 : return {};
650 : : }
651 : :
652 : : // Fill SignatureData with input info
653 : 6 : SignatureData sigdata;
654 [ + - ]: 6 : input.FillSignatureData(sigdata);
655 : :
656 : : // Get UTXO
657 : 6 : bool require_witness_sig = false;
658 : 6 : CTxOut utxo;
659 : :
660 [ + - ]: 6 : if (input.non_witness_utxo) {
661 : : // If we're taking our information from a non-witness UTXO, verify that it matches the prevout.
662 [ + - ]: 6 : COutPoint prevout = input.GetOutPoint();
663 [ - + - + ]: 6 : if (prevout.n >= input.non_witness_utxo->vout.size()) {
664 : 0 : return util::Unexpected{PSBTError::MISSING_INPUTS};
665 : : }
666 [ + - ]: 6 : if (input.non_witness_utxo->GetHash() != prevout.hash) {
667 : 0 : return util::Unexpected{PSBTError::MISSING_INPUTS};
668 : : }
669 : 6 : utxo = input.non_witness_utxo->vout[prevout.n];
670 [ # # ]: 0 : } else if (!input.witness_utxo.IsNull()) {
671 : 0 : utxo = input.witness_utxo;
672 : : // When we're taking our information from a witness UTXO, we can't verify it is actually data from
673 : : // the output being spent. This is safe in case a witness signature is produced (which includes this
674 : : // information directly in the hash), but not for non-witness signatures. Remember that we require
675 : : // a witness signature in this situation.
676 : 0 : require_witness_sig = true;
677 : : } else {
678 : 0 : return util::Unexpected{PSBTError::MISSING_INPUTS};
679 : : }
680 : :
681 : : // Get the sighash type
682 : : // If both the field and the parameter are provided, they must match
683 : : // If only the parameter is provided, use it and add it to the PSBT if it is other than SIGHASH_DEFAULT
684 : : // for all input types, and not SIGHASH_ALL for non-taproot input types.
685 : : // If neither are provided, use SIGHASH_DEFAULT if it is taproot, and SIGHASH_ALL for everything else.
686 [ + - + - : 12 : int sighash{options.sighash_type.value_or(utxo.scriptPubKey.IsPayToTaproot() ? SIGHASH_DEFAULT : SIGHASH_ALL)};
- + ]
687 : :
688 : : // For user safety, the desired sighash must be provided if the PSBT wants something other than the default set in the previous line.
689 [ - + - - ]: 6 : if (input.sighash_type && input.sighash_type != sighash) {
690 : 0 : return util::Unexpected{PSBTError::SIGHASH_MISMATCH};
691 : : }
692 : : // Set the PSBT sighash field when sighash is not DEFAULT or ALL
693 : : // DEFAULT is allowed for non-taproot inputs since DEFAULT may be passed for them (e.g. the psbt being signed also has taproot inputs)
694 : : // Note that signing already aliases DEFAULT to ALL for non-taproot inputs.
695 [ + - - + : 12 : if (utxo.scriptPubKey.IsPayToTaproot() ? sighash != SIGHASH_DEFAULT :
- + ]
696 : 6 : (sighash != SIGHASH_DEFAULT && sighash != SIGHASH_ALL)) {
697 : 0 : input.sighash_type = sighash;
698 : : }
699 : :
700 : : // Check all existing signatures use the sighash type
701 [ - + ]: 6 : if (sighash == SIGHASH_DEFAULT) {
702 [ # # # # : 0 : if (!input.m_tap_key_sig.empty() && input.m_tap_key_sig.size() != 64) {
# # ]
703 : 0 : return util::Unexpected{PSBTError::SIGHASH_MISMATCH};
704 : : }
705 [ # # # # ]: 0 : for (const auto& [_, sig] : input.m_tap_script_sigs) {
706 [ # # # # ]: 0 : if (sig.size() != 64) return util::Unexpected{PSBTError::SIGHASH_MISMATCH};
707 : : }
708 : : } else {
709 [ - + - - : 6 : if (!input.m_tap_key_sig.empty() && (input.m_tap_key_sig.size() != 65 || input.m_tap_key_sig.back() != sighash)) {
- - - - ]
710 : 0 : return util::Unexpected{PSBTError::SIGHASH_MISMATCH};
711 : : }
712 [ - - - + ]: 6 : for (const auto& [_, sig] : input.m_tap_script_sigs) {
713 [ # # # # : 0 : if (sig.size() != 65 || sig.back() != sighash) return util::Unexpected{PSBTError::SIGHASH_MISMATCH};
# # ]
714 : : }
715 [ - - - + ]: 6 : for (const auto& [_, sig] : input.partial_sigs) {
716 [ # # ]: 0 : if (sig.second.back() != sighash) return util::Unexpected{PSBTError::SIGHASH_MISMATCH};
717 : : }
718 : : }
719 : :
720 : 6 : sigdata.witness = false;
721 : 6 : bool sig_complete;
722 [ - + ]: 6 : if (txdata == nullptr) {
723 [ # # ]: 0 : sig_complete = ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, utxo.scriptPubKey, sigdata);
724 : : } else {
725 [ + - ]: 6 : MutableTransactionSignatureCreator creator(tx, index, utxo.nValue, txdata, {.sighash_type = sighash});
726 [ + - ]: 6 : sig_complete = ProduceSignature(provider, creator, utxo.scriptPubKey, sigdata);
727 : 6 : }
728 : : // Verify that a witness signature was produced in case one was required.
729 [ - + - - ]: 6 : if (require_witness_sig && !sigdata.witness) return util::Unexpected{PSBTError::INCOMPLETE};
730 : :
731 : : // If we are not finalizing, set sigdata.complete to false to not set the scriptWitness
732 [ - + - - ]: 6 : if (!options.finalize && sigdata.complete) sigdata.complete = false;
733 : :
734 [ + - ]: 6 : input.FromSignatureData(sigdata);
735 : :
736 : : // If we have a witness signature, put a witness UTXO.
737 [ + + ]: 6 : if (sigdata.witness) {
738 : 1 : input.witness_utxo = utxo;
739 : : // We can remove the non_witness_utxo if and only if there are no non-segwit or segwit v0
740 : : // inputs in this transaction. Since this requires inspecting the entire transaction, this
741 : : // is something for the caller to deal with (i.e. FillPSBT).
742 : : }
743 : :
744 : : // Fill in the missing info
745 [ - + ]: 6 : if (out_sigdata) {
746 [ # # ]: 0 : out_sigdata->missing_pubkeys = sigdata.missing_pubkeys;
747 [ # # ]: 0 : out_sigdata->missing_sigs = sigdata.missing_sigs;
748 : 0 : out_sigdata->missing_redeem_script = sigdata.missing_redeem_script;
749 : 0 : out_sigdata->missing_witness_script = sigdata.missing_witness_script;
750 : : }
751 : :
752 [ + - ]: 6 : if (!sig_complete) return util::Unexpected{PSBTError::INCOMPLETE};
753 : 0 : return {};
754 : 12 : }
755 : :
756 : 1 : void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx)
757 : : {
758 : : // Figure out if any non_witness_utxos should be dropped
759 : 1 : std::vector<unsigned int> to_drop;
760 [ - + + - ]: 1 : for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {
761 [ + - ]: 1 : const auto& input = psbtx.inputs.at(i);
762 : 1 : int wit_ver;
763 : 1 : std::vector<unsigned char> wit_prog;
764 [ - + - - : 1 : if (input.witness_utxo.IsNull() || !input.witness_utxo.scriptPubKey.IsWitnessProgram(wit_ver, wit_prog)) {
- - ]
765 : : // There's a non-segwit input, so we cannot drop any non_witness_utxos
766 [ - + ]: 1 : to_drop.clear();
767 : : break;
768 : : }
769 [ # # ]: 0 : if (wit_ver == 0) {
770 : : // Segwit v0, so we cannot drop any non_witness_utxos
771 [ # # ]: 0 : to_drop.clear();
772 : : break;
773 : : }
774 : : // non_witness_utxos cannot be dropped if the sighash type includes SIGHASH_ANYONECANPAY
775 : : // Since callers should have called SignPSBTInput which updates the sighash type in the PSBT, we only
776 : : // need to look at that field. If it is not present, then we can assume SIGHASH_DEFAULT or SIGHASH_ALL.
777 [ # # # # ]: 0 : if (input.sighash_type != std::nullopt && (*input.sighash_type & 0x80) == SIGHASH_ANYONECANPAY) {
778 [ - - ]: 1 : to_drop.clear();
779 : : break;
780 : : }
781 : :
782 [ # # ]: 0 : if (input.non_witness_utxo) {
783 [ # # ]: 0 : to_drop.push_back(i);
784 : : }
785 : 1 : }
786 : :
787 : : // Drop the non_witness_utxos that we can drop
788 [ - + ]: 1 : for (unsigned int i : to_drop) {
789 [ # # # # ]: 0 : psbtx.inputs.at(i).non_witness_utxo = nullptr;
790 : : }
791 : 1 : }
792 : :
793 : 0 : bool FinalizePSBT(PartiallySignedTransaction& psbtx)
794 : : {
795 : : // Finalize input signatures -- in case we have partial signatures that add up to a complete
796 : : // signature, but have not combined them yet (e.g. because the combiner that created this
797 : : // PartiallySignedTransaction did not understand them), this will combine them into a final
798 : : // script.
799 : 0 : bool complete = true;
800 : 0 : std::optional<PrecomputedTransactionData> txdata_res = PrecomputePSBTData(psbtx);
801 [ # # ]: 0 : if (!txdata_res) {
802 : : return false;
803 : : }
804 : : const PrecomputedTransactionData& txdata = *txdata_res;
805 [ # # # # ]: 0 : for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {
806 [ # # ]: 0 : PSBTInput& input = psbtx.inputs.at(i);
807 [ # # ]: 0 : const auto sign_result = SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, &txdata, {.sighash_type = input.sighash_type, .finalize = true}, /*out_sigdata=*/nullptr);
808 : 0 : complete &= sign_result.has_value();
809 : : }
810 : :
811 : : return complete;
812 : 0 : }
813 : :
814 : 0 : bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransaction& result)
815 : : {
816 : : // It's not safe to extract a PSBT that isn't finalized, and there's no easy way to check
817 : : // whether a PSBT is finalized without finalizing it, so we just do this.
818 [ # # ]: 0 : if (!FinalizePSBT(psbtx)) {
819 : : return false;
820 : : }
821 : :
822 : 0 : std::optional<CMutableTransaction> unsigned_tx = psbtx.GetUnsignedTx();
823 [ # # ]: 0 : if (!unsigned_tx) {
824 : : return false;
825 : : }
826 [ # # ]: 0 : result = *unsigned_tx;
827 [ # # # # ]: 0 : for (unsigned int i = 0; i < result.vin.size(); ++i) {
828 : 0 : result.vin[i].scriptSig = psbtx.inputs[i].final_script_sig;
829 [ # # ]: 0 : result.vin[i].scriptWitness = psbtx.inputs[i].final_script_witness;
830 : : }
831 : : return true;
832 : 0 : }
833 : :
834 : 0 : std::optional<PartiallySignedTransaction> CombinePSBTs(const std::vector<PartiallySignedTransaction>& psbtxs)
835 : : {
836 : 0 : PartiallySignedTransaction out = psbtxs[0]; // Copy the first one
837 : :
838 : : // Merge
839 [ # # ]: 0 : for (auto it = std::next(psbtxs.begin()); it != psbtxs.end(); ++it) {
840 [ # # # # ]: 0 : if (!out.Merge(*it)) {
841 : 0 : return std::nullopt;
842 : : }
843 : : }
844 : 0 : return out;
845 : 0 : }
846 : :
847 : 0 : std::string PSBTRoleName(PSBTRole role) {
848 [ # # # # : 0 : switch (role) {
# # ]
849 : 0 : case PSBTRole::CREATOR: return "creator";
850 : 0 : case PSBTRole::UPDATER: return "updater";
851 : 0 : case PSBTRole::SIGNER: return "signer";
852 : 0 : case PSBTRole::FINALIZER: return "finalizer";
853 : 0 : case PSBTRole::EXTRACTOR: return "extractor";
854 : : } // no default case, so the compiler can warn about missing cases
855 : 0 : assert(false);
856 : : }
857 : :
858 : 10 : util::Result<PartiallySignedTransaction> DecodeBase64PSBT(const std::string& base64_tx)
859 : : {
860 [ - + ]: 10 : auto tx_data = DecodeBase64(base64_tx);
861 [ - + ]: 10 : if (!tx_data) {
862 [ # # # # ]: 0 : return util::Error{Untranslated("invalid base64")};
863 : : }
864 [ + - ]: 10 : return DecodeRawPSBT(MakeByteSpan(*tx_data));
865 : 10 : }
866 : :
867 : 10 : util::Result<PartiallySignedTransaction> DecodeRawPSBT(std::span<const std::byte> tx_data)
868 : : {
869 [ + - ]: 10 : SpanReader ss_data{tx_data};
870 : 10 : try {
871 [ + - ]: 10 : PartiallySignedTransaction psbt(deserialize, ss_data);
872 [ - + ]: 10 : if (!ss_data.empty()) {
873 [ # # # # ]: 0 : return util::Error{Untranslated("extra data after PSBT")};
874 : : }
875 : 10 : return psbt;
876 [ - - ]: 10 : } catch (const std::exception& e) {
877 [ - - - - ]: 0 : return util::Error{Untranslated(e.what())};
878 : 0 : }
879 : : }
880 : :
881 : 127 : uint32_t PartiallySignedTransaction::GetVersion() const
882 : : {
883 [ + + ]: 127 : if (m_version != std::nullopt) {
884 : 104 : return *m_version;
885 : : }
886 : : return 0;
887 : : }
|