Jack Grigg
6 years ago
No known key found for this signature in database
GPG Key ID: 1B8D649257DB0829
3 changed files with
61 additions and
9 deletions
-
src/gtest/test_rpc.cpp
-
src/pow.cpp
-
src/rpc/blockchain.cpp
|
|
@ -9,6 +9,33 @@ |
|
|
|
#include "streams.h" |
|
|
|
#include "utilstrencodings.h" |
|
|
|
|
|
|
|
TEST(rpc, GetDifficultyTestnetRules) { |
|
|
|
SelectParams(CBaseChainParams::TESTNET); |
|
|
|
|
|
|
|
CBlockIndex prev; |
|
|
|
prev.nTime = 1472700000; |
|
|
|
prev.nBits = 0x201fffff; |
|
|
|
|
|
|
|
CBlockIndex curr; |
|
|
|
curr.pprev = &prev; |
|
|
|
curr.nTime = 1472700300; |
|
|
|
curr.nBits = 0x207fffff; |
|
|
|
|
|
|
|
// Time interval is within 5 minutes, so the min-difficulty block should be
|
|
|
|
// interpreted as a valid network difficulty.
|
|
|
|
EXPECT_EQ(1, GetDifficulty(&curr)); |
|
|
|
EXPECT_EQ(1, GetNetworkDifficulty(&curr)); |
|
|
|
|
|
|
|
curr.nTime += 1; |
|
|
|
|
|
|
|
// Time interval is over 5 minutes, so the min-difficulty block should be
|
|
|
|
// ignored for network difficulty determination.
|
|
|
|
EXPECT_EQ(1, GetDifficulty(&curr)); |
|
|
|
// We have to check this directly, because of some combination of rounding
|
|
|
|
// and truncation issues that result in Google Test displaying 4 != 4
|
|
|
|
EXPECT_EQ((double)0x7fffff/(double)0x1fffff, GetNetworkDifficulty(&curr)); |
|
|
|
} |
|
|
|
|
|
|
|
extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); |
|
|
|
|
|
|
|
TEST(rpc, check_blockToJSON_returns_minified_solution) { |
|
|
|
|
|
@ -24,6 +24,23 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead |
|
|
|
if (pindexLast == NULL) |
|
|
|
return nProofOfWorkLimit; |
|
|
|
|
|
|
|
const CBlockIndex* pindexBits = pindexLast; |
|
|
|
{ |
|
|
|
if (params.fPowAllowMinDifficultyBlocks) |
|
|
|
{ |
|
|
|
// Special difficulty rule for testnet:
|
|
|
|
// If the new block's timestamp is more than 2* 2.5 minutes
|
|
|
|
// then allow mining of a min-difficulty block.
|
|
|
|
if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2) |
|
|
|
return nProofOfWorkLimit; |
|
|
|
else { |
|
|
|
// Get the last non-min-difficulty (or at worst the genesis difficulty)
|
|
|
|
while (pindexBits->pprev && pindexBits->nBits == nProofOfWorkLimit) |
|
|
|
pindexBits = pindexBits->pprev; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Find the first block in the averaging interval
|
|
|
|
const CBlockIndex* pindexFirst = pindexLast; |
|
|
|
arith_uint256 bnTot {0}; |
|
|
|
|
|
@ -38,21 +38,29 @@ double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficul |
|
|
|
blockindex = chainActive.Tip(); |
|
|
|
} |
|
|
|
|
|
|
|
uint32_t bits; |
|
|
|
if (networkDifficulty) { |
|
|
|
bits = GetNextWorkRequired(blockindex, nullptr, Params().GetConsensus()); |
|
|
|
} else { |
|
|
|
bits = blockindex->nBits; |
|
|
|
} |
|
|
|
|
|
|
|
uint32_t powLimit = |
|
|
|
UintToArith256(Params().GetConsensus().powLimit).GetCompact(); |
|
|
|
int nShift = (bits >> 24) & 0xff; |
|
|
|
{ |
|
|
|
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 = |
|
|
|
(double)(powLimit & 0x00ffffff) / |
|
|
|
(double)(bits & 0x00ffffff); |
|
|
|
(double)(blockindex->nBits & 0x00ffffff); |
|
|
|
|
|
|
|
while (nShift < nShiftAmount) |
|
|
|
{ |
|
|
|