diff options
author | Russell Yanofsky <russ@yanofsky.org> | 2020-01-21 15:00:33 -0500 |
---|---|---|
committer | Russell Yanofsky <russ@yanofsky.org> | 2020-03-31 08:36:02 -0500 |
commit | f7ba881bc669451a60fedac58a449794702a3e23 (patch) | |
tree | c7a5782b68d6f6b71fb2da9ec94530cfaaa06deb /src/interfaces/chain.cpp | |
parent | bc96a9bfc61afdb696fb92cb644ed5fc3d1793f1 (diff) | |
download | bitcoin-f7ba881bc669451a60fedac58a449794702a3e23.tar.xz |
wallet: Avoid use of Chain::Lock in listsinceblock
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. Previously listsinceblock might not have returned
all transactions up to the claimed "lastblock" value in this case, resulting in
race conditions and potentially missing transactions in cases where
listsinceblock was called in a loop like
https://github.com/bitcoin/bitcoin/issues/14338#issuecomment-426706574
Diffstat (limited to 'src/interfaces/chain.cpp')
-rw-r--r-- | src/interfaces/chain.cpp | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp index dbc49eca1b..8cd4ab0b6d 100644 --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -260,6 +260,16 @@ public: WAIT_LOCK(cs_main, lock); return FillBlock(LookupBlockIndex(hash), block, lock); } + bool findAncestorByHeight(const uint256& block_hash, int ancestor_height, const FoundBlock& ancestor_out) override + { + WAIT_LOCK(cs_main, lock); + if (const CBlockIndex* block = LookupBlockIndex(block_hash)) { + if (const CBlockIndex* ancestor = block->GetAncestor(ancestor_height)) { + return FillBlock(ancestor, ancestor_out, lock); + } + } + return FillBlock(nullptr, ancestor_out, lock); + } bool findAncestorByHash(const uint256& block_hash, const uint256& ancestor_hash, const FoundBlock& ancestor_out) override { WAIT_LOCK(cs_main, lock); @@ -268,6 +278,14 @@ public: if (block && ancestor && block->GetAncestor(ancestor->nHeight) != ancestor) ancestor = nullptr; return FillBlock(ancestor, ancestor_out, lock); } + bool findCommonAncestor(const uint256& block_hash1, const uint256& block_hash2, const FoundBlock& ancestor_out, const FoundBlock& block1_out, const FoundBlock& block2_out) override + { + WAIT_LOCK(cs_main, lock); + const CBlockIndex* block1 = LookupBlockIndex(block_hash1); + const CBlockIndex* block2 = LookupBlockIndex(block_hash2); + const CBlockIndex* ancestor = block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr; + return FillBlock(ancestor, ancestor_out, lock) & FillBlock(block1, block1_out, lock) & FillBlock(block2, block2_out, lock); + } void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(m_node, coins); } double guessVerificationProgress(const uint256& block_hash) override { |