Bitcoin Core 31.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 <psbt.h>
6
7#include <boost/test/unit_test.hpp>
9
11
12void CheckTimeLock(const std::string& base64_psbt, std::optional<uint32_t> timelock)
13{
15 BOOST_CHECK(psbt);
16
17 std::optional<uint32_t> computed_timelock = psbt->ComputeTimeLock();
18 std::optional<CMutableTransaction> tx = psbt->GetUnsignedTx();
19 if (timelock) {
20 BOOST_CHECK(computed_timelock);
21 BOOST_CHECK_EQUAL(*computed_timelock, *timelock);
22 BOOST_CHECK(tx);
23 BOOST_CHECK_EQUAL(tx->nLockTime, *timelock);
24 } else {
25 BOOST_CHECK(!computed_timelock);
26 BOOST_CHECK(!tx);
27 }
28}
29
30BOOST_AUTO_TEST_CASE(psbt2_timelock_test)
31{
32 CheckTimeLock("cHNidP8BAgQCAAAAAQQBAQEFAQIB+wQCAAAAAAEOIAsK2SFBnByHGXNdctxzn56p4GONH+TB7vD5lECEgV/IAQ8EAAAAAAABAwgACK8vAAAAAAEEFgAUxDD2TEdW2jENvRoIVXLvKZkmJywAAQMIi73rCwAAAAABBBYAFE3Rk6yWSlasG54cyoRU/i9HT4UTAA==", 0);
33 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAAAAQ4gOhs7PIN9ZInqejHY5sfdUDwAG+8+BpWOdXSAjWjKeKUBDwQAAAAAAAEDCE+TNXcAAAAAAQQWABQLE1LKzQPPaqG388jWOIZxs0peEQA=", 0);
34 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEgQQJwAAAAEOIDobOzyDfWSJ6nox2ObH3VA8ABvvPgaVjnV0gI1oynilAQ8EAAAAAAABAwhPkzV3AAAAAAEEFgAUCxNSys0Dz2qht/PI1jiGcbNKXhEA", 10000);
35 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEgQQJwAAAAEOIDobOzyDfWSJ6nox2ObH3VA8ABvvPgaVjnV0gI1oynilAQ8EAAAAAAESBCgjAAAAAQMIT5M1dwAAAAABBBYAFAsTUsrNA89qobfzyNY4hnGzSl4RAA==", 10000);
36 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEgQQJwAAAAEOIDobOzyDfWSJ6nox2ObH3VA8ABvvPgaVjnV0gI1oynilAQ8EAAAAAAERBIyNxGIBEgQoIwAAAAEDCE+TNXcAAAAAAQQWABQLE1LKzQPPaqG388jWOIZxs0peEQA=", 10000);
37 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEQSLjcRiARIEECcAAAABDiA6Gzs8g31kiep6Mdjmx91QPAAb7z4GlY51dICNaMp4pQEPBAAAAAABEQSMjcRiARIEKCMAAAABAwhPkzV3AAAAAAEEFgAUCxNSys0Dz2qht/PI1jiGcbNKXhEA", 10000);
38 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEQSLjcRiAAEOIDobOzyDfWSJ6nox2ObH3VA8ABvvPgaVjnV0gI1oynilAQ8EAAAAAAERBIyNxGIBEgQoIwAAAAEDCE+TNXcAAAAAAQQWABQLE1LKzQPPaqG388jWOIZxs0peEQA=", 1657048460);
39 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEQSLjcRiARIEECcAAAABDiA6Gzs8g31kiep6Mdjmx91QPAAb7z4GlY51dICNaMp4pQEPBAAAAAABEQSMjcRiAAEDCE+TNXcAAAAAAQQWABQLE1LKzQPPaqG388jWOIZxs0peEQA=", 1657048460);
40 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAAAAQ4gOhs7PIN9ZInqejHY5sfdUDwAG+8+BpWOdXSAjWjKeKUBDwQAAAAAAREEjI3EYgABAwhPkzV3AAAAAAEEFgAUCxNSys0Dz2qht/PI1jiGcbNKXhEA", 1657048460);
41 CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEgQQJwAAAAEOIDobOzyDfWSJ6nox2ObH3VA8ABvvPgaVjnV0gI1oynilAQ8EAAAAAAERBIyNxGIAAQMIT5M1dwAAAAABBBYAFAsTUsrNA89qobfzyNY4hnGzSl4RAA==", std::nullopt);
42}
43
44BOOST_AUTO_TEST_CASE(psbt2_addinput)
45{
46 FastRandomContext rng(/*fDeterministic=*/true);
47
49 PartiallySignedTransaction psbt(mtx, /*version=*/2);
50 psbt.m_tx_modifiable.emplace();
51 psbt.m_tx_modifiable->set(0, true);
52 BOOST_CHECK_EQUAL(psbt.inputs.size(), 0);
53
54 // Same PSBT version is required
55 uint256 txid;
57 PSBTInput psbtin_v0(/*psbt_version=*/0, Txid::FromUint256(txid), /*prev_out=*/0);
58 BOOST_CHECK(!psbt.AddInput(psbtin_v0));
59 BOOST_CHECK_EQUAL(psbt.inputs.size(), 0);
61 PSBTInput psbtin(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
62 BOOST_CHECK(psbt.AddInput(psbtin));
63 BOOST_CHECK_EQUAL(psbt.inputs.size(), 1);
64
65 // Duplicates are not allowed
66 BOOST_CHECK(!psbt.AddInput(psbtin));
67 BOOST_CHECK_EQUAL(psbt.inputs.size(), 1);
68
69 // Input with a unique txid is allowed
71 PSBTInput psbtin2(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
72 BOOST_CHECK(psbt.AddInput(psbtin2));
73 BOOST_CHECK_EQUAL(psbt.inputs.size(), 2);
74
75 // Disabling inputs modifiable flag prevents adding new inputs
76 psbt.m_tx_modifiable->set(0, false);
78 PSBTInput psbtin3(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
79 BOOST_CHECK(!psbt.AddInput(psbtin3));
80 BOOST_CHECK_EQUAL(psbt.inputs.size(), 2);
81 psbt.m_tx_modifiable->set(0, true);
82
83 // Make sure that timelock compatibility checks are working
84 // No previous required timelocks, new input with both height and time timelocks is allowed
86 PSBTInput psbtin4(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
88 psbtin4.height_locktime = 100;
89 BOOST_CHECK(psbt.AddInput(psbtin4));
90 BOOST_CHECK_EQUAL(psbt.inputs.size(), 3);
91
92 // Input with only a time timelock is allowed
94 PSBTInput psbtin5(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
96 BOOST_CHECK(psbt.AddInput(psbtin5));
97 BOOST_CHECK_EQUAL(psbt.inputs.size(), 4);
98
99 // Input with only a height timelock is not allowed because of previous
101 PSBTInput psbtin6(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
102 psbtin6.height_locktime = 100;
103 BOOST_CHECK(!psbt.AddInput(psbtin6));
104 BOOST_CHECK_EQUAL(psbt.inputs.size(), 4);
105
106 // Adding an input that already has a signature is allowed
108 PSBTInput psbtin7(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
109 psbtin7.final_script_sig << OP_1;
110 BOOST_CHECK(psbt.AddInput(psbtin7));
111 BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
112
113 // Same thing, but with other things that have signatures
114 psbtin7.final_script_sig.clear();
115 psbtin7.final_script_witness.stack.emplace_back();
116 BOOST_CHECK(!psbt.AddInput(psbtin7));
117 BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
119 psbtin7.partial_sigs.emplace();
120 BOOST_CHECK(!psbt.AddInput(psbtin7));
121 BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
122 psbtin7.partial_sigs.clear();
123 psbtin7.m_tap_key_sig.push_back(0);
124 BOOST_CHECK(!psbt.AddInput(psbtin7));
125 BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
126 psbtin7.m_tap_key_sig.clear();
127 psbtin7.m_tap_script_sigs.emplace();
128 BOOST_CHECK(!psbt.AddInput(psbtin7));
129 BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
130 psbtin7.m_tap_script_sigs.clear();
131 psbtin7.m_musig2_partial_sigs.emplace();
132 BOOST_CHECK(!psbt.AddInput(psbtin7));
133 BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
134
135 // Adding an input that changes the timelock is no longer allowed
137 PSBTInput psbtin8(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
138 psbtin8.time_locktime = LOCKTIME_THRESHOLD + 2;
139 BOOST_CHECK(!psbt.AddInput(psbtin8));
140 BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
141}
142
143BOOST_AUTO_TEST_CASE(psbt2_addoutput)
144{
146 PartiallySignedTransaction psbt(mtx, /*version=*/2);
147 psbt.m_tx_modifiable.emplace();
148 psbt.m_tx_modifiable->set(1, true);
149 BOOST_CHECK_EQUAL(psbt.outputs.size(), 0);
150
151 // Same PSBT version is required
152 PSBTOutput psbtout_v0(/*psbt_version=*/0, /*amount=*/1, CScript());
153 BOOST_CHECK(!psbt.AddOutput(psbtout_v0));
154 BOOST_CHECK_EQUAL(psbt.outputs.size(), 0);
155 PSBTOutput psbtout(/*psbt_version=*/2, /*amount=*/1, CScript());
156 BOOST_CHECK(psbt.AddOutput(psbtout));
157 BOOST_CHECK_EQUAL(psbt.outputs.size(), 1);
158
159 // Disabling outputs modifiable flag prevents adding new outputs
160 psbt.m_tx_modifiable->set(1, false);
161 PSBTOutput psbtout2(/*psbt_version=*/2, /*amount=*/1, CScript());
162 BOOST_CHECK(!psbt.AddOutput(psbtout2));
163 BOOST_CHECK_EQUAL(psbt.outputs.size(), 1);
164 psbt.m_tx_modifiable->set(1, true);
165 PSBTOutput psbtout3(/*psbt_version=*/2, /*amount=*/1, CScript());
166 BOOST_CHECK(psbt.AddOutput(psbtout3));
167 BOOST_CHECK_EQUAL(psbt.outputs.size(), 2);
168}
169
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:405
void clear()
Definition: script.h:568
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:280
std::vector< unsigned char > m_tap_key_sig
Definition: psbt.h:305
CScriptWitness final_script_witness
Definition: psbt.h:290
std::map< CKeyID, SigPair > partial_sigs
Definition: psbt.h:292
std::map< std::pair< XOnlyPubKey, uint256 >, std::vector< unsigned char > > m_tap_script_sigs
Definition: psbt.h:306
std::optional< uint32_t > time_locktime
Definition: psbt.h:301
std::map< std::pair< CPubKey, uint256 >, std::map< CPubKey, uint256 > > m_musig2_partial_sigs
Definition: psbt.h:317
CScript final_script_sig
Definition: psbt.h:289
std::optional< uint32_t > height_locktime
Definition: psbt.h:302
A structure for PSBTs which contains per output information.
Definition: psbt.h:938
A version of CTransaction with the PSBT format.
Definition: psbt.h:1239
std::optional< std::bitset< 8 > > m_tx_modifiable
Definition: psbt.h:1247
std::vector< PSBTInput > inputs
Definition: psbt.h:1248
std::vector< PSBTOutput > outputs
Definition: psbt.h:1249
bool AddOutput(const PSBTOutput &psbtout)
Definition: psbt.cpp:245
bool AddInput(const PSBTInput &psbtin)
Definition: psbt.cpp:162
static transaction_identifier FromUint256(const uint256 &id)
256-bit opaque blob.
Definition: uint256.h:196
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
Definition: common.h:30
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:17
#define BOOST_CHECK(expr)
Definition: object.cpp:16
util::Result< PartiallySignedTransaction > DecodeBase64PSBT(const std::string &base64_tx)
Decode a base64ed PSBT into a PartiallySignedTransaction.
Definition: psbt.cpp:861
BOOST_AUTO_TEST_CASE(psbt2_timelock_test)
Definition: psbt_tests.cpp:30
void CheckTimeLock(const std::string &base64_psbt, std::optional< uint32_t > timelock)
Definition: psbt_tests.cpp:12
static const unsigned int LOCKTIME_THRESHOLD
Definition: script.h:47
@ OP_1
Definition: script.h:83
auto MakeWritableByteSpan(V &&v) noexcept
Definition: span.h:89
Basic testing setup.
Definition: setup_common.h:61
A mutable version of CTransaction.
Definition: transaction.h:358
std::vector< std::vector< unsigned char > > stack
Definition: script.h:580
void SetNull()
Definition: script.h:587