tl&dr for consensus-code only reviewers: the first commit splits CheckProofOfWorkImpl()
in order to create a DeriveTarget()
helper. The rest of this PR does not touch consensus code.
There are three ways to represent the proof-of-work in a block:
- nBits
- Difficulty
- Target
The latter notation is useful when you want to compare share work against either the pool target (to get paid) or network difficulty (found an actual block). E.g. for difficulty 1 which corresponds to an nBits value of 0x00ffff
:
0share hash: f6b973257df982284715b0c7a20640dad709d22b0b1a58f2f88d35886ea5ac45
1target: 7fffff0000000000000000000000000000000000000000000000000000000000
It’s immediately clear that the share is invalid because the hash is above the target.
This type of logging is mostly done by the pool software. It’s a nice extra convenience, but not very important. It impacts the following RPC calls:
gettarget
gives the target for the tip block, akin togetdifficulty
getmininginfo
displays thetarget
for the tip blockgetblock
andgetblockheader
display thetarget
for a specific block (ditto for their REST equivalents)
The gettarget
and getdifficulty
methods are a bit useless in their current state, because what miners really want to know if the target / difficulty for the next block. So I added a boolean argument next
to getdifficulty
and gettarget
. (These values are typically the same, except for the first block in a retarget period. On testnet3 / testnet4 they change when no block is found after 20 minutes).
Similarly I added a next
object to getmininginfo
which shows bit
, difficulty
and target
for the next block.
In order to test the difficulty transition, an alternate mainnet chain with 2016 blocks was generated and used in mining_mainnet.py
. The chain is deterministic except for its timestamp and nonce values, which are stored in mainnet_alt.json
.
As described at the top, this PR introduces a helper method DeriveTarget()
which is split out from CheckProofOfWorkImpl
. The proposed checkblock
RPC in #31564 needs this helper method internally to figure out the consensus target.
Finally, this PR moves pow.cpp
and chain.cpp
from bitcoin_node
to bitcoin_common
, in order to give rpc/util.cpp
(which lives in bitcoin_common
) access to pow.h
.