Skip to content

Dynamic EMA difficulty algorithm #5

@zawy12

Description

@zawy12

This keeps a really smooth difficulty by defaulting to a large N, but switches to a smaller N if there is a sudden >3x increase or <1/3 decrease in hashrate. It may be that the basic EMA with N=70 is generally just as good for all coins. N here is in a e^(-2/N) formula instead of e^(-1/N).

# Dynamic EMA difficulty algo (Jacob Eliosoff's EMA and Zawy's adjustable window). 
# Bitcoin cash dev(?) came up with the median of three to reduce timestamp errors.
# "Dynamic" means it triggers to a faster-responding value for N if a substantial change in hashrate
# is detected. It increases from that event back to Nmax

Nmax=140 # max EMA window
Nmin=50 # min EMA window
A=11, B=2.1, C=0.36  # A,B,C = 11,2.1,0.36 or 20, 1.65 0.45, 

# TS=timestamp, T=target solvetime, i.e. 600 seconds
# Find the most recent unusual event in the past 20 blocks event
for (i=height-Nmax; i < height; i++) {  # height - 1 = most recently solved block
   if ( (median(TS[i],TS[i-1],TS[i-2]) - median(TS[i-A],TS[i-A-1],TS[i-A-2]))/T/A  > B 
          or  
        (median(TS[i],TS[i-1],TS[i-2]) - median(TS[i-A],TS[i-A-1],TS[i-A-2]))/T/A  < C  ) 
     {   unusual_event= i-height+1+Nmin   } 
}
N = min(Nmax, unusual_event))

# now do the EMA-Z with this N. See link below:

See EMA-Z algorithm for the rest of the algorithm.

Another dynamic window idea I want to test and specify here triggers on a more advanced and more responsive rule. The above has a problem: it needs 20 blocks out of fear of timestamp manipulation. The statistical check could be more precise and flexible. I'm thinking along the lines of:
For past i= 3 to N/2 blocks, check if the sumST of each "i" is above or below the (say) 1% level of expectation. It has to be done carefully. For example, getting only 3 when we expect 10 occurs 1% of time. "Out of the time" means per group of 10 blocks. How does a rolling check on this figure into it if the 10 should be a random selection? But it appears it would be triggered 1 per 1000 blocks. Let's jump ahead to i=7 and I see this few may occur in 16xT at the 1% level...but it's in 16xT blocks, so it occurs 1 per 1600. To get 1 in 1000 again, I need i=7 or less in time 15.3xT. It looks like a lot of work and trial and error to get the constants for each "i", but it might work a lot better than the above.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions