MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / GetPubKey

Method GetPubKey

src/script/descriptor.cpp:446–506  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

444 size_t GetSize() const override { return 33; }
445 bool IsBIP32() const override { return true; }
446 std::optional<CPubKey> GetPubKey(int pos, const SigningProvider& arg, FlatSigningProvider& out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
447 {
448 KeyOriginInfo info;
449 CKeyID keyid = m_root_extkey.pubkey.GetID();
450 std::copy(keyid.begin(), keyid.begin() + sizeof(info.fingerprint), info.fingerprint);
451 info.path = m_path;
452 if (m_derive == DeriveType::UNHARDENED_RANGED) info.path.push_back((uint32_t)pos);
453 if (m_derive == DeriveType::HARDENED_RANGED) info.path.push_back(((uint32_t)pos) | 0x80000000L);
454
455 // Derive keys or fetch them from cache
456 CExtPubKey final_extkey = m_root_extkey;
457 CExtPubKey parent_extkey = m_root_extkey;
458 CExtPubKey last_hardened_extkey;
459 bool der = true;
460 if (read_cache) {
461 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
462 if (m_derive == DeriveType::HARDENED_RANGED) return std::nullopt;
463 // Try to get the derivation parent
464 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey)) return std::nullopt;
465 final_extkey = parent_extkey;
466 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.Derive(final_extkey, pos);
467 }
468 } else if (IsHardened()) {
469 CExtKey xprv;
470 CExtKey lh_xprv;
471 if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return std::nullopt;
472 parent_extkey = xprv.Neuter();
473 if (m_derive == DeriveType::UNHARDENED_RANGED) der = xprv.Derive(xprv, pos);
474 if (m_derive == DeriveType::HARDENED_RANGED) der = xprv.Derive(xprv, pos | 0x80000000UL);
475 final_extkey = xprv.Neuter();
476 if (lh_xprv.key.IsValid()) {
477 last_hardened_extkey = lh_xprv.Neuter();
478 }
479 } else {
480 for (auto entry : m_path) {
481 if (!parent_extkey.Derive(parent_extkey, entry)) return std::nullopt;
482 }
483 final_extkey = parent_extkey;
484 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.Derive(final_extkey, pos);
485 assert(m_derive != DeriveType::HARDENED_RANGED);
486 }
487 if (!der) return std::nullopt;
488
489 out.origins.emplace(final_extkey.pubkey.GetID(), std::make_pair(final_extkey.pubkey, info));
490 out.pubkeys.emplace(final_extkey.pubkey.GetID(), final_extkey.pubkey);
491
492 if (write_cache) {
493 // Only cache parent if there is any unhardened derivation
494 if (m_derive != DeriveType::HARDENED_RANGED) {
495 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
496 // Cache last hardened xpub if we have it
497 if (last_hardened_extkey.pubkey.IsValid()) {
498 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
499 }
500 } else if (info.path.size() > 0) {
501 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
502 }
503 }

Callers

nothing calls this directly

Calls 13

NeuterMethod · 0.80
emplaceMethod · 0.80
CacheParentExtPubKeyMethod · 0.80
CacheDerivedExtPubKeyMethod · 0.80
GetIDMethod · 0.45
beginMethod · 0.45
push_backMethod · 0.45
DeriveMethod · 0.45
IsValidMethod · 0.45

Tested by

no test coverage detected