5

I received a mining job with target = f3220000.

My XMRig miner logged the following statement:

new job from ... diff 480045 algo rx/0 height 2027084

I want to find answers to the following questions:

  1. How to get a decimal value of difficulty (480045) by a hexadecimal value of a given target in hex (f3220000) ?

  2. How to get a hexadecimal value of target (f3220000) by a decimal value of a given difficulty (480045)?

My research led to the following formula: target = targetmax / diff when targetmax = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

I also found the something in the source of some pools here and here. They have a different logic and I can’t understand it anyway.

1 Answer 1

6
  1. How to get a decimal value of difficulty (480045) by a hexadecimal value of a given target in hex (f3220000) ?

Swap endian f3220000 and remove padding gets 22f3, then 0x100000001 / 0x22f3 yields: 480045.

  1. How to get a hexadecimal value of target (f3220000) by a decimal value of a given difficulty (480045)?

((2^256-1) / 480045) >> 224 is decimal 8947, hex 0x22f3. Swap endian and pad yields: f3220000.

The reason for both the division in #1 and shift in #2 is because we are exploiting the fact that we are working with only a 32 bit difficulty target. Thus, we are only concerning ourselves with the most significant 32 bits of a 256 bit number.

It's worth noting that this calculation is just legacy hangover of how the pools and miners were doing this when forked, which nobody felt strongly enough to improve upon. The current miner implementations foresaw this 32 bit limitation and do have code to handle larger targets [ref], though most pools do not, as can be seen by the pools you cite. In retrospect, it would probably be more sensible if the pools and miners calculated/checked difficulty more akin to how Monero does (i.e. if hash multiplied by difficulty doesn't overflow, it's good), as whilst this would mean passing around a slightly larger target in the stratum job message, it's more future-proof.

15
  • 1
    Max diff is 2^256-1 and we are only working with a 32 bit difficulty target. Hence >>224 is shifting out the bottom 224 bits from our division of the base diff to take only the top 32 bits.
    – jtgrassie
    Commented Feb 5, 2020 at 23:52
  • 1
    "Swap endian is not very obvious. Can you can add a little more detailed answer?" <- You want to know how to swap endian?
    – jtgrassie
    Commented Feb 5, 2020 at 23:55
  • 1
    Why someone decided to use BE byte order vs LE in the stratum message is really not relevant. It is in that byte order so you need to swap.
    – jtgrassie
    Commented Feb 6, 2020 at 0:43
  • 1
    You are just witnessing rounding at play. E.g.0x100000001 / 200000 = 21474.836485 is a float, and the reverse calc/truncation (with the shift), is using integers, thus you won't always get an exact match both ways.
    – jtgrassie
    Commented Apr 8, 2020 at 7:51
  • 2
    You can't convert mainnet current difficulty to stratum's 32 bits, it's too big. The current miner implementations, any hex string bigger than 4 bytes (8 chars) is treated directly as the target, no conversion. See the last paragraph of my answer.
    – jtgrassie
    Commented Apr 16, 2020 at 1:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.