Skip to content

Commit ea36d27

Browse files
committed
Merge bitcoin#31340: test: add missing segwitv1 test cases to script_standard_tests
8284229 refactor: deduplicate anchor witness program bytes (`0x4e,0x73`) (Sebastian Falbesoner) 41f2f05 test: add missing segwitv1 test cases to `script_standard_tests` (Sebastian Falbesoner) Pull request description: Currently we have two segwitv1 output script types that are considered standard: - `TxoutType::WITNESS_V1_TAPROOT` (P2TR): witness program has size 32 (introduced with taproot soft-fork) - `TxoutType::ANCHOR` (P2A): witness program is {0x4e, 0x7e} (introduced with bitcoin#30352) This PR adds them to the script standardness unit tests where missing, i.e. for using them with the `ExtractDestination` and `GetScriptForDestination` functions. ACKs for top commit: rkrux: ACK 8284229 instagibbs: reACK 8284229 hodlinator: Code Review ACK 8284229 Tree-SHA512: d4a3b47fd31ba33f62d4367811e72a7f442c01b046b0a7217a66be0b9dea5c9041eebfe812c31839ec0f0b14c56948c7c016d3d2de79283583ad8e32c192c6ff
2 parents 80e47b1 + 8284229 commit ea36d27

File tree

3 files changed

+53
-9
lines changed

3 files changed

+53
-9
lines changed

Diff for: src/addresstype.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,13 @@ struct WitnessUnknown
117117
}
118118
};
119119

120+
/** Witness program for Pay-to-Anchor output script type */
121+
static const std::vector<unsigned char> ANCHOR_BYTES{0x4e, 0x73};
122+
120123
struct PayToAnchor : public WitnessUnknown
121124
{
122-
PayToAnchor() : WitnessUnknown(1, {0x4e, 0x73}) {
123-
Assume(CScript::IsPayToAnchor(1, {0x4e, 0x73}));
125+
PayToAnchor() : WitnessUnknown(1, ANCHOR_BYTES) {
126+
Assume(CScript::IsPayToAnchor(1, ANCHOR_BYTES));
124127
};
125128
};
126129

Diff for: src/test/script_standard_tests.cpp

+47-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <test/data/bip341_wallet_vectors.json.h>
66

7+
#include <addresstype.h>
78
#include <key.h>
89
#include <key_io.h>
910
#include <script/script.h>
@@ -130,9 +131,8 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
130131
BOOST_CHECK(solutions[1] == ToByteVector(uint256::ONE));
131132

132133
// TxoutType::ANCHOR
133-
std::vector<unsigned char> anchor_bytes{0x4e, 0x73};
134134
s.clear();
135-
s << OP_1 << anchor_bytes;
135+
s << OP_1 << ANCHOR_BYTES;
136136
BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::ANCHOR);
137137
BOOST_CHECK(solutions.empty());
138138

@@ -197,14 +197,22 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_failure)
197197
s << OP_RETURN << std::vector<unsigned char>({75}) << OP_ADD;
198198
BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
199199

200-
// TxoutType::WITNESS_UNKNOWN with incorrect program size
200+
// TxoutType::WITNESS_V0_{KEY,SCRIPT}HASH with incorrect program size (-> consensus-invalid, i.e. non-standard)
201201
s.clear();
202202
s << OP_0 << std::vector<unsigned char>(19, 0x01);
203203
BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
204204

205+
// TxoutType::WITNESS_V1_TAPROOT with incorrect program size (-> undefined, but still policy-valid)
206+
s.clear();
207+
s << OP_1 << std::vector<unsigned char>(31, 0x01);
208+
BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_UNKNOWN);
209+
s.clear();
210+
s << OP_1 << std::vector<unsigned char>(33, 0x01);
211+
BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_UNKNOWN);
212+
205213
// TxoutType::ANCHOR but wrong witness version
206214
s.clear();
207-
s << OP_2 << std::vector<unsigned char>{0x4e, 0x73};
215+
s << OP_2 << ANCHOR_BYTES;
208216
BOOST_CHECK(!s.IsPayToAnchor());
209217
BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_UNKNOWN);
210218

@@ -268,12 +276,32 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
268276
BOOST_CHECK(ExtractDestination(s, address));
269277
BOOST_CHECK(std::get<WitnessV0ScriptHash>(address) == scripthash);
270278

279+
// TxoutType::WITNESS_V1_TAPROOT
280+
s.clear();
281+
auto xpk = XOnlyPubKey(pubkey);
282+
s << OP_1 << ToByteVector(xpk);
283+
BOOST_CHECK(ExtractDestination(s, address));
284+
BOOST_CHECK(std::get<WitnessV1Taproot>(address) == WitnessV1Taproot(xpk));
285+
286+
// TxoutType::ANCHOR
287+
s.clear();
288+
s << OP_1 << ANCHOR_BYTES;
289+
BOOST_CHECK(ExtractDestination(s, address));
290+
BOOST_CHECK(std::get<PayToAnchor>(address) == PayToAnchor());
291+
271292
// TxoutType::WITNESS_UNKNOWN with unknown version
293+
// -> segwit version 1 with an undefined program size (33 bytes in this test case)
272294
s.clear();
273295
s << OP_1 << ToByteVector(pubkey);
274296
BOOST_CHECK(ExtractDestination(s, address));
275-
WitnessUnknown unk{1, ToByteVector(pubkey)};
276-
BOOST_CHECK(std::get<WitnessUnknown>(address) == unk);
297+
WitnessUnknown unk_v1{1, ToByteVector(pubkey)};
298+
BOOST_CHECK(std::get<WitnessUnknown>(address) == unk_v1);
299+
s.clear();
300+
// -> segwit versions 2+ are not specified yet
301+
s << OP_2 << ToByteVector(xpk);
302+
BOOST_CHECK(ExtractDestination(s, address));
303+
WitnessUnknown unk_v2{2, ToByteVector(xpk)};
304+
BOOST_CHECK(std::get<WitnessUnknown>(address) == unk_v2);
277305
}
278306

279307
BOOST_AUTO_TEST_CASE(script_standard_GetScriptFor_)
@@ -341,6 +369,19 @@ BOOST_AUTO_TEST_CASE(script_standard_GetScriptFor_)
341369
expected << OP_0 << ToByteVector(scriptHash);
342370
result = GetScriptForDestination(WitnessV0ScriptHash(witnessScript));
343371
BOOST_CHECK(result == expected);
372+
373+
// WitnessV1Taproot
374+
auto xpk = XOnlyPubKey(pubkeys[0]);
375+
expected.clear();
376+
expected << OP_1 << ToByteVector(xpk);
377+
result = GetScriptForDestination(WitnessV1Taproot(xpk));
378+
BOOST_CHECK(result == expected);
379+
380+
// PayToAnchor
381+
expected.clear();
382+
expected << OP_1 << ANCHOR_BYTES;
383+
result = GetScriptForDestination(PayToAnchor());
384+
BOOST_CHECK(result == expected);
344385
}
345386

346387
BOOST_AUTO_TEST_CASE(script_standard_taproot_builder)

Diff for: src/test/transaction_tests.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1040,7 +1040,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
10401040
}
10411041

10421042
// Check anchor outputs
1043-
t.vout[0].scriptPubKey = CScript() << OP_1 << std::vector<unsigned char>{0x4e, 0x73};
1043+
t.vout[0].scriptPubKey = CScript() << OP_1 << ANCHOR_BYTES;
10441044
BOOST_CHECK(t.vout[0].scriptPubKey.IsPayToAnchor());
10451045
t.vout[0].nValue = 240;
10461046
CheckIsStandard(t);

0 commit comments

Comments
 (0)