diff --git a/src/miner.h b/src/miner.h --- a/src/miner.h +++ b/src/miner.h @@ -20,6 +20,10 @@ class Config; class CScript; +namespace Consensus { +struct Params; +} + static const bool DEFAULT_PRINTPRIORITY = false; struct CBlockTemplateEntry { @@ -235,6 +239,6 @@ void IncrementExtraNonce(const Config &config, CBlock *pblock, const CBlockIndex *pindexPrev, unsigned int &nExtraNonce); -int64_t UpdateTime(CBlockHeader *pblock, const Config &config, +int64_t UpdateTime(CBlockHeader *pblock, const Consensus::Params ¶ms, const CBlockIndex *pindexPrev); #endif // BITCOIN_MINER_H diff --git a/src/miner.cpp b/src/miner.cpp --- a/src/miner.cpp +++ b/src/miner.cpp @@ -40,7 +40,7 @@ uint64_t nLastBlockTx = 0; uint64_t nLastBlockSize = 0; -int64_t UpdateTime(CBlockHeader *pblock, const Config &config, +int64_t UpdateTime(CBlockHeader *pblock, const Consensus::Params ¶ms, const CBlockIndex *pindexPrev) { int64_t nOldTime = pblock->nTime; int64_t nNewTime = @@ -50,12 +50,9 @@ pblock->nTime = nNewTime; } - const Consensus::Params &consensusParams = - config.GetChainParams().GetConsensus(); - // Updating time can change work required on testnet: - if (consensusParams.fPowAllowMinDifficultyBlocks) { - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, config); + if (params.fPowAllowMinDifficultyBlocks) { + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, params); } return nNewTime - nOldTime; @@ -212,8 +209,9 @@ // Fill in header. pblock->hashPrevBlock = pindexPrev->GetBlockHash(); - UpdateTime(pblock, *config, pindexPrev); - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, *config); + UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); + pblock->nBits = + GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus()); pblock->nNonce = 0; pblocktemplate->entries[0].txSigOps = GetSigOpCountWithoutP2SH( *pblocktemplate->entries[0].tx, STANDARD_SCRIPT_VERIFY_FLAGS); diff --git a/src/pow.h b/src/pow.h --- a/src/pow.h +++ b/src/pow.h @@ -10,26 +10,31 @@ class CBlockHeader; class CBlockIndex; -class Config; class uint256; +namespace Consensus { +struct Params; +} + uint32_t GetNextWorkRequired(const CBlockIndex *pindexPrev, - const CBlockHeader *pblock, const Config &config); + const CBlockHeader *pblock, + const Consensus::Params ¶ms); uint32_t CalculateNextWorkRequired(const CBlockIndex *pindexPrev, int64_t nFirstBlockTime, - const Config &config); + const Consensus::Params ¶ms); /** * Check whether a block hash satisfies the proof-of-work requirement specified * by nBits */ -bool CheckProofOfWork(uint256 hash, uint32_t nBits, const Config &config); +bool CheckProofOfWork(uint256 hash, uint32_t nBits, + const Consensus::Params ¶ms); /** * Bitcoin cash's difficulty adjustment mechanism. */ uint32_t GetNextCashWorkRequired(const CBlockIndex *pindexPrev, const CBlockHeader *pblock, - const Config &config); + const Consensus::Params ¶ms); #endif // BITCOIN_POW_H diff --git a/src/pow.cpp b/src/pow.cpp --- a/src/pow.cpp +++ b/src/pow.cpp @@ -8,8 +8,6 @@ #include #include -#include -#include #include #include #include @@ -22,9 +20,7 @@ */ static uint32_t GetNextEDAWorkRequired(const CBlockIndex *pindexPrev, const CBlockHeader *pblock, - const Config &config) { - const Consensus::Params ¶ms = config.GetChainParams().GetConsensus(); - + const Consensus::Params ¶ms) { // Only change once per difficulty adjustment interval uint32_t nHeight = pindexPrev->nHeight + 1; if (nHeight % params.DifficultyAdjustmentInterval() == 0) { @@ -35,7 +31,7 @@ assert(pindexFirst); return CalculateNextWorkRequired(pindexPrev, - pindexFirst->GetBlockTime(), config); + pindexFirst->GetBlockTime(), params); } const uint32_t nProofOfWorkLimit = @@ -93,9 +89,8 @@ } uint32_t GetNextWorkRequired(const CBlockIndex *pindexPrev, - const CBlockHeader *pblock, const Config &config) { - const Consensus::Params ¶ms = config.GetChainParams().GetConsensus(); - + const CBlockHeader *pblock, + const Consensus::Params ¶ms) { // GetNextWorkRequired should never be called on the genesis block assert(pindexPrev != nullptr); @@ -105,17 +100,15 @@ } if (IsDAAEnabled(params, pindexPrev)) { - return GetNextCashWorkRequired(pindexPrev, pblock, config); + return GetNextCashWorkRequired(pindexPrev, pblock, params); } - return GetNextEDAWorkRequired(pindexPrev, pblock, config); + return GetNextEDAWorkRequired(pindexPrev, pblock, params); } uint32_t CalculateNextWorkRequired(const CBlockIndex *pindexPrev, int64_t nFirstBlockTime, - const Config &config) { - const Consensus::Params ¶ms = config.GetChainParams().GetConsensus(); - + const Consensus::Params ¶ms) { if (params.fPowNoRetargeting) { return pindexPrev->nBits; } @@ -137,12 +130,15 @@ bnNew *= nActualTimespan; bnNew /= params.nPowTargetTimespan; - if (bnNew > bnPowLimit) bnNew = bnPowLimit; + if (bnNew > bnPowLimit) { + bnNew = bnPowLimit; + } return bnNew.GetCompact(); } -bool CheckProofOfWork(uint256 hash, uint32_t nBits, const Config &config) { +bool CheckProofOfWork(uint256 hash, uint32_t nBits, + const Consensus::Params ¶ms) { bool fNegative; bool fOverflow; arith_uint256 bnTarget; @@ -151,8 +147,7 @@ // Check range if (fNegative || bnTarget == 0 || fOverflow || - bnTarget > - UintToArith256(config.GetChainParams().GetConsensus().powLimit)) { + bnTarget > UintToArith256(params.powLimit)) { return false; } @@ -246,9 +241,7 @@ */ uint32_t GetNextCashWorkRequired(const CBlockIndex *pindexPrev, const CBlockHeader *pblock, - const Config &config) { - const Consensus::Params ¶ms = config.GetChainParams().GetConsensus(); - + const Consensus::Params ¶ms) { // This cannot handle the genesis block and early blocks in general. assert(pindexPrev); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -145,7 +145,8 @@ } while (nMaxTries > 0 && pblock->nNonce < nInnerLoopCount && - !CheckProofOfWork(pblock->GetHash(), pblock->nBits, config)) { + !CheckProofOfWork(pblock->GetHash(), pblock->nBits, + config.GetChainParams().GetConsensus())) { ++pblock->nNonce; --nMaxTries; } @@ -600,7 +601,7 @@ CBlock *pblock = &pblocktemplate->block; // Update nTime - UpdateTime(pblock, config, pindexPrev); + UpdateTime(pblock, config.GetChainParams().GetConsensus(), pindexPrev); pblock->nNonce = 0; UniValue aCaps(UniValue::VARR); diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp --- a/src/test/blockencodings_tests.cpp +++ b/src/test/blockencodings_tests.cpp @@ -55,7 +55,8 @@ assert(!mutated); GlobalConfig config; - while (!CheckProofOfWork(block.GetHash(), block.nBits, config)) { + const Consensus::Params ¶ms = config.GetChainParams().GetConsensus(); + while (!CheckProofOfWork(block.GetHash(), block.nBits, params)) { ++block.nNonce; } @@ -356,7 +357,8 @@ assert(!mutated); GlobalConfig config; - while (!CheckProofOfWork(block.GetHash(), block.nBits, config)) { + const Consensus::Params ¶ms = config.GetChainParams().GetConsensus(); + while (!CheckProofOfWork(block.GetHash(), block.nBits, params)) { ++block.nNonce; } diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -26,7 +26,8 @@ pindexLast.nTime = 1262152739; // Block #32255 pindexLast.nBits = 0x1d00ffff; BOOST_CHECK_EQUAL( - CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, config), + CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, + config.GetChainParams().GetConsensus()), 0x1d00d86a); } @@ -40,7 +41,8 @@ pindexLast.nTime = 1233061996; // Block #2015 pindexLast.nBits = 0x1d00ffff; BOOST_CHECK_EQUAL( - CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, config), + CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, + config.GetChainParams().GetConsensus()), 0x1d00ffff); } @@ -54,7 +56,8 @@ pindexLast.nTime = 1279297671; // Block #68543 pindexLast.nBits = 0x1c05a3f4; BOOST_CHECK_EQUAL( - CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, config), + CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, + config.GetChainParams().GetConsensus()), 0x1c0168fd); } @@ -68,7 +71,8 @@ pindexLast.nTime = 1269211443; // Block #46367 pindexLast.nBits = 0x1c387f6f; BOOST_CHECK_EQUAL( - CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, config), + CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, + config.GetChainParams().GetConsensus()), 0x1d00e1fd); } @@ -143,7 +147,7 @@ for (size_t i = 100; i < 110; i++) { blocks[i] = GetBlockIndex(&blocks[i - 1], 2 * 3600, initialBits); BOOST_CHECK_EQUAL( - GetNextWorkRequired(&blocks[i], &blkHeaderDummy, config), + GetNextWorkRequired(&blocks[i], &blkHeaderDummy, params), initialBits); } @@ -152,7 +156,7 @@ currentPow.SetCompact(currentPow.GetCompact()); currentPow += (currentPow >> 2); BOOST_CHECK_EQUAL( - GetNextWorkRequired(&blocks[110], &blkHeaderDummy, config), + GetNextWorkRequired(&blocks[110], &blkHeaderDummy, params), currentPow.GetCompact()); // As we continue with 2h blocks, difficulty continue to decrease. @@ -161,7 +165,7 @@ currentPow.SetCompact(currentPow.GetCompact()); currentPow += (currentPow >> 2); BOOST_CHECK_EQUAL( - GetNextWorkRequired(&blocks[111], &blkHeaderDummy, config), + GetNextWorkRequired(&blocks[111], &blkHeaderDummy, params), currentPow.GetCompact()); // We decrease again. @@ -170,7 +174,7 @@ currentPow.SetCompact(currentPow.GetCompact()); currentPow += (currentPow >> 2); BOOST_CHECK_EQUAL( - GetNextWorkRequired(&blocks[112], &blkHeaderDummy, config), + GetNextWorkRequired(&blocks[112], &blkHeaderDummy, params), currentPow.GetCompact()); // We check that we do not go below the minimal difficulty. @@ -180,14 +184,14 @@ currentPow += (currentPow >> 2); BOOST_CHECK(powLimit.GetCompact() != currentPow.GetCompact()); BOOST_CHECK_EQUAL( - GetNextWorkRequired(&blocks[113], &blkHeaderDummy, config), + GetNextWorkRequired(&blocks[113], &blkHeaderDummy, params), powLimit.GetCompact()); // Once we reached the minimal difficulty, we stick with it. blocks[114] = GetBlockIndex(&blocks[113], 2 * 3600, powLimit.GetCompact()); BOOST_CHECK(powLimit.GetCompact() != currentPow.GetCompact()); BOOST_CHECK_EQUAL( - GetNextWorkRequired(&blocks[114], &blkHeaderDummy, config), + GetNextWorkRequired(&blocks[114], &blkHeaderDummy, params), powLimit.GetCompact()); } @@ -220,13 +224,13 @@ CBlockHeader blkHeaderDummy; uint32_t nBits = - GetNextCashWorkRequired(&blocks[2049], &blkHeaderDummy, config); + GetNextCashWorkRequired(&blocks[2049], &blkHeaderDummy, params); // Difficulty stays the same as long as we produce a block every 10 mins. for (size_t j = 0; j < 10; i++, j++) { blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits); BOOST_CHECK_EQUAL( - GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, config), + GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params), nBits); } @@ -235,30 +239,30 @@ // expected timestamp. blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); BOOST_CHECK_EQUAL( - GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, config), nBits); + GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params), nBits); blocks[i] = GetBlockIndex(&blocks[i - 1], 2 * 600 - 6000, nBits); BOOST_CHECK_EQUAL( - GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, config), nBits); + GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params), nBits); // The system should continue unaffected by the block with a bogous // timestamps. for (size_t j = 0; j < 20; i++, j++) { blocks[i] = GetBlockIndex(&blocks[i - 1], 600, nBits); BOOST_CHECK_EQUAL( - GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, config), + GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params), nBits); } // We start emitting blocks slightly faster. The first block has no impact. blocks[i] = GetBlockIndex(&blocks[i - 1], 550, nBits); BOOST_CHECK_EQUAL( - GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, config), nBits); + GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params), nBits); // Now we should see difficulty increase slowly. for (size_t j = 0; j < 10; i++, j++) { blocks[i] = GetBlockIndex(&blocks[i - 1], 550, nBits); const uint32_t nextBits = - GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, config); + GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); arith_uint256 currentTarget; currentTarget.SetCompact(nBits); @@ -279,7 +283,7 @@ for (size_t j = 0; j < 20; i++, j++) { blocks[i] = GetBlockIndex(&blocks[i - 1], 10, nBits); const uint32_t nextBits = - GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, config); + GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); arith_uint256 currentTarget; currentTarget.SetCompact(nBits); @@ -299,7 +303,7 @@ // We start to emit blocks significantly slower. The first block has no // impact. blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); - nBits = GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, config); + nBits = GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params); // Check the actual value. BOOST_CHECK_EQUAL(nBits, 0x1c0d9222); @@ -308,7 +312,7 @@ for (size_t j = 0; j < 93; i++, j++) { blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); const uint32_t nextBits = - GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, config); + GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); arith_uint256 currentTarget; currentTarget.SetCompact(nBits); @@ -329,7 +333,7 @@ // Due to the window of time being bounded, next block's difficulty actually // gets harder. blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); - nBits = GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, config); + nBits = GetNextCashWorkRequired(&blocks[i++], &blkHeaderDummy, params); BOOST_CHECK_EQUAL(nBits, 0x1c2ee9bf); // And goes down again. It takes a while due to the window being bounded and @@ -337,7 +341,7 @@ for (size_t j = 0; j < 192; i++, j++) { blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); const uint32_t nextBits = - GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, config); + GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); arith_uint256 currentTarget; currentTarget.SetCompact(nBits); @@ -360,7 +364,7 @@ for (size_t j = 0; j < 5; i++, j++) { blocks[i] = GetBlockIndex(&blocks[i - 1], 6000, nBits); const uint32_t nextBits = - GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, config); + GetNextCashWorkRequired(&blocks[i], &blkHeaderDummy, params); // Check the difficulty stays constant. BOOST_CHECK_EQUAL(nextBits, powLimitBits); diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -189,7 +189,8 @@ IncrementExtraNonce(config, &block, chainActive.Tip(), extraNonce); } - while (!CheckProofOfWork(block.GetHash(), block.nBits, config)) { + const Consensus::Params ¶ms = config.GetChainParams().GetConsensus(); + while (!CheckProofOfWork(block.GetHash(), block.nBits, params)) { ++block.nNonce; } diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp --- a/src/test/validation_block_tests.cpp +++ b/src/test/validation_block_tests.cpp @@ -68,11 +68,11 @@ return pblock; } -std::shared_ptr FinalizeBlock(const Config &config, +std::shared_ptr FinalizeBlock(const Consensus::Params ¶ms, std::shared_ptr pblock) { pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); - while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, config)) { + while (!CheckProofOfWork(pblock->GetHash(), pblock->nBits, params)) { ++(pblock->nNonce); } @@ -82,7 +82,8 @@ // construct a valid block const std::shared_ptr GoodBlock(const Config &config, const uint256 &prev_hash) { - return FinalizeBlock(config, Block(config, prev_hash)); + return FinalizeBlock(config.GetChainParams().GetConsensus(), + Block(config, prev_hash)); } // construct an invalid block (but with a valid header) @@ -98,7 +99,7 @@ CTransactionRef tx = MakeTransactionRef(coinbase_spend); pblock->vtx.push_back(tx); - auto ret = FinalizeBlock(config, pblock); + auto ret = FinalizeBlock(config.GetChainParams().GetConsensus(), pblock); return ret; } diff --git a/src/txdb.h b/src/txdb.h --- a/src/txdb.h +++ b/src/txdb.h @@ -20,7 +20,10 @@ class CBlockIndex; class CCoinsViewDBCursor; class uint256; -class Config; + +namespace Consensus { +struct Params; +} //! No need to periodic flush if at least this much space still available. static constexpr int MAX_BLOCK_COINSDB_USAGE = 10; @@ -101,7 +104,7 @@ bool WriteFlag(const std::string &name, bool fValue); bool ReadFlag(const std::string &name, bool &fValue); bool LoadBlockIndexGuts( - const Config &config, + const Consensus::Params ¶ms, std::function insertBlockIndex); }; diff --git a/src/txdb.cpp b/src/txdb.cpp --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -263,7 +263,7 @@ } bool CBlockTreeDB::LoadBlockIndexGuts( - const Config &config, + const Consensus::Params ¶ms, std::function insertBlockIndex) { std::unique_ptr pcursor(NewIterator()); @@ -299,7 +299,7 @@ pindexNew->nTx = diskindex.nTx; if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, - config)) { + params)) { return error("%s: CheckProofOfWork failed: %s", __func__, pindexNew->ToString()); } diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -952,7 +952,8 @@ } // Check the header - if (!CheckProofOfWork(block.GetHash(), block.nBits, config)) { + if (!CheckProofOfWork(block.GetHash(), block.nBits, + config.GetChainParams().GetConsensus())) { return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString()); } @@ -3443,7 +3444,8 @@ BlockValidationOptions validationOptions = BlockValidationOptions()) { // Check proof of work matches claimed amount if (validationOptions.shouldValidatePoW() && - !CheckProofOfWork(block.GetHash(), block.nBits, config)) { + !CheckProofOfWork(block.GetHash(), block.nBits, + config.GetChainParams().GetConsensus())) { return state.DoS(50, false, REJECT_INVALID, "high-hash", false, "proof of work failed"); } @@ -3585,7 +3587,8 @@ // Check proof of work const Consensus::Params &consensusParams = config.GetChainParams().GetConsensus(); - if (block.nBits != GetNextWorkRequired(pindexPrev, &block, config)) { + if (block.nBits != + GetNextWorkRequired(pindexPrev, &block, consensusParams)) { LogPrintf("bad bits after height: %d\n", pindexPrev->nHeight); return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false, "incorrect proof of work"); @@ -4393,9 +4396,10 @@ bool CChainState::LoadBlockIndex(const Config &config, CBlockTreeDB &blocktree) { - if (!blocktree.LoadBlockIndexGuts(config, [this](const uint256 &hash) { - return this->InsertBlockIndex(hash); - })) { + if (!blocktree.LoadBlockIndexGuts(config.GetChainParams().GetConsensus(), + [this](const uint256 &hash) { + return this->InsertBlockIndex(hash); + })) { return false; }