Meni Rosenfeld
Donator
Legendary
Offline
Activity: 1918


April 23, 2013, 03:54:43 PM 

Not really. If for example X=0.5 then still normally a block will be paid out 100% to recent miners  each share will be paid twice the PPS rate. But in lucky times when there aren't enough unpaid shares, past miners can be paid. An X < 1 will further increase the time to maturity on old shares, won't it? Is there a way in a payoncePPLNS model to avoid an unbounded time to maturity? It's variance, not maturity time. A miner submitting a share has a chance to get more than the PPS amount, but also a chance to get nothing at all, ever. If he does get paid, it will be with high probability in a short time.





Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.




roy7


April 23, 2013, 05:28:03 PM 

To be really wacky one could do paytwicePPLNS with X=2.
I should probably force myself to go with DGM and be done with it. I just like the simplicity of CPPSRB.
Thank you for your time and for writing the Analysis paper.

RoyalMiningCo: Pools retired. Was fun!



Meni Rosenfeld
Donator
Legendary
Offline
Activity: 1918


April 23, 2013, 08:42:26 PM 

I should probably force myself to go with DGM and be done with it. I just like the simplicity of CPPSRB.
If you want a simple hoppingproof method, PPLNS is it (not the payonce variant), assuming it's implemented correctly. Or shiftPPLNS which is more scaleable. Thank you for your time and for writing the Analysis paper.
You're welcome.




roy7


April 23, 2013, 10:26:56 PM 

If you want a simple hoppingproof method, PPLNS is it (not the payonce variant), assuming it's implemented correctly. Is there a hopping proof way to implement the payonce variant? Assuming you store d/D as your score for shares submitted as you outline in original post (this is the way I store share data already).

RoyalMiningCo: Pools retired. Was fun!



Meni Rosenfeld
Donator
Legendary
Offline
Activity: 1918


April 24, 2013, 08:23:32 AM 

If you want a simple hoppingproof method, PPLNS is it (not the payonce variant), assuming it's implemented correctly. Is there a hopping proof way to implement the payonce variant? Assuming you store d/D as your score for shares submitted as you outline in original post (this is the way I store share data already). To be clear, when I said payonce isn't it, I meant it's not simple, not that it's not hoppingproof. I think if you follow the original method, and just cap the payment for each share to (sB/X), skipping already paid shares, it will work fine and be protected from hopping based on both pool past and future difficulty changes. You'll need to keep for each share not only whether it was paid, but how much, so if it was partially paid, it can be paid more in future blocks. I added in a later comment that to be protected from hopping based on block reward (which will be critical when the reward is based on tx fees), B for each share needs to be chosen when the share is submitted, not when the block is found.




roy7


April 24, 2013, 12:55:50 PM 

Ah okay, excellent. The initial pool I'm setting up is for TRC where the difficulty changes with each block. I store in my shares database d (user selected difficulty) and D (difficulty of the block you just submitted a share for) but do all of the payment logic based on sum(d/D for each share submitted individually, ie: D will vary over time) in LIFO (most recent) order. I mark shares if paid and then ignore them moving forward (stored for graphing and historical record).
The only thing I'm not doing is storing the reward based on B at the time you submit a share. I was only storing "You have earned sum(d/D) blocks" and then pay it out when a block is found based on the reward of the block found, not the reward at the time of submission. Which is exactly what you said not to do. I'll need to look at that.

RoyalMiningCo: Pools retired. Was fun!



roy7


April 24, 2013, 10:34:57 PM 

I added in a later comment that to be protected from hopping based on block reward (which will be critical when the reward is based on tx fees), B for each share needs to be chosen when the share is submitted, not when the block is found.
When a reward drop is coming up, like when Bitcoin went from 50 to 25, the shares submitted before the drop would be earning twice the reward as the shares after the drop if you store credit by current potential reward at the time of submission instead of the actual reward at the time a block is found. Is that that intentional? In a pure PPS model, that's how it'd have worked of course. But in a payonce PPNLS model you can only pay back as many shares as you actually received from the found block. So if the D shares up to the reward drop didn't find a block, then D+1 finds a block with half the reward, you're only going to be able to pay the most recent D/2 shares. It seems a bit counter intuitive to me, I'd think the last D shares would all get paid on the actual block (half reward than if we found the block sooner, but it is what it is, you can only pay out what the pool receives). I guess the same applies longterm with transaction fee based blocks, although then the reward would be going up and down from block to block. For payonce, does it just boil down to this then: 1 Knowing exactly what you are earning (share of potential reward+fees for current block, the reward you earned never changes between now and when you get paid) but not knowing how long until you get paid (if reward drops, your time until getting paid increases if your shares weren't recent enough) OR 2 Knowing a better idea when you get paid (based on average time to solve blocks regardless of varying reward) but not knowing how much you'll earn (reward+transaction fees of the block actually found in the future). As far as I understand things currently, most PPS models (should, if coded to use reward at time of share) fall under #1. PayOncePPLNS using block rewards at time shares are submitted would also fall under #1. Proportional would fall under #2.

RoyalMiningCo: Pools retired. Was fun!



Meni Rosenfeld
Donator
Legendary
Offline
Activity: 1918


April 25, 2013, 03:52:31 PM 

PPLNS is "supposed to be" a method where there is no operator risk, he just pays out the rewards for each block in some way. However, for the method (or any other method) to be hoppingproof even when the block reward changes, this is no longer the case.
Shares are still paid (Bd / DX) duntil the total of d/D reaches X. If, when a block is found, the reward is low in comparison to the reward at the time recent shares were submitted, the amount he has to pay according to the method is higher than the block reward, and he must pay the difference from his own pocket. And conversely, if the actual block reward is higher he keeps the difference.
If B is highly variable it can cause quite a lot of risk to the operator. It could be mitigated by basing the credit per share not only on the expected contribution but also the variance created.
In payonce PPLNS you know the maximum amount you can be paid for a share, but you don't know whether you'll be paid it at all or not. It's not just that you don't know when you'll get it. Future B has no effect on whether you get paid and when.




bloke
Newbie
Offline
Activity: 19


June 22, 2013, 07:12:59 AM 

I am currently implementing the "correct method" PPLNS and I have one question.
When a block is found, is the "winning share" counted in the window? (the original post suggests that it isn't) If it isn't counted, what is the reasoning behind this?




Meni Rosenfeld
Donator
Legendary
Offline
Activity: 1918


June 22, 2013, 07:10:50 PM 

I am currently implementing the "correct method" PPLNS and I have one question.
When a block is found, is the "winning share" counted in the window? (the original post suggests that it isn't) If it isn't counted, what is the reasoning behind this?
Correct, it isn't. If you included it, the expected payout for a share would depend on future difficulty changes. For example let X=1 and take an extreme case where after I submit a share, the difficulty changes to 1. Then the next share found will be a block and it will take the entire reward, and I will get nothing. The same happens if instead of the global difficulty changing, a different share difficulty is submitted. In practice the differences will be minor because shares are small. Where the difference between the naive method and the unitbased method is measured in percentage, the difference in how you count the edges is measured in ppm. Actually, the question prompted me to revisit the model (it's been a while), and I noticed there was a small correction which I included in AoBPMRS but didn't fix in this post; for the last share, instead of a payout of (srB)/(tX), it should be (sB)/(tX) * min (r,t). I fixed it now. PS. You should consider shiftPPLNS, I've specified the exact way to do it in this comment.




bloke
Newbie
Offline
Activity: 19


June 24, 2013, 04:23:10 PM 

Thanks for that explanation.
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).
My final question: Is X=2 an acceptable setting for realworld usage?




Meni Rosenfeld
Donator
Legendary
Offline
Activity: 1918


June 24, 2013, 10:36:13 PM 

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<t ; hence for any share the reward is min (sB/X, sBr/tX) = sB/tX * min (r,t). 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 realworld 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).




bloke
Newbie
Offline
Activity: 19


June 26, 2013, 11:03:08 PM 

Thanks for the indepth 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)




Meni Rosenfeld
Donator
Legendary
Offline
Activity: 1918


June 27, 2013, 11:37:23 AM 

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<t. Thanks for the indepth 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 2835328418 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 unitbased 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.




robotrebellion


August 06, 2013, 03:24:59 PM 

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?




Meni Rosenfeld
Donator
Legendary
Offline
Activity: 1918


August 06, 2013, 07:10:36 PM 

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.




robotrebellion


August 06, 2013, 07:29:14 PM 

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 underestimating, else the total payout wouldn't equal the block reward. Would I need to add anything to X*D to avoid underestimation?




Meni Rosenfeld
Donator
Legendary
Offline
Activity: 1918


August 08, 2013, 06:44:59 AM 

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 underestimating, 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, offbyone 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.





lawabider
Newbie
Offline
Activity: 4


March 07, 2014, 12:07:28 AM 

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 Dwindow, 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.




