mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 20:03:34 -03:00
Clean up context dependent checks in descriptor parsing
This changes all context dependent checks in the parser to be disjunctions of equality checks, rather than also including inequalities. This makes sure that adding a new context enum in the future won't change semantics for existing checks. The error messages are also made a bit more consistent.
This commit is contained in:
parent
33275a9649
commit
0b188b751f
2 changed files with 22 additions and 16 deletions
|
@ -973,8 +973,8 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const
|
|||
if (!pubkey) return nullptr;
|
||||
++key_exp_index;
|
||||
return std::make_unique<ComboDescriptor>(std::move(pubkey));
|
||||
} else if (ctx != ParseScriptContext::TOP && Func("combo", expr)) {
|
||||
error = "Cannot have combo in non-top level";
|
||||
} else if (Func("combo", expr)) {
|
||||
error = "Can only have combo() at top level";
|
||||
return nullptr;
|
||||
}
|
||||
if ((sorted_multi = Func("sortedmulti", expr)) || Func("multi", expr)) {
|
||||
|
@ -1022,29 +1022,29 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const
|
|||
}
|
||||
return std::make_unique<MultisigDescriptor>(thres, std::move(providers), sorted_multi);
|
||||
}
|
||||
if (ctx != ParseScriptContext::P2WSH && Func("wpkh", expr)) {
|
||||
if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) && Func("wpkh", expr)) {
|
||||
auto pubkey = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH, out, error);
|
||||
if (!pubkey) return nullptr;
|
||||
key_exp_index++;
|
||||
return std::make_unique<WPKHDescriptor>(std::move(pubkey));
|
||||
} else if (ctx == ParseScriptContext::P2WSH && Func("wpkh", expr)) {
|
||||
error = "Cannot have wpkh within wsh";
|
||||
} else if (Func("wpkh", expr)) {
|
||||
error = "Can only have wpkh() at top level or inside sh()";
|
||||
return nullptr;
|
||||
}
|
||||
if (ctx == ParseScriptContext::TOP && Func("sh", expr)) {
|
||||
auto desc = ParseScript(key_exp_index, expr, ParseScriptContext::P2SH, out, error);
|
||||
if (!desc || expr.size()) return nullptr;
|
||||
return std::make_unique<SHDescriptor>(std::move(desc));
|
||||
} else if (ctx != ParseScriptContext::TOP && Func("sh", expr)) {
|
||||
error = "Cannot have sh in non-top level";
|
||||
} else if (Func("sh", expr)) {
|
||||
error = "Can only have sh() at top level";
|
||||
return nullptr;
|
||||
}
|
||||
if (ctx != ParseScriptContext::P2WSH && Func("wsh", expr)) {
|
||||
if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) && Func("wsh", expr)) {
|
||||
auto desc = ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH, out, error);
|
||||
if (!desc || expr.size()) return nullptr;
|
||||
return std::make_unique<WSHDescriptor>(std::move(desc));
|
||||
} else if (ctx == ParseScriptContext::P2WSH && Func("wsh", expr)) {
|
||||
error = "Cannot have wsh within wsh";
|
||||
} else if (Func("wsh", expr)) {
|
||||
error = "Can only have wsh() at top level or inside sh()";
|
||||
return nullptr;
|
||||
}
|
||||
if (ctx == ParseScriptContext::TOP && Func("addr", expr)) {
|
||||
|
@ -1054,6 +1054,9 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const
|
|||
return nullptr;
|
||||
}
|
||||
return std::make_unique<AddressDescriptor>(std::move(dest));
|
||||
} else if (Func("addr", expr)) {
|
||||
error = "Can only have addr() at top level";
|
||||
return nullptr;
|
||||
}
|
||||
if (ctx == ParseScriptContext::TOP && Func("raw", expr)) {
|
||||
std::string str(expr.begin(), expr.end());
|
||||
|
@ -1063,6 +1066,9 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const
|
|||
}
|
||||
auto bytes = ParseHex(str);
|
||||
return std::make_unique<RawDescriptor>(CScript(bytes.begin(), bytes.end()));
|
||||
} else if (Func("raw", expr)) {
|
||||
error = "Can only have raw() at top level";
|
||||
return nullptr;
|
||||
}
|
||||
if (ctx == ParseScriptContext::P2SH) {
|
||||
error = "A function is needed within P2SH";
|
||||
|
|
|
@ -24,7 +24,7 @@ void CheckUnparsable(const std::string& prv, const std::string& pub, const std::
|
|||
auto parse_pub = Parse(pub, keys_pub, error);
|
||||
BOOST_CHECK_MESSAGE(!parse_priv, prv);
|
||||
BOOST_CHECK_MESSAGE(!parse_pub, pub);
|
||||
BOOST_CHECK(error == expected_error);
|
||||
BOOST_CHECK_EQUAL(error, expected_error);
|
||||
}
|
||||
|
||||
constexpr int DEFAULT = 0;
|
||||
|
@ -355,12 +355,12 @@ BOOST_AUTO_TEST_CASE(descriptor_test)
|
|||
|
||||
// Check for invalid nesting of structures
|
||||
CheckUnparsable("sh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)", "sh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)", "A function is needed within P2SH"); // P2SH needs a script, not a key
|
||||
CheckUnparsable("sh(combo(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1))", "sh(combo(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))", "Cannot have combo in non-top level"); // Old must be top level
|
||||
CheckUnparsable("sh(combo(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1))", "sh(combo(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))", "Can only have combo() at top level"); // Old must be top level
|
||||
CheckUnparsable("wsh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)", "wsh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)", "A function is needed within P2WSH"); // P2WSH needs a script, not a key
|
||||
CheckUnparsable("wsh(wpkh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1))", "wsh(wpkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))", "Cannot have wpkh within wsh"); // Cannot embed witness inside witness
|
||||
CheckUnparsable("wsh(sh(pk(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)))", "wsh(sh(pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)))", "Cannot have sh in non-top level"); // Cannot embed P2SH inside P2WSH
|
||||
CheckUnparsable("sh(sh(pk(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)))", "sh(sh(pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)))", "Cannot have sh in non-top level"); // Cannot embed P2SH inside P2SH
|
||||
CheckUnparsable("wsh(wsh(pk(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)))", "wsh(wsh(pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)))", "Cannot have wsh within wsh"); // Cannot embed P2WSH inside P2WSH
|
||||
CheckUnparsable("wsh(wpkh(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1))", "wsh(wpkh(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd))", "Can only have wpkh() at top level or inside sh()"); // Cannot embed witness inside witness
|
||||
CheckUnparsable("wsh(sh(pk(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)))", "wsh(sh(pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)))", "Can only have sh() at top level"); // Cannot embed P2SH inside P2WSH
|
||||
CheckUnparsable("sh(sh(pk(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)))", "sh(sh(pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)))", "Can only have sh() at top level"); // Cannot embed P2SH inside P2SH
|
||||
CheckUnparsable("wsh(wsh(pk(L4rK1yDtCWekvXuE6oXD9jCYfFNV2cWRpVuPLBcCU2z8TrisoyY1)))", "wsh(wsh(pk(03a34b99f22c790c4e36b2b3c2c35a36db06226e41c692fc82b8b56ac1c540c5bd)))", "Can only have wsh() at top level or inside sh()"); // Cannot embed P2WSH inside P2WSH
|
||||
|
||||
// Checksums
|
||||
Check("sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfy", "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t", "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfy", "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t", DEFAULT, {{"a91445a9a622a8b0a1269944be477640eedc447bbd8487"}}, OutputType::LEGACY, {{0x8000006FUL,222},{0}});
|
||||
|
|
Loading…
Reference in a new issue