Clean up + higher modular design

This commit is contained in:
Sergi Delgado Segura
2019-10-03 11:49:49 +01:00
parent 5ba6fcb9ef
commit 3e0cca14d7
2 changed files with 50 additions and 101 deletions

View File

@@ -1,13 +1,17 @@
from binascii import hexlify, unhexlify
from uuid import uuid4
from queue import Queue
from threading import Thread
from pisa import logging, bitcoin_cli
from pisa import logging
from pisa.responder import Responder
from pisa.conf import MAX_APPOINTMENTS
from pisa.block_processor import BlockProcessor
from pisa.cleaner import Cleaner
from pisa.utils.zmq_subscriber import ZMQHandler
from pisa.utils.auth_proxy import JSONRPCException
from hashlib import sha256
from uuid import uuid4
from pisa.conf import MAX_APPOINTMENTS, EXPIRY_DELTA
# WIP: MOVED BLOCKCHAIN RELATED TASKS TO BLOCK PROCESSOR IN AN AIM TO MAKE THE CODE MORE MODULAR. THIS SHOULD HELP
# WITH CODE REUSE WHEN MERGING THE DATA PERSISTENCE PART.
class Watcher:
@@ -72,29 +76,20 @@ class Watcher:
def do_watch(self):
while len(self.appointments) > 0:
block_hash = self.block_queue.get()
logging.info("[Watcher] new block received {}".format(block_hash))
try:
block = bitcoin_cli.getblock(block_hash)
block = BlockProcessor.getblock(block_hash)
if block is not None:
txids = block.get('tx')
logging.info("[Watcher] new block received {}".format(block_hash))
logging.info("[Watcher] list of transactions: {}".format(txids))
self.delete_expired_appointment(block)
self.appointments, self.locator_uuid_map = Cleaner.delete_expired_appointment(
block, self.appointments, self.locator_uuid_map)
potential_locators = {sha256(unhexlify(txid)).hexdigest(): txid for txid in txids}
# Check is any of the tx_ids in the received block is an actual match
# Get the locators that are both in the map and in the potential locators dict.
intersection = set(self.locator_uuid_map.keys()).intersection(potential_locators.keys())
potential_matches = {locator: potential_locators[locator] for locator in intersection}
if len(potential_matches) > 0:
logging.info("[Watcher] list of potential matches: {}".format(potential_matches))
else:
logging.info("[Watcher] no potential matches found")
matches = self.check_potential_matches(potential_matches)
potential_matches = BlockProcessor.get_potential_matches(txids, self.locator_uuid_map)
matches = BlockProcessor.get_matches(potential_matches, self.locator_uuid_map, self.appointments)
for locator, uuid, dispute_txid, justice_txid, justice_rawtx in matches:
logging.info("[Watcher] notifying responder about {} and deleting appointment {} (uuid: {})"
@@ -108,58 +103,15 @@ class Watcher:
# If there was only one appointment that matches the locator we can delete the whole list
if len(self.locator_uuid_map[locator]) == 1:
# ToDo: #9-add-data-persistency
# ToDo: #9-add-data-persistence
self.locator_uuid_map.pop(locator)
else:
# Otherwise we just delete the appointment that matches locator:appointment_pos
# ToDo: #9-add-data-persistency
# ToDo: #9-add-data-persistence
self.locator_uuid_map[locator].remove(uuid)
except JSONRPCException as e:
logging.error("[Watcher] couldn't get block from bitcoind. Error code {}".format(e))
# Go back to sleep if there are no more appointments
self.asleep = True
self.zmq_subscriber.terminate = True
logging.error("[Watcher] no more pending appointments, going back to sleep")
def delete_expired_appointment(self, block):
to_delete = [uuid for uuid, appointment in self.appointments.items() if block["height"] > appointment.end_time
+ EXPIRY_DELTA]
for uuid in to_delete:
# ToDo: #9-add-data-persistency
locator = self.appointments[uuid].locator
self.appointments.pop(uuid)
if len(self.locator_uuid_map[locator]) == 1:
self.locator_uuid_map.pop(locator)
else:
self.locator_uuid_map[locator].remove(uuid)
logging.info("[Watcher] end time reached with no match! Deleting appointment {} (uuid: {})".format(locator,
uuid))
def check_potential_matches(self, potential_matches):
matches = []
for locator, dispute_txid in potential_matches.items():
for uuid in self.locator_uuid_map[locator]:
try:
# ToDo: #20-test-tx-decrypting-edge-cases
justice_rawtx = self.appointments[uuid].encrypted_blob.decrypt(unhexlify(dispute_txid))
justice_rawtx = hexlify(justice_rawtx).decode()
justice_txid = bitcoin_cli.decoderawtransaction(justice_rawtx).get('txid')
matches.append((locator, uuid, dispute_txid, justice_txid, justice_rawtx))
logging.info("[Watcher] match found for locator {} (uuid: {}): {}".format(locator, uuid,
justice_txid))
except JSONRPCException as e:
# Tx decode failed returns error code -22, maybe we should be more strict here. Leaving it simple
# for the POC
logging.error("[Watcher] can't build transaction from decoded data. Error code {}".format(e))
return matches