diff options
| author | Russell Yanofsky <[email protected]> | 2020-01-21 17:08:12 -0500 |
|---|---|---|
| committer | Russell Yanofsky <[email protected]> | 2020-03-31 08:36:02 -0500 |
| commit | 1be8ff280c78c30baabae9429c53c0bebb89c44d (patch) | |
| tree | e028b55f2c2821390f9e913be5d5fb1c3516f5a9 /src/interfaces/chain.cpp | |
| parent | wallet refactor: Avoid use of Chain::Lock in CWallet::RescanFromTime (diff) | |
| download | discoin-1be8ff280c78c30baabae9429c53c0bebb89c44d.tar.xz discoin-1be8ff280c78c30baabae9429c53c0bebb89c44d.zip | |
wallet: Avoid use of Chain::Lock in rescanblockchain
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. The rescanblockchain error height error checking
will just be stricter in this case and only accept values up to the last
processed height
Diffstat (limited to 'src/interfaces/chain.cpp')
| -rw-r--r-- | src/interfaces/chain.cpp | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp index 0d69c33be..1c578b56c 100644 --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -103,20 +103,6 @@ class LockImpl : public Chain::Lock, public UniqueLock<RecursiveMutex> } return nullopt; } - Optional<int> findPruned(int start_height, Optional<int> stop_height) override - { - LockAssertion lock(::cs_main); - if (::fPruneMode) { - CBlockIndex* block = stop_height ? ::ChainActive()[*stop_height] : ::ChainActive().Tip(); - while (block && block->nHeight >= start_height) { - if ((block->nStatus & BLOCK_HAVE_DATA) == 0) { - return block->nHeight; - } - block = block->pprev; - } - } - return nullopt; - } Optional<int> findFork(const uint256& hash, Optional<int>* height) override { LockAssertion lock(::cs_main); @@ -297,6 +283,25 @@ public: LOCK(cs_main); return GuessVerificationProgress(Params().TxData(), LookupBlockIndex(block_hash)); } + bool hasBlocks(const uint256& block_hash, int min_height, Optional<int> max_height) override + { + // hasBlocks returns true if all ancestors of block_hash in specified + // range have block data (are not pruned), false if any ancestors in + // specified range are missing data. + // + // For simplicity and robustness, min_height and max_height are only + // used to limit the range, and passing min_height that's too low or + // max_height that's too high will not crash or change the result. + LOCK(::cs_main); + if (CBlockIndex* block = LookupBlockIndex(block_hash)) { + if (max_height && block->nHeight >= *max_height) block = block->GetAncestor(*max_height); + for (; block->nStatus & BLOCK_HAVE_DATA; block = block->pprev) { + // Check pprev to not segfault if min_height is too low + if (block->nHeight <= min_height || !block->pprev) return true; + } + } + return false; + } RBFTransactionState isRBFOptIn(const CTransaction& tx) override { LOCK(::mempool.cs); |