Drop the chain argument to GetDifficulty

This removes the need to include rpc/blockchain.cpp in order to put
GetDifficulty under test. GetDifficulty was called in two ways:
* with a guaranteed non-null blockindex
* with no argument

Change the latter case to be provided chainActive.Tip() explicitly.
This commit is contained in:
Ben Woosley 2018-05-20 14:04:15 -07:00
parent d792e47421
commit ebec7317ca
No known key found for this signature in database
GPG key ID: 4D8CA4BA18040906
4 changed files with 10 additions and 69 deletions

View file

@ -6,7 +6,6 @@
#include <rpc/blockchain.h> #include <rpc/blockchain.h>
#include <amount.h> #include <amount.h>
#include <chain.h>
#include <chainparams.h> #include <chainparams.h>
#include <checkpoints.h> #include <checkpoints.h>
#include <coins.h> #include <coins.h>
@ -47,17 +46,13 @@ static std::mutex cs_blockchange;
static std::condition_variable cond_blockchange; static std::condition_variable cond_blockchange;
static CUpdatedBlock latestblock; static CUpdatedBlock latestblock;
/* Calculate the difficulty for a given block index, /* Calculate the difficulty for a given block index.
* or the block index of the given chain.
*/ */
double GetDifficulty(const CChain& chain, const CBlockIndex* blockindex) double GetDifficulty(const CBlockIndex* blockindex)
{ {
if (blockindex == nullptr) if (blockindex == nullptr)
{ {
if (chain.Tip() == nullptr) return 1.0;
return 1.0;
else
blockindex = chain.Tip();
} }
int nShift = (blockindex->nBits >> 24) & 0xff; int nShift = (blockindex->nBits >> 24) & 0xff;
@ -78,11 +73,6 @@ double GetDifficulty(const CChain& chain, const CBlockIndex* blockindex)
return dDiff; return dDiff;
} }
double GetDifficulty(const CBlockIndex* blockindex)
{
return GetDifficulty(chainActive, blockindex);
}
UniValue blockheaderToJSON(const CBlockIndex* blockindex) UniValue blockheaderToJSON(const CBlockIndex* blockindex)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
@ -352,7 +342,7 @@ static UniValue getdifficulty(const JSONRPCRequest& request)
); );
LOCK(cs_main); LOCK(cs_main);
return GetDifficulty(); return GetDifficulty(chainActive.Tip());
} }
static std::string EntryDescriptionString() static std::string EntryDescriptionString()
@ -1229,7 +1219,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
obj.pushKV("blocks", (int)chainActive.Height()); obj.pushKV("blocks", (int)chainActive.Height());
obj.pushKV("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1); obj.pushKV("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1);
obj.pushKV("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()); obj.pushKV("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex());
obj.pushKV("difficulty", (double)GetDifficulty()); obj.pushKV("difficulty", (double)GetDifficulty(chainActive.Tip()));
obj.pushKV("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast()); obj.pushKV("mediantime", (int64_t)chainActive.Tip()->GetMedianTimePast());
obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip())); obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), chainActive.Tip()));
obj.pushKV("initialblockdownload", IsInitialBlockDownload()); obj.pushKV("initialblockdownload", IsInitialBlockDownload());

View file

@ -16,7 +16,7 @@ class UniValue;
* @return A floating point number that is a multiple of the main net minimum * @return A floating point number that is a multiple of the main net minimum
* difficulty (4295032833 hashes). * difficulty (4295032833 hashes).
*/ */
double GetDifficulty(const CBlockIndex* blockindex = nullptr); double GetDifficulty(const CBlockIndex* blockindex);
/** Callback for when block tip changed. */ /** Callback for when block tip changed. */
void RPCNotifyBlockChange(bool ibd, const CBlockIndex *); void RPCNotifyBlockChange(bool ibd, const CBlockIndex *);
@ -34,4 +34,3 @@ UniValue mempoolToJSON(bool fVerbose = false);
UniValue blockheaderToJSON(const CBlockIndex* blockindex); UniValue blockheaderToJSON(const CBlockIndex* blockindex);
#endif #endif

View file

@ -214,7 +214,7 @@ static UniValue getmininginfo(const JSONRPCRequest& request)
obj.pushKV("blocks", (int)chainActive.Height()); obj.pushKV("blocks", (int)chainActive.Height());
obj.pushKV("currentblockweight", (uint64_t)nLastBlockWeight); obj.pushKV("currentblockweight", (uint64_t)nLastBlockWeight);
obj.pushKV("currentblocktx", (uint64_t)nLastBlockTx); obj.pushKV("currentblocktx", (uint64_t)nLastBlockTx);
obj.pushKV("difficulty", (double)GetDifficulty()); obj.pushKV("difficulty", (double)GetDifficulty(chainActive.Tip()));
obj.pushKV("networkhashps", getnetworkhashps(request)); obj.pushKV("networkhashps", getnetworkhashps(request));
obj.pushKV("pooledtx", (uint64_t)mempool.size()); obj.pushKV("pooledtx", (uint64_t)mempool.size());
obj.pushKV("chain", Params().NetworkIDString()); obj.pushKV("chain", Params().NetworkIDString());

View file

@ -2,7 +2,7 @@
#include "stdlib.h" #include "stdlib.h"
#include "rpc/blockchain.cpp" #include "rpc/blockchain.h"
#include "test/test_bitcoin.h" #include "test/test_bitcoin.h"
/* Equality between doubles is imprecise. Comparison should be done /* Equality between doubles is imprecise. Comparison should be done
@ -22,14 +22,6 @@ static CBlockIndex* CreateBlockIndexWithNbits(uint32_t nbits)
return block_index; return block_index;
} }
static CChain CreateChainWithNbits(uint32_t nbits)
{
CBlockIndex* block_index = CreateBlockIndexWithNbits(nbits);
CChain chain;
chain.SetTip(block_index);
return chain;
}
static void RejectDifficultyMismatch(double difficulty, double expected_difficulty) { static void RejectDifficultyMismatch(double difficulty, double expected_difficulty) {
BOOST_CHECK_MESSAGE( BOOST_CHECK_MESSAGE(
DoubleEquals(difficulty, expected_difficulty, 0.00001), DoubleEquals(difficulty, expected_difficulty, 0.00001),
@ -43,12 +35,7 @@ static void RejectDifficultyMismatch(double difficulty, double expected_difficul
static void TestDifficulty(uint32_t nbits, double expected_difficulty) static void TestDifficulty(uint32_t nbits, double expected_difficulty)
{ {
CBlockIndex* block_index = CreateBlockIndexWithNbits(nbits); CBlockIndex* block_index = CreateBlockIndexWithNbits(nbits);
/* Since we are passing in block index explicitly, double difficulty = GetDifficulty(block_index);
* there is no need to set up anything within the chain itself.
*/
CChain chain;
double difficulty = GetDifficulty(chain, block_index);
delete block_index; delete block_index;
RejectDifficultyMismatch(difficulty, expected_difficulty); RejectDifficultyMismatch(difficulty, expected_difficulty);
@ -84,43 +71,8 @@ BOOST_AUTO_TEST_CASE(get_difficulty_for_very_high_target)
// Verify that difficulty is 1.0 for an empty chain. // Verify that difficulty is 1.0 for an empty chain.
BOOST_AUTO_TEST_CASE(get_difficulty_for_null_tip) BOOST_AUTO_TEST_CASE(get_difficulty_for_null_tip)
{ {
CChain chain; double difficulty = GetDifficulty(nullptr);
double difficulty = GetDifficulty(chain, nullptr);
RejectDifficultyMismatch(difficulty, 1.0); RejectDifficultyMismatch(difficulty, 1.0);
} }
/* Verify that if difficulty is based upon the block index
* in the chain, if no block index is explicitly specified.
*/
BOOST_AUTO_TEST_CASE(get_difficulty_for_null_block_index)
{
CChain chain = CreateChainWithNbits(0x1df88f6f);
double difficulty = GetDifficulty(chain, nullptr);
delete chain.Tip();
double expected_difficulty = 0.004023;
RejectDifficultyMismatch(difficulty, expected_difficulty);
}
/* Verify that difficulty is based upon the explicitly specified
* block index rather than being taken from the provided chain,
* when both are present.
*/
BOOST_AUTO_TEST_CASE(get_difficulty_for_block_index_overrides_tip)
{
CChain chain = CreateChainWithNbits(0x1df88f6f);
/* This block index's nbits should be used
* instead of the chain's when calculating difficulty.
*/
CBlockIndex* override_block_index = CreateBlockIndexWithNbits(0x12345678);
double difficulty = GetDifficulty(chain, override_block_index);
delete chain.Tip();
delete override_block_index;
RejectDifficultyMismatch(difficulty, 5913134931067755359633408.0);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()