mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-02 09:46:52 -05:00
Pass in DescriptorCache to ToNormalizedString
Use the descriptor xpub cache in ToNormalizedString so that the wallet does not need to be unlocked in order to get the normalized descriptor.
This commit is contained in:
parent
7a26ff10c2
commit
3280704886
3 changed files with 36 additions and 26 deletions
|
@ -181,7 +181,7 @@ public:
|
|||
virtual bool ToPrivateString(const SigningProvider& arg, std::string& out) const = 0;
|
||||
|
||||
/** Get the descriptor string form with the xpub at the last hardened derivation */
|
||||
virtual bool ToNormalizedString(const SigningProvider& arg, std::string& out) const = 0;
|
||||
virtual bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache = nullptr) const = 0;
|
||||
|
||||
/** Derive a private key, if private data is available in arg. */
|
||||
virtual bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const = 0;
|
||||
|
@ -216,10 +216,10 @@ public:
|
|||
ret = "[" + OriginString() + "]" + std::move(sub);
|
||||
return true;
|
||||
}
|
||||
bool ToNormalizedString(const SigningProvider& arg, std::string& ret) const override
|
||||
bool ToNormalizedString(const SigningProvider& arg, std::string& ret, const DescriptorCache* cache) const override
|
||||
{
|
||||
std::string sub;
|
||||
if (!m_provider->ToNormalizedString(arg, sub)) return false;
|
||||
if (!m_provider->ToNormalizedString(arg, sub, cache)) return false;
|
||||
// If m_provider is a BIP32PubkeyProvider, we may get a string formatted like a OriginPubkeyProvider
|
||||
// In that case, we need to strip out the leading square bracket and fingerprint from the substring,
|
||||
// and append that to our own origin string.
|
||||
|
@ -263,7 +263,7 @@ public:
|
|||
ret = EncodeSecret(key);
|
||||
return true;
|
||||
}
|
||||
bool ToNormalizedString(const SigningProvider& arg, std::string& ret) const override
|
||||
bool ToNormalizedString(const SigningProvider& arg, std::string& ret, const DescriptorCache* cache) const override
|
||||
{
|
||||
ret = ToString();
|
||||
return true;
|
||||
|
@ -412,7 +412,7 @@ public:
|
|||
}
|
||||
return true;
|
||||
}
|
||||
bool ToNormalizedString(const SigningProvider& arg, std::string& out) const override
|
||||
bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override
|
||||
{
|
||||
// For hardened derivation type, just return the typical string, nothing to normalize
|
||||
if (m_derive == DeriveType::HARDENED) {
|
||||
|
@ -431,29 +431,39 @@ public:
|
|||
out = ToString();
|
||||
return true;
|
||||
}
|
||||
// Derive the xpub at the last hardened step
|
||||
CExtKey xprv;
|
||||
if (!GetExtKey(arg, xprv)) return false;
|
||||
// Get the path to the last hardened stup
|
||||
KeyOriginInfo origin;
|
||||
int k = 0;
|
||||
for (; k <= i; ++k) {
|
||||
// Derive
|
||||
xprv.Derive(xprv, m_path.at(k));
|
||||
// Add to the path
|
||||
origin.path.push_back(m_path.at(k));
|
||||
// First derivation element, get the fingerprint for origin
|
||||
if (k == 0) {
|
||||
std::copy(xprv.vchFingerprint, xprv.vchFingerprint + 4, origin.fingerprint);
|
||||
}
|
||||
}
|
||||
// Build the remaining path
|
||||
KeyPath end_path;
|
||||
for (; k < (int)m_path.size(); ++k) {
|
||||
end_path.push_back(m_path.at(k));
|
||||
}
|
||||
// Get the fingerprint
|
||||
CKeyID id = m_root_extkey.pubkey.GetID();
|
||||
std::copy(id.begin(), id.begin() + 4, origin.fingerprint);
|
||||
|
||||
CExtPubKey xpub;
|
||||
CExtKey lh_xprv;
|
||||
// If we have the cache, just get the parent xpub
|
||||
if (cache != nullptr) {
|
||||
cache->GetCachedLastHardenedExtPubKey(m_expr_index, xpub);
|
||||
}
|
||||
if (!xpub.pubkey.IsValid()) {
|
||||
// Cache miss, or nor cache, or need privkey
|
||||
CExtKey xprv;
|
||||
if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return false;
|
||||
xpub = lh_xprv.Neuter();
|
||||
}
|
||||
assert(xpub.pubkey.IsValid());
|
||||
|
||||
// Build the string
|
||||
std::string origin_str = HexStr(origin.fingerprint) + FormatHDKeypath(origin.path);
|
||||
out = "[" + origin_str + "]" + EncodeExtPubKey(xprv.Neuter()) + FormatHDKeypath(end_path);
|
||||
out = "[" + origin_str + "]" + EncodeExtPubKey(xpub) + FormatHDKeypath(end_path);
|
||||
if (IsRange()) {
|
||||
out += "/*";
|
||||
assert(m_derive == DeriveType::UNHARDENED);
|
||||
|
@ -533,19 +543,19 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type) const
|
||||
virtual bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const
|
||||
{
|
||||
size_t pos = 0;
|
||||
for (const auto& scriptarg : m_subdescriptor_args) {
|
||||
if (pos++) ret += ",";
|
||||
std::string tmp;
|
||||
if (!scriptarg->ToStringHelper(arg, tmp, type)) return false;
|
||||
if (!scriptarg->ToStringHelper(arg, tmp, type, cache)) return false;
|
||||
ret += std::move(tmp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type) const
|
||||
bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type, const DescriptorCache* cache = nullptr) const
|
||||
{
|
||||
std::string extra = ToStringExtra();
|
||||
size_t pos = extra.size() > 0 ? 1 : 0;
|
||||
|
@ -555,7 +565,7 @@ public:
|
|||
std::string tmp;
|
||||
switch (type) {
|
||||
case StringType::NORMALIZED:
|
||||
if (!pubkey->ToNormalizedString(*arg, tmp)) return false;
|
||||
if (!pubkey->ToNormalizedString(*arg, tmp, cache)) return false;
|
||||
break;
|
||||
case StringType::PRIVATE:
|
||||
if (!pubkey->ToPrivateString(*arg, tmp)) return false;
|
||||
|
@ -567,7 +577,7 @@ public:
|
|||
ret += std::move(tmp);
|
||||
}
|
||||
std::string subscript;
|
||||
if (!ToStringSubScriptHelper(arg, subscript, type)) return false;
|
||||
if (!ToStringSubScriptHelper(arg, subscript, type, cache)) return false;
|
||||
if (pos && subscript.size()) ret += ',';
|
||||
out = std::move(ret) + std::move(subscript) + ")";
|
||||
return true;
|
||||
|
@ -587,9 +597,9 @@ public:
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool ToNormalizedString(const SigningProvider& arg, std::string& out) const override final
|
||||
bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override final
|
||||
{
|
||||
bool ret = ToStringHelper(&arg, out, StringType::NORMALIZED);
|
||||
bool ret = ToStringHelper(&arg, out, StringType::NORMALIZED, cache);
|
||||
out = AddChecksum(out);
|
||||
return ret;
|
||||
}
|
||||
|
@ -843,7 +853,7 @@ protected:
|
|||
out.tr_spenddata[output].Merge(builder.GetSpendData());
|
||||
return Vector(GetScriptForDestination(output));
|
||||
}
|
||||
bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type) const override
|
||||
bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const override
|
||||
{
|
||||
if (m_depths.empty()) return true;
|
||||
std::vector<bool> path;
|
||||
|
@ -854,7 +864,7 @@ protected:
|
|||
path.push_back(false);
|
||||
}
|
||||
std::string tmp;
|
||||
if (!m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type)) return false;
|
||||
if (!m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)) return false;
|
||||
ret += std::move(tmp);
|
||||
while (!path.empty() && path.back()) {
|
||||
if (path.size() > 1) ret += '}';
|
||||
|
|
|
@ -115,7 +115,7 @@ struct Descriptor {
|
|||
virtual bool ToPrivateString(const SigningProvider& provider, std::string& out) const = 0;
|
||||
|
||||
/** Convert the descriptor to a normalized string. Normalized descriptors have the xpub at the last hardened step. This fails if the provided provider does not have the private keys to derive that xpub. */
|
||||
virtual bool ToNormalizedString(const SigningProvider& provider, std::string& out) const = 0;
|
||||
virtual bool ToNormalizedString(const SigningProvider& provider, std::string& out, const DescriptorCache* cache = nullptr) const = 0;
|
||||
|
||||
/** Expand a descriptor at a specified position.
|
||||
*
|
||||
|
|
|
@ -2276,7 +2276,7 @@ bool DescriptorScriptPubKeyMan::GetDescriptorString(std::string& out) const
|
|||
FlatSigningProvider provider;
|
||||
provider.keys = GetKeys();
|
||||
|
||||
return m_wallet_descriptor.descriptor->ToNormalizedString(provider, out);
|
||||
return m_wallet_descriptor.descriptor->ToNormalizedString(provider, out, &m_wallet_descriptor.cache);
|
||||
}
|
||||
|
||||
void DescriptorScriptPubKeyMan::UpgradeDescriptorCache()
|
||||
|
|
Loading…
Add table
Reference in a new issue