| 2612 | }; |
| 2613 | |
| 2614 | void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const { |
| 2615 | AssertLockHeld(cs_wallet); // mapKeyMetadata |
| 2616 | mapKeyBirth.clear(); |
| 2617 | |
| 2618 | // get birth times for keys with metadata |
| 2619 | for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++) |
| 2620 | if (it->second.nCreateTime) |
| 2621 | mapKeyBirth[it->first] = it->second.nCreateTime; |
| 2622 | |
| 2623 | // map in which we'll infer heights of other keys |
| 2624 | CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin |
| 2625 | std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock; |
| 2626 | std::set<CKeyID> setKeys; |
| 2627 | GetKeys(setKeys); |
| 2628 | BOOST_FOREACH(const CKeyID &keyid, setKeys) { |
| 2629 | if (mapKeyBirth.count(keyid) == 0) |
| 2630 | mapKeyFirstBlock[keyid] = pindexMax; |
| 2631 | } |
| 2632 | setKeys.clear(); |
| 2633 | |
| 2634 | // if there are no such keys, we're done |
| 2635 | if (mapKeyFirstBlock.empty()) |
| 2636 | return; |
| 2637 | |
| 2638 | // find first block that affects those keys, if there are any left |
| 2639 | std::vector<CKeyID> vAffected; |
| 2640 | for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) { |
| 2641 | // iterate over all wallet transactions... |
| 2642 | const CWalletTx &wtx = (*it).second; |
| 2643 | BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock); |
| 2644 | if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) { |
| 2645 | // ... which are already in a block |
| 2646 | int nHeight = blit->second->nHeight; |
| 2647 | BOOST_FOREACH(const CTxOut &txout, wtx.vout) { |
| 2648 | // iterate over all their outputs |
| 2649 | CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey); |
| 2650 | BOOST_FOREACH(const CKeyID &keyid, vAffected) { |
| 2651 | // ... and all their affected keys |
| 2652 | std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid); |
| 2653 | if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight) |
| 2654 | rit->second = blit->second; |
| 2655 | } |
| 2656 | vAffected.clear(); |
| 2657 | } |
| 2658 | } |
| 2659 | } |
| 2660 | |
| 2661 | // Extract block timestamps for those keys |
| 2662 | for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++) |
| 2663 | mapKeyBirth[it->first] = it->second->GetBlockTime() - 7200; // block times can be 2h off |
| 2664 | } |
| 2665 | |
| 2666 | bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value) |
| 2667 | { |
no test coverage detected