aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Yanofsky <russ@yanofsky.org>2020-01-22 17:15:17 -0500
committerRussell Yanofsky <russ@yanofsky.org>2020-03-31 08:36:02 -0500
commit48973402d8bccb673eaeb68b7aa86faa39d3cb8a (patch)
tree307622d91c87c8b1cd79d8e66ac5522d638420d7
parente958ff9ab5607da2cd321f29fc785a6d359e44f4 (diff)
downloadbitcoin-48973402d8bccb673eaeb68b7aa86faa39d3cb8a.tar.xz
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.
-rw-r--r--src/interfaces/chain.cpp7
-rw-r--r--src/interfaces/chain.h3
-rw-r--r--src/wallet/wallet.cpp25
3 files changed, 15 insertions, 20 deletions
diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp
index 2b2d3a4b86..c8311b2986 100644
--- a/src/interfaces/chain.cpp
+++ b/src/interfaces/chain.cpp
@@ -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);
diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h
index ef5a002f54..a2d381b5c6 100644
--- a/src/interfaces/chain.h
+++ b/src/interfaces/chain.h
@@ -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;
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 37c61991a1..da8e7ee38d 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -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
+ }
}
/**