|
|
@@ -18,20 +18,20 @@ blockchain achieve consensus.
|
|
|
|
|
|
## Miner main loop
|
|
|
|
|
|
-DarkFi is using Proof of Work RandomX algorithm paired with delayed finality.
|
|
|
+DarkFi uses a Proof of Work RandomX algorithm paired with delayed finality.
|
|
|
Therefore, block production involves the following steps:
|
|
|
|
|
|
-First, a miner grabs its current best ranking fork and extends it with a block
|
|
|
-composed of unproposed transactions from the miner's mempool.
|
|
|
+* First, a miner grabs its current best ranking fork and extends it with a
|
|
|
+ block composed of unproposed transactions from the miner's mempool.
|
|
|
|
|
|
-Then the miner tries to find a nonce such that when the block header is hashed
|
|
|
-its bytes produce a number that is less than the current difficulty target of
|
|
|
-the network, using the [RandomX mining
|
|
|
-algorithm](https://github.com/tevador/RandomX).
|
|
|
+* Then the miner tries to find a nonce such that when the block header is
|
|
|
+ hashed its bytes produce a number that is less than the current difficulty
|
|
|
+ target of the network, using the [RandomX mining
|
|
|
+ algorithm](https://github.com/tevador/RandomX).
|
|
|
|
|
|
-Once the miner finds such a nonce, it broadcasts its block proposal to the P2P
|
|
|
-network. Finally the miner triggers a finalization check to see if its newly
|
|
|
-extended fork can be finalized.
|
|
|
+* Once the miner finds such a nonce, it broadcasts its block proposal to the
|
|
|
+ P2P network. Finally the miner triggers a finalization check to see if its
|
|
|
+ newly extended fork can be finalized.
|
|
|
|
|
|
Pseudocode:
|
|
|
```
|
|
|
@@ -52,10 +52,10 @@ loop {
|
|
|
|
|
|
## Listening for block proposals
|
|
|
|
|
|
-Each node listens for new block proposals on the network. Upon receiving block
|
|
|
-proposals, nodes try to extend the proposals onto a fork held in memory (this
|
|
|
-process is described in the next section). Then nodes trigger a finalization
|
|
|
-check to see if their newly extended fork can be finalized.
|
|
|
+Each node listens for new block proposals on the P2P network. Upon receiving
|
|
|
+block proposals, nodes try to extend the proposals onto a fork held in memory
|
|
|
+(this process is described in the next section). Then nodes trigger a
|
|
|
+finalization check to see if their newly extended fork can be finalized.
|
|
|
|
|
|
Upon receiving a new block proposal, miners also check if the extended fork
|
|
|
rank is better than the one they are currently trying to extend. If the fork
|
|
|
@@ -66,27 +66,30 @@ new best fork.
|
|
|
|
|
|
Block producers create a reward transaction containing a `ECVRF` proof that
|
|
|
contributes to ranking logic. The `VRF` is built using the `pallas::Base` of
|
|
|
-the $`(n-1)`$-block proposal nonce, the $`(n-1)`$-block proposal hash, and the
|
|
|
-`pallas::Base` of the proposal's block height. The `VRF`'s purpose is to
|
|
|
-eliminate long range attacks by predicting a future block with a high ranking
|
|
|
-that we can produce in advance.
|
|
|
+the $(n-1)$-block proposal's nonce, the $(n-2)$-block proposal's hash, and the
|
|
|
+`pallas::Base` of the block proposal's block height. The `VRF`'s purpose is to
|
|
|
+eliminate long range attacks by predicting a high-ranking future block that we
|
|
|
+can produce in advance.
|
|
|
|
|
|
-Each block proposal is ranked based on the modulus of the $`(n-1)`$-block
|
|
|
+Each block proposal is ranked based on the modulus of the $(n-2)$-block
|
|
|
proposal, a `VRF` proof (attached to the block producer's reward transaction)
|
|
|
and its `nonce`.
|
|
|
|
|
|
The rank of the genesis block is 0. The rank of the following 2 blocks is equal
|
|
|
-to the nonce, since there is no `n-1` block producer or a `VRF` attached to the
|
|
|
-reward transaction. For all other blocks, the rank is computed as follows:
|
|
|
+to the nonce, since there is no $(n-2)$-block producer or `VRF` attached to the
|
|
|
+reward transaction.
|
|
|
|
|
|
-1. Grab the `VRF` proof from the reward transaction of the $`(n-1)`$-block proposal
|
|
|
+For all other blocks, the rank is computed as follows:
|
|
|
+
|
|
|
+1. Grab the `VRF` proof from the reward transaction of the $(n-2)$-block proposal
|
|
|
2. Generate a `pallas::Base` from the `blake3::Hash` bytes of the proof
|
|
|
-3. Generate a `u64` using the first 8 bytes from the `pallas::Base` of the proofs hash
|
|
|
+3. Generate a `u64` using the first 8 bytes from the `pallas::Base` of the proof's hash
|
|
|
4. Compute the rank: `vrf_u64` % `nonce` (If `nonce` is 0, rank is equal to `vrf_u64`)
|
|
|
|
|
|
-To calculate each fork rank, we simply multiply the sum of every block proposal
|
|
|
-rank in the fork by the fork's length. We use the length multiplier to give a
|
|
|
-preference to longer forks, as longer forks have a chance at a higher ranking.
|
|
|
+To calculate each fork rank, we simply multiply the sum of every block
|
|
|
+proposal's rank in the fork by the fork's length. We use the length
|
|
|
+multiplier to give a preference to longer forks (i.e. longer forks are
|
|
|
+likely to have a higher ranking).
|
|
|
|
|
|
## Fork extension
|
|
|
|
|
|
@@ -157,24 +160,24 @@ Extending the canonical blockchain with a new block proposal:
|
|
|
|
|
|
When the finalization check kicks in, each node will grab its best fork.
|
|
|
|
|
|
-If more than one fork exists with same rank, the node will not finalize any
|
|
|
-block proposals. If the fork's length exceeds the security threshold, the node
|
|
|
-will finalize all block proposals, excluding the $`(n-1)`$-block proposal, by
|
|
|
-appending them to the canonical blockchain. We exclude the $`(n-1)`$-block
|
|
|
-proposal to eliminate network race conditions for same block heights.
|
|
|
+If more than one fork exists with same rank, the node will not finalize
|
|
|
+any block proposals. If the fork's length exceeds the security threshold,
|
|
|
+the node will finalize all block proposals, excluding the $(n-1)$-block
|
|
|
+proposal, by appending them to the canonical blockchain. We exclude the
|
|
|
+$(n-1)$-block proposal to eliminate network race conditions for blocks
|
|
|
+of the same height.
|
|
|
|
|
|
Once finalized, all the remaining fork chains are removed from the node's
|
|
|
memory pool.
|
|
|
|
|
|
Because of this design, finalization cannot occur while there are competing
|
|
|
fork chains of the same rank whose length exceeds the security threshold. In
|
|
|
-such a case, finalization will occur when a single highest ranking fork
|
|
|
-emerges.
|
|
|
+this case, finalization will occur when a single highest ranking fork emerges.
|
|
|
|
|
|
We continue Case 3 from the previous section to visualize this logic.
|
|
|
|
|
|
The finalization threshold used in this example is 3 blocks. A node observes 2
|
|
|
-proposals. One extends the F0 fork, and the other extends the F2 fork:
|
|
|
+proposals. One extends the F0 fork and the other extends the F2 fork:
|
|
|
|
|
|
|--[M0]--[M2]+--[M5] <-- F0
|
|
|
[C]--...--[C]--|
|
|
|
@@ -208,7 +211,7 @@ other forks get dropped:
|
|
|
|
|
|
|
|/--[M4] <-- F3
|
|
|
|
|
|
-The canonical blockchain now contains blocks M0, M3, M6 from fork F2, and the
|
|
|
+The canonical blockchain now contains blocks M0, M3, M6 from fork F2. The
|
|
|
current state is:
|
|
|
|
|
|
[C]--...--[C]--|--[M7] <-- F2
|