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

Method GetKeyBirthTimes

src/wallet/wallet.cpp:2696–2754  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2694/** @} */ // end of Actions
2695
2696void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t>& mapKeyBirth) const {
2697 AssertLockHeld(cs_wallet);
2698 mapKeyBirth.clear();
2699
2700 // map in which we'll infer heights of other keys
2701 std::map<CKeyID, const TxStateConfirmed*> mapKeyFirstBlock;
2702 TxStateConfirmed max_confirm{uint256{}, /*height=*/-1, /*index=*/-1};
2703 max_confirm.confirmed_block_height = GetLastBlockHeight() > 144 ? GetLastBlockHeight() - 144 : 0; // the tip can be reorganized; use a 144-block safety margin
2704 CHECK_NONFATAL(chain().findAncestorByHeight(GetLastBlockHash(), max_confirm.confirmed_block_height, FoundBlock().hash(max_confirm.confirmed_block_hash)));
2705
2706 {
2707 LegacyScriptPubKeyMan* spk_man = GetLegacyScriptPubKeyMan();
2708 assert(spk_man != nullptr);
2709 LOCK(spk_man->cs_KeyStore);
2710
2711 // get birth times for keys with metadata
2712 for (const auto& entry : spk_man->mapKeyMetadata) {
2713 if (entry.second.nCreateTime) {
2714 mapKeyBirth[entry.first] = entry.second.nCreateTime;
2715 }
2716 }
2717
2718 // Prepare to infer birth heights for keys without metadata
2719 for (const CKeyID &keyid : spk_man->GetKeys()) {
2720 if (mapKeyBirth.count(keyid) == 0)
2721 mapKeyFirstBlock[keyid] = &max_confirm;
2722 }
2723
2724 // if there are no such keys, we're done
2725 if (mapKeyFirstBlock.empty())
2726 return;
2727
2728 // find first block that affects those keys, if there are any left
2729 for (const auto& entry : mapWallet) {
2730 // iterate over all wallet transactions...
2731 const CWalletTx &wtx = entry.second;
2732 if (auto* conf = wtx.state<TxStateConfirmed>()) {
2733 // ... which are already in a block
2734 for (const CTxOut &txout : wtx.tx->vout) {
2735 // iterate over all their outputs
2736 for (const auto &keyid : GetAffectedKeys(txout.scriptPubKey, *spk_man)) {
2737 // ... and all their affected keys
2738 auto rit = mapKeyFirstBlock.find(keyid);
2739 if (rit != mapKeyFirstBlock.end() && conf->confirmed_block_height < rit->second->confirmed_block_height) {
2740 rit->second = conf;
2741 }
2742 }
2743 }
2744 }
2745 }
2746 }
2747
2748 // Extract block timestamps for those keys
2749 for (const auto& entry : mapKeyFirstBlock) {
2750 int64_t block_time;
2751 CHECK_NONFATAL(chain().findBlock(entry.second->confirmed_block_hash, FoundBlock().time(block_time)));
2752 mapKeyBirth[entry.first] = block_time - TIMESTAMP_WINDOW; // block times can be 2h off
2753 }

Callers 1

dumpwalletFunction · 0.80

Calls 11

FoundBlockClass · 0.85
GetAffectedKeysFunction · 0.85
findAncestorByHeightMethod · 0.80
hashMethod · 0.80
countMethod · 0.80
findMethod · 0.80
findBlockMethod · 0.80
clearMethod · 0.45
GetKeysMethod · 0.45
emptyMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected