Doing PoW prioritization differently

Instead of prioritizing transactions based on PoW difficulty, which has the downside that a spammer generates high difficulty PoW by chance and competes vs regular users increasing their PoWs deliberately, we could prioritize not on difficulty itself, but by amount of PoWs, so that high difficulty PoWs done by chance don't skip to the top of the line.

Specific suggestion:

  1. The PoW field on the blocks become an object that can contain up to 5 different ordered PoWs. For a block to be valid it only needs the first PoW to be valid. The rest are used only for prioritization and do not get added to the DB.

  2. The first PoW is the same as today. Based on the previous (or height) field. The second PoW is based on the previous + the first PoW. The third PoW is based on the previous + 2nd PoW. And so on until the 5th poW.

  3. Blocks are ordered based on how many PoWs they have in them, not their individual difficulty. This prevents individual lucky high difficulty PoWs being prioritized by chance.

In order to maximize costs for a spammer to affect regular users, the difficulty of every single PoW could be different.

So the first PoW is based on ledger bloat costs. The second is 2x the first. The 3rd difficulty is 5x the difficulty of the first. The 4th is 10x times and the 5th is 20x.


  1. In this system, a 2 PoW block always takes priority over a 1 PoW block, a 3 PoW block always take precedent over a 2 PoW block. During the recent spam, it was suggested to increase PoW difficulty to 20x to actually skip the queue over the spammer given his high difficulty blocks done by chance.

  2. After a block is cemented, you can discard the extra PoWs and keep only the first one in the DB, so the DB remains the same size.

  3. This also permits a user to update his PoW live. Imagine during saturation a user send a 1 PoW block. They can now compute a second PoW and broadcast again, skipping the line.


  1. The blocks can become bigger. A block with 5 poWs is obviously bigger than a block with a single PoW, although the difference is not particularly relevant I believe. But it is an increase in bandwidth during a moment where bandwidth is being used at it's highest (saturation).

  2. More PoW checks. But that's the point of the first PoW. It still serves the same purpose of gatekeeper of the node resources. But still, more checks in a moment where resources are being used to the limit (saturation).

Update based on PlasmaPower Feedback

Plasma made a suggestion that is equivalent with less work. The first byte of the PoW field is choosen by the user to indicate the PoW level he is doing.

So transactions are ordered by the first byte of the PoW field, with each increasing number indicating a harder difficulty.

So a PoW with a low first byte would never be considered a high difficulty PoW, even if by chance it actually has a high difficulty.


I am trying to understand the Plasma option, but a little confused. So in that version, a user would say pow level 2 is their target, which represents double the base difficulty required to be valid (2x). So they generate work by mixing in a 2 into the PoW calculation (so blake2b(x || nonce || prev_block_hash) > x*threshold where x is a hex value representing an integer) and then putting the result in the block (say that generates a value of 2fbffed7c73b61367) which allows validation against that higher threshold by extracting the first byte as the multiplier?

So then someone who pre-determines a multiplier of 2 doesn't get the advantage of a work value that actually is 50x higher than the chosen threshold?


Well, yes but for all practical purposes consider that that the nonce is actually the (x || nonce) in your equation (we made the variable part of the nonce smaller). With that there's fewer code changes required, because validation is simply H(nonce || block_hash) > get_difficulty(pow[0]) .

It can be a direct multiplier like you said or any other function but it could also map to fixed difficulties (my personal suggestion is some kind of log function so that it really becomes impossible to do lots of blocks at a high difficulty).

And yes, the desired consequence is what you said in the end.

1 Like

Ok, that makes sense. And a log function does seem more appropriate here to scale quick enough to limit the number of prefixed bytes required to reach a sufficient level of difficulty.