Skip to content

Commit 2b95b11

Browse files
committed
test: Unit test for inferring scripts with hybrid and uncompressed keys
1 parent 9b6f9a1 commit 2b95b11

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

src/test/descriptor_tests.cpp

+61
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,54 @@ void Check(const std::string& prv, const std::string& pub, const std::string& no
384384
}
385385
}
386386

387+
void CheckInferDescriptor(const std::string& script_hex, const std::string& expected_desc, const std::vector<std::string>& hex_scripts, const std::vector<std::pair<std::string, std::string>>& origin_pubkeys)
388+
{
389+
std::vector<unsigned char> script_bytes{ParseHex(script_hex)};
390+
const CScript& script{script_bytes.begin(), script_bytes.end()};
391+
392+
FlatSigningProvider provider;
393+
for (const std::string& prov_script_hex : hex_scripts) {
394+
std::vector<unsigned char> prov_script_bytes{ParseHex(prov_script_hex)};
395+
const CScript& prov_script{prov_script_bytes.begin(), prov_script_bytes.end()};
396+
provider.scripts.emplace(CScriptID(prov_script), prov_script);
397+
}
398+
for (const auto& [pubkey_hex, origin_str] : origin_pubkeys) {
399+
CPubKey origin_pubkey{ParseHex(pubkey_hex)};
400+
provider.pubkeys.emplace(origin_pubkey.GetID(), origin_pubkey);
401+
402+
if (!origin_str.empty()) {
403+
using namespace spanparsing;
404+
KeyOriginInfo info;
405+
Span<const char> origin_sp{origin_str};
406+
std::vector<Span<const char>> origin_split = Split(origin_sp, "/");
407+
std::string fpr_str(origin_split[0].begin(), origin_split[0].end());
408+
auto fpr_bytes = ParseHex(fpr_str);
409+
std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.fingerprint);
410+
for (size_t i = 1; i < origin_split.size(); ++i) {
411+
Span<const char> elem = origin_split[i];
412+
bool hardened = false;
413+
if (elem.size() > 0) {
414+
const char last = elem[elem.size() - 1];
415+
if (last == '\'' || last == 'h') {
416+
elem = elem.first(elem.size() - 1);
417+
hardened = true;
418+
}
419+
}
420+
uint32_t p;
421+
assert(ParseUInt32(std::string(elem.begin(), elem.end()), &p));
422+
info.path.push_back(p | (((uint32_t)hardened) << 31));
423+
}
424+
425+
provider.origins.emplace(origin_pubkey.GetID(), std::make_pair(origin_pubkey, info));
426+
}
427+
}
428+
429+
std::string checksum{GetDescriptorChecksum(expected_desc)};
430+
431+
std::unique_ptr<Descriptor> desc = InferDescriptor(script, provider);
432+
BOOST_CHECK_EQUAL(desc->ToString(), expected_desc + "#" + checksum);
433+
}
434+
387435
}
388436

389437
BOOST_FIXTURE_TEST_SUITE(descriptor_tests, BasicTestingSetup)
@@ -582,6 +630,19 @@ BOOST_AUTO_TEST_CASE(descriptor_test)
582630
// Same for hash256
583631
Check("wsh(and_v(v:hash256(ae253ca2a54debcac7ecf414f6734f48c56421a08bb59182ff9f39a6fffdb588),pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc)))", "wsh(and_v(v:hash256(ae253ca2a54debcac7ecf414f6734f48c56421a08bb59182ff9f39a6fffdb588),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", "wsh(and_v(v:hash256(ae253ca2a54debcac7ecf414f6734f48c56421a08bb59182ff9f39a6fffdb588),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", SIGNABLE_FAILS, {{"0020cf62bf97baf977aec69cbc290c372899f913337a9093e8f066ab59b8657a365c"}}, OutputType::BECH32, /*op_desc_id=*/uint256S("8412ba3ac20ba3a30f81442d10d32e0468fa52814960d04e959bf84a9b813b88"), {{}}, /*spender_nlocktime=*/0, /*spender_nsequence=*/CTxIn::SEQUENCE_FINAL, {});
584632
Check("wsh(and_v(v:hash256(ae253ca2a54debcac7ecf414f6734f48c56421a08bb59182ff9f39a6fffdb588),pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc)))", "wsh(and_v(v:hash256(ae253ca2a54debcac7ecf414f6734f48c56421a08bb59182ff9f39a6fffdb588),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", "wsh(and_v(v:hash256(ae253ca2a54debcac7ecf414f6734f48c56421a08bb59182ff9f39a6fffdb588),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", SIGNABLE, {{"0020cf62bf97baf977aec69cbc290c372899f913337a9093e8f066ab59b8657a365c"}}, OutputType::BECH32, /*op_desc_id=*/uint256S("8412ba3ac20ba3a30f81442d10d32e0468fa52814960d04e959bf84a9b813b88"), {{}}, /*spender_nlocktime=*/0, /*spender_nsequence=*/CTxIn::SEQUENCE_FINAL, {{ParseHex("ae253ca2a54debcac7ecf414f6734f48c56421a08bb59182ff9f39a6fffdb588"), ParseHex("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")}});
633+
634+
// Basic sh(pkh()) with key origin
635+
CheckInferDescriptor("a9141a31ad23bf49c247dd531a623c2ef57da3c400c587", "sh(pkh([deadbeef/0h/0h/0]03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))", {"76a9149a1c78a507689f6f54b847ad1cef1e614ee23f1e88ac"}, {{"03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd", "deadbeef/0h/0h/0"}});
636+
// p2pk script with hybrid key must infer as raw()
637+
CheckInferDescriptor("41069228de6902abb4f541791f6d7f925b10e2078ccb1298856e5ea5cc5fd667f930eac37a00cc07f9a91ef3c2d17bf7a17db04552ff90ac312a5b8b4caca6c97aa4ac", "raw(41069228de6902abb4f541791f6d7f925b10e2078ccb1298856e5ea5cc5fd667f930eac37a00cc07f9a91ef3c2d17bf7a17db04552ff90ac312a5b8b4caca6c97aa4ac)", {}, {{"069228de6902abb4f541791f6d7f925b10e2078ccb1298856e5ea5cc5fd667f930eac37a00cc07f9a91ef3c2d17bf7a17db04552ff90ac312a5b8b4caca6c97aa4", ""}});
638+
// p2pkh script with hybrid key must infer as addr()
639+
CheckInferDescriptor("76a91445ff7c2327866472639d507334a9a00119dfd32688ac", "addr(17P7ge56F2QcdHxxRBa2NyzmejFggPwBJ9)", {}, {{"069228de6902abb4f541791f6d7f925b10e2078ccb1298856e5ea5cc5fd667f930eac37a00cc07f9a91ef3c2d17bf7a17db04552ff90ac312a5b8b4caca6c97aa4", ""}});
640+
// p2wpkh script with uncompressed key must infer as addr()
641+
CheckInferDescriptor("001422e363a523947a110d9a9eb114820de183aca313", "addr(bc1qyt3k8ffrj3apzrv6n6c3fqsduxp6egcnk2r66j)", {}, {{"049228de6902abb4f541791f6d7f925b10e2078ccb1298856e5ea5cc5fd667f930eac37a00cc07f9a91ef3c2d17bf7a17db04552ff90ac312a5b8b4caca6c97aa4", ""}});
642+
// Infer pkh() from p2pkh with uncompressed key
643+
CheckInferDescriptor("76a914a31725c74421fadc50d35520ab8751ed120af80588ac", "pkh(04c56fe4a92d401bcbf1b3dfbe4ac3dac5602ca155a3681497f02c1b9a733b92d704e2da6ec4162e4846af9236ef4171069ac8b7f8234a8405b6cadd96f34f5a31)", {}, {{"04c56fe4a92d401bcbf1b3dfbe4ac3dac5602ca155a3681497f02c1b9a733b92d704e2da6ec4162e4846af9236ef4171069ac8b7f8234a8405b6cadd96f34f5a31", ""}});
644+
// Infer pk() from p2pk with uncompressed key
645+
CheckInferDescriptor("4104032540df1d3c7070a8ab3a9cdd304dfc7fd1e6541369c53c4c3310b2537d91059afc8b8e7673eb812a32978dabb78c40f2e423f7757dca61d11838c7aeeb5220ac", "pk(04032540df1d3c7070a8ab3a9cdd304dfc7fd1e6541369c53c4c3310b2537d91059afc8b8e7673eb812a32978dabb78c40f2e423f7757dca61d11838c7aeeb5220)#59dvf0e2", {}, {{"04032540df1d3c7070a8ab3a9cdd304dfc7fd1e6541369c53c4c3310b2537d91059afc8b8e7673eb812a32978dabb78c40f2e423f7757dca61d11838c7aeeb5220", ""}});
585646
}
586647

587648
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)