aboutsummaryrefslogtreecommitdiff
path: root/src/chain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/chain.cpp')
-rw-r--r--src/chain.cpp64
1 files changed, 54 insertions, 10 deletions
diff --git a/src/chain.cpp b/src/chain.cpp
index e76073674..2ce98818f 100644
--- a/src/chain.cpp
+++ b/src/chain.cpp
@@ -1,30 +1,30 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Copyright (c) 2009-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "chain.h"
-
-#include "main.h"
+#include "validation.h"
using namespace std;
/* Moved here from the header, because we need auxpow and the logic
becomes more involved. */
-CBlockHeader CBlockIndex::GetBlockHeader() const
+CBlockHeader CBlockIndex::GetBlockHeader(const Consensus::Params& consensusParams) const
{
CBlockHeader block;
+ block.nVersion = nVersion;
+
/* The CBlockIndex object's block header is missing the auxpow.
So if this is an auxpow block, read it from disk instead. We only
have to read the actual *header*, not the full block. */
- if (nVersion.IsAuxpow())
+ if (block.IsAuxpow())
{
- ReadBlockHeaderFromDisk(block, this);
+ ReadBlockHeaderFromDisk(block, this, consensusParams);
return block;
}
- block.nVersion = nVersion;
if (pprev)
block.hashPrevBlock = pprev->GetBlockHash();
block.hashMerkleRoot = hashMerkleRoot;
@@ -78,6 +78,9 @@ CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const {
}
const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {
+ if (pindex == NULL) {
+ return NULL;
+ }
if (pindex->nHeight > Height())
pindex = pindex->GetAncestor(Height());
while (pindex && !Contains(pindex))
@@ -85,6 +88,13 @@ const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {
return pindex;
}
+CBlockIndex* CChain::FindEarliestAtLeast(int64_t nTime) const
+{
+ 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() ? NULL : *lower);
+}
+
/** Turn the lowest '1' bit in the binary representation of a number into a '0'. */
int static inline InvertLowestOne(int n) { return n & (n - 1); }
@@ -109,13 +119,15 @@ CBlockIndex* CBlockIndex::GetAncestor(int height)
while (heightWalk > height) {
int heightSkip = GetSkipHeight(heightWalk);
int heightSkipPrev = GetSkipHeight(heightWalk - 1);
- if (heightSkip == height ||
- (heightSkip > height && !(heightSkipPrev < heightSkip - 2 &&
- heightSkipPrev >= height))) {
+ if (pindexWalk->pskip != NULL &&
+ (heightSkip == height ||
+ (heightSkip > height && !(heightSkipPrev < heightSkip - 2 &&
+ heightSkipPrev >= height)))) {
// Only follow pskip if pprev->pskip isn't better than pskip->pprev.
pindexWalk = pindexWalk->pskip;
heightWalk = heightSkip;
} else {
+ assert(pindexWalk->pprev);
pindexWalk = pindexWalk->pprev;
heightWalk--;
}
@@ -133,3 +145,35 @@ void CBlockIndex::BuildSkip()
if (pprev)
pskip = pprev->GetAncestor(GetSkipHeight(nHeight));
}
+
+arith_uint256 GetBlockProof(const CBlockIndex& block)
+{
+ arith_uint256 bnTarget;
+ bool fNegative;
+ bool fOverflow;
+ bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
+ if (fNegative || fOverflow || bnTarget == 0)
+ return 0;
+ // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
+ // as it's too large for a arith_uint256. However, as 2**256 is at least as large
+ // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
+ // or ~bnTarget / (nTarget+1) + 1.
+ return (~bnTarget / (bnTarget + 1)) + 1;
+}
+
+int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params)
+{
+ arith_uint256 r;
+ int sign = 1;
+ if (to.nChainWork > from.nChainWork) {
+ r = to.nChainWork - from.nChainWork;
+ } else {
+ r = from.nChainWork - to.nChainWork;
+ sign = -1;
+ }
+ r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip);
+ if (r.bits() > 63) {
+ return sign * std::numeric_limits<int64_t>::max();
+ }
+ return sign * r.GetLow64();
+}