Browse Source

verifier: small clean-up

master
SomberNight 7 years ago
parent
commit
dcab22dcc7
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
  1. 3
      electrum/synchronizer.py
  2. 34
      electrum/verifier.py

3
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

34
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)

Loading…
Cancel
Save