Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show First 20 Lines • Show All 3,832 Lines • ▼ Show 20 Lines | void CWallet::GetKeyBirthTimes(interfaces::Chain::Lock &locked_chain, | ||||
// Get birth times for keys with metadata. | // Get birth times for keys with metadata. | ||||
for (const auto &entry : spk_man->mapKeyMetadata) { | for (const auto &entry : spk_man->mapKeyMetadata) { | ||||
if (entry.second.nCreateTime) { | if (entry.second.nCreateTime) { | ||||
mapKeyBirth[entry.first] = entry.second.nCreateTime; | mapKeyBirth[entry.first] = entry.second.nCreateTime; | ||||
} | } | ||||
} | } | ||||
// Map in which we'll infer heights of other keys | // map in which we'll infer heights of other keys | ||||
const Optional<int> tip_height = locked_chain.getHeight(); | std::map<CKeyID, const CWalletTx::Confirmation *> mapKeyFirstBlock; | ||||
CWalletTx::Confirmation max_confirm; | |||||
// the tip can be reorganized; use a 144-block safety margin | // the tip can be reorganized; use a 144-block safety margin | ||||
const int max_height = | max_confirm.block_height = | ||||
tip_height && *tip_height > 144 ? *tip_height - 144 : 0; | GetLastBlockHeight() > 144 ? GetLastBlockHeight() - 144 : 0; | ||||
std::map<CKeyID, int> mapKeyFirstBlock; | CHECK_NONFATAL(chain().findAncestorByHeight( | ||||
GetLastBlockHash(), max_confirm.block_height, | |||||
FoundBlock().hash(max_confirm.hashBlock))); | |||||
for (const CKeyID &keyid : spk_man->GetKeys()) { | for (const CKeyID &keyid : spk_man->GetKeys()) { | ||||
if (mapKeyBirth.count(keyid) == 0) { | if (mapKeyBirth.count(keyid) == 0) { | ||||
mapKeyFirstBlock[keyid] = max_height; | mapKeyFirstBlock[keyid] = &max_confirm; | ||||
} | } | ||||
} | } | ||||
// If there are no such keys, we're done. | // If there are no such keys, we're done. | ||||
if (mapKeyFirstBlock.empty()) { | if (mapKeyFirstBlock.empty()) { | ||||
return; | return; | ||||
} | } | ||||
// Find first block that affects those keys, if there are any left. | // Find first block that affects those keys, if there are any left. | ||||
for (const auto &entry : mapWallet) { | for (const auto &entry : mapWallet) { | ||||
// iterate over all wallet transactions... | // iterate over all wallet transactions... | ||||
const CWalletTx &wtx = entry.second; | const CWalletTx &wtx = entry.second; | ||||
if (Optional<int> height = | if (wtx.m_confirm.status == CWalletTx::CONFIRMED) { | ||||
locked_chain.getBlockHeight(wtx.m_confirm.hashBlock)) { | |||||
// ... which are already in a block | // ... which are already in a block | ||||
for (const CTxOut &txout : wtx.tx->vout) { | for (const CTxOut &txout : wtx.tx->vout) { | ||||
// Iterate over all their outputs... | // Iterate over all their outputs... | ||||
for (const auto &keyid : | for (const auto &keyid : | ||||
GetAffectedKeys(txout.scriptPubKey, *spk_man)) { | GetAffectedKeys(txout.scriptPubKey, *spk_man)) { | ||||
// ... and all their affected keys. | // ... and all their affected keys. | ||||
std::map<CKeyID, int>::iterator rit = | auto rit = mapKeyFirstBlock.find(keyid); | ||||
mapKeyFirstBlock.find(keyid); | |||||
if (rit != mapKeyFirstBlock.end() && | if (rit != mapKeyFirstBlock.end() && | ||||
*height < rit->second) { | wtx.m_confirm.block_height < | ||||
rit->second = *height; | rit->second->block_height) { | ||||
rit->second = &wtx.m_confirm; | |||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// Extract block timestamps for those keys. | // Extract block timestamps for those keys. | ||||
for (const auto &entry : mapKeyFirstBlock) { | for (const auto &entry : mapKeyFirstBlock) { | ||||
int64_t block_time; | |||||
CHECK_NONFATAL(chain().findBlock(entry.second->hashBlock, | |||||
FoundBlock().time(block_time))); | |||||
// block times can be 2h off | // block times can be 2h off | ||||
mapKeyBirth[entry.first] = | mapKeyBirth[entry.first] = block_time - TIMESTAMP_WINDOW; | ||||
locked_chain.getBlockTime(entry.second) - TIMESTAMP_WINDOW; | |||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Compute smart timestamp for a transaction being added to the wallet. | * Compute smart timestamp for a transaction being added to the wallet. | ||||
* | * | ||||
* Logic: | * Logic: | ||||
* - If sending a transaction, assign its timestamp to the current time. | * - If sending a transaction, assign its timestamp to the current time. | ||||
▲ Show 20 Lines • Show All 877 Lines • Show Last 20 Lines |