| 4085 | /** @} */ // end of Actions |
| 4086 | |
| 4087 | void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t>& mapKeyBirth) const { |
| 4088 | AssertLockHeld(cs_wallet); // mapKeyMetadata |
| 4089 | mapKeyBirth.clear(); |
| 4090 | |
| 4091 | // get birth times for keys with metadata |
| 4092 | for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++) |
| 4093 | if (it->second.nCreateTime) |
| 4094 | mapKeyBirth[it->first] = it->second.nCreateTime; |
| 4095 | |
| 4096 | // map in which we'll infer heights of other keys |
| 4097 | CBlockIndex* pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin |
| 4098 | std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock; |
| 4099 | std::set<CKeyID> setKeys = GetKeys(); |
| 4100 | for (const CKeyID& keyid : setKeys) { |
| 4101 | if (mapKeyBirth.count(keyid) == 0) |
| 4102 | mapKeyFirstBlock[keyid] = pindexMax; |
| 4103 | } |
| 4104 | setKeys.clear(); |
| 4105 | |
| 4106 | // if there are no such keys, we're done |
| 4107 | if (mapKeyFirstBlock.empty()) |
| 4108 | return; |
| 4109 | |
| 4110 | // find first block that affects those keys, if there are any left |
| 4111 | std::vector<CKeyID> vAffected; |
| 4112 | for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) { |
| 4113 | // iterate over all wallet transactions... |
| 4114 | const CWalletTx& wtx = (*it).second; |
| 4115 | CBlockIndex* pindex = LookupBlockIndex(wtx.hashBlock); |
| 4116 | if (pindex && chainActive.Contains(pindex)) { |
| 4117 | // ... which are already in a block |
| 4118 | int nHeight = pindex->nHeight; |
| 4119 | for (const CTxOut& txout : wtx.vout) { |
| 4120 | // iterate over all their outputs |
| 4121 | CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey); |
| 4122 | for (const CKeyID& keyid : vAffected) { |
| 4123 | // ... and all their affected keys |
| 4124 | std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid); |
| 4125 | if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight) |
| 4126 | rit->second = pindex; |
| 4127 | } |
| 4128 | vAffected.clear(); |
| 4129 | } |
| 4130 | } |
| 4131 | } |
| 4132 | |
| 4133 | // Extract block timestamps for those keys |
| 4134 | for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++) |
| 4135 | mapKeyBirth[it->first] = it->second->GetBlockTime() - 7200; // block times can be 2h off |
| 4136 | } |
| 4137 | |
| 4138 | bool CWallet::AddDestData(const CTxDestination& dest, const std::string& key, const std::string& value) |
| 4139 | { |
no test coverage detected