mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 10:43:19 -03:00
descriptors: Cache last hardened xpub
Cache the last hardenex xpub in the DescriptorCache
This commit is contained in:
parent
cacc391098
commit
d87b544b83
2 changed files with 61 additions and 3 deletions
|
@ -302,11 +302,14 @@ class BIP32PubkeyProvider final : public PubkeyProvider
|
|||
}
|
||||
|
||||
// Derives the last xprv
|
||||
bool GetDerivedExtKey(const SigningProvider& arg, CExtKey& xprv) const
|
||||
bool GetDerivedExtKey(const SigningProvider& arg, CExtKey& xprv, CExtKey& last_hardened) const
|
||||
{
|
||||
if (!GetExtKey(arg, xprv)) return false;
|
||||
for (auto entry : m_path) {
|
||||
xprv.Derive(xprv, entry);
|
||||
if (entry >> 31) {
|
||||
last_hardened = xprv;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -340,6 +343,7 @@ public:
|
|||
// Derive keys or fetch them from cache
|
||||
CExtPubKey final_extkey = m_root_extkey;
|
||||
CExtPubKey parent_extkey = m_root_extkey;
|
||||
CExtPubKey last_hardened_extkey;
|
||||
bool der = true;
|
||||
if (read_cache) {
|
||||
if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
|
||||
|
@ -351,11 +355,15 @@ public:
|
|||
}
|
||||
} else if (IsHardened()) {
|
||||
CExtKey xprv;
|
||||
if (!GetDerivedExtKey(arg, xprv)) return false;
|
||||
CExtKey lh_xprv;
|
||||
if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return false;
|
||||
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);
|
||||
final_extkey = xprv.Neuter();
|
||||
if (lh_xprv.key.IsValid()) {
|
||||
last_hardened_extkey = lh_xprv.Neuter();
|
||||
}
|
||||
} else {
|
||||
for (auto entry : m_path) {
|
||||
der = parent_extkey.Derive(parent_extkey, entry);
|
||||
|
@ -374,6 +382,10 @@ public:
|
|||
// Only cache parent if there is any unhardened derivation
|
||||
if (m_derive != DeriveType::HARDENED) {
|
||||
write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
|
||||
// Cache last hardened xpub if we have it
|
||||
if (last_hardened_extkey.pubkey.IsValid()) {
|
||||
write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
|
||||
}
|
||||
} else if (final_info_out.path.size() > 0) {
|
||||
write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
|
||||
}
|
||||
|
@ -454,7 +466,8 @@ public:
|
|||
bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
|
||||
{
|
||||
CExtKey extkey;
|
||||
if (!GetDerivedExtKey(arg, extkey)) return false;
|
||||
CExtKey dummy;
|
||||
if (!GetDerivedExtKey(arg, extkey, dummy)) return false;
|
||||
if (m_derive == DeriveType::UNHARDENED) extkey.Derive(extkey, pos);
|
||||
if (m_derive == DeriveType::HARDENED) extkey.Derive(extkey, pos | 0x80000000UL);
|
||||
key = extkey.key;
|
||||
|
@ -1400,6 +1413,11 @@ void DescriptorCache::CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_i
|
|||
xpubs[der_index] = xpub;
|
||||
}
|
||||
|
||||
void DescriptorCache::CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub)
|
||||
{
|
||||
m_last_hardened_xpubs[key_exp_pos] = xpub;
|
||||
}
|
||||
|
||||
bool DescriptorCache::GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const
|
||||
{
|
||||
const auto& it = m_parent_xpubs.find(key_exp_pos);
|
||||
|
@ -1418,6 +1436,14 @@ bool DescriptorCache::GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t d
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DescriptorCache::GetCachedLastHardenedExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const
|
||||
{
|
||||
const auto& it = m_last_hardened_xpubs.find(key_exp_pos);
|
||||
if (it == m_last_hardened_xpubs.end()) return false;
|
||||
xpub = it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
DescriptorCache DescriptorCache::MergeAndDiff(const DescriptorCache& other)
|
||||
{
|
||||
DescriptorCache diff;
|
||||
|
@ -1445,6 +1471,17 @@ DescriptorCache DescriptorCache::MergeAndDiff(const DescriptorCache& other)
|
|||
diff.CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
|
||||
}
|
||||
}
|
||||
for (const auto& lh_xpub_pair : other.GetCachedLastHardenedExtPubKeys()) {
|
||||
CExtPubKey xpub;
|
||||
if (GetCachedLastHardenedExtPubKey(lh_xpub_pair.first, xpub)) {
|
||||
if (xpub != lh_xpub_pair.second) {
|
||||
throw std::runtime_error(std::string(__func__) + ": New cached last hardened xpub does not match already cached last hardened xpub");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
CacheLastHardenedExtPubKey(lh_xpub_pair.first, lh_xpub_pair.second);
|
||||
diff.CacheLastHardenedExtPubKey(lh_xpub_pair.first, lh_xpub_pair.second);
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
|
@ -1457,3 +1494,8 @@ const std::unordered_map<uint32_t, ExtPubKeyMap> DescriptorCache::GetCachedDeriv
|
|||
{
|
||||
return m_derived_xpubs;
|
||||
}
|
||||
|
||||
const ExtPubKeyMap DescriptorCache::GetCachedLastHardenedExtPubKeys() const
|
||||
{
|
||||
return m_last_hardened_xpubs;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ private:
|
|||
std::unordered_map<uint32_t, ExtPubKeyMap> m_derived_xpubs;
|
||||
/** Map key expression index -> parent xpub */
|
||||
ExtPubKeyMap m_parent_xpubs;
|
||||
/** Map key expression index -> last hardened xpub */
|
||||
ExtPubKeyMap m_last_hardened_xpubs;
|
||||
|
||||
public:
|
||||
/** Cache a parent xpub
|
||||
|
@ -50,11 +52,25 @@ public:
|
|||
* @param[in] xpub The CExtPubKey to get from cache
|
||||
*/
|
||||
bool GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey& xpub) const;
|
||||
/** Cache a last hardened xpub
|
||||
*
|
||||
* @param[in] key_exp_pos Position of the key expression within the descriptor
|
||||
* @param[in] xpub The CExtPubKey to cache
|
||||
*/
|
||||
void CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub);
|
||||
/** Retrieve a cached last hardened xpub
|
||||
*
|
||||
* @param[in] key_exp_pos Position of the key expression within the descriptor
|
||||
* @param[in] xpub The CExtPubKey to get from cache
|
||||
*/
|
||||
bool GetCachedLastHardenedExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const;
|
||||
|
||||
/** Retrieve all cached parent xpubs */
|
||||
const ExtPubKeyMap GetCachedParentExtPubKeys() const;
|
||||
/** Retrieve all cached derived xpubs */
|
||||
const std::unordered_map<uint32_t, ExtPubKeyMap> GetCachedDerivedExtPubKeys() const;
|
||||
/** Retrieve all cached last hardened xpubs */
|
||||
const ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const;
|
||||
|
||||
/** Combine another DescriptorCache into this one.
|
||||
* Returns a cache containing the items from the other cache unknown to current cache
|
||||
|
|
Loading…
Add table
Reference in a new issue