commit cf84068fdb0bcdf92bc6946fd6990bd3fd9da722
parent 8834ed9714f207bec41e4f8fa7ae26ff25a1c1f6
Author: ThomasV <thomasv@electrum.org>
Date: Sat, 15 Jul 2017 13:51:40 +0200
blockchain fixes
Diffstat:
2 files changed, 31 insertions(+), 16 deletions(-)
diff --git a/lib/blockchain.py b/lib/blockchain.py
@@ -65,19 +65,27 @@ class Blockchain(util.PrintError):
'''Manages blockchain headers and their verification'''
- def __init__(self, config, filename, fork_point):
+ def __init__(self, config, filename):
self.config = config
self.filename = filename
self.catch_up = None # interface catching up
- if fork_point is None:
- self.is_saved = True
- self.checkpoint = int(filename[16:]) if filename.startswith('blockchain_fork_') else 0
- else:
- self.is_saved = False
- self.checkpoint = fork_point
+ self.is_saved = True
+ self.checkpoint = int(filename[16:]) if filename.startswith('blockchain_fork_') else 0
self.headers = []
self.set_local_height()
+ def fork(parent, fork_point):
+ self = Blockchain(parent.config, parent.filename)
+ self.is_saved = False
+ if parent.is_saved:
+ self.checkpoint = fork_point
+ else:
+ if fork_point > parent.checkpoint:
+ self.headers = parent.headers[0: fork_point - parent.checkpoint]
+ else:
+ self.headers = []
+ return self
+
def height(self):
if self.headers:
return self.checkpoint + len(self.headers) - 1
@@ -122,7 +130,7 @@ class Blockchain(util.PrintError):
def save_chunk(self, index, chunk):
if not self.is_saved:
- self.fork_and_save()
+ self.save()
filename = self.path()
with open(filename, 'rb+') as f:
f.seek(index * 2016 * 80)
@@ -130,7 +138,7 @@ class Blockchain(util.PrintError):
h = f.write(chunk)
self.set_local_height()
- def fork_and_save(self):
+ def save(self):
import shutil
self.print_error("save fork")
height = self.checkpoint
@@ -152,7 +160,7 @@ class Blockchain(util.PrintError):
assert height == self.checkpoint + len(self.headers)
self.headers.append(header)
if len(self.headers) > 10:
- self.fork_and_save()
+ self.save()
return
self.write_header(header)
diff --git a/lib/network.py b/lib/network.py
@@ -206,10 +206,10 @@ class Network(util.DaemonThread):
util.DaemonThread.__init__(self)
self.config = SimpleConfig(config) if type(config) == type({}) else config
self.num_server = 10 if not self.config.get('oneserver') else 0
- self.blockchains = { 0:Blockchain(self.config, 'blockchain_headers', None) }
+ self.blockchains = { 0:Blockchain(self.config, 'blockchain_headers') }
for x in os.listdir(self.config.path):
if x.startswith('blockchain_fork_'):
- b = Blockchain(self.config, x, None)
+ b = Blockchain(self.config, x)
self.blockchains[b.checkpoint] = b
self.print_error("blockchains", self.blockchains.keys())
self.blockchain_index = config.get('blockchain_index', 0)
@@ -864,12 +864,17 @@ class Network(util.DaemonThread):
next_height = (interface.bad + interface.good) // 2
else:
interface.print_error("can connect at %d"% interface.good)
- interface.blockchain = Blockchain(self.config, interface.blockchain.filename, interface.good)
- interface.blockchain.catch_up = interface.server
- self.blockchains[interface.good] = interface.blockchain
- interface.print_error("catching up with new chain")
+ b = self.blockchains.get(interface.good)
+ if b is None:
+ b = interface.blockchain.fork(interface.good)
+ b.catch_up = interface.server
+ interface.print_error("catching up with new chain")
+ self.blockchains[interface.good] = b
interface.mode = 'catch_up'
next_height = interface.good
+ interface.blockchain = b
+ # todo: garbage collect blockchain objects
+ self.notify('updated')
elif interface.mode == 'catch_up':
if can_connect:
@@ -906,6 +911,8 @@ class Network(util.DaemonThread):
self.request_chunk(interface, next_height // 2016)
else:
self.request_header(interface, next_height)
+ # refresh network dialog
+ self.notify('interfaces')
def maintain_requests(self):
for interface in self.interfaces.values():