Post
Topic
Board Development & Technical Discussion
Re: Regtest Consensus Forking Behavior Introduced in Bitcoin Core in May 2014
by
TierNolan
on 20/05/2015, 08:57:37 UTC
Thanks for answering.  Unfortunately, the regtest network is currently essentially unusable in the intended way once you've generated enough blocks to reach the first retarget interval.

Is the problem that "nActualTimespan" is to large, right?

The statement:

Code:
bnNew *= nActualTimespan;

means multiply the old target by nActualTimespan and it overflows.

The powLimit is 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, which means 2 hashes per block.

The safe condition is that nActualTimespan * powLimit < (2^256) -1.  

If you can control the timestamps on the blocks, then you can for nActualTimestamp to anything.

A compromise solution would be to allow nPowTargetTimespan and powLimit to be modified for testing.  This keeps the code the same for both, while not increasing the block difficulty for all the other tests.

The timestamp must increase every 5 blocks due to the median rule.  This means that 2016 blocks must take at least 2016 / 5 = 404 seconds.

There could be a RetargetRegtest chain with a powLimit to 0x003fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff (so 4096 hashes per block) and nPowTargetTimespan to 1024, then you would get one block every 1024 seconds.  

This would be slower to build the chain, but at least it would work, assuming < 4096 seconds between re-targetting.

This could enabled with a "-regtest2" flag or maybe the 2 parameters could be independently set.  "-regtest -powlimit=4096 -targettimespan=1024".

It also means that for the main chain, when the timestamp wraps, the code will have to have a rule of a max 2^32 seconds per block.

[Edit]
Quote
I think today a somewhat different approach would make more sense for the regtest shortcutting and would result in a smaller divergence from the normal network behavior.  (e.g. when in testing mode, mask out the highest bits of the block hashes before the target check).

That's a better idea.  It emulates running lots of hashes by only running one.

[Edit 2]

It could even be a permanent thing, just change the CheckProofOfWork() method and use a default mask of all ones.