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