diff options
| author | Ross Nicoll <[email protected]> | 2017-12-28 15:04:08 +0000 |
|---|---|---|
| committer | Ross Nicoll <[email protected]> | 2018-09-19 19:24:06 +0100 |
| commit | 1be681a1b97b686f838af90682a57f2030d26015 (patch) | |
| tree | b2795e4a1d35004dbfd84d49b07bc54413a2a9e1 | |
| parent | Change BIP65/66 enforcement to match Dogecoin (#1403) (diff) | |
| download | discoin-1be681a1b97b686f838af90682a57f2030d26015.tar.xz discoin-1be681a1b97b686f838af90682a57f2030d26015.zip | |
Modify chain consensus parameters to be height aware (#1396)
* Modify chain consensus parameters to be height aware
* Correct implementation of simplified rewards in parameters
* Correct max money
* Use base block version in IsSuperMajority() instead of full version
* Correct mining of blocks in AuxPoW tests
* Add in missing pre-AuxPoW consensus checks
| -rw-r--r-- | src/amount.h | 2 | ||||
| -rw-r--r-- | src/bench/checkblock.cpp | 4 | ||||
| -rw-r--r-- | src/blockencodings.cpp | 3 | ||||
| -rw-r--r-- | src/chainparams.cpp | 112 | ||||
| -rw-r--r-- | src/chainparams.h | 20 | ||||
| -rw-r--r-- | src/consensus/params.h | 24 | ||||
| -rw-r--r-- | src/dogecoin.cpp | 17 | ||||
| -rw-r--r-- | src/init.cpp | 8 | ||||
| -rw-r--r-- | src/miner.cpp | 15 | ||||
| -rw-r--r-- | src/net_processing.cpp | 42 | ||||
| -rw-r--r-- | src/pow.cpp | 16 | ||||
| -rw-r--r-- | src/qt/bitcoingui.cpp | 2 | ||||
| -rw-r--r-- | src/qt/modaloverlay.cpp | 2 | ||||
| -rw-r--r-- | src/qt/sendcoinsdialog.cpp | 3 | ||||
| -rw-r--r-- | src/rest.cpp | 6 | ||||
| -rw-r--r-- | src/rpc/blockchain.cpp | 6 | ||||
| -rw-r--r-- | src/rpc/mining.cpp | 12 | ||||
| -rw-r--r-- | src/rpc/rawtransaction.cpp | 7 | ||||
| -rw-r--r-- | src/test/auxpow_tests.cpp | 10 | ||||
| -rw-r--r-- | src/test/blockencodings_tests.cpp | 8 | ||||
| -rw-r--r-- | src/test/dogecoin_tests.cpp | 56 | ||||
| -rw-r--r-- | src/test/pow_tests.cpp | 10 | ||||
| -rw-r--r-- | src/test/test_bitcoin.cpp | 2 | ||||
| -rw-r--r-- | src/test/versionbits_tests.cpp | 4 | ||||
| -rw-r--r-- | src/validation.cpp | 123 | ||||
| -rw-r--r-- | src/validation.h | 8 | ||||
| -rw-r--r-- | src/wallet/rpcwallet.cpp | 2 | ||||
| -rw-r--r-- | src/wallet/wallet.cpp | 2 | ||||
| -rw-r--r-- | src/zmq/zmqpublishnotifier.cpp | 2 |
29 files changed, 356 insertions, 172 deletions
diff --git a/src/amount.h b/src/amount.h index a5afcc721..e6e503905 100644 --- a/src/amount.h +++ b/src/amount.h @@ -28,7 +28,7 @@ extern const std::string CURRENCY_UNIT; * critical; in unusual circumstances like a(nother) overflow bug that allowed * for the creation of coins out of thin air modification could lead to a fork. * */ -static const CAmount MAX_MONEY = 1000000000 * COIN; // Dogecoin: maximum of 100B coins (given some randomness), max transaction 10,000,000,000 +static const CAmount MAX_MONEY = 10000000000 * COIN; // Dogecoin: maximum of 100B coins (given some randomness), max transaction 10,000,000,000 inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } /** diff --git a/src/bench/checkblock.cpp b/src/bench/checkblock.cpp index 230e4ca77..77181b296 100644 --- a/src/bench/checkblock.cpp +++ b/src/bench/checkblock.cpp @@ -40,15 +40,13 @@ static void DeserializeAndCheckBlockTest(benchmark::State& state) char a; stream.write(&a, 1); // Prevent compaction - Consensus::Params params = Params(CBaseChainParams::MAIN).GetConsensus(); - while (state.KeepRunning()) { CBlock block; // Note that CBlock caches its checked state, so we need to recreate it here stream >> block; assert(stream.Rewind(sizeof(block_bench::block413567))); CValidationState validationState; - assert(CheckBlock(block, validationState, params)); + assert(CheckBlock(block, validationState)); } } diff --git a/src/blockencodings.cpp b/src/blockencodings.cpp index 4a311cbba..ef27877c6 100644 --- a/src/blockencodings.cpp +++ b/src/blockencodings.cpp @@ -199,7 +199,8 @@ ReadStatus PartiallyDownloadedBlock::FillBlock(CBlock& block, const std::vector< return READ_STATUS_INVALID; CValidationState state; - if (!CheckBlock(block, state, Params().GetConsensus())) { + // TODO: Make sure lack of block height doesn't cause verification problems + if (!CheckBlock(block, state)) { // TODO: We really want to just check merkle tree manually here, // but that is expensive, and CheckBlock caches a block's // "checked-status" (in the CBlock?). CBlock should be able to diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 5e0e51f27..96540938c 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -67,9 +67,14 @@ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits */ class CMainParams : public CChainParams { +private: + Consensus::Params digishieldConsensus; + Consensus::Params auxpowConsensus; public: CMainParams() { strNetworkID = "main"; + + // Blocks 0 - 144999 are conventional difficulty calculation consensus.nSubsidyHalvingInterval = 100000; consensus.nMajorityEnforceBlockUpgrade = 1500; consensus.nMajorityRejectBlockOutdated = 1900; @@ -82,7 +87,9 @@ public: consensus.powLimit = uint256S("0x00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 20; consensus.nPowTargetTimespan = 4 * 60 * 60; // pre-digishield: 4 hours consensus.nPowTargetSpacing = 60; // 1 minute + consensus.fDigishieldDifficultyCalculation = false; consensus.fPowAllowMinDifficultyBlocks = false; + consensus.fPowAllowDigishieldMinDifficultyBlocks = false; consensus.fPowNoRetargeting = false; consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016 consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing @@ -108,10 +115,30 @@ public: // By default assume that the signatures in ancestors of this block are valid. consensus.defaultAssumeValid = uint256S("0xca5eb72f1e0d160f1481f74d56d7cc4a27d91aa585ba012da8018a5fe934d61b"); // 1,600,000 + // AuxPoW parameters consensus.nAuxpowChainId = 0x0062; // 98 - Josh Wise! - consensus.nAuxpowStartHeight = 371337; consensus.fStrictChainId = true; - consensus.nLegacyBlocksBefore = 371337; + consensus.fAllowLegacyBlocks = true; + consensus.nHeightEffective = 0; + + // Blocks 145000 - 371336 are Digishield without AuxPoW + digishieldConsensus = consensus; + digishieldConsensus.nHeightEffective = 145000; + digishieldConsensus.fSimplifiedRewards = true; + digishieldConsensus.fDigishieldDifficultyCalculation = true; + digishieldConsensus.nPowTargetTimespan = 60; // post-digishield: 1 minute + digishieldConsensus.nCoinbaseMaturity = 240; + + // Blocks 371337+ are AuxPoW + auxpowConsensus = digishieldConsensus; + auxpowConsensus.nHeightEffective = 371337; + auxpowConsensus.fAllowLegacyBlocks = false; + + // Assemble the binary search tree of consensus parameters + pConsensusRoot = &digishieldConsensus; + digishieldConsensus.pLeft = &consensus; + digishieldConsensus.pRight = &auxpowConsensus; + /** * The message start string is designed to be unlikely to occur in normal data. * The characters are rarely used upper ASCII, not valid as UTF-8, and produce @@ -127,6 +154,8 @@ public: genesis = CreateGenesisBlock(1386325540, 99943, 0x1e0ffff0, 1, 88 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); + digishieldConsensus.hashGenesisBlock = consensus.hashGenesisBlock; + auxpowConsensus.hashGenesisBlock = consensus.hashGenesisBlock; assert(consensus.hashGenesisBlock == uint256S("0x1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691")); assert(genesis.hashMerkleRoot == uint256S("0x5b2a3f53f605d62c53e62932dac6925e3d74afa5a4b459745c36d42d0ed26a69")); @@ -181,9 +210,20 @@ static CMainParams mainParams; * Testnet (v3) */ class CTestNetParams : public CChainParams { +private: + Consensus::Params digishieldConsensus; + Consensus::Params auxpowConsensus; + Consensus::Params minDifficultyConsensus; public: CTestNetParams() { strNetworkID = "test"; + + // Blocks 0 - 144999 are pre-Digishield + consensus.nHeightEffective = 0; + consensus.nPowTargetTimespan = 4 * 60 * 60; // pre-digishield: 4 hours + consensus.fDigishieldDifficultyCalculation = false; + consensus.fPowAllowMinDifficultyBlocks = true; + consensus.fPowAllowDigishieldMinDifficultyBlocks = false; consensus.nSubsidyHalvingInterval = 100000; consensus.nMajorityEnforceBlockUpgrade = 501; consensus.nMajorityRejectBlockOutdated = 750; @@ -196,7 +236,6 @@ public: consensus.powLimit = uint256S("0x00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 20; consensus.nPowTargetTimespan = 4 * 60 * 60; // pre-digishield: 4 hours consensus.nPowTargetSpacing = 60; // 1 minute - consensus.fPowAllowMinDifficultyBlocks = true; consensus.fPowNoRetargeting = false; consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains consensus.nMinerConfirmationWindow = 240; // nPowTargetTimespan / nPowTargetSpacing @@ -222,9 +261,38 @@ public: // By default assume that the signatures in ancestors of this block are valid. consensus.defaultAssumeValid = uint256S("0x6943eaeaba98dc7d09f7e73398daccb4abcabb18b66c8c875e52b07638d93951"); // 900,000 - consensus.nAuxpowStartHeight = 158100; + // AuxPoW parameters + consensus.nAuxpowChainId = 0x0062; // 98 - Josh Wise! consensus.fStrictChainId = false; - consensus.nLegacyBlocksBefore = -1; + consensus.nHeightEffective = 0; + consensus.fAllowLegacyBlocks = true; + + // Blocks 145000 - 157499 are Digishield without minimum difficulty on all blocks + digishieldConsensus = consensus; + digishieldConsensus.nHeightEffective = 145000; + digishieldConsensus.nPowTargetTimespan = 60; // post-digishield: 1 minute + digishieldConsensus.fDigishieldDifficultyCalculation = true; + digishieldConsensus.fSimplifiedRewards = true; + digishieldConsensus.fPowAllowMinDifficultyBlocks = false; + digishieldConsensus.nCoinbaseMaturity = 240; + + // Blocks 157500 - 158099 are Digishield with minimum difficulty on all blocks + minDifficultyConsensus = digishieldConsensus; + minDifficultyConsensus.nHeightEffective = 157500; + minDifficultyConsensus.fPowAllowDigishieldMinDifficultyBlocks = true; + minDifficultyConsensus.fPowAllowMinDifficultyBlocks = true; + + // Enable AuxPoW at 158100 + auxpowConsensus = minDifficultyConsensus; + auxpowConsensus.nHeightEffective = 158100; + auxpowConsensus.fPowAllowDigishieldMinDifficultyBlocks = true; + auxpowConsensus.fAllowLegacyBlocks = false; + + // Assemble the binary search tree of parameters + pConsensusRoot = &digishieldConsensus; + digishieldConsensus.pLeft = &consensus; + digishieldConsensus.pRight = &minDifficultyConsensus; + minDifficultyConsensus.pRight = &auxpowConsensus; pchMessageStart[0] = 0xfc; pchMessageStart[1] = 0xc1; @@ -235,6 +303,9 @@ public: genesis = CreateGenesisBlock(1391503289, 997879, 0x1e0ffff0, 1, 88 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); + digishieldConsensus.hashGenesisBlock = consensus.hashGenesisBlock; + minDifficultyConsensus.hashGenesisBlock = consensus.hashGenesisBlock; + auxpowConsensus.hashGenesisBlock = consensus.hashGenesisBlock; assert(consensus.hashGenesisBlock == uint256S("0xbb0a78264637406b6360aad926284d544d7049f45189db5664f3c4d07350559e")); assert(genesis.hashMerkleRoot == uint256S("0x5b2a3f53f605d62c53e62932dac6925e3d74afa5a4b459745c36d42d0ed26a69")); @@ -257,7 +328,6 @@ public: fRequireStandard = false; fMineBlocksOnDemand = false; - checkpointData = (CCheckpointData) { boost::assign::map_list_of ( 0, uint256S("0xbb0a78264637406b6360aad926284d544d7049f45189db5664f3c4d07350559e")) @@ -282,6 +352,9 @@ static CTestNetParams testNetParams; * Regression test */ class CRegTestParams : public CChainParams { +private: + Consensus::Params digishieldConsensus; + Consensus::Params auxpowConsensus; public: CRegTestParams() { strNetworkID = "regtest"; @@ -294,8 +367,8 @@ public: // consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in rpc activation tests) consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in rpc activation tests) consensus.powLimit = uint256S("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 1; - consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks - consensus.nPowTargetSpacing = 10 * 60; + consensus.nPowTargetTimespan = 4 * 60 * 60; // pre-digishield: 4 hours + consensus.nPowTargetSpacing = 1; // regtest: 1 second blocks consensus.fPowAllowMinDifficultyBlocks = true; consensus.fPowNoRetargeting = true; consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains @@ -316,8 +389,29 @@ public: // By default assume that the signatures in ancestors of this block are valid. consensus.defaultAssumeValid = uint256S("0x00"); + // AuxPow parameters + consensus.nAuxpowChainId = 0x0062; // 98 - Josh Wise! consensus.fStrictChainId = true; - consensus.nLegacyBlocksBefore = 0; + consensus.fAllowLegacyBlocks = true; + + // Dogecoin parameters + consensus.fSimplifiedRewards = true; + consensus.nCoinbaseMaturity = 60; // For easier testability in RPC tests + + digishieldConsensus = consensus; + digishieldConsensus.nHeightEffective = 10; + digishieldConsensus.nPowTargetTimespan = 1; // regtest: also retarget every second in digishield mode, for conformity + digishieldConsensus.fDigishieldDifficultyCalculation = true; + + auxpowConsensus = digishieldConsensus; + auxpowConsensus.fAllowLegacyBlocks = false; + auxpowConsensus.nHeightEffective = 20; + + // Assemble the binary search tree of parameters + digishieldConsensus.pLeft = &consensus; + digishieldConsensus.pRight = &auxpowConsensus; + pConsensusRoot = &digishieldConsensus; + pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; pchMessageStart[2] = 0xb5; diff --git a/src/chainparams.h b/src/chainparams.h index 22843b886..14ceff4c7 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -56,7 +56,24 @@ public: MAX_BASE58_TYPES }; - const Consensus::Params& GetConsensus() const { return consensus; } + const Consensus::Params& GetConsensus(uint32_t nTargetHeight) const { + return *GetConsensus(nTargetHeight, pConsensusRoot); + } + + Consensus::Params *GetConsensus(uint32_t nTargetHeight, Consensus::Params *pRoot) const { + if (nTargetHeight < pRoot -> nHeightEffective && pRoot -> pLeft != NULL) { + return GetConsensus(nTargetHeight, pRoot -> pLeft); + } else if (nTargetHeight > pRoot -> nHeightEffective && pRoot -> pRight != NULL) { + Consensus::Params *pCandidate = GetConsensus(nTargetHeight, pRoot -> pRight); + if (pCandidate->nHeightEffective <= nTargetHeight) { + return pCandidate; + } + } + + // No better match below the target height + return pRoot; + } + const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } int GetDefaultPort() const { return nDefaultPort; } @@ -82,6 +99,7 @@ protected: CChainParams() {} Consensus::Params consensus; + Consensus::Params *pConsensusRoot; // Binary search tree root CMessageHeader::MessageStartChars pchMessageStart; int nDefaultPort; uint64_t nPruneAfterHeight; diff --git a/src/consensus/params.h b/src/consensus/params.h index 7d8d53c44..a3a61747d 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -66,26 +66,24 @@ struct Params { int64_t nPowTargetSpacing; int64_t nPowTargetTimespan; int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; } + + /** Dogecoin-specific parameters */ + bool fDigishieldDifficultyCalculation; + bool fPowAllowDigishieldMinDifficultyBlocks; // Allow minimum difficulty blocks where a retarget would normally occur + bool fSimplifiedRewards; // Use block height derived rewards rather than previous block hash derived + uint256 nMinimumChainWork; uint256 defaultAssumeValid; /** Auxpow parameters */ int32_t nAuxpowChainId; - int nAuxpowStartHeight; bool fStrictChainId; - int nLegacyBlocksBefore; // -1 for "always allow" + bool fAllowLegacyBlocks; - /** - * Check whether or not to allow legacy blocks at the given height. - * @param nHeight Height of the block to check. - * @return True if it is allowed to have a legacy version. - */ - bool AllowLegacyBlocks(unsigned nHeight) const - { - if (nLegacyBlocksBefore < 0) - return true; - return static_cast<int> (nHeight) < nLegacyBlocksBefore; - } + /** Height-aware consensus parameters */ + uint32_t nHeightEffective; // When these parameters come into use + struct Params *pLeft; // Left hand branch + struct Params *pRight; // Right hand branch }; } // namespace Consensus diff --git a/src/dogecoin.cpp b/src/dogecoin.cpp index 76db22f94..f06849d61 100644 --- a/src/dogecoin.cpp +++ b/src/dogecoin.cpp @@ -37,18 +37,13 @@ bool AllowDigishieldMinDifficultyForBlock(const CBlockIndex* pindexLast, const C unsigned int CalculateDogecoinNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params) { int nHeight = pindexLast->nHeight + 1; - bool fNewDifficultyProtocol = (nHeight >= 145000); - // bool fNewDifficultyProtocol = (nHeight >= params.GetDigiShieldForkBlock()); - const int64_t retargetTimespan = fNewDifficultyProtocol ? 60 // params.DigiShieldTargetTimespan() - : - params.nPowTargetTimespan; - + const int64_t retargetTimespan = params.nPowTargetTimespan; const int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime; int64_t nModulatedTimespan = nActualTimespan; int64_t nMaxTimespan; int64_t nMinTimespan; - if (fNewDifficultyProtocol) //DigiShield implementation - thanks to RealSolid & WDC for this code + if (params.fDigishieldDifficultyCalculation) //DigiShield implementation - thanks to RealSolid & WDC for this code { // amplitude filter - thanks to daft27 for this code nModulatedTimespan = retargetTimespan + (nModulatedTimespan - retargetTimespan) / 8; @@ -84,12 +79,6 @@ unsigned int CalculateDogecoinNextWorkRequired(const CBlockIndex* pindexLast, in if (bnNew > bnPowLimit) bnNew = bnPowLimit; - /// debug print - LogPrintf("GetNextWorkRequired RETARGET\n"); - LogPrintf("params.nPowTargetTimespan = %d nActualTimespan = %d\n", params.nPowTargetTimespan, nActualTimespan); - LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString()); - LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString()); - return bnNew.GetCompact(); } @@ -134,7 +123,7 @@ CAmount GetDogecoinBlockSubsidy(int nHeight, const Consensus::Params& consensusP { int halvings = nHeight / consensusParams.nSubsidyHalvingInterval; - if (nHeight < 145000) // && !consensusParams.SimplifiedRewards()) + if (!consensusParams.fSimplifiedRewards) { // Old-style rewards derived from the previous block hash const std::string cseed_str = prevHash.ToString().substr(7, 7); diff --git a/src/init.cpp b/src/init.cpp index 6c39b1496..c4b446c52 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -328,7 +328,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-blocknotify=<cmd>", _("Execute command when the best block changes (%s in cmd is replaced by block hash)")); if (showDebug) strUsage += HelpMessageOpt("-blocksonly", strprintf(_("Whether to operate in a blocks only mode (default: %u)"), DEFAULT_BLOCKSONLY)); - strUsage +=HelpMessageOpt("-assumevalid=<hex>", strprintf(_("If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s)"), Params(CBaseChainParams::MAIN).GetConsensus().defaultAssumeValid.GetHex(), Params(CBaseChainParams::TESTNET).GetConsensus().defaultAssumeValid.GetHex())); + strUsage +=HelpMessageOpt("-assumevalid=<hex>", strprintf(_("If this block is in the chain assume that it and its ancestors are valid and potentially skip their script verification (0 to verify all, default: %s, testnet: %s)"), Params(CBaseChainParams::MAIN).GetConsensus(0).defaultAssumeValid.GetHex(), Params(CBaseChainParams::TESTNET).GetConsensus(0).defaultAssumeValid.GetHex())); strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), BITCOIN_CONF_FILENAME)); if (mode == HMM_BITCOIND) { @@ -940,7 +940,7 @@ bool AppInitParameterInteraction() fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks()); fCheckpointsEnabled = GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED); - hashAssumeValid = uint256S(GetArg("-assumevalid", chainparams.GetConsensus().defaultAssumeValid.GetHex())); + hashAssumeValid = uint256S(GetArg("-assumevalid", chainparams.GetConsensus(0).defaultAssumeValid.GetHex())); if (!hashAssumeValid.IsNull()) LogPrintf("Assuming ancestors of block %s have valid signatures.\n", hashAssumeValid.GetHex()); else @@ -1453,7 +1453,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) // If the loaded chain has a wrong genesis, bail out immediately // (we're likely using a testnet datadir, or the other way around). - if (!mapBlockIndex.empty() && mapBlockIndex.count(chainparams.GetConsensus().hashGenesisBlock) == 0) + if (!mapBlockIndex.empty() && mapBlockIndex.count(chainparams.GetConsensus(0).hashGenesisBlock) == 0) return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?")); // Initialize the block index (no-op if non-empty database was already loaded) @@ -1573,7 +1573,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) } } - if (chainparams.GetConsensus().vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0) { + if (chainparams.GetConsensus(0).vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0) { // Only advertise witness capabilities if they have a reasonable start time. // This allows us to have the code merged without a defined softfork, by setting its // end time to 0. diff --git a/src/miner.cpp b/src/miner.cpp index 736d5f878..da0001a5b 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -149,9 +149,10 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc CBlockIndex* pindexPrev = chainActive.Tip(); nHeight = pindexPrev->nHeight + 1; - const int32_t nChainId = chainparams.GetConsensus ().nAuxpowChainId; + const Consensus::Params& consensus = chainparams.GetConsensus(nHeight); + const int32_t nChainId = consensus.nAuxpowChainId; // FIXME: Active version bits after the always-auxpow fork! - // const int32_t nVersion = ComputeBlockVersion(pindexPrev, chainparams.GetConsensus()), nChainId); + // const int32_t nVersion = ComputeBlockVersion(pindexPrev, consensus), nChainId); const int32_t nVersion = 4; pblock->SetBaseVersion(nVersion, nChainId); // -regtest only: allow overriding block.nVersion with @@ -172,7 +173,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc // -promiscuousmempoolflags is used. // TODO: replace this with a call to main to assess validity of a mempool // transaction (which in most cases can be a no-op). - fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus()) && fMineWitnessTx; + fIncludeWitness = IsWitnessEnabled(pindexPrev, consensus) && fMineWitnessTx; addPriorityTxs(); int nPackagesSelected = 0; @@ -191,11 +192,11 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc coinbaseTx.vin[0].prevout.SetNull(); coinbaseTx.vout.resize(1); coinbaseTx.vout[0].scriptPubKey = scriptPubKeyIn; - coinbaseTx.vout[0].nValue = nFees + GetDogecoinBlockSubsidy(nHeight, chainparams.GetConsensus(), pindexPrev->GetBlockHash( + coinbaseTx.vout[0].nValue = nFees + GetDogecoinBlockSubsidy(nHeight, consensus, pindexPrev->GetBlockHash( )); coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0; pblock->vtx[0] = MakeTransactionRef(std::move(coinbaseTx)); - pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus()); + pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, consensus); pblocktemplate->vTxFees[0] = -nFees; uint64_t nSerializeSize = GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION); @@ -203,8 +204,8 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); - UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, chainparams.GetConsensus()); + UpdateTime(pblock, consensus, pindexPrev); + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensus); pblock->nNonce = 0; pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 7c576afae..856072f32 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -787,7 +787,7 @@ void PeerLogicValidation::NewPoWValidBlock(const CBlockIndex *pindex, const std: return; nHighestFastAnnounce = pindex->nHeight; - bool fWitnessEnabled = IsWitnessEnabled(pindex->pprev, Params().GetConsensus()); + bool fWitnessEnabled = IsWitnessEnabled(pindex->pprev, Params().GetConsensus(pindex->nHeight)); uint256 hashBlock(pblock->GetHash()); { @@ -1531,7 +1531,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr LOCK(cs_main); - uint32_t nFetchFlags = GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus()); + uint32_t nFetchFlags = GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus(chainActive.Height())); std::vector<CInv> vToFetch; @@ -1597,7 +1597,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id); pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end()); - ProcessGetData(pfrom, chainparams.GetConsensus(), connman, interruptMsgProc); + ProcessGetData(pfrom, chainparams.GetConsensus(chainActive.Height()), connman, interruptMsgProc); } @@ -1643,7 +1643,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } // If pruning, don't inv blocks unless we have on disk and are likely to still have // for some reasonable time window (1 hour) that block relay might require. - const int nPrunedBlocksLikelyToHave = MIN_BLOCKS_TO_KEEP - 3600 / chainparams.GetConsensus().nPowTargetSpacing; + const int nPrunedBlocksLikelyToHave = MIN_BLOCKS_TO_KEEP - 3600 / chainparams.GetConsensus(pindex->nHeight).nPowTargetSpacing; if (fPruneMode && (!(pindex->nStatus & BLOCK_HAVE_DATA) || pindex->nHeight <= chainActive.Tip()->nHeight - nPrunedBlocksLikelyToHave)) { LogPrint("net", " getblocks stopping, pruned or too old block at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); @@ -1700,12 +1700,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr inv.type = State(pfrom->GetId())->fWantsCmpctWitness ? MSG_WITNESS_BLOCK : MSG_BLOCK; inv.hash = req.blockhash; pfrom->vRecvGetData.push_back(inv); - ProcessGetData(pfrom, chainparams.GetConsensus(), connman, interruptMsgProc); + ProcessGetData(pfrom, chainparams.GetConsensus(it->second->nHeight), connman, interruptMsgProc); return true; } CBlock block; - bool ret = ReadBlockFromDisk(block, it->second, chainparams.GetConsensus()); + bool ret = ReadBlockFromDisk(block, it->second, chainparams.GetConsensus(it->second->nHeight)); assert(ret); SendBlockTransactions(block, req, pfrom, connman); @@ -1748,7 +1748,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr LogPrint("net", "getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), pfrom->id); for (; pindex; pindex = chainActive.Next(pindex)) { - vHeaders.push_back(pindex->GetBlockHeader(chainparams.GetConsensus())); + vHeaders.push_back(pindex->GetBlockHeader(chainparams.GetConsensus(pindex->nHeight))); if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop) break; } @@ -1883,7 +1883,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } } if (!fRejectedParents) { - uint32_t nFetchFlags = GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus()); + uint32_t nFetchFlags = GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus(chainActive.Height())); BOOST_FOREACH(const CTxIn& txin, tx.vin) { CInv _inv(MSG_TX | nFetchFlags, txin.prevout.hash); pfrom->AddInventoryKnown(_inv); @@ -2019,19 +2019,19 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr // We requested this block for some reason, but our mempool will probably be useless // so we just grab the block via normal getdata std::vector<CInv> vInv(1); - vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus()), cmpctblock.header.GetHash()); + vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus(pindex->pprev->nHeight)), cmpctblock.header.GetHash()); connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETDATA, vInv)); } return true; } // If we're not close to tip yet, give up and let parallel block fetch work its magic - if (!fAlreadyInFlight && !CanDirectFetch(chainparams.GetConsensus())) + if (!fAlreadyInFlight && !CanDirectFetch(chainparams.GetConsensus(pindex->pprev->nHeight))) return true; CNodeState *nodestate = State(pfrom->GetId()); - if (IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus()) && !nodestate->fSupportsDesiredCmpctVersion) { + if (IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus(pindex->pprev->nHeight)) && !nodestate->fSupportsDesiredCmpctVersion) { // Don't bother trying to process compact blocks from v1 peers // after segwit activates. return true; @@ -2043,7 +2043,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr if ((!fAlreadyInFlight && nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) || (fAlreadyInFlight && blockInFlightIt->second.first == pfrom->GetId())) { std::list<QueuedBlock>::iterator* queuedBlockIt = NULL; - if (!MarkBlockAsInFlight(pfrom->GetId(), pindex->GetBlockHash(), chainparams.GetConsensus(), pindex, &queuedBlockIt)) { + if (!MarkBlockAsInFlight(pfrom->GetId(), pindex->GetBlockHash(), chainparams.GetConsensus(pindex->nHeight), pindex, &queuedBlockIt)) { if (!(*queuedBlockIt)->partialBlock) (*queuedBlockIt)->partialBlock.reset(new PartiallyDownloadedBlock(&mempool)); else { @@ -2063,7 +2063,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } else if (status == READ_STATUS_FAILED) { // Duplicate txindexes, the block is now in-flight, so just request it std::vector<CInv> vInv(1); - vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus()), cmpctblock.header.GetHash()); + vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus(pindex->pprev->nHeight)), cmpctblock.header.GetHash()); connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETDATA, vInv)); return true; } @@ -2106,7 +2106,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr // We requested this block, but its far into the future, so our // mempool will probably be useless - request the block normally std::vector<CInv> vInv(1); - vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus()), cmpctblock.header.GetHash()); + vInv[0] = CInv(MSG_BLOCK | GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus(pindex->pprev->nHeight)), cmpctblock.header.GetHash()); connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETDATA, vInv)); return true; } else { @@ -2177,7 +2177,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } else if (status == READ_STATUS_FAILED) { // Might have collided, fall back to getdata now :( std::vector<CInv> invs; - invs.push_back(CInv(MSG_BLOCK | GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus()), resp.blockhash)); + invs.push_back(CInv(MSG_BLOCK | GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus(chainActive.Height())), resp.blockhash)); connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETDATA, invs)); } else { // Block is either okay, or possibly we received @@ -2313,7 +2313,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexLast), uint256())); } - bool fCanDirectFetch = CanDirectFetch(chainparams.GetConsensus()); + bool fCanDirectFetch = CanDirectFetch(chainparams.GetConsensus(0)); // If this set of headers is valid and ends in a block with at least as // much work as our tip, download as much as possible. if (fCanDirectFetch && pindexLast->IsValid(BLOCK_VALID_TREE) && chainActive.Tip()->nChainWork <= pindexLast->nChainWork) { @@ -2323,7 +2323,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr while (pindexWalk && !chainActive.Contains(pindexWalk) && vToFetch.size() <= MAX_BLOCKS_IN_TRANSIT_PER_PEER) { if (!(pindexWalk->nStatus & BLOCK_HAVE_DATA) && !mapBlocksInFlight.count(pindexWalk->GetBlockHash()) && - (!IsWitnessEnabled(pindexWalk->pprev, chainparams.GetConsensus()) || State(pfrom->GetId())->fHaveWitness)) { + (!IsWitnessEnabled(pindexWalk->pprev, chainparams.GetConsensus(pindexWalk->pprev->nHeight)) || State(pfrom->GetId())->fHaveWitness)) { // We don't have this block, and it's not yet in flight. vToFetch.push_back(pindexWalk); } @@ -2345,9 +2345,9 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr // Can't download any more from this peer break; } - uint32_t nFetchFlags = GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus()); + uint32_t nFetchFlags = GetFetchFlags(pfrom, pindex->pprev, chainparams.GetConsensus(pindex->pprev->nHeight)); vGetData.push_back(CInv(MSG_BLOCK | nFetchFlags, pindex->GetBlockHash())); - MarkBlockAsInFlight(pfrom->GetId(), pindex->GetBlockHash(), chainparams.GetConsensus(), pindex); + MarkBlockAsInFlight(pfrom->GetId(), pindex->GetBlockHash(), chainparams.GetConsensus(pindex->nHeight), pindex); LogPrint("net", "Requesting block %s from peer=%d\n", pindex->GetBlockHash().ToString(), pfrom->id); } @@ -2652,7 +2652,7 @@ bool ProcessMessages(CNode* pfrom, CConnman& connman, const std::atomic<bool>& i bool fMoreWork = false; if (!pfrom->vRecvGetData.empty()) - ProcessGetData(pfrom, chainparams.GetConsensus(), connman, interruptMsgProc); + ProcessGetData(pfrom, chainparams.GetConsensus(chainActive.Height()), connman, interruptMsgProc); if (pfrom->fDisconnect) return false; @@ -2777,7 +2777,7 @@ public: bool SendMessages(CNode* pto, CConnman& connman, const std::atomic<bool>& interruptMsgProc) { - const Consensus::Params& consensusParams = Params().GetConsensus(); + const Consensus::Params& consensusParams = Params().GetConsensus(chainActive.Height()); { // Don't send anything until the version handshake is complete if (!pto->fSuccessfullyConnected || pto->fDisconnect) diff --git a/src/pow.cpp b/src/pow.cpp index b569e709a..b0deab393 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -13,6 +13,22 @@ #include "uint256.h" #include "util.h" +// Determine if the for the given block, a min difficulty setting applies +bool AllowMinDifficultyForBlock(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) +{ + // check if the chain allows minimum difficulty blocks + if (!params.fPowAllowMinDifficultyBlocks) + return false; + + // Dogecoin: Magic number at which reset protocol switches + // check if we allow minimum difficulty at this block-height + if (pindexLast->nHeight < 157500) + return false; + + // Allow for a minimum block time if the elapsed time > 2*nTargetSpacing + return (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2); +} + unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params) { unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact(); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 5c26baef9..bab6c8689 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -755,7 +755,7 @@ void BitcoinGUI::updateHeadersSyncProgressLabel() { int64_t headersTipTime = clientModel->getHeaderTipTime(); int headersTipHeight = clientModel->getHeaderTipHeight(); - int estHeadersLeft = (GetTime() - headersTipTime) / Params().GetConsensus().nPowTargetSpacing; + int estHeadersLeft = (GetTime() - headersTipTime) / Params().GetConsensus(headersTipHeight).nPowTargetSpacing; if (estHeadersLeft > HEADER_HEIGHT_DELTA_SYNC) progressBarLabel->setText(tr("Syncing Headers (%1%)...").arg(QString::number(100.0 / (headersTipHeight+estHeadersLeft)*headersTipHeight, 'f', 1))); } diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp index 4779ffa43..bf632d28c 100644 --- a/src/qt/modaloverlay.cpp +++ b/src/qt/modaloverlay.cpp @@ -127,7 +127,7 @@ void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVeri // estimate the number of headers left based on nPowTargetSpacing // and check if the gui is not aware of the the best header (happens rarely) - int estimateNumHeadersLeft = bestHeaderDate.secsTo(currentDate) / Params().GetConsensus().nPowTargetSpacing; + int estimateNumHeadersLeft = bestHeaderDate.secsTo(currentDate) / Params().GetConsensus(bestHeaderHeight).nPowTargetSpacing; bool hasBestHeader = bestHeaderHeight >= count; // show remaining number of blocks diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 65ca00755..1041bbd41 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -610,7 +610,8 @@ void SendCoinsDialog::updateGlobalFeeVariables() CoinControlDialog::coinControl->nMinimumTotalFee = 0; // show the estimated required time for confirmation - ui->confirmationTargetLabel->setText(GUIUtil::formatDurationStr(nConfirmTarget * Params().GetConsensus().nPowTargetSpacing) + " / " + tr("%n block(s)", "", nConfirmTarget)); + // Dogecoin: We manually set height well past the last hard fork here + ui->confirmationTargetLabel->setText(GUIUtil::formatDurationStr(nConfirmTarget * Params().GetConsensus(400000).nPowTargetSpacing) + " / " + tr("%n block(s)", "", nConfirmTarget)); } else { diff --git a/src/rest.cpp b/src/rest.cpp index e9d0a8cef..7dc3a42f0 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -162,7 +162,7 @@ static bool rest_headers(HTTPRequest* req, CDataStream ssHeader(SER_NETWORK, PROTOCOL_VERSION); const CChainParams& chainparams = Params(); BOOST_FOREACH(const CBlockIndex *pindex, headers) { - ssHeader << pindex->GetBlockHeader(chainparams.GetConsensus()); + ssHeader << pindex->GetBlockHeader(chainparams.GetConsensus(pindex->nHeight)); } switch (rf) { @@ -222,7 +222,7 @@ static bool rest_block(HTTPRequest* req, if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)"); - if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) + if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus(pblockindex->nHeight))) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } @@ -363,7 +363,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) CTransactionRef tx; uint256 hashBlock = uint256(); - if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) + if (!GetTransaction(hash, tx, Params().GetConsensus(0), hashBlock, true)) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index d06c00cbc..6fb45a515 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -720,7 +720,7 @@ UniValue getblockheader(const JSONRPCRequest& request) if (!fVerbose) { CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); - ssBlock << pblockindex->GetBlockHeader(Params().GetConsensus()); + ssBlock << pblockindex->GetBlockHeader(Params().GetConsensus(pblockindex->nHeight)); std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); return strHex; } @@ -787,7 +787,7 @@ UniValue getblock(const JSONRPCRequest& request) if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)"); - if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) + if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus(pblockindex->nHeight))) // Block not found on disk. This could be because we have the block // header in our index but don't have the block (for example if a // non-whitelisted node sends us an unrequested long chain of valid @@ -1185,7 +1185,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request) obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); obj.push_back(Pair("pruned", fPruneMode)); - const Consensus::Params& consensusParams = Params().GetConsensus(); + const Consensus::Params& consensusParams = Params().GetConsensus(0); CBlockIndex* tip = chainActive.Tip(); UniValue softforks(UniValue::VARR); UniValue bip9_softforks(UniValue::VOBJ); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index b355ccdc9..0e2dbe2cb 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -48,7 +48,8 @@ UniValue GetNetworkHashPS(int lookup, int height) { // If lookup is -1, then use blocks since last difficulty change. if (lookup <= 0) - lookup = pb->nHeight % Params().GetConsensus().DifficultyAdjustmentInterval() + 1; + lookup = pb->nHeight % Params().GetConsensus(pb->nHeight).DifficultyAdjustmentInterval() + 1; + // // If lookup is larger than chain, then set it to chain length. if (lookup > pb->nHeight) @@ -125,7 +126,7 @@ UniValue generateBlocks(boost::shared_ptr<CReserveScript> coinbaseScript, int nG } CAuxPow::initAuxPow(*pblock); CPureBlockHeader& miningHeader = pblock->auxpow->parentBlock; - while (nMaxTries > 0 && miningHeader.nNonce < nInnerLoopCount && !CheckProofOfWork(miningHeader.GetHash(), pblock->nBits, Params().GetConsensus())) { + while (nMaxTries > 0 && miningHeader.nNonce < nInnerLoopCount && !CheckProofOfWork(miningHeader.GetHash(), pblock->nBits, Params().GetConsensus(nHeight))) { ++miningHeader.nNonce; --nMaxTries; } @@ -561,7 +562,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request) pindexPrev = pindexPrevNew; } CBlock* pblock = &pblocktemplate->block; // pointer for convenience - const Consensus::Params& consensusParams = Params().GetConsensus(); + const Consensus::Params& consensusParams = Params().GetConsensus(pindexPrev->nHeight + 1); // Update nTime UpdateTime(pblock, consensusParams, pindexPrev); @@ -778,7 +779,8 @@ UniValue submitblock(const JSONRPCRequest& request) LOCK(cs_main); BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); if (mi != mapBlockIndex.end()) { - UpdateUncommittedBlockStructures(block, mi->second, Params().GetConsensus()); + int nHeight = chainActive.Height() + 1; + UpdateUncommittedBlockStructures(block, mi->second, Params().GetConsensus(nHeight)); } } @@ -990,7 +992,7 @@ UniValue getauxblock(const JSONRPCRequest& request) past the point of merge-mining start. Check nevertheless. */ { LOCK(cs_main); - if (chainActive.Height() + 1 < Params().GetConsensus().nAuxpowStartHeight) + if (Params().GetConsensus(chainActive.Height() + 1).fAllowLegacyBlocks) throw std::runtime_error("getauxblock method is not yet available"); } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 0fabb9f5a..994057e20 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -219,7 +219,8 @@ UniValue getrawtransaction(const JSONRPCRequest& request) CTransactionRef tx; uint256 hashBlock; - if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) + // Dogecoin: Is this the best value for consensus height? + if (!GetTransaction(hash, tx, Params().GetConsensus(0), hashBlock, true)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string(fTxIndex ? "No such mempool or blockchain transaction" : "No such mempool transaction. Use -txindex to enable blockchain transaction queries") + ". Use gettransaction for wallet transactions."); @@ -290,7 +291,7 @@ UniValue gettxoutproof(const JSONRPCRequest& request) if (pblockindex == NULL) { CTransactionRef tx; - if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock, false) || hashBlock.IsNull()) + if (!GetTransaction(oneTxid, tx, Params().GetConsensus(0), hashBlock, false) || hashBlock.IsNull()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block"); if (!mapBlockIndex.count(hashBlock)) throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt"); @@ -298,7 +299,7 @@ UniValue gettxoutproof(const JSONRPCRequest& request) } CBlock block; - if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) + if(!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus(pblockindex->nHeight))) throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); unsigned int ntxFound = 0; diff --git a/src/test/auxpow_tests.cpp b/src/test/auxpow_tests.cpp index 5cb2e3269..ca1a93062 100644 --- a/src/test/auxpow_tests.cpp +++ b/src/test/auxpow_tests.cpp @@ -181,7 +181,7 @@ CAuxpowBuilder::buildCoinbaseData(bool header, const std::vector<unsigned char>& BOOST_AUTO_TEST_CASE(check_auxpow) { - const Consensus::Params& params = Params().GetConsensus(); + const Consensus::Params& params = Params().GetConsensus(371337); CAuxpowBuilder builder(5, 42); CAuxPow auxpow; @@ -333,7 +333,7 @@ mineBlock(CBlockHeader& block, bool ok, int nBits = -1) block.nNonce = 0; while (true) { - const bool nowOk = (UintToArith256(block.GetHash()) <= target); + const bool nowOk = (UintToArith256(block.GetPoWHash()) <= target); if ((ok && nowOk) || (!ok && !nowOk)) break; @@ -341,16 +341,16 @@ mineBlock(CBlockHeader& block, bool ok, int nBits = -1) } if (ok) - BOOST_CHECK(CheckProofOfWork(block.GetHash(), nBits, Params().GetConsensus())); + BOOST_CHECK(CheckProofOfWork(block.GetPoWHash(), nBits, Params().GetConsensus(0))); else - BOOST_CHECK(!CheckProofOfWork(block.GetHash(), nBits, Params().GetConsensus())); + BOOST_CHECK(!CheckProofOfWork(block.GetPoWHash(), nBits, Params().GetConsensus(0))); } BOOST_AUTO_TEST_CASE(auxpow_pow) { /* Use regtest parameters to allow mining with easy difficulty. */ SelectParams(CBaseChainParams::REGTEST); - const Consensus::Params& params = Params().GetConsensus(); + const Consensus::Params& params = Params().GetConsensus(371337); const arith_uint256 target = (~arith_uint256(0) >> 1); CBlockHeader block; diff --git a/src/test/blockencodings_tests.cpp b/src/test/blockencodings_tests.cpp index d8d772f6b..8d5323532 100644 --- a/src/test/blockencodings_tests.cpp +++ b/src/test/blockencodings_tests.cpp @@ -47,7 +47,7 @@ static CBlock BuildBlockTestCase() { bool mutated; block.hashMerkleRoot = BlockMerkleRoot(block, &mutated); assert(!mutated); - while (!CheckProofOfWork(block.GetPoWHash(), block.nBits, Params().GetConsensus())) ++block.nNonce; + while (!CheckProofOfWork(block.GetPoWHash(), block.nBits, Params().GetConsensus(0))) ++block.nNonce; return block; } @@ -103,6 +103,7 @@ BOOST_AUTO_TEST_CASE(SimpleRoundTripTest) BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated)); CBlock block3; + // FIXME: Somehow this seems to be broken by adding chain ID to RegTest BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[1]}) == READ_STATUS_OK); BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString()); BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString()); @@ -206,6 +207,7 @@ BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest) CBlock block3; PartiallyDownloadedBlock partialBlockCopy = partialBlock; + // FIXME: Somehow this seems to be broken by adding chain ID to RegTest BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[0]}) == READ_STATUS_OK); BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString()); BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString()); @@ -256,6 +258,7 @@ BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest) CBlock block2; PartiallyDownloadedBlock partialBlockCopy = partialBlock; + // FIXME: Somehow this seems to be broken by adding chain ID to RegTest BOOST_CHECK(partialBlock.FillBlock(block2, {}) == READ_STATUS_OK); BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString()); bool mutated; @@ -289,7 +292,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest) bool mutated; block.hashMerkleRoot = BlockMerkleRoot(block, &mutated); assert(!mutated); - while (!CheckProofOfWork(block.GetPoWHash(), block.nBits, Params().GetConsensus())) ++block.nNonce; + while (!CheckProofOfWork(block.GetPoWHash(), block.nBits, Params().GetConsensus(0))) ++block.nNonce; // Test simple header round-trip with only coinbase { @@ -307,6 +310,7 @@ BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest) CBlock block2; std::vector<CTransactionRef> vtx_missing; + // FIXME: Somehow this seems to be broken by adding chain ID to RegTest BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_OK); BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString()); BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString()); diff --git a/src/test/dogecoin_tests.cpp b/src/test/dogecoin_tests.cpp index db6d7c89a..3ba86618e 100644 --- a/src/test/dogecoin_tests.cpp +++ b/src/test/dogecoin_tests.cpp @@ -62,23 +62,26 @@ BOOST_AUTO_TEST_CASE(subsidy_limit_test) { int nHeight = 0; int nStepSize= 1; - const Consensus::Params& params = Params(CBaseChainParams::MAIN).GetConsensus(); + const CChainParams& mainParams = Params(CBaseChainParams::MAIN); CAmount nSum = 0; uint256 prevHash = uint256S("0"); for (nHeight = 0; nHeight <= 100000; nHeight++) { + const Consensus::Params& params = mainParams.GetConsensus(nHeight); CAmount nSubsidy = GetDogecoinBlockSubsidy(nHeight, params, prevHash); BOOST_CHECK(MoneyRange(nSubsidy)); BOOST_CHECK(nSubsidy <= 1000000 * COIN); nSum += nSubsidy * nStepSize; } for (; nHeight <= 145000; nHeight++) { + const Consensus::Params& params = mainParams.GetConsensus(nHeight); CAmount nSubsidy = GetDogecoinBlockSubsidy(nHeight, params, prevHash); BOOST_CHECK(MoneyRange(nSubsidy)); BOOST_CHECK(nSubsidy <= 500000 * COIN); nSum += nSubsidy * nStepSize; } for (; nHeight < 600000; nHeight++) { + const Consensus::Params& params = mainParams.GetConsensus(nHeight); CAmount nSubsidy = GetDogecoinBlockSubsidy(nHeight, params, prevHash); CAmount nExpectedSubsidy = (500000 >> (nHeight / 100000)) * COIN; BOOST_CHECK(MoneyRange(nSubsidy)); @@ -94,7 +97,8 @@ BOOST_AUTO_TEST_CASE(subsidy_limit_test) BOOST_CHECK(nSum >= lowerlimit); // Test reward at 600k+ is constant - CAmount nConstantSubsidy = GetDogecoinBlockSubsidy(600000, params, prevHash); + const Consensus::Params& params = mainParams.GetConsensus(nHeight); + CAmount nConstantSubsidy = GetDogecoinBlockSubsidy(nHeight, params, prevHash); BOOST_CHECK_EQUAL(nConstantSubsidy, 10000 * COIN); nConstantSubsidy = GetDogecoinBlockSubsidy(700000, params, prevHash); @@ -104,7 +108,7 @@ BOOST_AUTO_TEST_CASE(subsidy_limit_test) BOOST_AUTO_TEST_CASE(get_next_work_difficulty_limit) { SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); + const Consensus::Params& params = Params().GetConsensus(0); CBlockIndex pindexLast; int64_t nLastRetargetTime = 1386474927; // Block # 1 @@ -118,7 +122,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_difficulty_limit) BOOST_AUTO_TEST_CASE(get_next_work_pre_digishield) { SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); + const Consensus::Params& params = Params().GetConsensus(0); CBlockIndex pindexLast; int64_t nLastRetargetTime = 1386942008; // Block 9359 @@ -132,7 +136,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_pre_digishield) BOOST_AUTO_TEST_CASE(get_next_work_digishield) { SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); + const Consensus::Params& params = Params().GetConsensus(145000); CBlockIndex pindexLast; int64_t nLastRetargetTime = 1395094427; @@ -147,7 +151,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_digishield) BOOST_AUTO_TEST_CASE(get_next_work_digishield_modulated_upper) { SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); + const Consensus::Params& params = Params().GetConsensus(145000); CBlockIndex pindexLast; int64_t nLastRetargetTime = 1395100835; @@ -162,7 +166,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_digishield_modulated_upper) BOOST_AUTO_TEST_CASE(get_next_work_digishield_modulated_lower) { SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); + const Consensus::Params& params = Params().GetConsensus(145000); CBlockIndex pindexLast; int64_t nLastRetargetTime = 1395380517; @@ -177,7 +181,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_digishield_modulated_lower) BOOST_AUTO_TEST_CASE(get_next_work_digishield_rounding) { SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); + const Consensus::Params& params = Params().GetConsensus(145000); CBlockIndex pindexLast; int64_t nLastRetargetTime = 1395094679; @@ -190,4 +194,40 @@ BOOST_AUTO_TEST_CASE(get_next_work_digishield_rounding) BOOST_CHECK_EQUAL(CalculateDogecoinNextWorkRequired(&pindexLast, nLastRetargetTime, params), 0x1b6558a4); } +BOOST_AUTO_TEST_CASE(hardfork_parameters) +{ + SelectParams(CBaseChainParams::MAIN); + const Consensus::Params& initialParams = Params().GetConsensus(0); + + BOOST_CHECK_EQUAL(initialParams.nPowTargetTimespan, 14400); + BOOST_CHECK_EQUAL(initialParams.fAllowLegacyBlocks, true); + BOOST_CHECK_EQUAL(initialParams.fDigishieldDifficultyCalculation, false); + + const Consensus::Params& initialParamsEnd = Params().GetConsensus(144999); + BOOST_CHECK_EQUAL(initialParamsEnd.nPowTargetTimespan, 14400); + BOOST_CHECK_EQUAL(initialParamsEnd.fAllowLegacyBlocks, true); + BOOST_CHECK_EQUAL(initialParamsEnd.fDigishieldDifficultyCalculation, false); + + const Consensus::Params& digishieldParams = Params().GetConsensus(145000); + BOOST_CHECK_EQUAL(digishieldParams.nPowTargetTimespan, 60); + BOOST_CHECK_EQUAL(digishieldParams.fAllowLegacyBlocks, true); + BOOST_CHECK_EQUAL(digishieldParams.fDigishieldDifficultyCalculation, true); + + const Consensus::Params& digishieldParamsEnd = Params().GetConsensus(371336); + BOOST_CHECK_EQUAL(digishieldParamsEnd.nPowTargetTimespan, 60); + BOOST_CHECK_EQUAL(digishieldParamsEnd.fAllowLegacyBlocks, true); + BOOST_CHECK_EQUAL(digishieldParamsEnd.fDigishieldDifficultyCalculation, true); + + const Consensus::Params& auxpowParams = Params().GetConsensus(371337); + BOOST_CHECK_EQUAL(auxpowParams.nHeightEffective, 371337); + BOOST_CHECK_EQUAL(auxpowParams.nPowTargetTimespan, 60); + BOOST_CHECK_EQUAL(auxpowParams.fAllowLegacyBlocks, false); + BOOST_CHECK_EQUAL(auxpowParams.fDigishieldDifficultyCalculation, true); + + const Consensus::Params& auxpowHighParams = Params().GetConsensus(700000); // Arbitrary point after last hard-fork + BOOST_CHECK_EQUAL(auxpowHighParams.nPowTargetTimespan, 60); + BOOST_CHECK_EQUAL(auxpowHighParams.fAllowLegacyBlocks, false); + BOOST_CHECK_EQUAL(auxpowHighParams.fDigishieldDifficultyCalculation, true); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index a51714ad7..a90e6896b 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -18,7 +18,7 @@ BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup) /* BOOST_AUTO_TEST_CASE(get_next_work) { SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); + const Consensus::Params& params = Params().GetConsensus(0); int64_t nLastRetargetTime = 1261130161; // Block #30240 CBlockIndex pindexLast; @@ -33,7 +33,7 @@ BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup) /* BOOST_AUTO_TEST_CASE(get_next_work_pow_limit) { SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); + const Consensus::Params& params = Params().GetConsensus(0); int64_t nLastRetargetTime = 1231006505; // Block #0 CBlockIndex pindexLast; @@ -48,7 +48,7 @@ BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup) /* BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual) { SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); + const Consensus::Params& params = Params().GetConsensus(0); int64_t nLastRetargetTime = 1279008237; // Block #66528 CBlockIndex pindexLast; @@ -63,7 +63,7 @@ BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup) /* BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual) { SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); + const Consensus::Params& params = Params().GetConsensus(0); int64_t nLastRetargetTime = 1263163443; // NOTE: Not an actual block time CBlockIndex pindexLast; @@ -76,7 +76,7 @@ BOOST_FIXTURE_TEST_SUITE(pow_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test) { SelectParams(CBaseChainParams::MAIN); - const Consensus::Params& params = Params().GetConsensus(); + const Consensus::Params& params = Params().GetConsensus(0); std::vector<CBlockIndex> blocks(10000); for (int i = 0; i < 10000; i++) { diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 9a499357f..9a3eecf99 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -127,7 +127,7 @@ TestChain240Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& unsigned int extraNonce = 0; IncrementExtraNonce(&block, chainActive.Tip(), extraNonce); - while (!CheckProofOfWork(block.GetPoWHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce; + while (!CheckProofOfWork(block.GetPoWHash(), block.nBits, chainparams.GetConsensus(0))) ++block.nNonce; std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block); ProcessNewBlock(chainparams, shared_pblock, true, NULL); diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index e2b5573ab..7427a1e57 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -209,7 +209,7 @@ BOOST_AUTO_TEST_CASE(versionbits_test) } // Sanity checks of version bit deployments - const Consensus::Params &mainnetParams = Params(CBaseChainParams::MAIN).GetConsensus(); + const Consensus::Params &mainnetParams = Params(CBaseChainParams::MAIN).GetConsensus(0); for (int i=0; i<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) { uint32_t bitmask = VersionBitsMask(mainnetParams, (Consensus::DeploymentPos)i); // Make sure that no deployment tries to set an invalid bit. @@ -235,7 +235,7 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion) { // Check that ComputeBlockVersion will set the appropriate bit correctly // on mainnet. - const Consensus::Params &mainnetParams = Params(CBaseChainParams::MAIN).GetConsensus(); + const Consensus::Params &mainnetParams = Params(CBaseChainParams::MAIN).GetConsensus(0); // Use the TESTDUMMY deployment for testing purposes. int64_t bit = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit; diff --git a/src/validation.cpp b/src/validation.cpp index b233e1044..e4ae9c045 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -19,6 +19,7 @@ #include "policy/policy.h" #include "pow.h" #include "primitives/block.h" +#include "primitives/pureheader.h" #include "primitives/transaction.h" #include "random.h" #include "script/script.h" @@ -594,7 +595,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C return state.DoS(100, false, REJECT_INVALID, "coinbase"); // Reject transactions with witness before segregated witness activates (override with -prematurewitness) - bool witnessEnabled = IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus()); + bool witnessEnabled = IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus(chainActive.Height())); if (!GetBoolArg("-prematurewitness",false) && tx.HasWitness() && !witnessEnabled) { return state.DoS(0, false, REJECT_NONSTANDARD, "no-witness-yet", true); } @@ -1219,7 +1220,7 @@ bool IsInitialBlockDownload() return true; if (chainActive.Tip() == NULL) return true; - if (chainActive.Tip()->nChainWork < UintToArith256(chainParams.GetConsensus().nMinimumChainWork)) + if (chainActive.Tip()->nChainWork < UintToArith256(chainParams.GetConsensus(chainActive.Height()).nMinimumChainWork)) return true; if (chainActive.Tip()->GetBlockTime() < (GetTime() - nMaxTipAge)) return true; @@ -1770,10 +1771,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin { AssertLockHeld(cs_main); + const Consensus::Params& consensus = Params().GetConsensus(pindex->nHeight); int64_t nTimeStart = GetTimeMicros(); // Check it again in case a previous version let a bad block in - if (!CheckBlock(block, state, chainparams.GetConsensus(), !fJustCheck, !fJustCheck)) + if (!CheckBlock(block, state, !fJustCheck, !fJustCheck)) return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); // verify that the view's current state corresponds to the previous block @@ -1782,7 +1784,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // Special case for the genesis block, skipping connection of its transactions // (its coinbase is unspendable) - if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) { + if (block.GetHash() == consensus.hashGenesisBlock) { if (!fJustCheck) view.SetBestBlock(pindex->GetBlockHash()); return true; @@ -1799,7 +1801,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin if (it != mapBlockIndex.end()) { if (it->second->GetAncestor(pindex->nHeight) == pindex && pindexBestHeader->GetAncestor(pindex->nHeight) == pindex && - pindexBestHeader->nChainWork >= UintToArith256(chainparams.GetConsensus().nMinimumChainWork)) { + pindexBestHeader->nChainWork >= UintToArith256(consensus.nMinimumChainWork)) { // This block is a member of the assumed verified chain and an ancestor of the best header. // The equivalent time check discourages hashpower from extorting the network via DOS attack // into accepting an invalid block through telling users they must manually set assumevalid. @@ -1809,7 +1811,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // artificially set the default assumed verified block further back. // The test against nMinimumChainWork prevents the skipping when denied access to any chain at // least as good as the expected chain. - fScriptChecks = (GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, chainparams.GetConsensus()) <= 60 * 60 * 24 * 7 * 2); + fScriptChecks = (GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, consensus) <= 60 * 60 * 24 * 7 * 2); } } } @@ -1839,9 +1841,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // before the first had been spent. Since those coinbases are sufficiently buried its no longer possible to create further // duplicate transactions descending from the known pairs either. // If we're on the known chain at height greater than where BIP34 activated, we can save the db accesses needed for the BIP30 check. - CBlockIndex *pindexBIP34height = pindex->pprev->GetAncestor(chainparams.GetConsensus().BIP34Height); + CBlockIndex *pindexBIP34height = pindex->pprev->GetAncestor(chainparams.GetConsensus(0).BIP34Height); //Only continue to enforce if we're below BIP34 activation height or the block hash at that height doesn't correspond. - fEnforceBIP30 = fEnforceBIP30 && (!pindexBIP34height || !(pindexBIP34height->GetBlockHash() == chainparams.GetConsensus().BIP34Hash)); + fEnforceBIP30 = fEnforceBIP30 && (!pindexBIP34height || !(pindexBIP34height->GetBlockHash() == chainparams.GetConsensus(0).BIP34Hash)); if (fEnforceBIP30) { for (const auto& tx : block.vtx) { @@ -1859,25 +1861,25 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE; // Start enforcing the DERSIG (BIP66) rule - if (pindex->nHeight >= chainparams.GetConsensus().BIP66Height) { + if (pindex->nHeight >= chainparams.GetConsensus(0).BIP66Height) { flags |= SCRIPT_VERIFY_DERSIG; } // Start enforcing CHECKLOCKTIMEVERIFY, (BIP65) for block.nVersion=4 // blocks, when 75% of the network has upgraded: - if (block.GetBaseVersion() >= 4 && IsSuperMajority(4, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) { + if (block.GetBaseVersion() >= 4 && IsSuperMajority(4, pindex->pprev, chainparams.GetConsensus(0).nMajorityEnforceBlockUpgrade, chainparams.GetConsensus(0))) { flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; } // Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) using versionbits logic. int nLockTimeFlags = 0; - if (VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_CSV, versionbitscache) == THRESHOLD_ACTIVE) { + if (VersionBitsState(pindex->pprev, consensus, Consensus::DEPLOYMENT_CSV, versionbitscache) == THRESHOLD_ACTIVE) { flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE; } // Start enforcing WITNESS rules using versionbits logic. - if (IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus())) { + if (IsWitnessEnabled(pindex->pprev, consensus)) { flags |= SCRIPT_VERIFY_WITNESS; flags |= SCRIPT_VERIFY_NULLDUMMY; } @@ -1959,7 +1961,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2; LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime3 - nTime2), 0.001 * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * 0.000001); - CAmount blockReward = nFees + GetDogecoinBlockSubsidy(pindex->nHeight, chainparams.GetConsensus(), hashPrevBlock); + CAmount blockReward = nFees + GetDogecoinBlockSubsidy(pindex->nHeight, chainparams.GetConsensus(pindex->nHeight), hashPrevBlock); if (block.vtx[0]->GetValueOut() > blockReward) return state.DoS(100, error("ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)", @@ -2154,7 +2156,7 @@ void static UpdateTip(CBlockIndex *pindexNew, const CChainParams& chainParams) { const CBlockIndex* pindex = chainActive.Tip(); for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) { WarningBitsConditionChecker checker(bit); - ThresholdState state = checker.GetStateFor(pindex, chainParams.GetConsensus(), warningcache[bit]); + ThresholdState state = checker.GetStateFor(pindex, chainParams.GetConsensus(pindex->nHeight), warningcache[bit]); if (state == THRESHOLD_ACTIVE || state == THRESHOLD_LOCKED_IN) { if (state == THRESHOLD_ACTIVE) { std::string strWarning = strprintf(_("Warning: unknown new rules activated (versionbit %i)"), bit); @@ -2171,7 +2173,7 @@ void static UpdateTip(CBlockIndex *pindexNew, const CChainParams& chainParams) { // Check the version of the last 100 blocks to see if we need to upgrade: for (int i = 0; i < 100 && pindex != NULL; i++) { - int32_t nExpectedVersion = ComputeBlockVersion(pindex->pprev, chainParams.GetConsensus()); + int32_t nExpectedVersion = ComputeBlockVersion(pindex->pprev, chainParams.GetConsensus(pindex->nHeight)); if (pindex->nVersion > VERSIONBITS_LAST_OLD_BLOCK_VERSION && (pindex->nVersion & ~nExpectedVersion) != 0) ++nUpgraded; pindex = pindex->pprev; @@ -2207,7 +2209,7 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara assert(pindexDelete); // Read block from disk. CBlock block; - if (!ReadBlockFromDisk(block, pindexDelete, chainparams.GetConsensus())) + if (!ReadBlockFromDisk(block, pindexDelete, chainparams.GetConsensus(chainActive.Height()))) return AbortNode(state, "Failed to read block"); // Apply the block atomically to the chain state. int64_t nStart = GetTimeMicros(); @@ -2284,7 +2286,7 @@ bool static ConnectTip(CValidationState& state, const CChainParams& chainparams, if (!pblock) { std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>(); connectTrace.blocksConnected.emplace_back(pindexNew, pblockNew); - if (!ReadBlockFromDisk(*pblockNew, pindexNew, chainparams.GetConsensus())) + if (!ReadBlockFromDisk(*pblockNew, pindexNew, chainparams.GetConsensus(pindexNew->nHeight))) return AbortNode(state, "Failed to read block"); } else { connectTrace.blocksConnected.emplace_back(pindexNew, pblock); @@ -2572,7 +2574,7 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, uiInterface.NotifyBlockTip(fInitialDownload, pindexNewTip); } } while (pindexNewTip != pindexMostWork); - CheckBlockIndex(chainparams.GetConsensus()); + CheckBlockIndex(chainparams.GetConsensus(pindexNewTip->nHeight)); // Write changes periodically to disk, after relay. if (!FlushStateToDisk(state, FLUSH_STATE_PERIODIC)) { @@ -2729,7 +2731,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl pindexNew->nDataPos = pos.nPos; pindexNew->nUndoPos = 0; pindexNew->nStatus |= BLOCK_HAVE_DATA; - if (IsWitnessEnabled(pindexNew->pprev, Params().GetConsensus())) { + if (IsWitnessEnabled(pindexNew->pprev, Params().GetConsensus(pindexNew->nHeight))) { pindexNew->nStatus |= BLOCK_OPT_WITNESS; } pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS); @@ -2857,16 +2859,19 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne return true; } -bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW) +bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW) { // Check proof of work matches claimed amount - if (fCheckPOW && !CheckProofOfWork(block.GetPoWHash(), block.nBits, consensusParams)) + // We don't have block height as this is called without context (i.e. without + // knowing the previous block), but that's okay, as the checks done are permissive + // (i.e. doesn't check work limit or whether AuxPoW is enabled) + if (fCheckPOW && !CheckAuxPowProofOfWork(block, Params().GetConsensus(0))) return state.DoS(50, false, REJECT_INVALID, "high-hash", false, "proof of work failed"); return true; } -bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW, bool fCheckMerkleRoot) +bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot) { // These are checks that are independent of context. @@ -2875,7 +2880,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P // Check that the header is valid (particularly PoW). This is mostly // redundant with the call in AcceptBlockHeader. - if (!CheckBlockHeader(block, state, consensusParams, fCheckPOW)) + if (!CheckBlockHeader(block, state, fCheckPOW)) return false; // Check the merkle root. @@ -2931,7 +2936,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P static bool CheckIndexAgainstCheckpoint(const CBlockIndex* pindexPrev, CValidationState& state, const CChainParams& chainparams, const uint256& hash) { - if (*pindexPrev->phashBlock == chainparams.GetConsensus().hashGenesisBlock) + if (*pindexPrev->phashBlock == chainparams.GetConsensus(pindexPrev->nHeight + 1).hashGenesisBlock) return true; int nHeight = pindexPrev->nHeight+1; @@ -2945,8 +2950,10 @@ static bool CheckIndexAgainstCheckpoint(const CBlockIndex* pindexPrev, CValidati bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params) { - LOCK(cs_main); - return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_ACTIVE); + // Dogecoin: Disable SegWit + return false; + // LOCK(cs_main); + // return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_ACTIVE); } // Compute at which vout of the block's coinbase transaction the witness @@ -3005,17 +3012,27 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc return commitment; } -bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) { const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1; + const Consensus::Params& consensusParams = Params().GetConsensus(nHeight); // Disallow legacy blocks after merge-mining start. - if (!Params().GetConsensus().AllowLegacyBlocks(nHeight) + if (!consensusParams.fAllowLegacyBlocks && block.IsLegacy()) return state.DoS(100, error("%s : legacy block after auxpow start", __func__), REJECT_INVALID, "late-legacy-block"); + // Dogecoin: Disallow AuxPow blocks before it is activated. + // TODO: Remove this test, as checkpoints will enforce this for us now + // NOTE: Previously this had its own fAllowAuxPoW flag, but that's always the opposite of fAllowLegacyBlocks + if (consensusParams.fAllowLegacyBlocks + && block.IsAuxpow()) + return state.DoS(100, error("%s : auxpow blocks are not allowed at height %d, parameters effective from %d", + __func__, pindexPrev->nHeight + 1, consensusParams.nHeightEffective), + REJECT_INVALID, "early-auxpow-block"); + // Check proof of work if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false, "incorrect proof of work"); @@ -3043,11 +3060,14 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta return true; } -bool ContextualCheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev) +bool ContextualCheckBlock(const CBlock& block, CValidationState& state, const CBlockIndex* pindexPrev) { const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1; + const CChainParams& chainParams = Params(); + const Consensus::Params& consensusParams = chainParams.GetConsensus(nHeight); // Start enforcing BIP113 (Median Time Past) using versionbits logic. + // Dogecoin: We probably want to disable this int nLockTimeFlags = 0; if (VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CSV, versionbitscache) == THRESHOLD_ACTIVE) { nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST; @@ -3131,7 +3151,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state uint256 hash = block.GetHash(); BlockMap::iterator miSelf = mapBlockIndex.find(hash); CBlockIndex *pindex = NULL; - if (hash != chainparams.GetConsensus().hashGenesisBlock) { + if (hash != chainparams.GetConsensus(0).hashGenesisBlock) { if (miSelf != mapBlockIndex.end()) { // Block header is already known. @@ -3143,7 +3163,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state return true; } - if (!CheckBlockHeader(block, state, chainparams.GetConsensus())) + if (!CheckBlockHeader(block, state)) return error("%s: Consensus::CheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); // Get prev block index @@ -3159,7 +3179,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, hash)) return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str()); - if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev, GetAdjustedTime())) + if (!ContextualCheckBlockHeader(block, state, pindexPrev, GetAdjustedTime())) return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); } if (pindex == NULL) @@ -3168,7 +3188,7 @@ static bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state if (ppindex) *ppindex = pindex; - CheckBlockIndex(chainparams.GetConsensus()); + CheckBlockIndex(chainparams.GetConsensus(pindex->nHeight)); return true; } @@ -3233,8 +3253,8 @@ static bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, CValidation } if (fNewBlock) *fNewBlock = true; - if (!CheckBlock(block, state, chainparams.GetConsensus()) || - !ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindex->pprev)) { + if (!CheckBlock(block, state) || + !ContextualCheckBlock(block, state, pindex->pprev)) { if (state.IsInvalid() && !state.CorruptionPossible()) { pindex->nStatus |= BLOCK_FAILED_VALID; setDirtyBlockIndex.insert(pindex); @@ -3277,7 +3297,7 @@ static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned unsigned int nFound = 0; for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++) { - if (pstart->nVersion >= minVersion) + if ((pstart->nVersion % CPureBlockHeader::VERSION_AUXPOW) >= minVersion) ++nFound; pstart = pstart->pprev; } @@ -3292,7 +3312,7 @@ bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<cons CValidationState state; // Ensure that CheckBlock() passes before calling AcceptBlock, as // belt-and-suspenders. - bool ret = CheckBlock(*pblock, state, chainparams.GetConsensus()); + bool ret = CheckBlock(*pblock, state); LOCK(cs_main); @@ -3300,7 +3320,7 @@ bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<cons // Store to disk ret = AcceptBlock(pblock, state, chainparams, &pindex, fForceProcessing, NULL, fNewBlock); } - CheckBlockIndex(chainparams.GetConsensus()); + CheckBlockIndex(chainparams.GetConsensus(chainActive.Height())); if (!ret) { GetMainSignals().BlockChecked(*pblock, state); return error("%s: AcceptBlock FAILED", __func__); @@ -3329,11 +3349,11 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, indexDummy.nHeight = pindexPrev->nHeight + 1; // NOTE: CheckBlockHeader is called by CheckBlock - if (!ContextualCheckBlockHeader(block, state, chainparams.GetConsensus(), pindexPrev, GetAdjustedTime())) + if (!ContextualCheckBlockHeader(block, state, pindexPrev, GetAdjustedTime())) return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, FormatStateMessage(state)); - if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot)) + if (!CheckBlock(block, state, fCheckPOW, fCheckMerkleRoot)) return error("%s: Consensus::CheckBlock: %s", __func__, FormatStateMessage(state)); - if (!ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindexPrev)) + if (!ContextualCheckBlock(block, state, pindexPrev)) return error("%s: Consensus::ContextualCheckBlock: %s", __func__, FormatStateMessage(state)); if (!ConnectBlock(block, state, &indexDummy, viewNew, chainparams, true)) return false; @@ -3702,10 +3722,10 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, } CBlock block; // check level 0: read from disk - if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) + if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus(pindex->nHeight))) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 1: verify block validity - if (nCheckLevel >= 1 && !CheckBlock(block, state, chainparams.GetConsensus())) + if (nCheckLevel >= 1 && !CheckBlock(block, state)) return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__, pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state)); // check level 2: verify undo validity @@ -3743,7 +3763,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, uiInterface.ShowProgress(_("Verifying blocks..."), std::max(1, std::min(99, 100 - (int)(((double)(chainActive.Height() - pindex->nHeight)) / (double)nCheckDepth * 50)))); pindex = chainActive.Next(pindex); CBlock block; - if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) + if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus(pindex->nHeight))) return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); if (!ConnectBlock(block, state, pindex, coins, chainparams)) return error("VerifyDB(): *** found unconnectable block at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); @@ -3762,7 +3782,7 @@ bool RewindBlockIndex(const CChainParams& params) int nHeight = 1; while (nHeight <= chainActive.Height()) { - if (IsWitnessEnabled(chainActive[nHeight - 1], params.GetConsensus()) && !(chainActive[nHeight]->nStatus & BLOCK_OPT_WITNESS)) { + if (IsWitnessEnabled(chainActive[nHeight - 1], params.GetConsensus(nHeight - 1)) && !(chainActive[nHeight]->nStatus & BLOCK_OPT_WITNESS)) { break; } nHeight++; @@ -3799,7 +3819,7 @@ bool RewindBlockIndex(const CChainParams& params) // this block or some successor doesn't HAVE_DATA, so we were unable to // rewind all the way. Blocks remaining on chainActive at this point // must not have their validity reduced. - if (IsWitnessEnabled(pindexIter->pprev, params.GetConsensus()) && !(pindexIter->nStatus & BLOCK_OPT_WITNESS) && !chainActive.Contains(pindexIter)) { + if (IsWitnessEnabled(pindexIter->pprev, params.GetConsensus(pindexIter->nHeight)) && !(pindexIter->nStatus & BLOCK_OPT_WITNESS) && !chainActive.Contains(pindexIter)) { // Reduce validity pindexIter->nStatus = std::min<unsigned int>(pindexIter->nStatus & BLOCK_VALID_MASK, BLOCK_VALID_TREE) | (pindexIter->nStatus & ~BLOCK_VALID_MASK); // Remove have-data flags. @@ -3831,7 +3851,7 @@ bool RewindBlockIndex(const CChainParams& params) PruneBlockIndexCandidates(); - CheckBlockIndex(params.GetConsensus()); + CheckBlockIndex(params.GetConsensus(chainActive.Height())); if (!FlushStateToDisk(state, FLUSH_STATE_ALWAYS)) { return false; @@ -3963,7 +3983,7 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB // detect out of order blocks, and store them for later uint256 hash = block.GetHash(); - if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) { + if (hash != chainparams.GetConsensus(0).hashGenesisBlock && mapBlockIndex.find(block.hashPrevBlock) == mapBlockIndex.end()) { LogPrint("reindex", "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(), block.hashPrevBlock.ToString()); if (dbp) @@ -3979,12 +3999,12 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB nLoaded++; if (state.IsError()) break; - } else if (hash != chainparams.GetConsensus().hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) { + } else if (hash != chainparams.GetConsensus(0).hashGenesisBlock && mapBlockIndex[hash]->nHeight % 1000 == 0) { LogPrint("reindex", "Block Import: already had block %s at height %d\n", hash.ToString(), mapBlockIndex[hash]->nHeight); } // Activate the genesis block so normal node progress can continue - if (hash == chainparams.GetConsensus().hashGenesisBlock) { + if (hash == chainparams.GetConsensus(0).hashGenesisBlock) { CValidationState state; if (!ActivateBestChain(state, chainparams)) { break; @@ -4003,7 +4023,8 @@ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskB while (range.first != range.second) { std::multimap<uint256, CDiskBlockPos>::iterator it = range.first; std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>(); - if (ReadBlockFromDisk(*pblockrecursive, it->second, chainparams.GetConsensus())) + // TODO: Need a valid consensus height + if (ReadBlockFromDisk(*pblockrecursive, it->second, chainparams.GetConsensus(0))) { LogPrint("reindex", "%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(), head.ToString()); diff --git a/src/validation.h b/src/validation.h index bd7d4b9a4..35eef1582 100644 --- a/src/validation.h +++ b/src/validation.h @@ -477,14 +477,14 @@ bool ReadBlockHeaderFromDisk(CBlockHeader& block, const CBlockIndex* pindex, con /** Functions for validating blocks and updating the block tree */ /** Context-independent validity checks */ -bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true); -bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, bool fCheckPOW = true, bool fCheckMerkleRoot = true); +bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true); +bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true); /** Context-dependent validity checks. * By "context", we mean only the previous block headers, but not the UTXO * set; UTXO-related validity checks are done in ConnectBlock(). */ -bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev, int64_t nAdjustedTime); -bool ContextualCheckBlock(const CBlock& block, CValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev); +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const CBlockIndex* pindexPrev, int64_t nAdjustedTime); +bool ContextualCheckBlock(const CBlock& block, CValidationState& state, const CBlockIndex* pindexPrev); /** Apply the effects of this block (with given index) on the UTXO set represented by coins. * Validity checks that depend on the UTXO set are also done; ConnectBlock() diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 7cc032016..d6b6d0142 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1110,7 +1110,7 @@ UniValue addwitnessaddress(const JSONRPCRequest& request) { LOCK(cs_main); - if (!IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus()) && !GetBoolArg("-walletprematurewitness", false)) { + if (!IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus(chainActive.Height())) && !GetBoolArg("-walletprematurewitness", false)) { throw JSONRPCError(RPC_WALLET_ERROR, "Segregated witness not enabled on network"); } } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 983aff862..3d35bc11e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1576,7 +1576,7 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool f } CBlock block; - if (ReadBlockFromDisk(block, pindex, Params().GetConsensus())) { + if (ReadBlockFromDisk(block, pindex, Params().GetConsensus(pindex->nHeight))) { for (size_t posInBlock = 0; posInBlock < block.vtx.size(); ++posInBlock) { AddToWalletIfInvolvingMe(*block.vtx[posInBlock], pindex, posInBlock, fUpdate); } diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index caca1248a..490e871fd 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -166,7 +166,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { LogPrint("zmq", "zmq: Publish rawblock %s\n", pindex->GetBlockHash().GetHex()); - const Consensus::Params& consensusParams = Params().GetConsensus(); + const Consensus::Params& consensusParams = Params().GetConsensus(pindex->nHeight); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); { LOCK(cs_main); |