Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: makinahmet on April 13, 2021, 07:48:49 PM



Title: Pool difficulty for compare wtih blockheader ??
Post by: makinahmet on April 13, 2021, 07:48:49 PM
Hi.

i am writing a little program for bitcoin mining.The program uses stratum servers protocol (Pool protocol). Actually i understand the basics from slush pools stratum V1 page. What i dont understand is how to use the difficulty that pool sends us. For example they send "65536" for setting the difficulty. I searched a alot internet and people says  "target difficulty  = 1 / pool difficulty". So, for 65536 target difficulty is 1/65536 = 0,0000152587890625 and as i understand i need to compare this walue with blockheader hash. So for comparing, will i count the zeros in the target difficulty that we found? or i misunderstand something?

Than you for kind answers

Best regards,
Makinahmet.


Title: Re: Pool difficulty for compare wtih blockheader ??
Post by: NotATether on April 14, 2021, 06:28:17 AM
The difficulty is represented as a 32-bit hex number (so if your difficulty is in decimal the convert it to hex first), which is converted into a 256-bit target like this:

<lower 24 bits> * 2**(8*(<upper 8 bits> - 3)) (Bitcoin Wiki (https://en.bitcoin.it/wiki/Difficulty))

The high 8 bits are an exponent that is itself magnified in the above expression to move the lower 24 bits several places to the left. So the target is actually the lower 24 hex bits moved somewhere higher up.

This 256-bit target can be directly compared with any SHA256 result using less-than.


Title: Re: Pool difficulty for compare wtih blockheader ??
Post by: odolvlobo on April 14, 2021, 03:16:21 PM
The difficulty value is only used by people. The target hash is what is used by the protocol for comparison. So rather than comparing to 1/65536 of the difficulty, you compare it to bitcoin target hash * pool max share difficulty / 65536.

Also, you don't count zeroes. You do an arithmetic comparison. The candidate must be less than or equal to the pool target in order to be accepted.


Title: Re: Pool difficulty for compare wtih blockheader ??
Post by: makinahmet on April 14, 2021, 09:40:44 PM
Thank you for explanations. What i understand is i need to study base arithmetics and number systems  :D :D


Title: Re: Pool difficulty for compare wtih blockheader ??
Post by: NotATether on April 15, 2021, 06:50:01 AM
Thank you for explanations. What i understand is i need to study base arithmetics and number systems  :D :D

It's not very difficult to understand actually. The difficulty-to-target conversion formula can also be done in decimal using double-precision numbers (because 256-bit arithmetic is too big for the integer types but they comfortably fit in a C++ double).

Then you can use a method to convert it into a hexadecimal string, not just the ones that cast a double into a 64-but int, you'd use something like this: https://gregstoll.com/~gregstoll/floattohex/ (no code but it's an interactive widget)  to understand how the double is represented.

The alternative is building your own 256-bit Int class which is kinda hard to do. I tried that myself.


Title: Re: Pool difficulty for compare wtih blockheader ??
Post by: pooya87 on April 15, 2021, 07:25:09 AM
Thank you for explanations. What i understand is i need to study base arithmetics and number systems  :D :D

It's not very difficult to understand actually. The difficulty-to-target conversion formula can also be done in decimal using double-precision numbers (because 256-bit arithmetic is too big for the integer types but they comfortably fit in a C++ double).

Then you can use a method to convert it into a hexadecimal string, not just the ones that cast a double into a 64-but int, you'd use something like this: https://gregstoll.com/~gregstoll/floattohex/ (no code but it's an interactive widget)  to understand how the double is represented.

The alternative is building your own 256-bit Int class which is kinda hard to do. I tried that myself.
It is not hard at all to build a 256-bit int class, in bitcoin we are already doing a lot of 256 bit arithmetic from (on topic) difficulty computation and validation for each block header to all the ECDSA signature generation and validation. You basically have to understand how basic math works (which I'm sure you already do) with small integers (like in base 10 where you perform the operation like add on each digit and carry the extra values to next step) then convert that knowledge to 256 bit arithmetic but instead of having each digit being from 0 to 9 (in base 10) you have the values from 0 to 0xffffffff and do your arithmetic operation in base 2^64.

Handbook of Applied Cryptography has a good chapter on this. See Chapter 14: Efficient Implementation


Title: Re: Pool difficulty for compare wtih blockheader ??
Post by: makinahmet on April 15, 2021, 07:28:16 PM
Actually i am writing in c# and i am just a mechanical engineer and trying to understand base things. i am weak about bits and bytes and i am learning it. Ok than;
 
1.Pool difficulty is 65536 -> 32 bit integer value?? (so the target is : 0,0000152587890625) ?
2.Founded hash is : 85cdec00a2626745c0b524b1f87f041a05bd4cb8885a9e209d06ebe0620ce9cb -> 256 bit hexadecimal number ??

How will you compare this two value ??


Title: Re: Pool difficulty for compare wtih blockheader ??
Post by: pooya87 on April 16, 2021, 03:15:22 AM
1.Pool difficulty is 65536 -> 32 bit integer value?? (so the target is : 0,0000152587890625) ?
2.Founded hash is : 85cdec00a2626745c0b524b1f87f041a05bd4cb8885a9e209d06ebe0620ce9cb -> 256 bit hexadecimal number ??
You compare it with "target" not with difficulty. The target value is already found inside the block header you would hash as a 32 bit integer.
First you take the first 23 bits from the target (target & 0x007fffff) then you compute the 256 bit integer value of that target by computing masked_value * 2^(8*(last_8bits - 3))
For example
Code:
0x1b0404cb
turns into:
00000000000404CB000000000000000000000000000000000000000000000000
or as integer
1653206561150525499452195696179626311675293455763937233695932416

Then you have to convert the block header hash to a 256-bit integer using the little endian notation.
Code:
85cdec00a2626745c0b524b1f87f041a05bd4cb8885a9e209d06ebe0620ce9cb 
turns into
60521441339092913078694912492755153710004602299172835061887865089033946065355

Now you compare the two integers (6052.... <= 16532...) if the comparison returns true then it is a valid hash and the block can be published otherwise it is rejected.
In c# you can use System.Numerics.BigInteger class


Title: Re: Pool difficulty for compare wtih blockheader ??
Post by: makinahmet on April 16, 2021, 09:33:28 PM
So what i have done here is true?

Code:

        public static bool FinalCompare(byte[] hash, byte[] target)
        {
            for (int i = hash.Length - 1; i >= 0; i--)
            {
                if ((hash[i] & 0xff) > (target[i] & 0xff))
                    return false;
                if ((hash[i] & 0xff) < (target[i] & 0xff))
                    return true;
            }
            return false;
        }



Title: Re: Pool difficulty for compare wtih blockheader ??
Post by: odolvlobo on April 17, 2021, 01:23:25 AM
So what i have done here is true?

Code:
        public static bool FinalCompare(byte[] hash, byte[] target)
        {
            for (int i = hash.Length - 1; i >= 0; i--)
            {
                if ((hash[i] & 0xff) > (target[i] & 0xff))
                    return false;
                if ((hash[i] & 0xff) < (target[i] & 0xff))
                    return true;
            }
            return false;
        }

That  should work except that the equal case should return true instead of false. The hash is treated as a little-endian number and you have accounted for that as long as the target is a little-endian number.

When it comes to pools, there is some terminology overlap -- there are Bitcoin difficulty and Bitcoin target, and share difficulty and share target.
For most pools, the share difficulty is assigned to you or you choose it. Then you must divide the bitcoin target by the pool's max share difficulty and then multiply it your share difficulty to get your share target. Your submit a hash when it is less than your share target.