tblockchain fixes - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit cf84068fdb0bcdf92bc6946fd6990bd3fd9da722 DIR parent 8834ed9714f207bec41e4f8fa7ae26ff25a1c1f6 HTML Author: ThomasV <thomasv@electrum.org> Date: Sat, 15 Jul 2017 13:51:40 +0200 blockchain fixes Diffstat: M lib/blockchain.py | 28 ++++++++++++++++++---------- M lib/network.py | 19 +++++++++++++------ 2 files changed, 31 insertions(+), 16 deletions(-) --- DIR diff --git a/lib/blockchain.py b/lib/blockchain.py t@@ -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 t@@ -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) t@@ -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 t@@ -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) DIR diff --git a/lib/network.py b/lib/network.py t@@ -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) t@@ -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: t@@ -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():