mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-05 14:06:27 -05:00
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:
parent
e958ff9ab5
commit
48973402d8
3 changed files with 15 additions and 20 deletions
|
@ -80,13 +80,6 @@ class LockImpl : public Chain::Lock, public UniqueLock<RecursiveMutex>
|
||||||
assert(block != nullptr);
|
assert(block != nullptr);
|
||||||
return block->GetBlockHash();
|
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
|
bool haveBlockOnDisk(int height) override
|
||||||
{
|
{
|
||||||
LockAssertion lock(::cs_main);
|
LockAssertion lock(::cs_main);
|
||||||
|
|
|
@ -100,9 +100,6 @@ public:
|
||||||
//! Get block hash. Height must be valid or this function will abort.
|
//! Get block hash. Height must be valid or this function will abort.
|
||||||
virtual uint256 getBlockHash(int height) = 0;
|
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
|
//! Check that the block is available on disk (i.e. has not been
|
||||||
//! pruned), and contains transactions.
|
//! pruned), and contains transactions.
|
||||||
virtual bool haveBlockOnDisk(int height) = 0;
|
virtual bool haveBlockOnDisk(int height) = 0;
|
||||||
|
|
|
@ -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
|
// 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;
|
||||||
const int max_height = tip_height && *tip_height > 144 ? *tip_height - 144 : 0; // the tip can be reorganized; use a 144-block safety margin
|
CWalletTx::Confirmation max_confirm;
|
||||||
std::map<CKeyID, int> mapKeyFirstBlock;
|
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()) {
|
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
|
||||||
|
@ -3570,23 +3571,27 @@ void CWallet::GetKeyBirthTimes(interfaces::Chain::Lock& locked_chain, std::map<C
|
||||||
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 = locked_chain.getBlockHeight(wtx.m_confirm.hashBlock)) {
|
if (wtx.m_confirm.status == CWalletTx::CONFIRMED) {
|
||||||
// ... 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 : GetAffectedKeys(txout.scriptPubKey, *spk_man)) {
|
for (const auto &keyid : GetAffectedKeys(txout.scriptPubKey, *spk_man)) {
|
||||||
// ... and all their affected keys
|
// ... and all their affected keys
|
||||||
std::map<CKeyID, int>::iterator rit = mapKeyFirstBlock.find(keyid);
|
auto rit = mapKeyFirstBlock.find(keyid);
|
||||||
if (rit != mapKeyFirstBlock.end() && *height < rit->second)
|
if (rit != mapKeyFirstBlock.end() && wtx.m_confirm.block_height < rit->second->block_height) {
|
||||||
rit->second = *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) {
|
||||||
mapKeyBirth[entry.first] = locked_chain.getBlockTime(entry.second) - TIMESTAMP_WINDOW; // block times can be 2h off
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue