Pages:
Author

Topic: PPLNS (Read 63183 times)

newbie
Activity: 2
Merit: 0
June 27, 2019, 03:54:14 AM
#51
Thank you kano, appreciate your answer!

I am using Mendis terminology. His "score" is the "share diff" / "NW diff" - just wording stuff.

Good to hear a confirmation of how PPLNS is supposed to work - in the end quite simple Wink

--

I was going after his various enhancements which he updated in this OP.
There he indicates to have a solution for some extreme on the edge cases, where I try to get my head around.

So I should rephrase my final question - then would be - if I correctly implemented the "Mendi Rosenfeld Windowed PPLNS" method Smiley
I figured btw - payouts of his method are different - as PPLNS in your description always pays out the exact Blockreward.
Mendis method has  variance in there.

Thx & Cheers!
legendary
Activity: 4634
Merit: 1851
Linux since 1997 RedHat 4
June 26, 2019, 09:11:13 PM
#50
PPLNS has no scoring.

Each share has the same value per difficulty, you just add up the total difficulty of a miner's shares and divide it by the total difficulty of all the shares used for N to get their % of the total reward.
newbie
Activity: 2
Merit: 0
June 26, 2019, 04:37:43 AM
#49
Heya everyone,

thank you very much esp. Meni Rosenfeld for explaining the PPLNS method in great detail. Maybe someone here can shed a bit of light to a little detail:
I am trying to implement the scheme and therefor have consulted this thread and re-read it numerous times.
Also I have studied the source code of some open source pools. I am pretty much sure to have understood it, but have found different implementations, and am in doubt especially about to how to understand the boundary conditions.

My main question still is - how to treat the "last" (oldest) share - meaning the one which brings the Totalscore > X.

a) let r become negative and include this share into the payment.

b) stop 1 share before - at the "last" share where Totalscore <= X.

After studying a lot I came to the following conclusion (method b) and would like to sum up and show how my understanding is, in one post so to say. It maybe help others, and would like to ask for comments if everything is correct.

Therefor I prepared an example with 10 shares, and easy to calculate numbers.
The following mini spreadsheet visualizes what I mean:

https://pasteboard.co/IlbdR2U.png

Boiling everything down, it looks like a very simple pseudo code:

Code:
0. TotalScore = 0, X = 2, B = Block.Reward


1. Calculate score of Winning share:

s = Share Diff / NW Diff and remember as t


2. Do WHILE TotalScore < X
      
      s = share.Difficulty / network.Difficulty

      TotalScore += s

      r = X - TotalScore

      Payout = (s * B) / (t * X) * min(r, t)

      TotalPayout += Payout

      share.Next()

What do you say - is that a correct PPLNS implementation?

Thank you very much!

Randominer  Smiley
legendary
Activity: 4634
Merit: 1851
Linux since 1997 RedHat 4
January 06, 2015, 05:54:08 PM
#48
the cex io guys deffered me to this link when asked why im having negative balance for holding 1gH/s

Now you know what kind of people your dealing with...
... "what kind of people" a sizable % of the network (>10%?) of people are silly enough to deal with ...
It's actually quite astounding that so many people do, and even before when this was already obvious, that a much higher % were.
legendary
Activity: 1302
Merit: 1001
January 06, 2015, 03:43:00 PM
#47
the cex io guys deffered me to this link when asked why im having negative balance for holding 1gH/s

Now you know what kind of people your dealing with...
donator
Activity: 2058
Merit: 1054
January 06, 2015, 05:55:54 AM
#46
the cex io guys deffered me to this link when asked why im having negative balance for holding 1gH/s
And that's bullshit on cex's part. PPLNS is a pooled mining reward system which you cannot possibly have a negative balance. You have a negative balance for buying a rip off cloud mining service which gets its "income" from a pooled mining reward.
I agree.
-ck
legendary
Activity: 4088
Merit: 1631
Ruu \o/
January 06, 2015, 03:54:13 AM
#45
the cex io guys deffered me to this link when asked why im having negative balance for holding 1gH/s
And that's bullshit on cex's part. PPLNS is a pooled mining reward system which you cannot possibly have a negative balance. You have a negative balance for buying a rip off cloud mining service which gets its "income" from a pooled mining reward.
sr. member
Activity: 637
Merit: 262
January 06, 2015, 03:39:52 AM
#44
the cex io guys deffered me to this link when asked why im having negative balance for holding 1gH/s
donator
Activity: 2058
Merit: 1054
March 23, 2014, 07:20:55 AM
#43
The correct method is as follows.
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.
2. 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.
3. 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.
4. 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.
How does this (specifically steps 2 & 3) change when a pool fee is involved? Is B simply reduced by the fee amount (e.g. B is only 99% of what it otherwise was in a 1% fee pool)?
This will be applied when the payment is calculated. If the fee is f (e.g., 1% fee is f=0.01), the amount to pay for a share will be (1-f)*(sB)/(tX) * min (r,t).
newbie
Activity: 56
Merit: 0
March 22, 2014, 12:25:04 AM
#42
The correct method is as follows.
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.
2. 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.
3. 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.
4. 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.

How does this (specifically steps 2 & 3) change when a pool fee is involved? Is B simply reduced by the fee amount (e.g. B is only 99% of what it otherwise was in a 1% fee pool)?
donator
Activity: 2058
Merit: 1054
March 07, 2014, 08:22:37 AM
#41
It doesn't help if N is chosen to be a given multiple of the difficulty at the time a block is found. If the difficulty is about to increase, it is more profitable to mine a short while before. For example, if N is set equal to the difficulty D, a share submitted D shares before the increase will be paid the full expectation in the D-window, and then when difficulty increased it will once again go inside the window and have more expected reward.

I am new to learning bitcoin mining, but I don't get your statement above: If N is set equal to D, then on average the window will just cover the round, so on average there will be no overlap.
That statement refers specifically to a change in difficulty at a roughly known future time. After the difficulty increases the retrospective window get larger, since it is a number of shares equal to the current difficulty.
newbie
Activity: 4
Merit: 0
March 06, 2014, 07:07:28 PM
#40
It doesn't help if N is chosen to be a given multiple of the difficulty at the time a block is found. If the difficulty is about to increase, it is more profitable to mine a short while before. For example, if N is set equal to the difficulty D, a share submitted D shares before the increase will be paid the full expectation in the D-window, and then when difficulty increased it will once again go inside the window and have more expected reward.

I am new to learning bitcoin mining, but I don't get your statement above: If N is set equal to D, then on average the window will just cover the round, so on average there will be no overlap.

member
Activity: 61
Merit: 10
August 08, 2013, 11:59:49 AM
#39
Works great, thanks!
donator
Activity: 2058
Merit: 1054
August 08, 2013, 01:44:59 AM
#38
Is it possible to calculate in advance how many shares will be included in the window? I'm thinking in terms of an implementation using a shares database (e.g., SQL). Before I begin collecting shares, can I compute approximately how many I will need to look at?
Yes, it will be approximately X * D. Depending on how you intend to use the approximation, a better one can be found.

My goal is to limit the number of rows fetched from the table to reduce server overhead. I would of course want to avoid the possibility of under-estimating, else the total payout wouldn't equal the block reward. Would I need to add anything to X*D to avoid underestimation?
If D1 is the current difficulty and D2 is the previous difficulty, an upper bound would be X * max (D1, D2) + 3. Taking the max makes sure that if the difficulty has just decreased, you won't miss the shares needed at the previously high difficulty; the +3 term helps with rounding, off-by-one errors etc., it can probably be tightened but it costs very little so I wouldn't bother.

Note that if the window spans more than one difficulty adjustment it may not work (you might need the maximum over previous difficulties as well) but that's not a situation I believe should happen.

If miners submit shares with difficulty greater than 1 this can be decreased. If d is the minimal difficulty that they can submit (assuming that throughout the window you only have shares with this difficulty or higher), and upper bound is X * max (D1, D2) / d + 3.
member
Activity: 61
Merit: 10
August 06, 2013, 02:29:14 PM
#37
Is it possible to calculate in advance how many shares will be included in the window? I'm thinking in terms of an implementation using a shares database (e.g., SQL). Before I begin collecting shares, can I compute approximately how many I will need to look at?
Yes, it will be approximately X * D. Depending on how you intend to use the approximation, a better one can be found.

My goal is to limit the number of rows fetched from the table to reduce server overhead. I would of course want to avoid the possibility of under-estimating, else the total payout wouldn't equal the block reward. Would I need to add anything to X*D to avoid underestimation?
donator
Activity: 2058
Merit: 1054
August 06, 2013, 02:10:36 PM
#36
Is it possible to calculate in advance how many shares will be included in the window? I'm thinking in terms of an implementation using a shares database (e.g., SQL). Before I begin collecting shares, can I compute approximately how many I will need to look at?
Yes, it will be approximately X * D. Depending on how you intend to use the approximation, a better one can be found.
member
Activity: 61
Merit: 10
August 06, 2013, 10:24:59 AM
#35
Is it possible to calculate in advance how many shares will be included in the window? I'm thinking in terms of an implementation using a shares database (e.g., SQL). Before I begin collecting shares, can I compute approximately how many I will need to look at?
donator
Activity: 2058
Merit: 1054
June 27, 2013, 06:37:23 AM
#34
I'm afraid I must make another correction to the OP: The payout (sB/tX) * min (r,t) is applied not just to the earliest share, but to all shares. For most shares r is much bigger than t so this reduces to sB/X, but there can be several early shares (not just the earliest) for which r
Thanks for the in-depth explanation.

After looking at this for over an hour, there is just 1 detail that I don't understand: For the final share (that only partially fits in the remainder of the window) how do we calculate the value of t?

Lets take the situation where a round has ended. (Network difficulty always = 240, block value always = 50, X=2, no pool fee)
The winning share is share number 28419 (which has share difficulty = 7).
Looking backwards from here, we begin paying out rewards with share number 28418 (which has share difficulty = 7).
....
We keep going until we get to a share that only partially fits in the remainder of the window: share number 28353 (which has share difficulty = 90).

When I calculate what I think is the value of t, the reward for the partial block ends up spilling well over the window boundary.
What would t be in this case?
(PS - This is actual data I have in a spreadsheet from a block mined on testnet)
t or r? t is simply the score of the winning share, 7/240 in this case.

For r, if all shares 28353-28418 are of difficulty 7, their total score is 66*7/240 = 1.925. Thus r = 0.075.

If you mean that the total payout is higher than the block reward, this is true. In this design, when small shares follow large shares the payout is bigger, when large shares follow small shares the payout is lower.

The practical difference is small since share scores aren't as big as 90/240 in reality.

Requiring that the payout is exactly equal to the block reward is not sustainable because the block reward is variable. However, if we assume the block reward is fixed, there are some alternative designs which satisfy this.

The "General unit-based framework" in AoBPMRS (currently section 5.2) does this, but isn't easy to implement. There's a randomized variant that is fairly easy though:

1. When a block is found, letting t be the score of the winning share, choose a random real u between 0 and t.

2. Pay out uB/X to the winning share.

3. Moving backwards, pay out sB/X to each share fully within the window, s being the share's score.

4. For the last (earliest) share, letting r be the score remaining to complete to X (where the winning share has contributed u), pay out rB/X.
newbie
Activity: 19
Merit: 0
June 26, 2013, 06:03:08 PM
#33
Thanks for the in-depth explanation.

After looking at this for over an hour, there is just 1 detail that I don't understand: For the final share (that only partially fits in the remainder of the window) how do we calculate the value of t?

Lets take the situation where a round has ended. (Network difficulty always = 240, block value always = 50, X=2, no pool fee)
The winning share is share number 28419 (which has share difficulty = 7).
Looking backwards from here, we begin paying out rewards with share number 28418 (which has share difficulty = 7).
....
We keep going until we get to a share that only partially fits in the remainder of the window: share number 28353 (which has share difficulty = 90).

When I calculate what I think is the value of t, the reward for the partial block ends up spilling well over the window boundary.
What would t be in this case?
(PS - This is actual data I have in a spreadsheet from a block mined on testnet)
donator
Activity: 2058
Merit: 1054
June 24, 2013, 05:36:13 PM
#32
Regarding the small correction you made, I don't quite understand what's happening.
Are we talking about the "oldest" share, the one that may get a partial reward (in order to get the total score to exactly X)?
If so, I don't see how "t" is relevant to the calculation, if "t" is the score of the "winning share" (i.e. the share that we didn't even take into consideration to begin with).
First we need to remember the goal; each share will have an expected reward of sB.

Thus we need to take a given share, and consider the rewards it will get from future shares.

We construct a timeline window of length X after the share and state that for every block found within this timeline, the original share will be rewarded by (sB/X). Since X blocks are expected to be found, the average reward will be sB.

More specifically, every future share found, with score t, will consume t units of the window, and will have probability t to result in a block giving a reward of sB/X, hence its expected reward is sBt/X. The invariant is that when t units are consumed, an expected reward of sBt/X is added. Thus, summing over shares totaling X units, the average reward is sB.

However, a problem remains with the last share in the window. It extends beyond the window, thus while its expected reward would be sBt/X, the amount of units it consumes is equal to the amount of units remaining in the window, which is r. To maintain the invariant, we modify the reward in case the last share is a block to sBr/tX (only a portion of r/t of the block, if found, is considered in the window). The expected reward would then be sBr/X, maintaining the invariant. This correction is only done for the last share in the window, which can be identified by the fact that r
This analysis took a share and looked at how much reward it needs to get from future shares if they end up a block; now we just need to look at it backwards to find out how much each block found needs to reward past shares. The result is what is in the OP.

My final question: Is X=2 an acceptable setting for real-world usage?
It depends on pool size and preference; for a smaller pool I'd say it's good, a larger pool could use a higher value (since maturity time becomes less of an issue).
Pages:
Jump to: