I was wondering what the mining difficulty epoch does so I decided to study it and write this guide when I finished. It's going to describe every important detail about mining difficulty and how it's determined.
The
target is a 256-bit integer known across the bitcoin network. For blocks to be accepted into the blockchain, their SHA256d (equal to SHA256(SHA256(x)) for a value x) hash must be less than the target. As the target decreases, mining becomes more difficult.
The target is stored in a floating-point number with a special precision to save space. You may know about single-precision and double-precision floating-point numbers which have different exponent/mantissa fields (it's not crucial if you don't know what these words are.) The target has an 8-bit exponent and then a 24-bit mantissa. The first three bits of the exponent are left at zero, and it has a base of 256 instead of 2.
0x1b0404cb is an example of a target, the mantissa is 0x0404cb and the exponent is 0x1b. It can be expanded into 256-bit format to do the division in the difficulty calculation below, using the formula
mantissa * 2**(8*(exponent - 3)). For the example target it expands to
0x00000000000404CB000000000000000000000000000000000000000000000000, it pushed the mantissa in front of
8/4 * (0x1b - 3) = 48 zeroes (4 is number of bits in a hex character).
You must be wondering why two forms of the target are needed. The answer is one is the compressed form of the other. The compressed form is stored in the blocks.
An
epoch is equal to 2016 blocks. After every 2016 blocks that are added, the difficulty changes. It's calculated using the below formula:
difficulty = difficulty_1_target / current_target
(target is a 256 bit number)
difficulty_1_target is sort of measurement unit for difficulty, it's a 256-number with the leading 32-bits zero and its value is usually
0x00000000FFFF0000000000000000000000000000000000000000000000000000, although there is another difficulty_1_target that produces a different difficulty metric (see below).
current_target is the target variable I described earlier, and as I said it's known across the entire network.
The difficulty that's calculated with the above difficulty_1_target value is called
bdiff,
block
difficulty. The other difficulty type uses a difficulty_1_target with the trailing zeros replaced with binary 1s (F), and its calue is
0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF. The difficulty calculated with this value is called
pdiff, short for
pool
difficulty. pdiff is used insted of bdiff by ASIC miners and most mining pools. The numerical difference between bdiff and pdiff is negligible.
For the example target above the bdiff and pdiff would be
0x00000000FFFF0000000000000000000000000000000000000000000000000000 /
0x00000000000404CB000000000000000000000000000000000000000000000000
= 16307.420938523983 (bdiff)
0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF /
0x00000000000404CB000000000000000000000000000000000000000000000000
= 16307.669773817162 (pdiff)
The highest target, which represents the lowest difficulty (1) is 0x1d00ffff. It's the compressed form of the difficulty_1_target for bdiff above, and the reason if has 4 F's instead of 6 is because of the leading 32-bit zero requirement. Remember that higher targets let blocks with larger hashes through so the maximum target will let blocks with any hash size through.
There is no lowest target defined in the bitcoin codebase.
Target AdjustmentThe target, and hence difficulty, is changed roughly every epoch (2016 blocks mined) which is
a variable amount of time, In a perfect scenario the blocks would be mined every 10 minutes which would make 2 week epoches. In practice blocks aren't perfectly mined every 10 minutes because of the random amount of time of finding a valid Proof of Work in order to create a block. If it took longer than 2 weeks to complete the epoch then the network adjusts the target up (difficulty
down). If on the contrary it took shorter than 2 weeks to complete the epoch then the target is adjusted down (difficulty
up).
It's important to note that the difficulty is
NOT changed every 2 weeks, that is merely the ideal epoch completion time if blocks were mined every 10 minutes.
You can use this site
https://diff.cryptothis.com/ to check how close we are to finishing an epoch. This page
https://blockexplorer.com/api/status?q=getDifficulty from the Block Explorer API fetches the current difficulty, and I'm not sure whether it returns bdiff or pdiff.