|
|
@ -50,7 +50,11 @@ class Blockchain(util.PrintError): |
|
|
|
self.print_error("prev hash mismatch: %s vs %s" |
|
|
|
% (prev_hash, header.get('prev_block_hash'))) |
|
|
|
return False |
|
|
|
try: |
|
|
|
bits, target = self.get_target(height/2016, chain) |
|
|
|
except AssertionError as e: |
|
|
|
self.print_error("target calculation error: %s" % (str(e))) |
|
|
|
return False |
|
|
|
if bits != header.get('bits'): |
|
|
|
self.print_error("bits mismatch: %s vs %s" |
|
|
|
% (bits, header.get('bits'))) |
|
|
@ -88,7 +92,7 @@ class Blockchain(util.PrintError): |
|
|
|
_hash = self.hash_header(header) |
|
|
|
assert previous_hash == header.get('prev_block_hash') |
|
|
|
assert bits == header.get('bits') |
|
|
|
assert int('0x'+_hash,16) < target |
|
|
|
assert int('0x'+_hash,16) <= target |
|
|
|
|
|
|
|
previous_header = header |
|
|
|
previous_hash = _hash |
|
|
@ -190,36 +194,33 @@ class Blockchain(util.PrintError): |
|
|
|
if h.get('block_height') == index*2016-1: |
|
|
|
last = h |
|
|
|
|
|
|
|
# bits to target |
|
|
|
bits = last.get('bits') |
|
|
|
bitsN = (bits >> 24) & 0xff |
|
|
|
assert bitsN >= 0x03 and bitsN <= 0x1d, "First part of bits should be in [0x03, 0x1d]" |
|
|
|
bitsBase = bits & 0xffffff |
|
|
|
assert bitsN >= 0x8000 and bitsN <= 0x7fffff, "Second part of bits should be in [0x8000, 0x7fffff]" |
|
|
|
target = bitsBase << (8*(bitsN-3)) |
|
|
|
|
|
|
|
# new target |
|
|
|
nActualTimespan = last.get('timestamp') - first.get('timestamp') |
|
|
|
nTargetTimespan = 14*24*60*60 |
|
|
|
nActualTimespan = max(nActualTimespan, nTargetTimespan/4) |
|
|
|
nActualTimespan = min(nActualTimespan, nTargetTimespan*4) |
|
|
|
new_target = min(max_target, (target * nActualTimespan)/nTargetTimespan) |
|
|
|
|
|
|
|
bits = last.get('bits') |
|
|
|
# convert to bignum |
|
|
|
MM = 256*256*256 |
|
|
|
a = bits%MM |
|
|
|
if a < 0x8000: |
|
|
|
a *= 256 |
|
|
|
target = (a) * pow(2, 8 * (bits/MM - 3)) |
|
|
|
|
|
|
|
# new target |
|
|
|
new_target = min( max_target, (target * nActualTimespan)/nTargetTimespan ) |
|
|
|
|
|
|
|
# convert it to bits |
|
|
|
c = ("%064X"%new_target)[2:] |
|
|
|
i = 31 |
|
|
|
while c[0:2]=="00": |
|
|
|
# convert new target to bits |
|
|
|
c = ("%064x" % new_target)[2:] |
|
|
|
while c[:2] == '00' and len(c) > 6: |
|
|
|
c = c[2:] |
|
|
|
i -= 1 |
|
|
|
|
|
|
|
c = int('0x'+c[0:6],16) |
|
|
|
if c >= 0x800000: |
|
|
|
c /= 256 |
|
|
|
i += 1 |
|
|
|
bitsN, bitsBase = len(c)/2, int('0x'+c[:6], 16) |
|
|
|
if bitsBase >= 0x800000: |
|
|
|
bitsN += 1 |
|
|
|
bitsBase >>= 8 |
|
|
|
|
|
|
|
new_bits = c + MM * i |
|
|
|
return new_bits, new_target |
|
|
|
new_bits = bitsN << 24 | bitsBase |
|
|
|
return new_bits, bitsBase << (8*(bitsN-3)) |
|
|
|
|
|
|
|
def connect_header(self, chain, header): |
|
|
|
'''Builds a header chain until it connects. Returns True if it has |
|
|
|