From f76733eda5f4c161e9eb47c74b949582ab8f448a Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Tue, 25 Feb 2020 18:28:05 -0500 Subject: Cache the immediate derivation parent xpub If unhardened derivation is used, cache the immediate derivation parent xpub and use it for unhardened derivation --- src/script/descriptor.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src/script/descriptor.cpp') diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index ac872c8cd2..30384fbd06 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -313,21 +313,30 @@ public: // Derive keys or fetch them from cache CExtPubKey final_extkey = m_root_extkey; + CExtPubKey parent_extkey = m_root_extkey; bool der = true; if (read_cache) { - if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) return false; + if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) { + if (m_derive == DeriveType::HARDENED) return false; + // Try to get the derivation parent + if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey)) return false; + final_extkey = parent_extkey; + if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos); + } } else if (IsHardened()) { CExtKey xprv; if (!GetDerivedExtKey(arg, 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(); } else { for (auto entry : m_path) { - der = final_extkey.Derive(final_extkey, entry); + der = parent_extkey.Derive(parent_extkey, entry); assert(der); } - if (m_derive == DeriveType::UNHARDENED) der = final_extkey.Derive(final_extkey, pos); + final_extkey = parent_extkey; + if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos); assert(m_derive != DeriveType::HARDENED); } assert(der); @@ -337,6 +346,10 @@ public: if (write_cache) { write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey); + // Only cache parent if there is any unhardened derivation + if (m_derive != DeriveType::HARDENED) { + write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey); + } } return true; -- cgit v1.2.3