wallet: Avoid use of Chain::Lock in CWallet::GetKeyBirthTimes

This is a step toward removing the Chain::Lock class and reducing cs_main
locking.

This change only affects behavior in the case where wallet last block processed
falls behind the chain tip, where it will treat the last block processed as the
current tip.
This commit is contained in:
Russell Yanofsky 2020-01-22 17:15:17 -05:00
parent e958ff9ab5
commit 48973402d8
3 changed files with 15 additions and 20 deletions

View file

@ -80,13 +80,6 @@ class LockImpl : public Chain::Lock, public UniqueLock<RecursiveMutex>
assert(block != nullptr);
return block->GetBlockHash();
}
int64_t getBlockTime(int height) override
{
LockAssertion lock(::cs_main);
CBlockIndex* block = ::ChainActive()[height];
assert(block != nullptr);
return block->GetBlockTime();
}
bool haveBlockOnDisk(int height) override
{
LockAssertion lock(::cs_main);

View file

@ -100,9 +100,6 @@ public:
//! Get block hash. Height must be valid or this function will abort.
virtual uint256 getBlockHash(int height) = 0;
//! Get block time. Height must be valid or this function will abort.
virtual int64_t getBlockTime(int height) = 0;
//! Check that the block is available on disk (i.e. has not been
//! pruned), and contains transactions.
virtual bool haveBlockOnDisk(int height) = 0;

View file

@ -3554,12 +3554,13 @@ void CWallet::GetKeyBirthTimes(interfaces::Chain::Lock& locked_chain, std::map<C
}
// map in which we'll infer heights of other keys
const Optional<int> tip_height = locked_chain.getHeight();
const int max_height = tip_height && *tip_height > 144 ? *tip_height - 144 : 0; // the tip can be reorganized; use a 144-block safety margin
std::map<CKeyID, int> mapKeyFirstBlock;
std::map<CKeyID, const CWalletTx::Confirmation*> mapKeyFirstBlock;
CWalletTx::Confirmation max_confirm;
max_confirm.block_height = GetLastBlockHeight() > 144 ? GetLastBlockHeight() - 144 : 0; // the tip can be reorganized; use a 144-block safety margin
CHECK_NONFATAL(chain().findAncestorByHeight(GetLastBlockHash(), max_confirm.block_height, FoundBlock().hash(max_confirm.hashBlock)));
for (const CKeyID &keyid : spk_man->GetKeys()) {
if (mapKeyBirth.count(keyid) == 0)
mapKeyFirstBlock[keyid] = max_height;
mapKeyFirstBlock[keyid] = &max_confirm;
}
// if there are no such keys, we're done
@ -3570,23 +3571,27 @@ void CWallet::GetKeyBirthTimes(interfaces::Chain::Lock& locked_chain, std::map<C
for (const auto& entry : mapWallet) {
// iterate over all wallet transactions...
const CWalletTx &wtx = entry.second;
if (Optional<int> height = locked_chain.getBlockHeight(wtx.m_confirm.hashBlock)) {
if (wtx.m_confirm.status == CWalletTx::CONFIRMED) {
// ... which are already in a block
for (const CTxOut &txout : wtx.tx->vout) {
// iterate over all their outputs
for (const auto &keyid : GetAffectedKeys(txout.scriptPubKey, *spk_man)) {
// ... and all their affected keys
std::map<CKeyID, int>::iterator rit = mapKeyFirstBlock.find(keyid);
if (rit != mapKeyFirstBlock.end() && *height < rit->second)
rit->second = *height;
auto rit = mapKeyFirstBlock.find(keyid);
if (rit != mapKeyFirstBlock.end() && wtx.m_confirm.block_height < rit->second->block_height) {
rit->second = &wtx.m_confirm;
}
}
}
}
}
// Extract block timestamps for those keys
for (const auto& entry : mapKeyFirstBlock)
mapKeyBirth[entry.first] = locked_chain.getBlockTime(entry.second) - TIMESTAMP_WINDOW; // block times can be 2h off
for (const auto& entry : mapKeyFirstBlock) {
int64_t block_time;
CHECK_NONFATAL(chain().findBlock(entry.second->hashBlock, FoundBlock().time(block_time)));
mapKeyBirth[entry.first] = block_time - TIMESTAMP_WINDOW; // block times can be 2h off
}
}
/**