## Generalities

The Riecoin protocol must ensure that the rate of found blocks remain constant (in average, the time between blocks should be 150 s). If more miners join, the blocks must be made harder in order to compensate the increased mining power, otherwise blocks would be found faster. Conversely, if some leave the network, the difficulty must be lowered. This is the role of the difficulty adjustment algorithm.

In Riecoin Core, the DAA is defined in the pow.cpp source file.

It is important to note that the Riecoin difficulty is not linear, in the sense that if it doubles, it does not take two times more mining power to find blocks at the same time, but rather about ${\displaystyle 2^{k+2.3}}$ times (the constellation power), ${\displaystyle k}$ being the constellation length.

## Before the second hard fork

The original Riecoin DAA is the same as Bitcoin's, but with a faster adjustment every 288 blocks (about 12 h in Riecoin) instead of 2016 (14 days in Bitcoin). The mining power is estimated to be proportional to the difficulty to the power ${\displaystyle k+3}$.

Every 288 blocks,
${\displaystyle D=\lfloor {\lfloor {\frac {T{D_{0}}^{k+3}}{T^{*}}}\rfloor }^{\frac {1}{k+3}}\rfloor }$
${\displaystyle D_{0}}$ is the old difficulty, ${\displaystyle D}$ is the new difficulty, ${\displaystyle T^{*}=43200}$ is the target duration for 288 blocks, and ${\displaystyle T}$ is the actual elapsed time between the first and the last block of the latest 288 blocks period (computed using the difference of their timestamps).
If ${\displaystyle T}$ is over or below ${\displaystyle T^{*}}$ by a factor 4, it is clipped to ${\displaystyle 4T^{*}}$ or ${\displaystyle {\frac {1}{4}}T^{*}}$, except for the first 576 blocks. The minimum difficulty is 304 (600 in Testnet).
In Testnet, if no block were found since 10 minutes, the difficulty is lowered to the minimum for the next block.

At the first hard fork, superblocks were introduced and added some modifications to the DAA. They are removed in the second hard fork.

## Starting from the second hard fork

The DAA is based on ASERT and the mining power is now estimated to be proportional to the difficulty to the power ${\displaystyle k+2.3}$. This DAA updates every block, with the next difficulty only basing on the time taken to find the previous one. One way to implement ASERT is to apply the formula

${\displaystyle {D_{n+1}}'={D_{n}}'\exp({\frac {1-{\frac {T_{n}}{T^{*}}}}{N}})}$
${\displaystyle {D_{n+1}}'={D_{n+1}}^{k+2.3}}$ and ${\displaystyle {D_{n}}'={D_{n}}^{k+2.3}}$ are the linearized difficulties (required mining power is proportional to them); ${\displaystyle D_{n+1}}$ and ${\displaystyle D_{n}}$ are simply the new difficulty and the difficulty of the previous block. ${\displaystyle T_{n}}$ is the time taken to find the previous block and ${\displaystyle T^{*}=150{\text{ s}}}$ is the target average time between blocks. ${\displaystyle N}$ is an arbitrary smoothing value, the higher it is, the smoother the adjustment will be, but the slower the DAA will react to mining power changes. In Riecoin, ${\displaystyle N=64}$.

This can be rewritten as

${\displaystyle D_{n+1}=({D_{n}}^{k+2.3}\exp({\frac {1-{\frac {T_{n}}{T^{*}}}}{N}}))^{\frac {1}{k+2.3}}=D_{n}\exp({\frac {1-{\frac {T_{n}}{T^{*}}}}{N(k+2.3)}})}$

As it takes small values, the exponential can be well approximated with

${\displaystyle \exp(x)\approx 1+x}$ (for x small)

Giving

${\displaystyle D_{n+1}=D_{n}(1+{\frac {1-{\frac {T_{n}}{T^{*}}}}{N(k+2.3)}})}$
Sometimes, the approximated ASERT is called EMA.

To reduce rounding errors, a factor ${\displaystyle f=65536}$ is introduced to some places of the formula to amplify intermediate values. Also, the 2.3 value is handled as a fraction. Below is how the DAA is implemented in Riecoin, without using any floating point arithmetic that may cause consistency issues across various systems.

difficulty = (previousDifficulty*(65536LL + 10LL*(65536LL - 65536LL*previousSolveTime/params.nPowTargetSpacing)/(N*cp)))/65536LL

The DAA change came with much stricter block timestamp limits. A block timestamp must be at most 15 s earlier than the previous one, and 15 s after the current time. In addition to this, nodes do not connect to peers with a time offset of more than 5 s. If it took more than 30 minutes to find the previous block, the solve time is clipped to 30 minutes.