Untitled
unknown
plain_text
2 years ago
4.9 kB
13
Indexable
// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2018 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 <pow.h> #include <arith_uint256.h> #include <chain.h> #include <primitives/block.h> #include <uint256.h> #include <bignum.h> #include <chainparams.h> #include <kernel.h> unsigned int GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake, const Consensus::Params& params) { if (pindexLast == nullptr) return UintToArith256(params.powLimit).GetCompact(); // genesis block const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake); if (pindexPrev->pprev == nullptr) return UintToArith256(params.bnInitialHashTarget).GetCompact(); // first block const CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake); if (pindexPrevPrev->pprev == nullptr) return UintToArith256(params.bnInitialHashTarget).GetCompact(); // second block int64_t nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); // rfc20 int64_t nHypotheticalSpacing = pindexLast->GetBlockTime() - pindexPrev->GetBlockTime(); // ***********For v13, we can keep the HypotheticalSpacing concept, but not overwrite the ActualSpacing if (!fProofOfStake && IsProtocolV12(pindexPrev) && (nHypotheticalSpacing > nActualSpacing) && !IsProtocolV13(pindexPrev)) nActualSpacing = nHypotheticalSpacing; // peercoin: target change every block // peercoin: retarget with exponential moving toward target spacing CBigNum bnNew; bnNew.SetCompact(pindexPrev->nBits); if (Params().NetworkIDString() != CBaseChainParams::REGTEST) { int64_t nTargetSpacing; if (fProofOfStake) { nTargetSpacing = params.nStakeTargetSpacing; } else { if (IsProtocolV09(pindexLast->nTime)) { nTargetSpacing = params.nStakeTargetSpacing * 6; } else { nTargetSpacing = std::min(params.nTargetSpacingWorkMax, params.nStakeTargetSpacing * (1 + pindexLast->nHeight - pindexPrev->nHeight)); } } //*********** for v13, we do the multiplication again with the hypothetical spacing, but let's just do all the v13 stuff up front so that we can adjust actual spacing for the PoS-PoW difference after. This should account for every combination of late and early blocks (i.e. late-late [the difficult case], late-early, earl-late, and early-early [which is a trivial case]) if (!fProofOfStake && (IsProtocolV13(pindexPrev))) { //********we should only do this if it exceeds the target if (nHypotheticalSpacing > nTargetSpacing)) { int64_t nInterval = params.nTargetTimespan / nTargetSpacing; bnNew *= ((nInterval - 1) * nTargetSpacing + nHypotheticalSpacing + nHypotheticalSpacing); bnNew /= ((nInterval + 1) * nTargetSpacing); } //******* Here is where we avoid pow-gap doublecount, and replace it with a PoS-PoW difference. This "if" case is such that we are always looking to adjust the difficulty based on a longer than target time. if (nActualSpacing > nTargetSpacing) { const CBlockIndex* pindexPrevPoS = GetLastBlockIndex(pindexPrev->pprev, !fProofOfStake); //********Using PoS block just before pprev, we get the delta between last PoW block and the PoS block before it nPoSPoWSpacing = pindexPrev->GetBlockTime() - pindexPrevPoS->GetBlockTime() If (nPoSPoWSpacing < nActualSpacing) { nActualSpacing = nTargetSpacing + nPoSPoWSpacing } //*************otherwise, nHypotheticalSpacing was zero } int64_t nInterval = params.nTargetTimespan / nTargetSpacing; bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing); bnNew /= ((nInterval + 1) * nTargetSpacing); } if (bnNew > CBigNum(params.powLimit)) bnNew = CBigNum(params.powLimit); return bnNew.GetCompact(); } bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params) { bool fNegative; bool fOverflow; arith_uint256 bnTarget; bnTarget.SetCompact(nBits, &fNegative, &fOverflow); // Check range if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit)) return false; // Check proof of work matches claimed amount if (UintToArith256(hash) > bnTarget) return false; return true; }
Editor is loading...
Leave a Comment