electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit dcab22dcc7672de3a608584bcbf33ef2321431cb
parent 78488ebcbf98cc5bf537d67dcf7c26845c90c2f5
Author: SomberNight <somber.night@protonmail.com>
Date:   Sun, 16 Sep 2018 22:21:49 +0200

verifier: small clean-up

Diffstat:
Melectrum/synchronizer.py | 3+++
Melectrum/verifier.py | 34++++++++++++++++++++--------------
2 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/electrum/synchronizer.py b/electrum/synchronizer.py @@ -59,6 +59,9 @@ class Synchronizer(PrintError): self.add_queue = asyncio.Queue() self.status_queue = asyncio.Queue() + def diagnostic_name(self): + return '{}:{}'.format(self.__class__.__name__, self.wallet.diagnostic_name()) + def is_up_to_date(self): return (not self.requested_addrs and not self.requested_histories diff --git a/electrum/verifier.py b/electrum/verifier.py @@ -26,11 +26,12 @@ from typing import Sequence, Optional from aiorpcx import TaskGroup -from .util import ThreadJob, bh2u, VerifiedTxInfo +from .util import PrintError, bh2u, VerifiedTxInfo from .bitcoin import Hash, hash_decode, hash_encode from .transaction import Transaction from .blockchain import hash_header from .interface import GracefulDisconnect +from . import constants class MerkleVerificationFailure(Exception): pass @@ -39,7 +40,7 @@ class MerkleRootMismatch(MerkleVerificationFailure): pass class InnerNodeOfSpvProofIsValidTx(MerkleVerificationFailure): pass -class SPV(ThreadJob): +class SPV(PrintError): """ Simple Payment Verification """ def __init__(self, network, wallet): @@ -49,8 +50,12 @@ class SPV(ThreadJob): self.merkle_roots = {} # txid -> merkle root (once it has been verified) self.requested_merkle = set() # txid set of pending requests + def diagnostic_name(self): + return '{}:{}'.format(self.__class__.__name__, self.wallet.diagnostic_name()) + async def main(self, group: TaskGroup): while True: + await self._maybe_undo_verifications() await self._request_proofs(group) await asyncio.sleep(0.1) @@ -70,8 +75,7 @@ class SPV(ThreadJob): header = blockchain.read_header(tx_height) if header is None: - index = tx_height // 2016 - if index < len(blockchain.checkpoints): + if tx_height < constants.net.max_checkpoint(): await group.spawn(self.network.request_chunk(tx_height, None, can_return_early=True)) elif (tx_hash not in self.requested_merkle and tx_hash not in self.merkle_roots): @@ -79,10 +83,6 @@ class SPV(ThreadJob): self.requested_merkle.add(tx_hash) await group.spawn(self._request_and_verify_single_proof, tx_hash, tx_height) - if self.network.blockchain() != self.blockchain: - self.blockchain = self.network.blockchain() - self._undo_verifications() - async def _request_and_verify_single_proof(self, tx_hash, tx_height): merkle = await self.network.get_merkle_for_transaction(tx_hash, tx_height) # Verify the hash of the server-provided merkle branch to a @@ -139,12 +139,18 @@ class SPV(ThreadJob): else: raise InnerNodeOfSpvProofIsValidTx() - def _undo_verifications(self): - height = self.blockchain.get_forkpoint() - tx_hashes = self.wallet.undo_verifications(self.blockchain, height) - for tx_hash in tx_hashes: - self.print_error("redoing", tx_hash) - self.remove_spv_proof_for_tx(tx_hash) + async def _maybe_undo_verifications(self): + def undo_verifications(): + height = self.blockchain.get_forkpoint() + self.print_error("undoing verifications back to height {}".format(height)) + tx_hashes = self.wallet.undo_verifications(self.blockchain, height) + for tx_hash in tx_hashes: + self.print_error("redoing", tx_hash) + self.remove_spv_proof_for_tx(tx_hash) + + if self.network.blockchain() != self.blockchain: + self.blockchain = self.network.blockchain() + undo_verifications() def remove_spv_proof_for_tx(self, tx_hash): self.merkle_roots.pop(tx_hash, None)