MCPcopy Create free account
hub / github.com/ElementsProject/elements / GetPubKey

Method GetPubKey

src/script/descriptor.cpp:337–402  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

335 bool IsRange() const override { return m_derive != DeriveType::NO; }
336 size_t GetSize() const override { return 33; }
337 bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key_out, KeyOriginInfo& final_info_out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
338 {
339 // Info of parent of the to be derived pubkey
340 KeyOriginInfo parent_info;
341 CKeyID keyid = m_root_extkey.pubkey.GetID();
342 std::copy(keyid.begin(), keyid.begin() + sizeof(parent_info.fingerprint), parent_info.fingerprint);
343 parent_info.path = m_path;
344
345 // Info of the derived key itself which is copied out upon successful completion
346 KeyOriginInfo final_info_out_tmp = parent_info;
347 if (m_derive == DeriveType::UNHARDENED) final_info_out_tmp.path.push_back((uint32_t)pos);
348 if (m_derive == DeriveType::HARDENED) final_info_out_tmp.path.push_back(((uint32_t)pos) | 0x80000000L);
349
350 // Derive keys or fetch them from cache
351 CExtPubKey final_extkey = m_root_extkey;
352 CExtPubKey parent_extkey = m_root_extkey;
353 CExtPubKey last_hardened_extkey;
354 bool der = true;
355 if (read_cache) {
356 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
357 if (m_derive == DeriveType::HARDENED) return false;
358 // Try to get the derivation parent
359 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey)) return false;
360 final_extkey = parent_extkey;
361 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
362 }
363 } else if (IsHardened()) {
364 CExtKey xprv;
365 CExtKey lh_xprv;
366 if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return false;
367 parent_extkey = xprv.Neuter();
368 if (m_derive == DeriveType::UNHARDENED) der = xprv.Derive(xprv, pos);
369 if (m_derive == DeriveType::HARDENED) der = xprv.Derive(xprv, pos | 0x80000000UL);
370 final_extkey = xprv.Neuter();
371 if (lh_xprv.key.IsValid()) {
372 last_hardened_extkey = lh_xprv.Neuter();
373 }
374 } else {
375 for (auto entry : m_path) {
376 der = parent_extkey.Derive(parent_extkey, entry);
377 assert(der);
378 }
379 final_extkey = parent_extkey;
380 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
381 assert(m_derive != DeriveType::HARDENED);
382 }
383 assert(der);
384
385 final_info_out = final_info_out_tmp;
386 key_out = final_extkey.pubkey;
387
388 if (write_cache) {
389 // Only cache parent if there is any unhardened derivation
390 if (m_derive != DeriveType::HARDENED) {
391 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
392 // Cache last hardened xpub if we have it
393 if (last_hardened_extkey.pubkey.IsValid()) {
394 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);

Callers

nothing calls this directly

Calls 12

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

Tested by

no test coverage detected