2828// Fancy popcount implementation
2929#include < libpopcnt.h>
3030
31+ // DeploymentActiveAfter
32+ #include < deploymentstatus.h>
33+
3134uint16_t GetNextWorkRequired (const CBlockIndex* pindexLast, const CBlockHeader* pblock, const Consensus::Params& params)
3235{
3336 assert (pindexLast != nullptr );
@@ -62,6 +65,73 @@ uint16_t GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader*
6265 return CalculateNextWorkRequired (pindexLast, pindexFirst->GetBlockTime (), params);
6366}
6467
68+ int32_t CalculateDifficultyDelta (const int32_t nBits, const double nPeriodTimeProportionConsumed, const bool isHardDiffRemoved) {
69+ if (!isHardDiffRemoved) {
70+ // Original difficulty adjustment algorithm
71+
72+ // Note for mainnet:
73+ // If it takes more than 1 minute over the target blocktime, reduce difficulty.
74+ if (nPeriodTimeProportionConsumed > 1 .0333f )
75+ return -1 ;
76+
77+ // Note for mainnet:
78+ // To increase difficulty the network must be able to move the blocktime
79+ // 3 minutes under target blocktime. This is to avoid the difficulty becoming
80+ // too much work for the network to handle. Based on heuristics.
81+ if (nPeriodTimeProportionConsumed < 0 .90f )
82+ return 1 ;
83+ } else {
84+ // Difficulty adjustment algorithm that skips over odd aka. hard diffs (2025)
85+
86+ // If block time is too long, decrease to the previous even diff
87+ if (nPeriodTimeProportionConsumed > 1 .0333f ) {
88+ int32_t nRetarget = 0 ;
89+ if (nBits % 2 == 0 ) {
90+ // Even diff to even diff
91+ nRetarget = -2 ;
92+ } else {
93+ // Odd diff to even diff
94+ nRetarget = -1 ;
95+ }
96+
97+ // If block time is way too long (>60 min on mainnet), decrease by 4 or 3 instead of by 2 or 1
98+ if (nPeriodTimeProportionConsumed > 2 .0f ) {
99+ nRetarget -= 2 ;
100+ }
101+
102+ return nRetarget;
103+ }
104+
105+ // If block time is too short, increase to the next even diff
106+ if (nPeriodTimeProportionConsumed < 0 .90f ) {
107+ int32_t nRetarget = 0 ;
108+ if (nBits % 2 == 0 ) {
109+ // Even diff to even diff
110+ nRetarget = 2 ;
111+ } else {
112+ // Odd diff to even diff
113+ nRetarget = 1 ;
114+ }
115+
116+ // If block time is way too short (<15 min on mainnet), increase by 4 or 3 instead of by 2 or 1
117+ if (nPeriodTimeProportionConsumed < 0 .5f ) {
118+ nRetarget += 2 ;
119+ }
120+
121+ return nRetarget;
122+ }
123+
124+ // The block time is just right. See if we should move away from an odd diff
125+ if (nBits % 2 == 0 ) {
126+ // Already even diff. Don't change difficulty
127+ return 0 ;
128+ } else {
129+ // Currently odd diff. Decrease diff by 1 to reach an even difficulty
130+ return -1 ;
131+ }
132+ }
133+ }
134+
65135uint16_t CalculateNextWorkRequired (const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
66136{
67137 if (params.fPowNoRetargeting )
@@ -70,22 +140,10 @@ uint16_t CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirst
70140 // Compute constants
71141 const int64_t nActualTimespan = pindexLast->GetBlockTime () - nFirstBlockTime;
72142 const double nPeriodTimeProportionConsumed = (double )nActualTimespan / (double )params.nPowTargetTimespan ;
143+ const bool isHardDiffRemoved = DeploymentActiveAfter (pindexLast, params, Consensus::DEPLOYMENT_HARD_DIFF_REMOVAL);
73144
74145 // Variable to set difficulty delta
75- int32_t nRetarget = 0 ;
76-
77- // Note for mainnet:
78- // If it takes more than 1 minute over the target blocktime, reduce difficulty.
79- if (nPeriodTimeProportionConsumed > 1 .0333f )
80- nRetarget = -1 ;
81-
82- // Note for mainnet:
83- // To increase difficulty the network must be able to move the blocktime
84- // 3 minutes under target blocktime. This is to avoid the difficulty becoming
85- // too much work for the network to handle. Based on heuristics.
86- if (nPeriodTimeProportionConsumed < 0 .90f )
87- nRetarget = 1 ;
88-
146+ int32_t nRetarget = CalculateDifficultyDelta (pindexLast->nBits , nPeriodTimeProportionConsumed, isHardDiffRemoved);
89147
90148 return (int32_t )pindexLast->nBits + nRetarget;
91149}
0 commit comments