Bitcoin Core 32.99.0
P2P Digital Currency
psbt_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2022 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or https://www.opensource.org/licenses/mit-license.php.
4
5#include <addresstype.h>
6#include <key.h>
7#include <psbt.h>
8#include <script/descriptor.h>
9#include <script/script.h>
11#include <script/solver.h>
13#include <util/strencodings.h>
14#include <util/string.h>
15
16#include <boost/test/unit_test.hpp>
17
18#include <string>
19#include <vector>
20
22
23static PSBTProprietary MakeProprietary(uint64_t subtype, uint8_t key_data, uint8_t value)
24{
25 return PSBTProprietary{
26 .subtype = subtype,
27 .identifier = {'p', 's', 'b', 't'},
28 .key = {key_data},
29 .value = {value},
30 };
31}
32
33void CheckTimeLock(const std::string& base64_psbt, std::optional<uint32_t> timelock)
34{
36 BOOST_CHECK(psbt);
37
38 std::optional<uint32_t> computed_timelock = psbt->ComputeTimeLock();
39 std::optional<CMutableTransaction> tx = psbt->GetUnsignedTx();
40 if (timelock) {
41 BOOST_CHECK(computed_timelock);
42 BOOST_CHECK_EQUAL(*computed_timelock, *timelock);
43 BOOST_CHECK(tx);
44 BOOST_CHECK_EQUAL(tx->nLockTime, *timelock);
45 } else {
46 BOOST_CHECK(!computed_timelock);
47 BOOST_CHECK(!tx);
48 }
49}
50
51BOOST_AUTO_TEST_CASE(psbt2_timelock_test)
52{
53 CheckTimeLock("cHNidP8BAgQCAAAAAQQBAQEFAQIB+wQCAAAAAAEOIAsK2SFBnByHGXNdctxzn56p4GONH+TB7vD5lECEgV/IAQ8EAAAAAAABAwgACK8vAAAAAAEEFgAUxDD2TEdW2jENvRoIVXLvKZkmJywAAQMIi73rCwAAAAABBBYAFE3Rk6yWSlasG54cyoRU/i9HT4UTAA==", 0);
54 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAAAAQ4gOhs7PIN9ZInqejHY5sfdUDwAG+8+BpWOdXSAjWjKeKUBDwQAAAAAAAEDCE+TNXcAAAAAAQQWABQLE1LKzQPPaqG388jWOIZxs0peEQA=", 0);
55 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEgQQJwAAAAEOIDobOzyDfWSJ6nox2ObH3VA8ABvvPgaVjnV0gI1oynilAQ8EAAAAAAABAwhPkzV3AAAAAAEEFgAUCxNSys0Dz2qht/PI1jiGcbNKXhEA", 10000);
56 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEgQQJwAAAAEOIDobOzyDfWSJ6nox2ObH3VA8ABvvPgaVjnV0gI1oynilAQ8EAAAAAAESBCgjAAAAAQMIT5M1dwAAAAABBBYAFAsTUsrNA89qobfzyNY4hnGzSl4RAA==", 10000);
57 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEgQQJwAAAAEOIDobOzyDfWSJ6nox2ObH3VA8ABvvPgaVjnV0gI1oynilAQ8EAAAAAAERBIyNxGIBEgQoIwAAAAEDCE+TNXcAAAAAAQQWABQLE1LKzQPPaqG388jWOIZxs0peEQA=", 10000);
58 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEQSLjcRiARIEECcAAAABDiA6Gzs8g31kiep6Mdjmx91QPAAb7z4GlY51dICNaMp4pQEPBAAAAAABEQSMjcRiARIEKCMAAAABAwhPkzV3AAAAAAEEFgAUCxNSys0Dz2qht/PI1jiGcbNKXhEA", 10000);
59 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEQSLjcRiAAEOIDobOzyDfWSJ6nox2ObH3VA8ABvvPgaVjnV0gI1oynilAQ8EAAAAAAERBIyNxGIBEgQoIwAAAAEDCE+TNXcAAAAAAQQWABQLE1LKzQPPaqG388jWOIZxs0peEQA=", 1657048460);
60 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEQSLjcRiARIEECcAAAABDiA6Gzs8g31kiep6Mdjmx91QPAAb7z4GlY51dICNaMp4pQEPBAAAAAABEQSMjcRiAAEDCE+TNXcAAAAAAQQWABQLE1LKzQPPaqG388jWOIZxs0peEQA=", 1657048460);
61 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAAAAQ4gOhs7PIN9ZInqejHY5sfdUDwAG+8+BpWOdXSAjWjKeKUBDwQAAAAAAREEjI3EYgABAwhPkzV3AAAAAAEEFgAUCxNSys0Dz2qht/PI1jiGcbNKXhEA", 1657048460);
62 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEgQQJwAAAAEOIDobOzyDfWSJ6nox2ObH3VA8ABvvPgaVjnV0gI1oynilAQ8EAAAAAAERBIyNxGIAAQMIT5M1dwAAAAABBBYAFAsTUsrNA89qobfzyNY4hnGzSl4RAA==", std::nullopt);
63 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiA6Gzs8g31kiep6Mdjmx91QPAAb7z4GlY51dICNaMp4pQEPBAAAAAABEQSMjcRiAAEOIA91jb+9TafBbIozCcPIHhEA9WHqZG21sBdSxIXhvd6fAQ8EAQAAAAESBBAnAAAAAQMIT5M1dwAAAAABBBYAFAsTUsrNA89qobfzyNY4hnGzSl4RAA==", std::nullopt);
64}
65
66BOOST_AUTO_TEST_CASE(psbt2_addinput)
67{
68 FastRandomContext rng(/*fDeterministic=*/true);
69
71 PartiallySignedTransaction psbt(mtx, /*version=*/2);
72 psbt.m_tx_modifiable.emplace();
73 psbt.m_tx_modifiable->set(0, true);
74 BOOST_CHECK_EQUAL(psbt.inputs.size(), 0);
75
76 // Same PSBT version is required
77 uint256 txid;
79 PSBTInput psbtin_v0(/*psbt_version=*/0, Txid::FromUint256(txid), /*prev_out=*/0);
80 BOOST_CHECK(!psbt.AddInput(psbtin_v0));
81 BOOST_CHECK_EQUAL(psbt.inputs.size(), 0);
83 PSBTInput psbtin(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
84 BOOST_CHECK(psbt.AddInput(psbtin));
85 BOOST_CHECK_EQUAL(psbt.inputs.size(), 1);
86
87 // Duplicates are not allowed
88 BOOST_CHECK(!psbt.AddInput(psbtin));
89 BOOST_CHECK_EQUAL(psbt.inputs.size(), 1);
90
91 // Input with a unique txid is allowed
93 PSBTInput psbtin2(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
94 BOOST_CHECK(psbt.AddInput(psbtin2));
95 BOOST_CHECK_EQUAL(psbt.inputs.size(), 2);
96
97 // Disabling inputs modifiable flag prevents adding new inputs
98 psbt.m_tx_modifiable->set(0, false);
100 PSBTInput psbtin3(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
101 BOOST_CHECK(!psbt.AddInput(psbtin3));
102 BOOST_CHECK_EQUAL(psbt.inputs.size(), 2);
103 psbt.m_tx_modifiable->set(0, true);
104
105 // Make sure that timelock compatibility checks are working
106 // No previous required timelocks, new input with both height and time timelocks is allowed
108 PSBTInput psbtin4(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
110 psbtin4.height_locktime = 100;
111 BOOST_CHECK(psbt.AddInput(psbtin4));
112 BOOST_CHECK_EQUAL(psbt.inputs.size(), 3);
113
114 // Input with only a time timelock is allowed
116 PSBTInput psbtin5(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
117 psbtin5.time_locktime = LOCKTIME_THRESHOLD + 1;
118 BOOST_CHECK(psbt.AddInput(psbtin5));
119 BOOST_CHECK_EQUAL(psbt.inputs.size(), 4);
120
121 // Input with only a height timelock is not allowed because of previous
123 PSBTInput psbtin6(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
124 psbtin6.height_locktime = 100;
125 BOOST_CHECK(!psbt.AddInput(psbtin6));
126 BOOST_CHECK_EQUAL(psbt.inputs.size(), 4);
127
128 // Adding an input that already has a signature is allowed
130 PSBTInput psbtin7(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
131 psbtin7.final_script_sig << OP_1;
132 BOOST_CHECK(psbt.AddInput(psbtin7));
133 BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
134
135 // Same thing, but with other things that have signatures
136 psbtin7.final_script_sig.clear();
137 psbtin7.final_script_witness.stack.emplace_back();
138 BOOST_CHECK(!psbt.AddInput(psbtin7));
139 BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
141 psbtin7.partial_sigs.emplace();
142 BOOST_CHECK(!psbt.AddInput(psbtin7));
143 BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
144 psbtin7.partial_sigs.clear();
145 psbtin7.m_tap_key_sig.push_back(0);
146 BOOST_CHECK(!psbt.AddInput(psbtin7));
147 BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
148 psbtin7.m_tap_key_sig.clear();
149 psbtin7.m_tap_script_sigs.emplace();
150 BOOST_CHECK(!psbt.AddInput(psbtin7));
151 BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
152 psbtin7.m_tap_script_sigs.clear();
153 psbtin7.m_musig2_partial_sigs.emplace();
154 BOOST_CHECK(!psbt.AddInput(psbtin7));
155 BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
156
157 // Adding an input that changes the timelock is no longer allowed
159 PSBTInput psbtin8(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
160 psbtin8.time_locktime = LOCKTIME_THRESHOLD + 2;
161 BOOST_CHECK(!psbt.AddInput(psbtin8));
162 BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
163}
164
165BOOST_AUTO_TEST_CASE(psbt2_addoutput)
166{
168 PartiallySignedTransaction psbt(mtx, /*version=*/2);
169 psbt.m_tx_modifiable.emplace();
170 psbt.m_tx_modifiable->set(1, true);
171 BOOST_CHECK_EQUAL(psbt.outputs.size(), 0);
172
173 // Same PSBT version is required
174 PSBTOutput psbtout_v0(/*psbt_version=*/0, /*amount=*/1, CScript());
175 BOOST_CHECK(!psbt.AddOutput(psbtout_v0));
176 BOOST_CHECK_EQUAL(psbt.outputs.size(), 0);
177 PSBTOutput psbtout(/*psbt_version=*/2, /*amount=*/1, CScript());
178 BOOST_CHECK(psbt.AddOutput(psbtout));
179 BOOST_CHECK_EQUAL(psbt.outputs.size(), 1);
180
181 // Disabling outputs modifiable flag prevents adding new outputs
182 psbt.m_tx_modifiable->set(1, false);
183 PSBTOutput psbtout2(/*psbt_version=*/2, /*amount=*/1, CScript());
184 BOOST_CHECK(!psbt.AddOutput(psbtout2));
185 BOOST_CHECK_EQUAL(psbt.outputs.size(), 1);
186 psbt.m_tx_modifiable->set(1, true);
187 PSBTOutput psbtout3(/*psbt_version=*/2, /*amount=*/1, CScript());
188 BOOST_CHECK(psbt.AddOutput(psbtout3));
189 BOOST_CHECK_EQUAL(psbt.outputs.size(), 2);
190}
191
192BOOST_AUTO_TEST_CASE(merge_proprietary_fields)
193{
195 tx.vin.emplace_back(COutPoint{});
196 tx.vout.emplace_back(0, CScript{});
197
200
201 const auto left_prop = MakeProprietary(/*subtype=*/1, /*key_data=*/0x01, /*value=*/0xaa);
202 const auto right_prop = MakeProprietary(/*subtype=*/2, /*key_data=*/0x02, /*value=*/0xbb);
203
204 left.m_proprietary.insert(left_prop);
205 left.inputs[0].m_proprietary.insert(left_prop);
206 left.outputs[0].m_proprietary.insert(left_prop);
207
208 right.m_proprietary.insert(right_prop);
209 right.inputs[0].m_proprietary.insert(right_prop);
210 right.outputs[0].m_proprietary.insert(right_prop);
211
212 BOOST_REQUIRE(left.Merge(right));
213
214 BOOST_REQUIRE_EQUAL(left.m_proprietary.size(), 2U);
215 BOOST_REQUIRE_EQUAL(left.inputs[0].m_proprietary.size(), 2U);
216 BOOST_REQUIRE_EQUAL(left.outputs[0].m_proprietary.size(), 2U);
217
218 const auto global_it = left.m_proprietary.find(right_prop);
219 BOOST_REQUIRE(global_it != left.m_proprietary.end());
220 BOOST_CHECK(global_it->value == right_prop.value);
221
222 const auto input_it = left.inputs[0].m_proprietary.find(right_prop);
223 BOOST_REQUIRE(input_it != left.inputs[0].m_proprietary.end());
224 BOOST_CHECK(input_it->value == right_prop.value);
225
226 const auto output_it = left.outputs[0].m_proprietary.find(right_prop);
227 BOOST_REQUIRE(output_it != left.outputs[0].m_proprietary.end());
228 BOOST_CHECK(output_it->value == right_prop.value);
229}
230
235
236 explicit PSBTOutputTest(std::string descriptor)
237 {
238 CKey key{GenerateRandomKey()};
239 pubkey = key.GetPubKey();
240 provider.keys.emplace(pubkey.GetID(), key);
241
242 util::ReplaceAll(descriptor, "<KEY>", HexStr(pubkey));
243 std::string error;
244 auto descriptors{Parse(descriptor, provider, error, /*require_checksum=*/false)};
245 BOOST_REQUIRE_MESSAGE(!descriptors.empty(), error);
246 std::vector<CScript> output_scripts;
247 BOOST_REQUIRE(descriptors[0]->Expand(/*pos=*/0, provider, output_scripts, provider));
248 BOOST_REQUIRE_EQUAL(output_scripts.size(), 1);
249 script_pubkey = output_scripts[0];
250 }
251
252 PSBTOutput UpdateOutput(bool has_input) const
253 {
255 if (has_input) tx.vin.emplace_back();
256 tx.vout.emplace_back(0, script_pubkey);
258 UpdatePSBTOutput(provider, psbt, 0);
259 return psbt.outputs[0];
260 }
261};
262
263BOOST_AUTO_TEST_CASE(update_psbt_output_keypaths)
264{
265 for (bool has_input : {false, true}) {
266 for (const auto& descriptor : {"pkh(<KEY>)", "wpkh(<KEY>)"}) {
267 PSBTOutputTest test{descriptor};
268 auto out{test.UpdateOutput(has_input)};
269 BOOST_CHECK(out.hd_keypaths.contains(test.pubkey));
270 BOOST_CHECK(out.redeem_script.empty());
271 BOOST_CHECK(out.witness_script.empty());
272 }
273 }
274}
275
276BOOST_AUTO_TEST_CASE(update_psbt_output_redeem_script)
277{
278 for (bool has_input : {false, true}) {
279 PSBTOutputTest test{"sh(wpkh(<KEY>))"};
280 auto out{test.UpdateOutput(has_input)};
281 BOOST_CHECK(out.redeem_script == GetScriptForDestination(WitnessV0KeyHash{test.pubkey}));
282 BOOST_CHECK(out.hd_keypaths.contains(test.pubkey));
283 }
284}
285
286BOOST_AUTO_TEST_CASE(update_psbt_output_witness_script)
287{
288 for (bool has_input : {false, true}) {
289 PSBTOutputTest test{"wsh(pk(<KEY>))"};
290 auto out{test.UpdateOutput(has_input)};
291 BOOST_CHECK(out.witness_script == GetScriptForRawPubKey(test.pubkey));
292 BOOST_CHECK(out.hd_keypaths.contains(test.pubkey));
293 }
294}
295
296BOOST_AUTO_TEST_CASE(update_psbt_output_miniscript_timelock)
297{
298 for (bool has_input : {false, true}) {
299 PSBTOutputTest test{"wsh(and_v(v:pk(<KEY>),older(144)))"};
300 auto out{test.UpdateOutput(has_input)};
301 BOOST_CHECK(GetScriptForDestination(WitnessV0ScriptHash{out.witness_script}) == test.script_pubkey);
302 BOOST_CHECK(out.hd_keypaths.contains(test.pubkey));
303 }
304}
305
306BOOST_AUTO_TEST_CASE(update_psbt_output_taproot)
307{
308 for (bool has_input : {false, true}) {
309 PSBTOutputTest test{"rawtr(<KEY>)"};
310 auto out{test.UpdateOutput(has_input)};
311 BOOST_CHECK(out.m_tap_bip32_paths.contains(XOnlyPubKey{test.pubkey}));
312 BOOST_CHECK(out.hd_keypaths.empty());
313 }
314}
315
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
An encapsulated private key.
Definition: key.h:40
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:29
An encapsulated public key.
Definition: pubkey.h:40
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:166
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:406
void clear()
Definition: script.h:569
Fast randomness source.
Definition: random.h:386
void fillrand(std::span< std::byte > output) noexcept
Fill a byte span with random bytes.
Definition: random.cpp:626
A structure for PSBTs which contain per-input information.
Definition: psbt.h:282
std::vector< unsigned char > m_tap_key_sig
Definition: psbt.h:307
CScriptWitness final_script_witness
Definition: psbt.h:292
std::map< CKeyID, SigPair > partial_sigs
Definition: psbt.h:294
std::map< std::pair< XOnlyPubKey, uint256 >, std::vector< unsigned char > > m_tap_script_sigs
Definition: psbt.h:308
std::optional< uint32_t > time_locktime
Definition: psbt.h:303
std::map< std::pair< CPubKey, uint256 >, std::map< CPubKey, uint256 > > m_musig2_partial_sigs
Definition: psbt.h:319
CScript final_script_sig
Definition: psbt.h:291
std::optional< uint32_t > height_locktime
Definition: psbt.h:304
A structure for PSBTs which contains per output information.
Definition: psbt.h:939
A version of CTransaction with the PSBT format.
Definition: psbt.h:1239
std::optional< std::bitset< 8 > > m_tx_modifiable
Definition: psbt.h:1247
bool Merge(const PartiallySignedTransaction &psbt)
Merge psbt into this.
Definition: psbt.cpp:37
std::vector< PSBTInput > inputs
Definition: psbt.h:1248
std::vector< PSBTOutput > outputs
Definition: psbt.h:1249
std::set< PSBTProprietary > m_proprietary
Definition: psbt.h:1251
bool AddOutput(const PSBTOutput &psbtout)
Definition: psbt.cpp:244
bool AddInput(const PSBTInput &psbtin)
Definition: psbt.cpp:161
static transaction_identifier FromUint256(const uint256 &id)
256-bit opaque blob.
Definition: uint256.h:196
static UniValue Parse(std::string_view raw, ParamFormat format=ParamFormat::JSON)
Parse string to UniValue or throw runtime_error if string contains invalid JSON.
Definition: client.cpp:408
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: hex_base.cpp:30
BOOST_CHECK_EQUAL(headers.FindFirst("key"), "value")
CKey GenerateRandomKey(bool compressed) noexcept
Definition: key.cpp:354
void ReplaceAll(std::string &in_out, std::string_view search, std::string_view substitute)
Replace every non-overlapping occurrence of search with substitute, treating both literally; the repl...
Definition: string.cpp:14
#define BOOST_CHECK(expr)
Definition: object.cpp:16
void UpdatePSBTOutput(const SigningProvider &provider, PartiallySignedTransaction &psbt, int index)
Updates a PSBTOutput with information from provider.
Definition: psbt.cpp:597
util::Result< PartiallySignedTransaction > DecodeBase64PSBT(const std::string &base64_tx)
Decode a base64ed PSBT into a PartiallySignedTransaction.
Definition: psbt.cpp:862
BOOST_AUTO_TEST_CASE(psbt2_timelock_test)
Definition: psbt_tests.cpp:51
static PSBTProprietary MakeProprietary(uint64_t subtype, uint8_t key_data, uint8_t value)
Definition: psbt_tests.cpp:23
void CheckTimeLock(const std::string &base64_psbt, std::optional< uint32_t > timelock)
Definition: psbt_tests.cpp:33
@ OP_1
Definition: script.h:84
constexpr unsigned int LOCKTIME_THRESHOLD
Definition: script.h:48
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: solver.cpp:213
auto MakeWritableByteSpan(V &&v) noexcept
Definition: span.h:89
Basic testing setup.
Definition: setup_common.h:58
A mutable version of CTransaction.
Definition: transaction.h:358
std::vector< CTxOut > vout
Definition: transaction.h:360
std::vector< CTxIn > vin
Definition: transaction.h:359
std::vector< std::vector< unsigned char > > stack
Definition: script.h:581
void SetNull()
Definition: script.h:588
std::map< CKeyID, CKey > keys
PSBTOutput UpdateOutput(bool has_input) const
Definition: psbt_tests.cpp:252
FlatSigningProvider provider
Definition: psbt_tests.cpp:233
PSBTOutputTest(std::string descriptor)
Definition: psbt_tests.cpp:236
CScript script_pubkey
Definition: psbt_tests.cpp:234
A structure for PSBT proprietary types.
Definition: psbt.h:101
uint64_t subtype
Definition: psbt.h:102
FastRandomContext rng
Definition: dbwrapper.cpp:413