# [Bitcoin-ml] Difficulty algorithm (The BEST!)

Scott Roberts wordsgalore at gmail.com
Sun Oct 29 23:54:30 UTC 2017

```I was asked to provide feedback on the difficulty algorithms being
considered for Bitcoin Cash and other coins.

I was going to tell you about the best difficulty algorithm in the world:

next_D= sum( past N D's) / sum(past N ST's)  * T

where ST=solve time and T= target time, 600 for bitcoin.

This is the un-mangled version of atrocities like Digishield v3. It's
bitcoin's algo converted to a rolling avg with a much smaller N.

But Degnr8 asked me to evaluate his TW algo and to my surprise he has
something better.  It is

# Degnr8 TW
for  i = 1 to N   (oldest to newest block)
tw += i * ST[i] / D[i]
i++
next_D = T * i / tw

It linearly gives more weight to the more recent blocks. I tried the
same kind of weighting on three different methods, but it didn't help.
I mention that I also tried the weighting to show it is not something
strange out of left field. More briefly, it is:

next_D = T / avg(weighted ST[i]/D[i])

Notice there are no added constants except N. Constants thrown in are
the mark of a difficulty algo that developers have ruined. Degnr8 has
struck gold.

I hope all the devs will agree "this is it".

It only needs N to be chosen and it might need a limit on bad
timestamps.  Choosing N is a balance between fast response to attacks
and not changing too much. You can't have both. Any fix will make it
worse. I think N=50 is good. N=144 is not safe. Alts have to hard fork
if they use Cryptonote's N=300.  N=30 to 100 might be a reasonable
range.  N=12 would work. Karbowanek is using mine at N=17.

I know people want to remove negative timestamps, but I'm sure it's
not good based on math and examples. I'm not sure what people are
doing in their testing that makes it look beneficial.  Preventing the
negatives is throwing in an asymmetry. It throws off the mathematical
definition of average. Bitcoin's MTP and 2 hour limits might be good
by themselves, although they're not symmetrical.

There are two different ways to symmetrically limit timestamps. The
one I prefer allows the algorithm to change as fast as it is expected
to ever need to, but not more, which is a way of limiting the
timestamp:

X=10; # max hash attack size expected
limit = X^(2/N); #  +/- 10% with N=50
next_D = T*limit if next_D > T*limit;
next_D = T/limit if next_D < T/limit;

The other method simply limits timestamps based on previous timestamp.

# TS=timestamp
R=8;
TS = TS_prev_blk + T + R*T if TS > TS_prev_blk + T + R*T;
TS = TS_prev_blk + T - R*T if TS < TS_prev_blk + T - R*T;

All timestamp limits need nodes to place a real-clock limit on the
forward stamp, otherwise a 51% hashrate can send the difficulty down
to 1, no matter what other limits are, even if you use MTP. If you
also prevent negative timestamps, then you only need about 20% hash
power to drive difficulty to 1.

I read the k-1 specification. Good gravy. Hashrate can go down 9% per
block for 2016 blocks before you do anything?  TW
```