Browse Source

Separate concepts of block difficulty and network difficulty in RPC

"Block difficulty" is the difficulty listed in a block's header, which in the
testnet can sometimes be min-difficulty (if time-since-last-block is too large).

"Network difficulty" is the difficulty that the network was trying to satisfy
at a particular block height. In mainnet this is always equal to the difficulty
of the solved block for that height, but in testnet the network difficulty is
derived from the last non-min-difficulty block difficulty.

This commit fixes the RPC APIs that are intended to show network difficulty, so
that on testnet they don't sometimes drop to 1.0, confusing users.

Closes #1181
pull/145/head
Jack Grigg 8 years ago
parent
commit
695a7a8826
  1. 33
      src/rpcblockchain.cpp
  2. 2
      src/rpcmining.cpp
  3. 1
      src/rpcserver.h

33
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));

2
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)));

1
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);

Loading…
Cancel
Save