With two different PoWs, and a time varying balance of block rewards between the two, Grin is not your average blockchain. This post will try to relate the network difficulty to the various Graph rates, in units of graphs-per-second. For simplicity, we’ll pretend that the primary PoW is is just Cuckatoo31, i.e. no-one is mining Cuckatoo on graphs with more than 2^31 edges.

In order to solve a block, you pick either PoW, and you pick a nonce, which, together with the rest of the header, determines a graph.

In this graph you then look for a 42-cycle. You need some luck here, since the expected number of L-cycles in a random graph is 1/L. Once you find a 42-cycle, you compute the cyclehash, which is the hash of the (sorted) 42 edge indices.

Now, in the hashcash PoW of most other coins, you would test whether this hash, interpreted as a huge 256-bit number, is below a target, in which case you solved the block. The difficulty is inversely proportional to the target, so higher difficulty corresponds to lower targets (you can see that it’s harder for a random hash to fall below a lower target).

In Grin we use difficulties directly, and skip the notion of a target. We convert the cyclehash into a solution difficulty, and test whether this is at least the network difficulty. The conversion depends on the choice of PoW though.

For the primary Cuckatoo31, the solution difficulty is the weight of 2^31 edges, 7936, divided by the cyclehash interpreted as a fraction in the interval (0,1).

For the secondary Cuckaroo29, the solution difficulty is the secondary scale, divided by the cyclehash interpreted as a fraction in the interval (0,1).

Again we have that the smaller the cyclehash, the higher the solution difficulty, and the more likely we pass the difficulty test.

With Cuckaroo29, the likelihood is also proportional to the secondary scale. This variable acts like a control knob, that is used to either dial up or dial down the rate of blocks solved by the secondary PoW, in order to achieve the desired balance.

And now for some math. Denote

PR31 = Primary Rate = global rate of Cuckatoo31 graphs per second

W31 = weight of a Cuckatoo31 graph = 31 * 2^8 = 7936

SR29 = Secondary Rate = global rate of Cukatoo29 graphs per second

S29 = ar_scale = secondary scale = variable scale of a Cukatoo29 graph

BR31 = rate of primary blocks

BR29 = rate of secondary blocks

ND = Network Difficulty

We have BR31 = (PR31 / 42) * (W31 / ND), BR29 = (SR29 / 42) * (S29 / ND),

for a combined block rate of BR31 + BR29 = (PR31 * W31 + SR29 * S29) / (42 * ND) which should ideally equal 1/60. So assuming the system has achieved equilibrium, we have

ND = (60/42) * (PR31 * W31 + SR29 * S29)

and at launch, when the secondary reward rate should be 90%, we have

(SR29 * S29) / (PR31 * W31) = 90% / 10%

This allows us to compute graph rates from network difficulty, secondary scale, and the current reward balance:

SR29 = ND * (42 / 60) * 90% / S29

PR31 = ND * (42 / 60) * 10% / W31

Also see the related post https://forum.grin.mw/t/what-to-mine-choosing-between-cuckatoo31-and-cuckaroo29