aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp3
-rw-r--r--src/net.cpp2
-rw-r--r--src/timedata.cpp18
-rw-r--r--src/txmempool.cpp7
4 files changed, 25 insertions, 5 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 84178b16e2..06ce15b5b3 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2016,7 +2016,7 @@ static CBlockIndex* FindMostWorkChain() {
CBlockIndex *pindexTest = pindexNew;
bool fInvalidAncestor = false;
while (pindexTest && !chainActive.Contains(pindexTest)) {
- if (!pindexTest->IsValid(BLOCK_VALID_TRANSACTIONS) || !(pindexTest->nStatus & BLOCK_HAVE_DATA)) {
+ if (pindexTest->nStatus & BLOCK_FAILED_MASK) {
// Candidate has an invalid ancestor, remove entire chain from the set.
if (pindexBestInvalid == NULL || pindexNew->nChainWork > pindexBestInvalid->nChainWork)
pindexBestInvalid = pindexNew;
@@ -2026,6 +2026,7 @@ static CBlockIndex* FindMostWorkChain() {
setBlockIndexValid.erase(pindexFailed);
pindexFailed = pindexFailed->pprev;
}
+ setBlockIndexValid.erase(pindexTest);
fInvalidAncestor = true;
break;
}
diff --git a/src/net.cpp b/src/net.cpp
index 329e0278ca..6c636d16b4 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1478,7 +1478,7 @@ bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOu
if (!pszDest) {
if (IsLocal(addrConnect) ||
FindNode((CNetAddr)addrConnect) || CNode::IsBanned(addrConnect) ||
- FindNode(addrConnect.ToStringIPPort().c_str()))
+ FindNode(addrConnect.ToStringIPPort()))
return false;
} else if (FindNode(pszDest))
return false;
diff --git a/src/timedata.cpp b/src/timedata.cpp
index 8a095d26dc..6c3bd9a48d 100644
--- a/src/timedata.cpp
+++ b/src/timedata.cpp
@@ -49,6 +49,24 @@ void AddTimeData(const CNetAddr& ip, int64_t nTime)
static CMedianFilter<int64_t> vTimeOffsets(200,0);
vTimeOffsets.input(nOffsetSample);
LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
+
+ // There is a known issue here (see issue #4521):
+ //
+ // - The structure vTimeOffsets contains up to 200 elements, after which
+ // any new element added to it will not increase its size, replacing the
+ // oldest element.
+ //
+ // - The condition to update nTimeOffset includes checking whether the
+ // number of elements in vTimeOffsets is odd, which will never happen after
+ // there are 200 elements.
+ //
+ // But in this case the 'bug' is protective against some attacks, and may
+ // actually explain why we've never seen attacks which manipulate the
+ // clock offset.
+ //
+ // So we should hold off on fixing this and clean it up as part of
+ // a timing cleanup that strengthens it in a number of other ways.
+ //
if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
{
int64_t nMedian = vTimeOffsets.median();
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index ebb1369e31..164e2741a2 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -602,14 +602,15 @@ void CTxMemPool::ClearPrioritisation(const uint256 hash)
CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) {
- if (base->GetCoins(txid, coins))
- return true;
+ // If an entry in the mempool exists, always return that one, as it's guaranteed to never
+ // conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
+ // transactions. First checking the underlying cache risks returning a pruned entry instead.
CTransaction tx;
if (mempool.lookup(txid, tx)) {
coins = CCoins(tx, MEMPOOL_HEIGHT);
return true;
}
- return false;
+ return (base->GetCoins(txid, coins) && !coins.IsPruned());
}
bool CCoinsViewMemPool::HaveCoins(const uint256 &txid) {