Skip to content
Tomáš edited this page Aug 19, 2017 · 15 revisions

Gridcoin PoS kernel v8

Author: Tomáš Brada. With credits to the PeerCoin and BlackCoin developers.

This document describes internals, effects and design decisions of Gridcoin PoS kernel stakev8. This V8 kernel will be used in blocks version 8 and replaces the previous kernel, V3, which was used in in blocks version 7.

Versions 4-7 were skipped and the kernel was simply named after the block version in order to reduce the amount of separate version numbers needed.

The most notable effect is that magnitude does no longer affect your stake weight. Investors and BOINCers now have the same chances to mint a block. This drastic change was needed to eliminate an exploit. On the other hand a compensation for less rich BOINCers is already being designed.

Basics

To create a next block in chain, miner must find a valid proof of something for it. Gridcoin is a PoS coin so the permission to create a next block is derived from the coins they own. There is also PoW, where the permission is derived from useless computation work the miner has to do.

First a data string (called kernel) is formed from the kernel components, then the kernel is hashed to obtain a proof hash, and then this proof hash is compared to the current difficulty target. Both proof hash and target are (big) numbers. The kernel forms a valid proof only if the proof hash is less than the difficulty target.

Change list

What changed in stake weight calculation and why:

  • RSA_WEIGHT (and thus magnitude) was removed from the weight calculation.
    • multiplication issue
    • not checked when receiving

What changed in stake kernel and why:

  • removed RSA_WEIGHT was removed from kernel
    • iterable nonce
  • Explicitly mask timestamps with STAKE_TIMESTAMP_MASK
    • just to be sure
    • mask was enforced elsewhere in prior version
  • removed por_nonce
    • iterable nonce
  • added Stake Modifier
    • prevent precomputation

New Components

Stake weight of Mature Unspent Transaction Output (MUTXO) is a linear function of only it's value.

Stake kernel is composed out of the following items:

  • current Stake Modifier
    • a number composed of enthropy gathered from past blocks
    • anti-pre-computation
  • Masked timestamp of the block where transaction whose output is used in this kernel is from
    • identification of the UTXO
  • hash of the abovementioned transaction
    • identification of the UTXO
  • output number of the kernel utxo
    • identification of the UTXO
  • current masked timestamp
    • time-bound iterable
    • a value that makes the kernel change in controlled manner

Old Issues

Total defeat of PoS purpose

Multiplication issue

Unchecked newbie weight bonus

Precomputation

Comments from the PR

I would like to fix the issue with 1) unchecked rsaweight, 2) magnitude weight multiplication issue and 3) proof of work nonce being included in pos kernel making this effectively a pow consensus coin.

I think I fixed the above issues by introducing a new stake kernel and bumping the block version to 8. I named this new kernel "V8 kernel". This new kernel does not consider rsa and magnitude weight for security reasons. Does not include nonce but include the Stake Modifier. See some recent github issues and wiki for explanation why rsa/mag weight is dangerous.

Plug proof-of-work exploit. Stake modifier is included without much understanding. Without the modifier, attacker can create transactions which output will stake at desired time. In other words attacker can check wheter transactionoutput will stake in the future and create transactions accordingly. Thus including modifier, even not completly researched, increases security.

  • Edit: I now understand how SatakeModifier works and think it is secure.
  • Note: Rsa or Magnitude weight not included due to multiplication issue.
  • Note: Payment age and magnitude restrictions not included as they are not important in my view and are too restrictive for honest users.

Vehemently rejected, locally generated, v7 blocks are expected as I didn't implement all of the checks in Miner and instead relying on main block checking. This should happen much less with higher difficulty.

Interest is encoded on only 2 decimal places in boincblock (in v7 blocks) and 0.0051 is rounded up to 0.01, that is why we can't stake less or equal to 0.005 interest even thought mint limiter is only 0.000010 (depends on diff). Interesting. The rounding is also applied when deserializing. So just increasing places won't work. Forking change necessary. Edit: This was fixed in block version v8 by increasing decimal places.

Side note: you can force it to re-process all blocks with new rules as if received, by renaming blk0001.dat to bootstrap.dat and deleting txleveldb folder. This process still takes time, but is faster than re-download.

If you want to test, delete txleveldb, rename blk0001.dat to bootstrap.dat, set your wallet nick-name and add the usual node. There is no superblock on that fork, to stake you must switch to investor mode. The node nick name (-org= option) is to identify the staker for easier debugging. Set it to something like your github nick and unique suffix for each node.

Test reports, fraction of blocks staked by nodes.

First test, two nodes with roughly same balance:

{
  "general" : {
  "blocks" : 1001,
  "first_height" : 288160,
  "last_height" : 289160,
  "time_span_hour" : 28.26666667
 },
 "orgs" : {
  "TomasBrod.Mg.A" : 0.41458541,
  "TomasBrod.Mg.C" : 0.39360639,
  "" : 0.19180819
}}

Node MgA got some research rewards that increased it's balance. I guess 41.5% to 39.4% is close enough and within the error margin.

Second test, 3 nodes, MgA with 59kGRC, MgC with 20k and MgD with 10k.

{ "general" : {
  "blocks" : 532,
  "first_height" : 290100,
  "last_height" : 290631,
  "time_span_hour" : 14.16000000
 },
 "orgs" : {
  "TomasBrod.Mg.A" : 0.69548872,
  "TomasBrod.MgC$20k" : 0.21052632,
  "TomasBrod.MgD$10k" : 0.09398496
}}

Here the error is sightly higher I am not sure what is the cause but I guess it is still acceptable. The percentages are supposed to be 66%, 22% and 11%.

The average block spacing over the entire testing fork was 98.8 seconds. There were on average 874.4 blocks per day, which is little lower than the 1k bpd target.

You can come and test yourself @denravonska and @Foggyx420. But I guess this is good enough.

See also

Blackcoin wiki

Clone this wiki locally