Quote from Meni Rosenfeld's post explaining PPLNS:
- 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.
- 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.
- 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?
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.