tfix undo_verification - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit 0c6de8ff56f417f67fc935b292d20e4dd84fe5d5 DIR parent a4149bf6b80282f93d51f1c98f2e1376c2009576 HTML Author: ThomasV <thomasv@electrum.org> Date: Thu, 20 Jul 2017 06:38:49 +0200 fix undo_verification Diffstat: M lib/verifier.py | 15 ++++++++------- M lib/wallet.py | 13 ++++++++----- 2 files changed, 16 insertions(+), 12 deletions(-) --- DIR diff --git a/lib/verifier.py b/lib/verifier.py t@@ -34,6 +34,7 @@ class SPV(ThreadJob): def __init__(self, network, wallet): self.wallet = wallet self.network = network + self.blockchain = network.blockchain() # Keyed by tx hash. Value is None if the merkle branch was # requested, and the merkle root once it has been verified self.merkle_roots = {} t@@ -50,14 +51,16 @@ class SPV(ThreadJob): self.print_error('requested merkle', tx_hash) self.merkle_roots[tx_hash] = None + if self.network.blockchain() != self.blockchain: + self.blockchain = self.network.blockchain() + self.undo_verifications() + def verify_merkle(self, r): if r.get('error'): self.print_error('received an error:', r) return - params = r['params'] merkle = r['result'] - # Verify the hash of the server-provided merkle branch to a # transaction matches the merkle root of its block tx_hash = params[0] t@@ -70,13 +73,11 @@ class SPV(ThreadJob): # recover from this, as this TX will now never verify self.print_error("merkle verification failed for", tx_hash) return - # we passed all the tests self.merkle_roots[tx_hash] = merkle_root self.print_error("verified %s" % tx_hash) self.wallet.add_verified_tx(tx_hash, (tx_height, header.get('timestamp'), pos)) - def hash_merkle_root(self, merkle_s, target_hash, pos): h = hash_decode(target_hash) for i in range(len(merkle_s)): t@@ -84,9 +85,9 @@ class SPV(ThreadJob): h = Hash( hash_decode(item) + h ) if ((pos >> i) & 1) else Hash( h + hash_decode(item) ) return hash_encode(h) - - def undo_verifications(self, height): - tx_hashes = self.wallet.undo_verifications(height) + def undo_verifications(self): + height = self.blockchain.get_checkpoint() + tx_hashes = self.wallet.undo_verifications(self.blockchain, height) for tx_hash in tx_hashes: self.print_error("redoing", tx_hash) self.merkle_roots.pop(tx_hash, None) DIR diff --git a/lib/wallet.py b/lib/wallet.py t@@ -314,15 +314,18 @@ class Abstract_Wallet(PrintError): '''Returns a map from tx hash to transaction height''' return self.unverified_tx - def undo_verifications(self, height): + def undo_verifications(self, blockchain, height): '''Used by the verifier when a reorg has happened''' - txs = [] + txs = set() with self.lock: - for tx_hash, item in self.verified_tx: + for tx_hash, item in self.verified_tx.items(): tx_height, timestamp, pos = item if tx_height >= height: - self.verified_tx.pop(tx_hash, None) - txs.append(tx_hash) + header = blockchain.read_header(tx_height) + # fixme: use block hash, not timestamp + if not header or header.get('timestamp') != timestamp: + self.verified_tx.pop(tx_hash, None) + txs.add(tx_hash) return txs def get_local_height(self):