From a099655f2e1be313a6b51bba9799ea512c6eda3c Mon Sep 17 00:00:00 2001 From: rkrux Date: Fri, 13 Jun 2025 16:15:13 +0530 Subject: [PATCH] scripted-diff: Update `DeriveType` enum values to mention ranged derivations While reviewing the MuSig2 descriptors PR 31244, I realized that the enum `DeriveType` here logically refers to the derive type for ranged descriptors. This became evident to me while going through the implementations of `IsRange` & `IsHardened` functions of `BIP32PubkeyProvider`, and the `ParsePubkeyInner` function. Initially I got confused by reading `IsRange` translating to `!= DeriveType::NO`, but later realised it specifically referred to the presence of ranged derivations. I propose explicitly mentioning "RANGED" in the values of the `DeriveType` enum would make it easier to parse the descriptors code. This enum is used in one file only - `script/descriptors.cpp`. That's why I explicitly passed it as the argument in the `sed` commands in the script below. -BEGIN VERIFY SCRIPT- sed -i 's/HARDENED\b/HARDENED_RANGED/g' src/script/descriptor.cpp sed -i 's/\bNO\b/NON_RANGED/g' src/script/descriptor.cpp -END VERIFY SCRIPT- --- src/script/descriptor.cpp | 54 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index bd819d365ae..aba92de6635 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -359,9 +359,9 @@ public: }; enum class DeriveType { - NO, - UNHARDENED, - HARDENED, + NON_RANGED, + UNHARDENED_RANGED, + HARDENED_RANGED, }; /** An object representing a parsed extended public key in a descriptor. */ @@ -401,7 +401,7 @@ class BIP32PubkeyProvider final : public PubkeyProvider bool IsHardened() const { - if (m_derive == DeriveType::HARDENED) return true; + if (m_derive == DeriveType::HARDENED_RANGED) return true; for (auto entry : m_path) { if (entry >> 31) return true; } @@ -410,7 +410,7 @@ class BIP32PubkeyProvider final : public PubkeyProvider public: BIP32PubkeyProvider(uint32_t exp_index, const CExtPubKey& extkey, KeyPath path, DeriveType derive, bool apostrophe) : PubkeyProvider(exp_index), m_root_extkey(extkey), m_path(std::move(path)), m_derive(derive), m_apostrophe(apostrophe) {} - bool IsRange() const override { return m_derive != DeriveType::NO; } + bool IsRange() const override { return m_derive != DeriveType::NON_RANGED; } size_t GetSize() const override { return 33; } bool IsBIP32() const override { return true; } std::optional GetPubKey(int pos, const SigningProvider& arg, FlatSigningProvider& out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override @@ -419,8 +419,8 @@ public: CKeyID keyid = m_root_extkey.pubkey.GetID(); std::copy(keyid.begin(), keyid.begin() + sizeof(info.fingerprint), info.fingerprint); info.path = m_path; - if (m_derive == DeriveType::UNHARDENED) info.path.push_back((uint32_t)pos); - if (m_derive == DeriveType::HARDENED) info.path.push_back(((uint32_t)pos) | 0x80000000L); + if (m_derive == DeriveType::UNHARDENED_RANGED) info.path.push_back((uint32_t)pos); + if (m_derive == DeriveType::HARDENED_RANGED) info.path.push_back(((uint32_t)pos) | 0x80000000L); // Derive keys or fetch them from cache CExtPubKey final_extkey = m_root_extkey; @@ -429,19 +429,19 @@ public: bool der = true; if (read_cache) { if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) { - if (m_derive == DeriveType::HARDENED) return std::nullopt; + if (m_derive == DeriveType::HARDENED_RANGED) return std::nullopt; // Try to get the derivation parent if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey)) return std::nullopt; final_extkey = parent_extkey; - if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos); + if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.Derive(final_extkey, pos); } } else if (IsHardened()) { CExtKey xprv; CExtKey lh_xprv; if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return std::nullopt; parent_extkey = xprv.Neuter(); - if (m_derive == DeriveType::UNHARDENED) der = xprv.Derive(xprv, pos); - if (m_derive == DeriveType::HARDENED) der = xprv.Derive(xprv, pos | 0x80000000UL); + if (m_derive == DeriveType::UNHARDENED_RANGED) der = xprv.Derive(xprv, pos); + if (m_derive == DeriveType::HARDENED_RANGED) der = xprv.Derive(xprv, pos | 0x80000000UL); final_extkey = xprv.Neuter(); if (lh_xprv.key.IsValid()) { last_hardened_extkey = lh_xprv.Neuter(); @@ -451,8 +451,8 @@ public: if (!parent_extkey.Derive(parent_extkey, entry)) return std::nullopt; } final_extkey = parent_extkey; - if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos); - assert(m_derive != DeriveType::HARDENED); + if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.Derive(final_extkey, pos); + assert(m_derive != DeriveType::HARDENED_RANGED); } if (!der) return std::nullopt; @@ -461,7 +461,7 @@ public: if (write_cache) { // Only cache parent if there is any unhardened derivation - if (m_derive != DeriveType::HARDENED) { + if (m_derive != DeriveType::HARDENED_RANGED) { write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey); // Cache last hardened xpub if we have it if (last_hardened_extkey.pubkey.IsValid()) { @@ -481,7 +481,7 @@ public: std::string ret = EncodeExtPubKey(m_root_extkey) + FormatHDKeypath(m_path, /*apostrophe=*/use_apostrophe); if (IsRange()) { ret += "/*"; - if (m_derive == DeriveType::HARDENED) ret += use_apostrophe ? '\'' : 'h'; + if (m_derive == DeriveType::HARDENED_RANGED) ret += use_apostrophe ? '\'' : 'h'; } return ret; } @@ -496,13 +496,13 @@ public: out = EncodeExtKey(key) + FormatHDKeypath(m_path, /*apostrophe=*/m_apostrophe); if (IsRange()) { out += "/*"; - if (m_derive == DeriveType::HARDENED) out += m_apostrophe ? '\'' : 'h'; + if (m_derive == DeriveType::HARDENED_RANGED) out += m_apostrophe ? '\'' : 'h'; } return true; } bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override { - if (m_derive == DeriveType::HARDENED) { + if (m_derive == DeriveType::HARDENED_RANGED) { out = ToString(StringType::PUBLIC, /*normalized=*/true); return true; @@ -554,7 +554,7 @@ public: out = "[" + origin_str + "]" + EncodeExtPubKey(xpub) + FormatHDKeypath(end_path); if (IsRange()) { out += "/*"; - assert(m_derive == DeriveType::UNHARDENED); + assert(m_derive == DeriveType::UNHARDENED_RANGED); } return true; } @@ -563,8 +563,8 @@ public: CExtKey extkey; CExtKey dummy; if (!GetDerivedExtKey(arg, extkey, dummy)) return; - if (m_derive == DeriveType::UNHARDENED && !extkey.Derive(extkey, pos)) return; - if (m_derive == DeriveType::HARDENED && !extkey.Derive(extkey, pos | 0x80000000UL)) return; + if (m_derive == DeriveType::UNHARDENED_RANGED && !extkey.Derive(extkey, pos)) return; + if (m_derive == DeriveType::HARDENED_RANGED && !extkey.Derive(extkey, pos | 0x80000000UL)) return; out.keys.emplace(extkey.key.GetPubKey().GetID(), extkey.key); } std::optional GetRootPubKey() const override @@ -595,7 +595,7 @@ private: const DeriveType m_derive; const bool m_ranged_participants; - bool IsRangedDerivation() const { return m_derive != DeriveType::NO; } + bool IsRangedDerivation() const { return m_derive != DeriveType::NON_RANGED; } public: MuSigPubkeyProvider( @@ -613,7 +613,7 @@ public: if (!Assume(!(m_ranged_participants && IsRangedDerivation()))) { throw std::runtime_error("musig(): Cannot have both ranged participants and ranged derivation"); } - if (!Assume(m_derive != DeriveType::HARDENED)) { + if (!Assume(m_derive != DeriveType::HARDENED_RANGED)) { throw std::runtime_error("musig(): Cannot have hardened derivation"); } } @@ -1723,14 +1723,14 @@ std::optional ParseKeyPathNum(std::span elem, bool& apostr static DeriveType ParseDeriveType(std::vector>& split, bool& apostrophe) { - DeriveType type = DeriveType::NO; + DeriveType type = DeriveType::NON_RANGED; if (std::ranges::equal(split.back(), std::span{"*"}.first(1))) { split.pop_back(); - type = DeriveType::UNHARDENED; + type = DeriveType::UNHARDENED_RANGED; } else if (std::ranges::equal(split.back(), std::span{"*'"}.first(2)) || std::ranges::equal(split.back(), std::span{"*h"}.first(2))) { apostrophe = std::ranges::equal(split.back(), std::span{"*'"}.first(2)); split.pop_back(); - type = DeriveType::HARDENED; + type = DeriveType::HARDENED_RANGED; } return type; } @@ -1872,7 +1872,7 @@ std::vector> ParsePubkey(uint32_t& key_exp_index } // Parse any derivation - DeriveType deriv_type = DeriveType::NO; + DeriveType deriv_type = DeriveType::NON_RANGED; std::vector derivation_multipaths; if (split.size() == 2 && Const("/", split.at(1), /*skip=*/false)) { if (!all_bip32) { @@ -1886,7 +1886,7 @@ std::vector> ParsePubkey(uint32_t& key_exp_index bool dummy = false; auto deriv_split = Split(split.at(1), '/'); deriv_type = ParseDeriveType(deriv_split, dummy); - if (deriv_type == DeriveType::HARDENED) { + if (deriv_type == DeriveType::HARDENED_RANGED) { error = "musig(): Cannot have hardened child derivation"; return {}; }