fix blockchain headers/checkpoints code
This commit is contained in:
parent
cf2eabb0c0
commit
fcc7de66cd
|
@ -39,6 +39,8 @@ POW_MAX_ADJUST_UP = 16
|
||||||
POW_DAMPING_FACTOR = 4
|
POW_DAMPING_FACTOR = 4
|
||||||
POW_TARGET_SPACING = 150
|
POW_TARGET_SPACING = 150
|
||||||
|
|
||||||
|
TARGET_CALC_BLOCKS = POW_AVERAGING_WINDOW + POW_MEDIAN_BLOCK_SPAN
|
||||||
|
|
||||||
AVERAGING_WINDOW_TIMESPAN = POW_AVERAGING_WINDOW * POW_TARGET_SPACING
|
AVERAGING_WINDOW_TIMESPAN = POW_AVERAGING_WINDOW * POW_TARGET_SPACING
|
||||||
|
|
||||||
MIN_ACTUAL_TIMESPAN = AVERAGING_WINDOW_TIMESPAN * \
|
MIN_ACTUAL_TIMESPAN = AVERAGING_WINDOW_TIMESPAN * \
|
||||||
|
@ -302,18 +304,14 @@ class Blockchain(util.PrintError):
|
||||||
return deserialize_header(h, height)
|
return deserialize_header(h, height)
|
||||||
|
|
||||||
def get_hash(self, height):
|
def get_hash(self, height):
|
||||||
len_checkpoints = len(self.checkpoints)
|
|
||||||
if height == -1:
|
if height == -1:
|
||||||
return '0000000000000000000000000000000000000000000000000000000000000000'
|
return '0000000000000000000000000000000000000000000000000000000000000000'
|
||||||
elif height == 0:
|
elif height == 0:
|
||||||
return constants.net.GENESIS
|
return constants.net.GENESIS
|
||||||
elif height < len_checkpoints * CHUNK_LEN - POW_AVERAGING_WINDOW:
|
elif height < len(self.checkpoints) * CHUNK_LEN - TARGET_CALC_BLOCKS:
|
||||||
assert (height+1) % CHUNK_LEN == 0, height
|
assert (height+1) % CHUNK_LEN == 0, height
|
||||||
index = height // CHUNK_LEN
|
index = height // CHUNK_LEN
|
||||||
if index < len_checkpoints - 1:
|
h, t, extra_headers = self.checkpoints[index]
|
||||||
h, t = self.checkpoints[index]
|
|
||||||
else:
|
|
||||||
h, t, extra_headers = self.checkpoints[index]
|
|
||||||
return h
|
return h
|
||||||
else:
|
else:
|
||||||
return hash_header(self.read_header(height))
|
return hash_header(self.read_header(height))
|
||||||
|
@ -334,7 +332,8 @@ class Blockchain(util.PrintError):
|
||||||
if not header and not chunk_empty \
|
if not header and not chunk_empty \
|
||||||
and min_height <= h <= max_height:
|
and min_height <= h <= max_height:
|
||||||
header = chunk_headers[h]
|
header = chunk_headers[h]
|
||||||
assert header and header.get('block_height') == h
|
if not header:
|
||||||
|
raise Exception("Can not read header at height %s" % h)
|
||||||
median.append(header.get('timestamp'))
|
median.append(header.get('timestamp'))
|
||||||
|
|
||||||
median.sort()
|
median.sort()
|
||||||
|
@ -359,7 +358,8 @@ class Blockchain(util.PrintError):
|
||||||
if not header and not chunk_empty \
|
if not header and not chunk_empty \
|
||||||
and min_height <= h <= max_height:
|
and min_height <= h <= max_height:
|
||||||
header = chunk_headers[h]
|
header = chunk_headers[h]
|
||||||
assert header and header.get('block_height') == h
|
if not header:
|
||||||
|
raise Exception("Can not read header at height %s" % h)
|
||||||
mean_target += self.bits_to_target(header.get('bits'))
|
mean_target += self.bits_to_target(header.get('bits'))
|
||||||
mean_target //= POW_AVERAGING_WINDOW
|
mean_target //= POW_AVERAGING_WINDOW
|
||||||
|
|
||||||
|
@ -442,20 +442,17 @@ class Blockchain(util.PrintError):
|
||||||
target = self.get_target(height)
|
target = self.get_target(height)
|
||||||
if len(h.strip('0')) == 0:
|
if len(h.strip('0')) == 0:
|
||||||
raise Exception('%s file has not enough data.' % self.path())
|
raise Exception('%s file has not enough data.' % self.path())
|
||||||
if index < n - 1:
|
extra_headers = []
|
||||||
cp.append((h, target))
|
if os.path.exists(self.path()):
|
||||||
else:
|
with open(self.path(), 'rb') as f:
|
||||||
dgw3_headers = []
|
lower_header = height - TARGET_CALC_BLOCKS
|
||||||
if os.path.exists(self.path()):
|
for height in range(height, lower_header-1, -1):
|
||||||
with open(self.path(), 'rb') as f:
|
f.seek(height*HDR_LEN)
|
||||||
lower_header = height - POW_AVERAGING_WINDOW
|
hd = f.read(HDR_LEN)
|
||||||
for height in range(height, lower_header-1, -1):
|
if len(hd) < HDR_LEN:
|
||||||
f.seek(height*80)
|
raise Exception(
|
||||||
hd = f.read(80)
|
'Expected to read a full header.'
|
||||||
if len(hd) < 80:
|
' This was only {} bytes'.format(len(hd)))
|
||||||
raise Exception(
|
extra_headers.append((height, bh2u(hd)))
|
||||||
'Expected to read a full header.'
|
cp.append((h, target, extra_headers))
|
||||||
' This was only {} bytes'.format(len(hd)))
|
|
||||||
dgw3_headers.append((height, bh2u(hd)))
|
|
||||||
cp.append((h, target, dgw3_headers))
|
|
||||||
return cp
|
return cp
|
||||||
|
|
14032
lib/checkpoints.json
14032
lib/checkpoints.json
File diff suppressed because it is too large
Load Diff
|
@ -984,14 +984,15 @@ class Network(util.DaemonThread):
|
||||||
def init_headers_file(self):
|
def init_headers_file(self):
|
||||||
b = self.blockchains[0]
|
b = self.blockchains[0]
|
||||||
filename = b.path()
|
filename = b.path()
|
||||||
length = HDR_LEN * len(constants.net.CHECKPOINTS) * CHUNK_LEN
|
len_checkpoints = len(constants.net.CHECKPOINTS)
|
||||||
|
length = HDR_LEN * len_checkpoints * CHUNK_LEN
|
||||||
if not os.path.exists(filename) or os.path.getsize(filename) < length:
|
if not os.path.exists(filename) or os.path.getsize(filename) < length:
|
||||||
with open(filename, 'wb') as f:
|
with open(filename, 'wb') as f:
|
||||||
if length > 0:
|
for i in range(len_checkpoints):
|
||||||
for height, hd in b.checkpoints[-1][2]:
|
for height, header_data in b.checkpoints[i][2]:
|
||||||
f.seek(height*80)
|
f.seek(height*HDR_LEN)
|
||||||
bd = bfh(hd)
|
bin_header = bfh(header_data)
|
||||||
f.write(bd)
|
f.write(bin_header)
|
||||||
with b.lock:
|
with b.lock:
|
||||||
b.update_size()
|
b.update_size()
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
from .util import ThreadJob
|
from .util import ThreadJob
|
||||||
from .bitcoin import *
|
from .bitcoin import *
|
||||||
|
from .blockchain import CHUNK_LEN
|
||||||
|
|
||||||
|
|
||||||
class SPV(ThreadJob):
|
class SPV(ThreadJob):
|
||||||
|
@ -49,7 +50,7 @@ class SPV(ThreadJob):
|
||||||
if (tx_height > 0) and (tx_height <= lh):
|
if (tx_height > 0) and (tx_height <= lh):
|
||||||
header = blockchain.read_header(tx_height)
|
header = blockchain.read_header(tx_height)
|
||||||
if header is None:
|
if header is None:
|
||||||
index = tx_height // 2016
|
index = tx_height // CHUNK_LEN
|
||||||
if index < len(blockchain.checkpoints):
|
if index < len(blockchain.checkpoints):
|
||||||
self.network.request_chunk(interface, index)
|
self.network.request_chunk(interface, index)
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in New Issue