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