Merge pull request #96 from jc23424/pow-adjust
Smooth out difficulty adjustment during fork
This commit is contained in:
commit
e96711d3ae
|
@ -27,7 +27,7 @@ TEST(PoW, DifficultyAveraging) {
|
|||
EXPECT_EQ(CalculateNextWorkRequired(bnAvg,
|
||||
blocks[lastBlk].GetMedianTimePast(),
|
||||
blocks[firstBlk].GetMedianTimePast(),
|
||||
params),
|
||||
params, UintToArith256(params.powLimit)),
|
||||
GetNextWorkRequired(&blocks[lastBlk], nullptr, params));
|
||||
// Result should be unchanged, modulo integer division precision loss
|
||||
arith_uint256 bnRes;
|
||||
|
@ -44,7 +44,7 @@ TEST(PoW, DifficultyAveraging) {
|
|||
EXPECT_EQ(CalculateNextWorkRequired(bnAvg,
|
||||
blocks[lastBlk].GetMedianTimePast(),
|
||||
blocks[firstBlk].GetMedianTimePast(),
|
||||
params),
|
||||
params, UintToArith256(params.powLimit)),
|
||||
GetNextWorkRequired(&blocks[lastBlk], nullptr, params));
|
||||
// Result should not be unchanged
|
||||
EXPECT_NE(0x1e7fffff, GetNextWorkRequired(&blocks[lastBlk], nullptr, params));
|
||||
|
@ -57,7 +57,7 @@ TEST(PoW, DifficultyAveraging) {
|
|||
EXPECT_NE(CalculateNextWorkRequired(bnAvg,
|
||||
blocks[lastBlk].GetMedianTimePast(),
|
||||
blocks[firstBlk].GetMedianTimePast(),
|
||||
params),
|
||||
params, UintToArith256(params.powLimit)),
|
||||
GetNextWorkRequired(&blocks[lastBlk], nullptr, params));
|
||||
|
||||
// Result should be the same as if the average difficulty was used
|
||||
|
@ -65,6 +65,6 @@ TEST(PoW, DifficultyAveraging) {
|
|||
EXPECT_EQ(CalculateNextWorkRequired(average,
|
||||
blocks[lastBlk].GetMedianTimePast(),
|
||||
blocks[firstBlk].GetMedianTimePast(),
|
||||
params),
|
||||
params, UintToArith256(params.powLimit)),
|
||||
GetNextWorkRequired(&blocks[lastBlk], nullptr, params));
|
||||
}
|
||||
|
|
11
src/main.cpp
11
src/main.cpp
|
@ -1457,7 +1457,16 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
|
|||
}
|
||||
|
||||
assert(nHeight > consensusParams.SubsidySlowStartShift());
|
||||
int halvings = (nHeight - consensusParams.SubsidySlowStartShift()) / consensusParams.nSubsidyHalvingInterval;
|
||||
|
||||
int halvingInterval = consensusParams.nSubsidyHalvingInterval;
|
||||
if(isForkEnabled(nHeight)) {
|
||||
halvingInterval >>= 2;
|
||||
}
|
||||
|
||||
int halvings = (nHeight - consensusParams.SubsidySlowStartShift()) / halvingInterval;
|
||||
if(isForkEnabled(nHeight))
|
||||
halvings += 2;
|
||||
|
||||
// Force block reward to zero when right shift is undefined.
|
||||
if (halvings >= 64)
|
||||
return 0;
|
||||
|
|
25
src/pow.cpp
25
src/pow.cpp
|
@ -23,17 +23,29 @@
|
|||
|
||||
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
|
||||
{
|
||||
unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
|
||||
int nHeight = pindexLast->nHeight + 1;
|
||||
|
||||
arith_uint256 proofOfWorkLimit;
|
||||
if(isForkBlock(nHeight) || isForkBlock(nHeight - params.nPowAveragingWindow))
|
||||
proofOfWorkLimit = UintToArith256(uint256S("07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
|
||||
else
|
||||
proofOfWorkLimit = UintToArith256(params.powLimit);
|
||||
|
||||
unsigned int nProofOfWorkLimit = proofOfWorkLimit.GetCompact();
|
||||
unsigned int nProofOfWorkBomb = UintToArith256(uint256S("000000000000000000000000000000000000000000000000000000000000ffff")).GetCompact();
|
||||
|
||||
// Genesis block
|
||||
if (pindexLast == NULL)
|
||||
return nProofOfWorkLimit;
|
||||
|
||||
// right post fork
|
||||
else if(!isForkBlock(pindexLast->nHeight + 1) && isForkBlock(pindexLast->nHeight + 1 - params.nPowAveragingWindow))
|
||||
// right at fork
|
||||
else if(isForkBlock(nHeight) && !isForkBlock(nHeight - params.nPowAveragingWindow))
|
||||
return nProofOfWorkLimit;
|
||||
|
||||
|
||||
// right post fork
|
||||
else if(!isForkBlock(nHeight) && isForkBlock(nHeight - params.nPowAveragingWindow))
|
||||
return nProofOfWorkLimit;
|
||||
|
||||
// difficulty bomb
|
||||
else if(pindexLast->nHeight > params.nPowDifficultyBombHeight)
|
||||
return nProofOfWorkBomb;
|
||||
|
@ -55,12 +67,12 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
|
|||
arith_uint256 bnAvg {bnTot / params.nPowAveragingWindow};
|
||||
|
||||
bool isFork = isForkBlock(pindexLast->nHeight + 1);
|
||||
return CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params, isFork);
|
||||
return CalculateNextWorkRequired(bnAvg, pindexLast->GetMedianTimePast(), pindexFirst->GetMedianTimePast(), params, proofOfWorkLimit, isFork);
|
||||
}
|
||||
|
||||
unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,
|
||||
int64_t nLastBlockTime, int64_t nFirstBlockTime,
|
||||
const Consensus::Params& params, bool isFork)
|
||||
const Consensus::Params& params, const arith_uint256 bnPowLimit, bool isFork)
|
||||
{
|
||||
// Limit adjustment step
|
||||
// Use medians to prevent time-warp attacks
|
||||
|
@ -75,7 +87,6 @@ unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,
|
|||
nActualTimespan = params.MaxActualTimespan(isFork);
|
||||
|
||||
// Retarget
|
||||
const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
|
||||
arith_uint256 bnNew {bnAvg};
|
||||
bnNew /= params.AveragingWindowTimespan(isFork);
|
||||
bnNew *= nActualTimespan;
|
||||
|
|
|
@ -19,7 +19,7 @@ class arith_uint256;
|
|||
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&);
|
||||
unsigned int CalculateNextWorkRequired(arith_uint256 bnAvg,
|
||||
int64_t nLastBlockTime, int64_t nFirstBlockTime,
|
||||
const Consensus::Params&, bool isFork = false);
|
||||
const Consensus::Params&, const arith_uint256, bool isFork = false);
|
||||
|
||||
/** Check whether the Equihash solution in a block header is valid */
|
||||
bool CheckEquihashSolution(const CBlockHeader *pblock, const CChainParams&);
|
||||
|
|
|
@ -24,7 +24,7 @@ BOOST_AUTO_TEST_CASE(get_next_work)
|
|||
arith_uint256 bnAvg;
|
||||
bnAvg.SetCompact(0x1d00ffff);
|
||||
BOOST_CHECK_EQUAL(0x1d011998,
|
||||
CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params));
|
||||
CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params, UintToArith256(params.powLimit)));
|
||||
}
|
||||
|
||||
/* Test the constraint on the upper bound for next work */
|
||||
|
@ -38,7 +38,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_pow_limit)
|
|||
arith_uint256 bnAvg;
|
||||
bnAvg.SetCompact(0x1f07ffff);
|
||||
BOOST_CHECK_EQUAL(0x1f07ffff,
|
||||
CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params));
|
||||
CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params, UintToArith256(params.powLimit)));
|
||||
}
|
||||
|
||||
/* Test the constraint on the lower bound for actual time taken */
|
||||
|
@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual)
|
|||
arith_uint256 bnAvg;
|
||||
bnAvg.SetCompact(0x1c05a3f4);
|
||||
BOOST_CHECK_EQUAL(0x1c04bceb,
|
||||
CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params));
|
||||
CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params, UintToArith256(params.powLimit)));
|
||||
}
|
||||
|
||||
/* Test the constraint on the upper bound for actual time taken */
|
||||
|
@ -66,7 +66,7 @@ BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual)
|
|||
arith_uint256 bnAvg;
|
||||
bnAvg.SetCompact(0x1c387f6f);
|
||||
BOOST_CHECK_EQUAL(0x1c4a93bb,
|
||||
CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params));
|
||||
CalculateNextWorkRequired(bnAvg, nThisTime, nLastRetargetTime, params, UintToArith256(params.powLimit)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test)
|
||||
|
|
Loading…
Reference in New Issue