mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-08 10:31:50 -05:00
refactor: move uncompressed-permitted logic into ParsePubkey*
This is a preparation for parsing xonly pubkeys, which will complicate this logic. It's cleaner to put the decision logic close to the public key parsing itself.
This commit is contained in:
parent
17e006ff8d
commit
33275a9649
1 changed files with 14 additions and 12 deletions
|
@ -821,9 +821,10 @@ public:
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum class ParseScriptContext {
|
||||
TOP,
|
||||
P2SH,
|
||||
P2WSH,
|
||||
TOP, //!< Top-level context (script goes directly in scriptPubKey)
|
||||
P2SH, //!< Inside sh() (script becomes P2SH redeemScript)
|
||||
P2WPKH, //!< Inside wpkh() (no script, pubkey only)
|
||||
P2WSH, //!< Inside wsh() (script becomes v0 witness script)
|
||||
};
|
||||
|
||||
/** Parse a key path, being passed a split list of elements (the first element is ignored). */
|
||||
|
@ -850,10 +851,11 @@ enum class ParseScriptContext {
|
|||
}
|
||||
|
||||
/** Parse a public key that excludes origin information. */
|
||||
std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const Span<const char>& sp, bool permit_uncompressed, FlatSigningProvider& out, std::string& error)
|
||||
std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
|
||||
{
|
||||
using namespace spanparsing;
|
||||
|
||||
bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
|
||||
auto split = Split(sp, '/');
|
||||
std::string str(split[0].begin(), split[0].end());
|
||||
if (str.size() == 0) {
|
||||
|
@ -911,7 +913,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const S
|
|||
}
|
||||
|
||||
/** Parse a public key including origin information (if enabled). */
|
||||
std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<const char>& sp, bool permit_uncompressed, FlatSigningProvider& out, std::string& error)
|
||||
std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
|
||||
{
|
||||
using namespace spanparsing;
|
||||
|
||||
|
@ -920,7 +922,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<c
|
|||
error = "Multiple ']' characters found for a single pubkey";
|
||||
return nullptr;
|
||||
}
|
||||
if (origin_split.size() == 1) return ParsePubkeyInner(key_exp_index, origin_split[0], permit_uncompressed, out, error);
|
||||
if (origin_split.size() == 1) return ParsePubkeyInner(key_exp_index, origin_split[0], ctx, out, error);
|
||||
if (origin_split[0].empty() || origin_split[0][0] != '[') {
|
||||
error = strprintf("Key origin start '[ character expected but not found, got '%c' instead",
|
||||
origin_split[0].empty() ? /** empty, implies split char */ ']' : origin_split[0][0]);
|
||||
|
@ -942,7 +944,7 @@ std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<c
|
|||
assert(fpr_bytes.size() == 4);
|
||||
std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.fingerprint);
|
||||
if (!ParseKeyPath(slash_split, info.path, error)) return nullptr;
|
||||
auto provider = ParsePubkeyInner(key_exp_index, origin_split[1], permit_uncompressed, out, error);
|
||||
auto provider = ParsePubkeyInner(key_exp_index, origin_split[1], ctx, out, error);
|
||||
if (!provider) return nullptr;
|
||||
return std::make_unique<OriginPubkeyProvider>(key_exp_index, std::move(info), std::move(provider));
|
||||
}
|
||||
|
@ -955,19 +957,19 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const
|
|||
auto expr = Expr(sp);
|
||||
bool sorted_multi = false;
|
||||
if (Func("pk", expr)) {
|
||||
auto pubkey = ParsePubkey(key_exp_index, expr, ctx != ParseScriptContext::P2WSH, out, error);
|
||||
auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
|
||||
if (!pubkey) return nullptr;
|
||||
++key_exp_index;
|
||||
return std::make_unique<PKDescriptor>(std::move(pubkey));
|
||||
}
|
||||
if (Func("pkh", expr)) {
|
||||
auto pubkey = ParsePubkey(key_exp_index, expr, ctx != ParseScriptContext::P2WSH, out, error);
|
||||
auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
|
||||
if (!pubkey) return nullptr;
|
||||
++key_exp_index;
|
||||
return std::make_unique<PKHDescriptor>(std::move(pubkey));
|
||||
}
|
||||
if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
|
||||
auto pubkey = ParsePubkey(key_exp_index, expr, true, out, error);
|
||||
auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
|
||||
if (!pubkey) return nullptr;
|
||||
++key_exp_index;
|
||||
return std::make_unique<ComboDescriptor>(std::move(pubkey));
|
||||
|
@ -990,7 +992,7 @@ std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const
|
|||
return nullptr;
|
||||
}
|
||||
auto arg = Expr(expr);
|
||||
auto pk = ParsePubkey(key_exp_index, arg, ctx != ParseScriptContext::P2WSH, out, error);
|
||||
auto pk = ParsePubkey(key_exp_index, arg, ctx, out, error);
|
||||
if (!pk) return nullptr;
|
||||
script_size += pk->GetSize() + 1;
|
||||
providers.emplace_back(std::move(pk));
|
||||
|
@ -1021,7 +1023,7 @@ 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)) {
|
||||
auto pubkey = ParsePubkey(key_exp_index, expr, false, out, error);
|
||||
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));
|
||||
|
|
Loading…
Add table
Reference in a new issue