Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Consensus] Add locking on the chain index vector. #950

Merged
merged 1 commit into from
May 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* CChain implementation
*/
void CChain::SetTip(CBlockIndex *pindex) {
LOCK(cs_vchain);
if (pindex == nullptr) {
vChain.clear();
return;
Expand Down Expand Up @@ -68,6 +69,7 @@ const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {

CBlockIndex* CChain::FindEarliestAtLeast(int64_t nTime) const
{
LOCK(cs_vchain);
std::vector<CBlockIndex*>::const_iterator lower = std::lower_bound(vChain.begin(), vChain.end(), nTime,
[](CBlockIndex* pBlock, const int64_t& time) -> bool { return pBlock->GetBlockTimeMax() < time; });
return (lower == vChain.end() ? nullptr : *lower);
Expand Down
12 changes: 11 additions & 1 deletion src/chain.h
Original file line number Diff line number Diff line change
Expand Up @@ -725,28 +725,36 @@ class CDiskBlockIndex : public CBlockIndex
/** An in-memory indexed chain of blocks. */
class CChain {
private:
std::vector<CBlockIndex*> vChain;
mutable CCriticalSection cs_vchain;
std::vector<CBlockIndex*> vChain GUARDED_BY(cs_vchain);

public:
/** Returns the index entry for the genesis block of this chain, or nullptr if none. */
CBlockIndex *Genesis() const {
LOCK(cs_vchain);
return vChain.size() > 0 ? vChain[0] : nullptr;
}

/** Returns the index entry for the tip of this chain, or nullptr if none. */
CBlockIndex *Tip() const {
LOCK(cs_vchain);
return vChain.size() > 0 ? vChain[vChain.size() - 1] : nullptr;
}

/** Returns the index entry at a particular height in this chain, or nullptr if no such height exists. */
CBlockIndex *operator[](int nHeight) const {
LOCK(cs_vchain);
if (nHeight < 0 || nHeight >= (int)vChain.size())
return nullptr;
return vChain[nHeight];
}

/** Compare two chains efficiently. */
friend bool operator==(const CChain &a, const CChain &b) {
// Maintain consistent lock order.
if (&b < &a) return b == a;

LOCK2(a.cs_vchain, b.cs_vchain);
return a.vChain.size() == b.vChain.size() &&
a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1];
}
Expand All @@ -758,6 +766,7 @@ class CChain {

/** Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip. */
CBlockIndex *Next(const CBlockIndex *pindex) const {
LOCK(cs_vchain);
if (Contains(pindex))
return (*this)[pindex->nHeight + 1];
else
Expand All @@ -766,6 +775,7 @@ class CChain {

/** Return the maximal height in the chain. Is equal to chain.Tip() ? chain.Tip()->nHeight : -1. */
int Height() const {
LOCK(cs_vchain);
return vChain.size() - 1;
}

Expand Down