<p>While I don't know how other PoS blockchains operate, I can give some insight about the PoSv2/3 version based on Peercoin's implementation of proof of stake; one such example would be Novacoin.</p>

<p>The total network weight is ~computed by <a href="https://github.com/novacoin-project/novacoin/blob/d6d619d8633d90f2d6815203613ab850d05554d8/src/rpcblockchain.cpp#L74" rel="nofollow noreferrer">this</a> function:</p>

<pre><code>double GetPoSKernelPS()
{
    int nPoSInterval = 72;
    double dStakeKernelsTriedAvg = 0;
    int nStakesHandled = 0, nStakesTime = 0;

    CBlockIndex* pindex = pindexBest;;
    CBlockIndex* pindexPrevStake = NULL;

    while (pindex &amp;&amp; nStakesHandled &lt; nPoSInterval)
    {
        if (pindex-&gt;IsProofOfStake())
        {
            dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296.0;
            nStakesTime += pindexPrevStake ? (pindexPrevStake-&gt;nTime - pindex-&gt;nTime) : 0;
            pindexPrevStake = pindex;
            nStakesHandled++;
        }

        pindex = pindex-&gt;pprev;
    }

    if (!nStakesHandled)
        return 0;

    return dStakeKernelsTriedAvg / nStakesTime;
}
</code></pre>

<p>How the weight estimation algorithm works is pretty interesting: it iterates backwards through the blockchain, from the latest known best block until it finds 72 blocks that were produced using a proof of stake (basically all the past 72 blocks).</p>

<p>Using these 72 PoS blocks, it calculates the total amount of time that has passed between each consecutive block pair (added up to a total -- <code>nStakesTime</code>) and the total amount of "difficulty" that was satisfied during the production of those blocks (<code>dStakeKernelsTriedAvg</code>).</p>

<p>The final network weight estimation is given by dividing the "amount of work" by the "amount of time". </p>

<p>This algorithm does not attempt to calculate the exact amount of coins that are being "at stake" at any given time, because as you noticed that wouldn't be possible; yet the estimations it gives are pretty accurate.</p>

CC BY-SA 4.0
2018-12-14T11:20:07.033Z
2018-12-14T11:20:07.033Z
theodor96
<p>Novacoins implementation of GetPoSKernelPS() does a splendid job to calculate the effective network staking weight. Someone wondering about the 4294967296.0 constant, see here: <a href="https://en.bitcoin.it/wiki/Difficulty#What_is_the_formula_for_difficulty.3F" rel="nofollow noreferrer">https://en.bitcoin.it/wiki/Difficulty#What_is_the_formula_for_difficulty.3F</a></p>

<p>However the value returned by GetPoSKernelPS() when used for staking reward time estimation does distort the result during times when the network weight is changing. This is because the chance to win a stake is solely dependent on the current difficulty and adjusting the difficulty, depending on the projects parameters, takes days.</p>

<p>This is why for Spectrecoins staking reward time estimation we use the following code (simplified): </p>

<pre><code>double GetPoSKernelPS()
{
    double result = 0;
    if (nNodeMode == NT_THIN)
    {
        if (pindexBestHeader-&gt;IsProofOfStake())
            result = GetHeaderDifficulty(pindexBestHeader) * 4294967296.0;
    }
    else
    {
        if (pindexBest-&gt;IsProofOfStake())
            result = GetDifficulty(pindexBest) * 4294967296.0;
    }

    if (result &gt; 0)
        result /= TARGET_BLOCK_TIME;

    if (Params().IsProtocolV2(nBestHeight))
        result *= STAKE_TIMESTAMP_MASK + 1;

    return result;
}

uint64_t nWeight = pwalletMain-&gt;GetStakeWeight() + pwalletMain-&gt;GetSpectreStakeWeight();    
uint64_t nNetworkWeight = GetPoSKernelPS();
uint64_t nExpectedTime = TARGET_BLOCK_TIME * nNetworkWeight / nWeight) 
</code></pre>

CC BY-SA 4.0
2019-07-03T06:48:18.917Z
2019-07-03T06:48:18.917Z
Tekener
<p>In PoS coins there is a common 'time to stake' estimate, this is based on the users own accumulated stake amount as a proportion of the network wide stake weight.</p>

<p>However there is no way for any node to reliably estimate the network stake weight, in theory it's just all nodes individual weights added together, but as no single node is guaranteed to see all others without duplication, I wanted to understand how this is calculated.</p>

<proof-of-stake>
In PoS how is Net Stake Weight calculated
Scalextrix
# In PoS how is Net Stake Weight calculated

(Asked by: username_0 on 2018-07-04)

In PoS coins there is a common 'time to stake' estimate, this is based on the users own accumulated stake amount as a proportion of the network wide stake weight.

However there is no way for any node to reliably estimate the network stake weight, in theory it's just all nodes individual weights added together, but as no single node is guaranteed to see all others without duplication, I wanted to understand how this is calculated.

**Tags:** proof-of-stake


---

## 2 answers

### Answer by username_1 on 2018-12-14. Score: 3 | Accepted answer

While I don't know how other PoS blockchains operate, I can give some insight about the PoSv2/3 version based on Peercoin's implementation of proof of stake; one such example would be Novacoin.

The total network weight is ~computed by [this](https://github.com/novacoin-project/novacoin/blob/d6d619d8633d90f2d6815203613ab850d05554d8/src/rpcblockchain.cpp#L74) function:

```
double GetPoSKernelPS()
{
    int nPoSInterval = 72;
    double dStakeKernelsTriedAvg = 0;
    int nStakesHandled = 0, nStakesTime = 0;

    CBlockIndex* pindex = pindexBest;;
    CBlockIndex* pindexPrevStake = NULL;

    while (pindex && nStakesHandled < nPoSInterval)
    {
        if (pindex->IsProofOfStake())
        {
            dStakeKernelsTriedAvg += GetDifficulty(pindex) * 4294967296.0;
            nStakesTime += pindexPrevStake ? (pindexPrevStake->nTime - pindex->nTime) : 0;
            pindexPrevStake = pindex;
            nStakesHandled++;
        }

        pindex = pindex->pprev;
    }

    if (!nStakesHandled)
        return 0;

    return dStakeKernelsTriedAvg / nStakesTime;
}

```

How the weight estimation algorithm works is pretty interesting: it iterates backwards through the blockchain, from the latest known best block until it finds 72 blocks that were produced using a proof of stake (basically all the past 72 blocks).

Using these 72 PoS blocks, it calculates the total amount of time that has passed between each consecutive block pair (added up to a total -- `nStakesTime`) and the total amount of "difficulty" that was satisfied during the production of those blocks (`dStakeKernelsTriedAvg`).

The final network weight estimation is given by dividing the "amount of work" by the "amount of time".

This algorithm does not attempt to calculate the exact amount of coins that are being "at stake" at any given time, because as you noticed that wouldn't be possible; yet the estimations it gives are pretty accurate.


---

### Answer by username_2 on 2019-07-03. Score: 0

Novacoins implementation of GetPoSKernelPS() does a splendid job to calculate the effective network staking weight. Someone wondering about the 4294967296.0 constant, see here: <https://en.bitcoin.it/wiki/Difficulty#What_is_the_formula_for_difficulty.3F>

However the value returned by GetPoSKernelPS() when used for staking reward time estimation does distort the result during times when the network weight is changing. This is because the chance to win a stake is solely dependent on the current difficulty and adjusting the difficulty, depending on the projects parameters, takes days.

This is why for Spectrecoins staking reward time estimation we use the following code (simplified):

```
double GetPoSKernelPS()
{
    double result = 0;
    if (nNodeMode == NT_THIN)
    {
        if (pindexBestHeader->IsProofOfStake())
            result = GetHeaderDifficulty(pindexBestHeader) * 4294967296.0;
    }
    else
    {
        if (pindexBest->IsProofOfStake())
            result = GetDifficulty(pindexBest) * 4294967296.0;
    }

    if (result > 0)
        result /= TARGET_BLOCK_TIME;

    if (Params().IsProtocolV2(nBestHeight))
        result *= STAKE_TIMESTAMP_MASK + 1;

    return result;
}

uint64_t nWeight = pwalletMain->GetStakeWeight() + pwalletMain->GetSpectreStakeWeight();    
uint64_t nNetworkWeight = GetPoSKernelPS();
uint64_t nExpectedTime = TARGET_BLOCK_TIME * nNetworkWeight / nWeight) 

```


---

