The Difficulty

In Riecoin, the Difficulty represents how many bits the prime numbers must have, so a Difficulty of 900 means that the Miners are looking for Prime Constellations of numbers around 2900. It is not proportional to how hard it is to solve a Block: if it doubles, it is not twice harder to find one for a given duration, but rather about 2k+2.3 times (the constellation power), k being the constellation length. So, a Block at Difficulty 1000 is about 2.66 times harder to solve than one at 900!

To manipulate a linearized metric, a normalized Mining Power metric can be considered and would be closer to "hashrate" metrics found in other PoWs. See the Stella PoW for explanations.

Difficulty Adjustment

Generalities

The Riecoin protocol must ensure that the rate of found blocks remains 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.

Before the second Hard Fork, the DAA was like 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 was estimated to be proportional to the difficulty to the power k+3. At the first hard fork, superblocks were introduced and added some modifications to the DAA. They were then removed in the second hard fork for the reasons explained in the link.

Algorithm

The current DAA is based on ASERT and the mining power is now estimated to be proportional to the difficulty to the power 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

Dn+1=Dnexp(1TnTN)
Dn+1=Dn+1k+2.3 and Dn=Dnk+2.3 are the linearized difficulties (required mining power is proportional to them); Dn+1 and Dn are simply the new difficulty and the difficulty of the previous block. Tn is the time taken to find the previous block and T=150 s is the target average time between blocks. 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, N=64.

This can be rewritten as

D n + 1 = ( D n k + 2.3 exp ( 1 T n T N ) ) 1 k + 2.3 = D n exp ( 1 T n T N ( k + 2.3 ) )

As it takes small values, the exponential can be well approximated with exp(x)1+x (for x small), giving

D n + 1 = D n ( 1 + 1 T n T N ( k + 2.3 ) )
Sometimes, the approximated ASERT is called EMA.

To reduce rounding errors, a factor 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 be implemented differently 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.