Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP-37: Tweaking Difficulty Adjustment Algorithm #79

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions eip-0037.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
Tweaking Difficulty Adjustment Algorithm
==========================================

* Author: kushti
* Status: Implmented
* Created: 23-Sep-2022
* Last edited: 02-Oct-2022
* License: CC0
* Forking: hard-fork needed

Motivation
----------

Difficulty adjustment (also, readjustment) algorithm tries to stabilize averate time to generate a block by changing difficulty of solving a Proof-of-Work puzzle by observing difficulties and timestamps of historical blocks. First Proof-of-Work cryptocurrency, Bitcoin, used simplest lienar difficulty recalculation[1], with some limits for it, such as a difficulty never be changed by more than a factor of 4 either way to prevent large changes.

Bitcoin's difficulty readjustment works more or less well since only dedicated and so loyal mining hardware working on PoW puzzlez. However, in other environments different issues were observed with it, including coin hopping. Thus different solutions to coin hopping appeared, inluding using a least squares method based predictive algorithm [3] as done in Ergo currently.

The Ergo's algorithm works well in most cases, inluding huge price drops, 100x initial difficulty misestimation during mainnet launch, and so on. However, current simplified and limitless version of algorithm is bumpy. Big influx of mining hashrate over multiple epochs, especially with super-linear hashrate growth over time may result in huge spike of difficulty. Similarly, few slow epochs may cause huge drop. Also, for dapps and other applications it would be desirable to make difficulty readjustment more reactive (currently, readjustment takes place every 1024 blocks, and 8 epochs, so about two weeks normally, are considered).

Related Work
------------

To prevent disastrous effects of hopping, widespread approach (see e.g. https://read.cash/@jtoomim/bch-upgrade-proposal-use-asert-as-the-new-daa-1d875696 ) is to use weighted averaging functions over past epochs which do prefer last epochs.
Hovewer, in case of natural hashrate migration such functions will likely be lagging (in opposite to proactive nature of predictive least square method).

Proposed Changes
----------------

We propose to make current difficulty readjustment more reactive and smoother by shortening epoch length, amplifying weight of the last epoch and put some limits on difficulty change as follows.

1. Epoch length to be set to 128 blocks.
2. We calculate *predictive* difficulty according to 8 epochs 128 blocks each and *classic* difficulty as done in Bitcoin.
We limit predictive difficulty change so that it never be changed by more than 50% per epoch. Then we took average from classic and predictive difficulties.
3. We limit change so that difficulty never be changed by more than 50% per epoch.


Simulations
-----------

Previous simulations [4,5] are based on observing historical data so ignoring the fact that miners will behave differently in the presence of different difficulty adjustment method.

Thus we made playground simulating random price walking in uptrend or downtrend. In a simulation, a blockchain is being mined by rational hashpower only. Hashrate is looking at current price and diffuculty. We assume that price and difficulty are changed at the same time, and then hashrate is moving in or out, which is affecting average block generation time *t*. We may assume then that *t = d * c / p*, so average block generation time *t* is proportinal to difficulty *d* and inversely proportional to price *p*. Fixing *t* (which is set to target block generation time, so 2 minutes), *d* and *p* at the beginning of the experiment, we can evaluate *c*. Then on each step we are randomly changing *p* and, according to difficulty from the previous epoch, we can get average block generation time for the new epoch. To have a trend in price, we are changing *p* by adding (or subtracting) a random value with fixed average, and also adding a random fluctuation.

Test results:

* if price growth is up to 5% per epoch, and possible fluctuation (up or down) is up to 10%:

*Bitcoin DAA*: total error: 158841, max delay: 133
*Current DAA*: total error: 189403, max delay: 151
*Proposed DAA: total error: 163893, max delay: 141


* if no price growth, and possible fluctuation (up or down) is up to 25% (so price is jumping up and down like crazy):

*Bitcoin DAA*: total error: 393770, max delay: 161
*Current DAA*: total error: 528003, max delay: 224
*Proposed DAA: total error: 429667, max delay: 193

* if average price growth is up 2% per epoch (max delay missed as it is 120s max for all the options):

*Bitcoin DAA*: total error: 30409
*Current DAA*: total error: 19111
*Proposed DAA: total error: 20691

* if average price growth is up 10% per epoch (max delay missed as it is 120s max for all the options):

*Bitcoin DAA*: total error: 143161
*Current DAA*: total error: 92861
*Proposed DAA: total error: 105741

* 3 epochs price going up, 3 epochs down , 25% max change
*Bitcoin DAA*: total error: 380139, max delay: 160
*Current DAA*: total error: 464081, max delay: 221
*Proposed DAA*: total error: 387880, max delay: 185

* Coin hopping - first epoch up to 50% of total hashrate jumping on, next epoch jumping off
*Bitcoin DAA*: total error: 770422, max delay: 192
*Current DAA*: total error: 586972, max delay: 210
*Proposed DAA*: total error: 670691, max delay: 182

Total error here is sum of differences between observed block generation time and target (120 s). The less total error, the better.

As we can see, proposed DAA as well as current one is working better during trends, and also in case of 1-epoch coin hopping, and proposed DAA softens swings better than current one.

Activation
----------

It is possible to activate EIP-37 after block #843,776 and before block #851,969 . For activation, 232 or more votes for activation required in the last 256 blocks, with voting checked every 128 blocks (for blocks which height % 128 == 1), and immediate activation once threshold is met.

Implementation
--------------

Proposed difficulty adjustment algorithm and its activation procedure are implemented in the reference protocol client 4.0.100, all the newer versions support them as well [6].


References
----------

1. BitcoinWiki. Difficulty in Mining https://en.bitcoinwiki.org/wiki/Difficulty_in_Mining
2. Bitcoin Wiki. Target https://en.bitcoin.it/wiki/Target#When_does_the_target_change_next.3F
3. Meshkov D., Chepurnoy A., Jansen M. Short paper: Revisiting difficulty control for blockchain systems
4. jtoomim BCH upgrade proposal: Use ASERT as the new DAA https://read.cash/@jtoomim/bch-upgrade-proposal-use-asert-as-the-new-daa-1d875696
5. Ergo Developers. DifficultyControlSimulator.scala https://github.com/ergoplatform/ergo/blob/0af9dd9d8846d672c1e2a77f8ab29963fa5acd1e/src/test/scala/org/ergoplatform/tools/DifficultyControlSimulator.scala
6. Ergo reference protocol client releases https://github.com/ergoplatform/ergo/releases