blockchain: fix difficulty retarget

"target" is a 256 bit int, but the "bits" field in the block headers
that is used to represent target is only 32 bits.
We were checking PoW against the untruncated target value, which is a
slightly larger value than the one that can actually be represented,
and hence we would have accepted a slightly lower difficulty chain
than what the consensus requires.
This commit is contained in:
SomberNight 2018-11-22 16:52:51 +01:00
parent 55963bd092
commit a8e6eaa247
No known key found for this signature in database
GPG key ID: B33B5F232C6271E9
2 changed files with 253 additions and 251 deletions

View file

@ -367,6 +367,8 @@ class Blockchain(util.PrintError):
nActualTimespan = max(nActualTimespan, nTargetTimespan // 4) nActualTimespan = max(nActualTimespan, nTargetTimespan // 4)
nActualTimespan = min(nActualTimespan, nTargetTimespan * 4) nActualTimespan = min(nActualTimespan, nTargetTimespan * 4)
new_target = min(MAX_TARGET, (target * nActualTimespan) // nTargetTimespan) new_target = min(MAX_TARGET, (target * nActualTimespan) // nTargetTimespan)
# not any target can be represented in 32 bits:
new_target = self.bits_to_target(self.target_to_bits(new_target))
return new_target return new_target
def bits_to_target(self, bits: int) -> int: def bits_to_target(self, bits: int) -> int:

File diff suppressed because it is too large Load diff