diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 20c669d5c..44e30c623 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -21,7 +21,7 @@ using namespace std; extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry); void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex); -double GetDifficulty(const CBlockIndex* blockindex) +double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficulty) { // Floating point number that is a multiple of the minimum difficulty, // minimum difficulty = 1.0. @@ -33,9 +33,24 @@ double GetDifficulty(const CBlockIndex* blockindex) blockindex = chainActive.Tip(); } - int nShift = (blockindex->nBits >> 24) & 0xff; uint32_t powLimit = UintToArith256(Params().GetConsensus().powLimit).GetCompact();; + { + if (networkDifficulty && Params().GetConsensus().fPowAllowMinDifficultyBlocks) + { + // Special difficulty rule for testnet: + // If a block's timestamp is more than 2*nPowTargetSpacing minutes after + // the previous block, then it is permitted to be min-difficulty. So + // get the last non-min-difficulty (or at worst the genesis difficulty). + auto window = Params().GetConsensus().nPowTargetSpacing*2; + while (blockindex->pprev && blockindex->nBits == powLimit && + blockindex->GetBlockTime() > blockindex->pprev->GetBlockTime() + window) { + blockindex = blockindex->pprev; + } + } + } + + int nShift = (blockindex->nBits >> 24) & 0xff; int nShiftAmount = (powLimit >> 24) & 0xff; double dDiff = @@ -56,6 +71,16 @@ double GetDifficulty(const CBlockIndex* blockindex) return dDiff; } +double GetDifficulty(const CBlockIndex* blockindex) +{ + return GetDifficultyINTERNAL(blockindex, false); +} + +double GetNetworkDifficulty(const CBlockIndex* blockindex) +{ + return GetDifficultyINTERNAL(blockindex, true); +} + Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { @@ -147,7 +172,7 @@ Value getdifficulty(const Array& params, bool fHelp) ); LOCK(cs_main); - return GetDifficulty(); + return GetNetworkDifficulty(); } @@ -542,7 +567,7 @@ Value getblockchaininfo(const Array& params, bool fHelp) obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1)); obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex())); - obj.push_back(Pair("difficulty", (double)GetDifficulty())); + obj.push_back(Pair("difficulty", (double)GetNetworkDifficulty())); obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(Params().Checkpoints(), chainActive.Tip()))); obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); obj.push_back(Pair("pruned", fPruneMode)); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 6e865cc56..70e3787bd 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -286,7 +286,7 @@ Value getmininginfo(const Array& params, bool fHelp) obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize)); obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); - obj.push_back(Pair("difficulty", (double)GetDifficulty())); + obj.push_back(Pair("difficulty", (double)GetNetworkDifficulty())); obj.push_back(Pair("errors", GetWarnings("statusbar"))); obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1))); obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); diff --git a/src/rpcserver.h b/src/rpcserver.h index 0e8b60b7b..5828dd489 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -140,6 +140,7 @@ extern int64_t nWalletUnlockTime; extern CAmount AmountFromValue(const json_spirit::Value& value); extern json_spirit::Value ValueFromAmount(const CAmount& amount); extern double GetDifficulty(const CBlockIndex* blockindex = NULL); +extern double GetNetworkDifficulty(const CBlockIndex* blockindex = NULL); extern std::string HelpRequiringPassphrase(); extern std::string HelpExampleCli(std::string methodname, std::string args); extern std::string HelpExampleRpc(std::string methodname, std::string args);