diff --git a/src/chain.h b/src/chain.h index f1d28a5b58..99b63408f7 100644 --- a/src/chain.h +++ b/src/chain.h @@ -200,6 +200,7 @@ class CBlockIndex //! (memory only) Maximum nTime in the chain up to and including this block. unsigned int nTimeMax{0}; + CBlockIndex *lastAlgoBlocks[NUM_ALGOS_IMPL]; CBlockIndex() { @@ -212,6 +213,9 @@ class CBlockIndex nBits{block.nBits}, nNonce{block.nNonce} { + for (unsigned i = 0; i < NUM_ALGOS_IMPL; i++) + lastAlgoBlocks[i] = nullptr; + lastAlgoBlocks[GetAlgo()] = this; } FlatFilePos GetBlockPos() const { diff --git a/src/pow.cpp b/src/pow.cpp index 9c178ed422..4a213cfbb7 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -200,7 +200,7 @@ unsigned int GetNextWorkRequiredV4(const CBlockIndex* pindexLast, const Consensu pindexFirst = pindexFirst->pprev; } - const CBlockIndex* pindexPrevAlgo = GetLastBlockIndexForAlgo(pindexLast, params, algo); + const CBlockIndex* pindexPrevAlgo = GetLastBlockIndexForAlgoFast(pindexLast, params, algo); if (pindexPrevAlgo == nullptr || pindexFirst == nullptr) { return InitialDifficulty(params, algo); @@ -239,6 +239,10 @@ unsigned int GetNextWorkRequiredV4(const CBlockIndex* pindexLast, const Consensu { bnNew *= (100 + params.nLocalTargetAdjustment); bnNew /= 100; + if (i % 16 == 0 && bnNew > UintToArith256(params.powLimit)) { + bnNew = UintToArith256(params.powLimit); + break; + } } } @@ -343,6 +347,25 @@ const CBlockIndex* GetLastBlockIndexForAlgo(const CBlockIndex* pindex, const Con return nullptr; } +const CBlockIndex* GetLastBlockIndexForAlgoFast(const CBlockIndex* pindex, const Consensus::Params& params, int algo) +{ + for (; pindex; pindex = pindex->lastAlgoBlocks[algo]) + { + if (pindex->GetAlgo() != algo) + continue; + if (params.fPowAllowMinDifficultyBlocks && + pindex->pprev && + pindex->nTime > pindex->pprev->nTime + params.nTargetSpacing*2) + { + pindex = pindex->pprev; + continue; + } + return pindex; + } + + return nullptr; +} + uint256 GetPoWAlgoHash(const CBlockHeader& block) { return block.GetPoWAlgoHash(Params().GetConsensus()); diff --git a/src/pow.h b/src/pow.h index 0a61af7128..9014311667 100644 --- a/src/pow.h +++ b/src/pow.h @@ -26,6 +26,7 @@ unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nF /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&); const CBlockIndex* GetLastBlockIndexForAlgo(const CBlockIndex* pindex, const Consensus::Params&, int algo); +const CBlockIndex* GetLastBlockIndexForAlgoFast(const CBlockIndex* pindex, const Consensus::Params&, int algo); uint256 GetPoWAlgoHash(const CBlockHeader& block); #endif // DIGIBYTE_POW_H diff --git a/src/validation.cpp b/src/validation.cpp index d6aca6c6e2..696893041e 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3097,6 +3097,13 @@ CBlockIndex* BlockManager::AddToBlockIndex(const CBlockHeader& block) pindexNew->nHeight = pindexNew->pprev->nHeight + 1; pindexNew->BuildSkip(); } + + if (pindexNew->pprev) { + for (unsigned i = 0; i < NUM_ALGOS_IMPL; i++) + pindexNew->lastAlgoBlocks[i] = pindexNew->pprev->lastAlgoBlocks[i]; + pindexNew->lastAlgoBlocks[pindexNew->GetAlgo()] = pindexNew; + } + pindexNew->nTimeMax = (pindexNew->pprev ? std::max(pindexNew->pprev->nTimeMax, pindexNew->nTime) : pindexNew->nTime); pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew); pindexNew->RaiseValidity(BLOCK_VALID_TREE); @@ -3889,6 +3896,13 @@ bool BlockManager::LoadBlockIndex( } if (ShutdownRequested()) return false; CBlockIndex* pindex = item.second; + + if (pindex->pprev) { + for (unsigned i = 0; i < NUM_ALGOS_IMPL; i++) + pindex->lastAlgoBlocks[i] = pindex->pprev->lastAlgoBlocks[i]; + pindex->lastAlgoBlocks[pindex->GetAlgo()] = pindex; + } + nHeight = pindex-> nHeight; pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex); pindex->nTimeMax = (pindex->pprev ? std::max(pindex->pprev->nTimeMax, pindex->nTime) : pindex->nTime);