@@ -84,7 +84,7 @@ BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test) {
8484 blocks[i].nTime = 1269211443 + i * params.nPowTargetSpacing ;
8585 blocks[i].nBits = 0x207fffff ; /* target 0x7fffff000... */
8686 blocks[i].nChainWork =
87- i ? blocks[i - 1 ].nChainWork + GetBlockProof (blocks[i - 1 ])
87+ i ? blocks[i - 1 ].nChainWork + GetBlockProof (blocks[i])
8888 : arith_uint256 (0 );
8989 }
9090
@@ -106,6 +106,7 @@ static CBlockIndex GetBlockIndex(CBlockIndex *pindexPrev, int64_t nTimeInterval,
106106 block.nTime = pindexPrev->nTime + nTimeInterval;
107107 block.nBits = nBits;
108108
109+ block.nChainWork = pindexPrev->nChainWork + GetBlockProof (block);
109110 return block;
110111}
111112
@@ -119,12 +120,14 @@ BOOST_AUTO_TEST_CASE(retargeting_test) {
119120 arith_uint256 currentPow = powLimit >> 1 ;
120121 uint32_t initialBits = currentPow.GetCompact ();
121122
122- // Genesis block?
123+ // Genesis block.
123124 blocks[0 ] = CBlockIndex ();
124125 blocks[0 ].nHeight = 0 ;
125126 blocks[0 ].nTime = 1269211443 ;
126127 blocks[0 ].nBits = initialBits;
127128
129+ blocks[0 ].nChainWork = GetBlockProof (blocks[0 ]);
130+
128131 // Pile up some blocks.
129132 for (size_t i = 1 ; i < 100 ; i++) {
130133 blocks[i] = GetBlockIndex (&blocks[i - 1 ], params.nPowTargetSpacing ,
@@ -187,4 +190,181 @@ BOOST_AUTO_TEST_CASE(retargeting_test) {
187190 powLimit.GetCompact ());
188191}
189192
193+ BOOST_AUTO_TEST_CASE (cash_difficulty_test) {
194+ SelectParams (CBaseChainParams::MAIN );
195+ const Consensus::Params ¶ms = Params ().GetConsensus ();
196+
197+ std::vector<CBlockIndex> blocks (3000 );
198+
199+ const arith_uint256 powLimit = UintToArith256 (params.powLimit );
200+ uint32_t powLimitBits = powLimit.GetCompact ();
201+ arith_uint256 currentPow = powLimit >> 4 ;
202+ uint32_t initialBits = currentPow.GetCompact ();
203+
204+ // Genesis block.
205+ blocks[0 ] = CBlockIndex ();
206+ blocks[0 ].nHeight = 0 ;
207+ blocks[0 ].nTime = 1269211443 ;
208+ blocks[0 ].nBits = initialBits;
209+
210+ blocks[0 ].nChainWork = GetBlockProof (blocks[0 ]);
211+
212+ // Block counter.
213+ size_t i;
214+
215+ // Pile up some blocks every 10 mins to establish some history.
216+ for (i = 1 ; i < 2050 ; i++) {
217+ blocks[i] = GetBlockIndex (&blocks[i - 1 ], 600 , initialBits);
218+ }
219+
220+ CBlockHeader blkHeaderDummy;
221+ uint32_t nBits =
222+ GetNextCashWorkRequired (&blocks[2049 ], &blkHeaderDummy, params);
223+
224+ // Difficulty stays the same as long as we produce a block every 10 mins.
225+ for (size_t j = 0 ; j < 10 ; i++, j++) {
226+ blocks[i] = GetBlockIndex (&blocks[i - 1 ], 600 , nBits);
227+ BOOST_CHECK_EQUAL (
228+ GetNextCashWorkRequired (&blocks[i], &blkHeaderDummy, params),
229+ nBits);
230+ }
231+
232+ // Make sure we skip over blocks that are out of wack. To do so, we produce
233+ // a block that is far in the future, and then produce a block with the
234+ // expected timestamp.
235+ blocks[i] = GetBlockIndex (&blocks[i - 1 ], 6000 , nBits);
236+ BOOST_CHECK_EQUAL (
237+ GetNextCashWorkRequired (&blocks[i++], &blkHeaderDummy, params), nBits);
238+ blocks[i] = GetBlockIndex (&blocks[i - 1 ], 2 * 600 - 6000 , nBits);
239+ BOOST_CHECK_EQUAL (
240+ GetNextCashWorkRequired (&blocks[i++], &blkHeaderDummy, params), nBits);
241+
242+ // The system should continue unaffected by the block with a bogous
243+ // timestamps.
244+ for (size_t j = 0 ; j < 20 ; i++, j++) {
245+ blocks[i] = GetBlockIndex (&blocks[i - 1 ], 600 , nBits);
246+ BOOST_CHECK_EQUAL (
247+ GetNextCashWorkRequired (&blocks[i], &blkHeaderDummy, params),
248+ nBits);
249+ }
250+
251+ // We start emitting blocks slightly faster. The first block has no impact.
252+ blocks[i] = GetBlockIndex (&blocks[i - 1 ], 550 , nBits);
253+ BOOST_CHECK_EQUAL (
254+ GetNextCashWorkRequired (&blocks[i++], &blkHeaderDummy, params), nBits);
255+
256+ // Now we should see difficulty increase slowly.
257+ for (size_t j = 0 ; j < 10 ; i++, j++) {
258+ blocks[i] = GetBlockIndex (&blocks[i - 1 ], 550 , nBits);
259+ const uint32_t nextBits =
260+ GetNextCashWorkRequired (&blocks[i], &blkHeaderDummy, params);
261+
262+ arith_uint256 currentTarget;
263+ currentTarget.SetCompact (nBits);
264+ arith_uint256 nextTarget;
265+ nextTarget.SetCompact (nextBits);
266+
267+ // Make sure that difficulty increases very slowly.
268+ BOOST_CHECK (nextTarget < currentTarget);
269+ BOOST_CHECK ((currentTarget - nextTarget) < (currentTarget >> 10 ));
270+
271+ nBits = nextBits;
272+ }
273+
274+ // Check the actual value.
275+ BOOST_CHECK_EQUAL (nBits, 0x1c0fe7b1 );
276+
277+ // If we dramatically shorten block production, difficulty increases faster.
278+ for (size_t j = 0 ; j < 20 ; i++, j++) {
279+ blocks[i] = GetBlockIndex (&blocks[i - 1 ], 10 , nBits);
280+ const uint32_t nextBits =
281+ GetNextCashWorkRequired (&blocks[i], &blkHeaderDummy, params);
282+
283+ arith_uint256 currentTarget;
284+ currentTarget.SetCompact (nBits);
285+ arith_uint256 nextTarget;
286+ nextTarget.SetCompact (nextBits);
287+
288+ // Make sure that difficulty increases faster.
289+ BOOST_CHECK (nextTarget < currentTarget);
290+ BOOST_CHECK ((currentTarget - nextTarget) < (currentTarget >> 4 ));
291+
292+ nBits = nextBits;
293+ }
294+
295+ // Check the actual value.
296+ BOOST_CHECK_EQUAL (nBits, 0x1c0db19f );
297+
298+ // We start to emit blocks significantly slower. The first block has no
299+ // impact.
300+ blocks[i] = GetBlockIndex (&blocks[i - 1 ], 6000 , nBits);
301+ nBits = GetNextCashWorkRequired (&blocks[i++], &blkHeaderDummy, params);
302+
303+ // Check the actual value.
304+ BOOST_CHECK_EQUAL (nBits, 0x1c0d9222 );
305+
306+ // If we dramatically slow down block production, difficulty decreases.
307+ for (size_t j = 0 ; j < 93 ; i++, j++) {
308+ blocks[i] = GetBlockIndex (&blocks[i - 1 ], 6000 , nBits);
309+ const uint32_t nextBits =
310+ GetNextCashWorkRequired (&blocks[i], &blkHeaderDummy, params);
311+
312+ arith_uint256 currentTarget;
313+ currentTarget.SetCompact (nBits);
314+ arith_uint256 nextTarget;
315+ nextTarget.SetCompact (nextBits);
316+
317+ // Check the difficulty decreases.
318+ BOOST_CHECK (nextTarget <= powLimit);
319+ BOOST_CHECK (nextTarget > currentTarget);
320+ BOOST_CHECK ((nextTarget - currentTarget) < (currentTarget >> 3 ));
321+
322+ nBits = nextBits;
323+ }
324+
325+ // Check the actual value.
326+ BOOST_CHECK_EQUAL (nBits, 0x1c2f13b9 );
327+
328+ // Due to the window of time being bounded, next block's difficulty actually
329+ // gets harder.
330+ blocks[i] = GetBlockIndex (&blocks[i - 1 ], 6000 , nBits);
331+ nBits = GetNextCashWorkRequired (&blocks[i++], &blkHeaderDummy, params);
332+ BOOST_CHECK_EQUAL (nBits, 0x1c2ee9bf );
333+
334+ // And goes down again. It takes a while due to the window being bounded and
335+ // the skewed block causes 2 blocks to get out of the window.
336+ for (size_t j = 0 ; j < 192 ; i++, j++) {
337+ blocks[i] = GetBlockIndex (&blocks[i - 1 ], 6000 , nBits);
338+ const uint32_t nextBits =
339+ GetNextCashWorkRequired (&blocks[i], &blkHeaderDummy, params);
340+
341+ arith_uint256 currentTarget;
342+ currentTarget.SetCompact (nBits);
343+ arith_uint256 nextTarget;
344+ nextTarget.SetCompact (nextBits);
345+
346+ // Check the difficulty decreases.
347+ BOOST_CHECK (nextTarget <= powLimit);
348+ BOOST_CHECK (nextTarget > currentTarget);
349+ BOOST_CHECK ((nextTarget - currentTarget) < (currentTarget >> 3 ));
350+
351+ nBits = nextBits;
352+ }
353+
354+ // Check the actual value.
355+ BOOST_CHECK_EQUAL (nBits, 0x1d00ffff );
356+
357+ // Once the difficulty reached the minimum allowed level, it doesn't get any
358+ // easier.
359+ for (size_t j = 0 ; j < 5 ; i++, j++) {
360+ blocks[i] = GetBlockIndex (&blocks[i - 1 ], 6000 , nBits);
361+ const uint32_t nextBits =
362+ GetNextCashWorkRequired (&blocks[i], &blkHeaderDummy, params);
363+
364+ // Check the difficulty stays constant.
365+ BOOST_CHECK_EQUAL (nextBits, powLimitBits);
366+ nBits = nextBits;
367+ }
368+ }
369+
190370BOOST_AUTO_TEST_SUITE_END ()
0 commit comments