<p>When a share of difficulty <em>d</em> > 1 is submitted, treat it as though <em>d</em> shares, each of difficulty 1, were submitted simultaneously.</p>

CC BY-SA 3.0
2017-07-24T18:46:57.877Z
So in essence the algorithm description assumes Diff1 shares and the calculated score must be multiplied by share-dificulty?
Oliver Weichhold
CC BY-SA 3.0
2017-07-24T18:54:54.933Z
@OliverWeichhold: Well, it assumes all shares are of equal difficulty; that difficulty doesn't necessarily have to equal 1.  You could have some "base difficulty" *d0*, and a share of higher difficulty *d* is treated as *d/d0* base-difficulty shares.  It wouldn't change anything.
Nate Eldredge
CC BY-SA 3.0
2017-07-24T20:19:27.480Z
Actually, while this gives a reasonable approximation, it's not as accurate and general as keeping it as one share but giving it a score of d/D instead of 1/D.
Meni Rosenfeld
CC BY-SA 3.0
2017-07-24T18:44:08.323Z
2017-07-24T18:44:08.323Z
Nate Eldredge
<p>Well, that post is quite old. Variable-difficulty shares weren't a thing then.</p>

<p>That said, I'm pretty sure the fix is as follows: When a share is submitted, the post says you should assign to it a score of 1/D. Instead, assign to it a score of d/D, where d is the share's difficulty. That's it.</p>

<p>Also, you should have a look at <a href="https://bitcoil.co.il/pool_analysis.pdf" rel="nofollow noreferrer">https://bitcoil.co.il/pool_analysis.pdf</a>, specifically the "unit-PPLNS" part of section 3.3. It's slightly more complicated, but IIRC it has the advantage that it is still hopping-proof when the block reward can change (which is much more relevant now than it was back then).</p>

<p>As for changes in the network difficulty - the score is based on the historical difficulty, and the current difficulty is not used at all in the calculation.</p>

<p>If this seems odd, consider that if the current network difficulty is higher, than each new share has less chance to become a block and reward historical shares, but on the other hand, have a lower score and thus more shares are needed until the historical share is out of the window. So it evens out.</p>

CC BY-SA 3.0
2017-07-24T20:18:09.687Z
2017-07-25T09:00:08.037Z
2017-07-25T09:00:08.037Z
Meni Rosenfeld
<p>Quote from Meni Rosenfeld's post <a href="https://bitcointalk.org/index.php?topic=39832" rel="nofollow noreferrer">explaining PPLNS</a>:</p>

<blockquote>
  <ol>
  <li>Choose a parameter X, which represents multiples of D to include in the window when difficulty is static. X=2 is a good choice. When a
  share is submitted, assign to it a score of 1/D, where D is the
  difficulty at the time the share is submitted.</li>
  <li>When a block is found, pay (sB)/X for the last share (the one before the winning share), where s is the share's score and B is the
  block reward. Continue backwards, paying each share based on its
  score, until you reach a share which brings the total score of the
  shares counted above X. Pay that share the amount (sB)/(tX) * min
  (r,t), where r is the score required to bring the total to exactly X
  and t is the score of the winning share. Don't pay any older shares.</li>
  <li>If the pool has just started, and a block is found before there are shares totaling a score of X, there will be leftover rewards and
  it should be decided what to do with them. It doesn't matter much, but
  I recommend that the operator keeps them (in a macroscopic view, if
  the pool ever changes, this is compensation for the funds needed to
  cash participants out). Other options include donating to charity, or
  distributing among the miners.</li>
  </ol>
</blockquote>

<p>So far so good. One thing I'm struggling to understand is where the difficulty of a share itself fits into the picture. How do I scale the reward by share difficulty without screwing up the algorithm?</p>

<p><strong>Update:</strong></p>

<p>What I also would like to know is how to handle cases where the network difficulty recorded with a share is different from the current network difficulty.</p>

CC BY-SA 3.0
2017-07-24T18:56:48.083Z
Re update: that is exactly what the post explains!  You use the difficulty recorded with a share to compute its score.  The "current" network difficulty (i.e. difficulty at the time the block is mined) never enters the computation at all.
Nate Eldredge
<mining-pools><pool-payout-methods>
PPLNS implementation
Oliver Weichhold
# PPLNS implementation

(Asked by: username_0 on 2017-07-24)

Quote from username_2 username_2's post [explaining PPLNS](https://bitcointalk.org/index.php?topic=39832):

> 1. Choose a parameter X, which represents multiples of D to include in the window when difficulty is static. X=2 is a good choice. When a
>    share is submitted, assign to it a score of 1/D, where D is the
>    difficulty at the time the share is submitted.
> 2. When a block is found, pay (sB)/X for the last share (the one before the winning share), where s is the share's score and B is the
>    block reward. Continue backwards, paying each share based on its
>    score, until you reach a share which brings the total score of the
>    shares counted above X. Pay that share the amount (sB)/(tX) \* min
>    (r,t), where r is the score required to bring the total to exactly X
>    and t is the score of the winning share. Don't pay any older shares.
> 3. If the pool has just started, and a block is found before there are shares totaling a score of X, there will be leftover rewards and
>    it should be decided what to do with them. It doesn't matter much, but
>    I recommend that the operator keeps them (in a macroscopic view, if
>    the pool ever changes, this is compensation for the funds needed to
>    cash participants out). Other options include donating to charity, or
>    distributing among the miners.

So far so good. One thing I'm struggling to understand is where the difficulty of a share itself fits into the picture. How do I scale the reward by share difficulty without screwing up the algorithm?

**Update:**

What I also would like to know is how to handle cases where the network difficulty recorded with a share is different from the current network difficulty.

**Tags:** mining-pools, pool-payout-methods

> **Comments:**
> **username_1**: Re update: that is exactly what the post explains!  You use the difficulty recorded with a share to compute its score.  The "current" network difficulty (i.e. difficulty at the time the block is mined) never enters the computation at all.  

---

## 2 answers

### Answer by username_2 on 2017-07-24. Score: 4 | Accepted answer

Well, that post is quite old. Variable-difficulty shares weren't a thing then.

That said, I'm pretty sure the fix is as follows: When a share is submitted, the post says you should assign to it a score of 1/D. Instead, assign to it a score of d/D, where d is the share's difficulty. That's it.

Also, you should have a look at <https://bitcoil.co.il/pool_analysis.pdf>, specifically the "unit-PPLNS" part of section 3.3. It's slightly more complicated, but IIRC it has the advantage that it is still hopping-proof when the block reward can change (which is much more relevant now than it was back then).

As for changes in the network difficulty - the score is based on the historical difficulty, and the current difficulty is not used at all in the calculation.

If this seems odd, consider that if the current network difficulty is higher, than each new share has less chance to become a block and reward historical shares, but on the other hand, have a lower score and thus more shares are needed until the historical share is out of the window. So it evens out.


---

### Answer by username_1 on 2017-07-24. Score: 1

When a share of difficulty *d* > 1 is submitted, treat it as though *d* shares, each of difficulty 1, were submitted simultaneously.

> **Comments:**
> **username_0**: So in essence the algorithm description assumes Diff1 shares and the calculated score must be multiplied by share-dificulty?  
> **username_1**: @username_0: Well, it assumes all shares are of equal difficulty; that difficulty doesn't necessarily have to equal 1.  You could have some "base difficulty" *d0*, and a share of higher difficulty *d* is treated as *d/d0* base-difficulty shares.  It wouldn't change anything.  
> **username_2**: Actually, while this gives a reasonable approximation, it's not as accurate and general as keeping it as one share but giving it a score of d/D instead of 1/D.  

---

