Fixes and tests updates

Updates tests so they run with the db_manager and fixes some bugs introduced in d7d42c9.
This commit is contained in:
Sergi Delgado Segura
2019-10-26 14:13:58 -07:00
parent ee1f024c51
commit f61474216c
9 changed files with 39 additions and 23 deletions

View File

@@ -5,7 +5,6 @@ from binascii import hexlify
from pisa import HOST, PORT, logging from pisa import HOST, PORT, logging
from pisa.logger import Logger from pisa.logger import Logger
from pisa.watcher import Watcher
from pisa.inspector import Inspector from pisa.inspector import Inspector
from pisa.appointment import Appointment from pisa.appointment import Appointment
from pisa.block_processor import BlockProcessor from pisa.block_processor import BlockProcessor

View File

@@ -14,6 +14,7 @@ class Appointment:
self.encrypted_blob = EncryptedBlob(encrypted_blob) self.encrypted_blob = EncryptedBlob(encrypted_blob)
self.cipher = cipher self.cipher = cipher
self.hash_function = hash_function self.hash_function = hash_function
self.triggered = False
@classmethod @classmethod
def from_dict(cls, appointment_data): def from_dict(cls, appointment_data):

View File

@@ -44,5 +44,5 @@ class Cleaner:
tx_job_map[justice_txid].remove(uuid) tx_job_map[justice_txid].remove(uuid)
# Delete appointment from the db (both watchers's and responder's) # Delete appointment from the db (both watchers's and responder's)
db_manager.ddelete_watcher_appointment(uuid) db_manager.delete_watcher_appointment(uuid)
db_manager.delete_responder_job(uuid) db_manager.delete_responder_job(uuid)

View File

@@ -108,7 +108,7 @@ class Responder:
if confirmations == 0: if confirmations == 0:
self.unconfirmed_txs.append(justice_txid) self.unconfirmed_txs.append(justice_txid)
self.db_manager.store_responder_job(uuid.encode, job.to_json()) self.db_manager.store_responder_job(uuid, job.to_json())
logger.info("New job added.", dispute_txid=dispute_txid, justice_txid=justice_txid, logger.info("New job added.", dispute_txid=dispute_txid, justice_txid=justice_txid,
appointment_end=appointment_end) appointment_end=appointment_end)
@@ -151,7 +151,7 @@ class Responder:
completed_jobs = self.get_completed_jobs(height) completed_jobs = self.get_completed_jobs(height)
Cleaner.delete_completed_jobs(self.jobs, self.tx_job_map, completed_jobs, height, self.db_manager) Cleaner.delete_completed_jobs(self.jobs, self.tx_job_map, completed_jobs, height, self.db_manager)
self.rebroadcast(txs_to_rebroadcast) self.rebroadcast(txs_to_rebroadcast, block_hash)
# NOTCOVERED # NOTCOVERED
else: else:
@@ -199,7 +199,7 @@ class Responder:
return completed_jobs return completed_jobs
def rebroadcast(self, txs_to_rebroadcast): def rebroadcast(self, txs_to_rebroadcast, block_hash):
# DISCUSS: #22-discuss-confirmations-before-retry # DISCUSS: #22-discuss-confirmations-before-retry
# ToDo: #23-define-behaviour-approaching-end # ToDo: #23-define-behaviour-approaching-end
@@ -211,7 +211,7 @@ class Responder:
for uuid in self.tx_job_map[txid]: for uuid in self.tx_job_map[txid]:
job = self.jobs[uuid] job = self.jobs[uuid]
receipt = self.add_response(uuid, job.dispute_txid, job.justice_txid, job.justice_rawtx, receipt = self.add_response(uuid, job.dispute_txid, job.justice_txid, job.justice_rawtx,
job.appointment_end, retry=True) job.appointment_end, block_hash, retry=True)
logger.warning("Transaction has missed many confirmations. Rebroadcasting.", logger.warning("Transaction has missed many confirmations. Rebroadcasting.",
justice_txid=job.justice_txid, confirmations_missed=CONFIRMATIONS_BEFORE_RETRY) justice_txid=job.justice_txid, confirmations_missed=CONFIRMATIONS_BEFORE_RETRY)

View File

@@ -137,7 +137,7 @@ class Watcher:
# DISCUSS: instead of deleting the appointment, we will mark it as triggered and delete it from both # DISCUSS: instead of deleting the appointment, we will mark it as triggered and delete it from both
# the watcher's and responder's db after fulfilled # the watcher's and responder's db after fulfilled
# Update appointment in the db # Update appointment in the db
appointment["triggered"] = True appointment.triggered = True
self.db_manager.store_watcher_appointment(uuid, appointment.to_json()) self.db_manager.store_watcher_appointment(uuid, appointment.to_json())
# Register the last processed block for the watcher # Register the last processed block for the watcher

View File

@@ -4,7 +4,10 @@ import requests
from time import sleep from time import sleep
from threading import Thread from threading import Thread
from pisa.conf import DB_PATH
from pisa.api import start_api from pisa.api import start_api
from pisa.watcher import Watcher
from pisa.db_manager import DBManager
from test.simulator.bitcoind_sim import run_simulator, HOST, PORT from test.simulator.bitcoind_sim import run_simulator, HOST, PORT
@@ -20,7 +23,10 @@ def run_bitcoind():
@pytest.fixture(scope='session') @pytest.fixture(scope='session')
def run_api(): def run_api():
api_thread = Thread(target=start_api) db_manager = DBManager(DB_PATH)
watcher = Watcher(db_manager)
api_thread = Thread(target=start_api, args=[watcher])
api_thread.daemon = True api_thread.daemon = True
api_thread.start() api_thread.start()
@@ -33,6 +39,11 @@ def prng_seed():
random.seed(0) random.seed(0)
@pytest.fixture(scope='session')
def db_manager():
return DBManager('test_db')
def get_random_value_hex(nbytes): def get_random_value_hex(nbytes):
pseudo_random_value = random.getrandbits(8*nbytes) pseudo_random_value = random.getrandbits(8*nbytes)
prv_hex = '{:x}'.format(pseudo_random_value) prv_hex = '{:x}'.format(pseudo_random_value)

View File

@@ -1,5 +1,4 @@
import random import random
from os import urandom
from uuid import uuid4 from uuid import uuid4
from pisa import logging from pisa import logging
@@ -59,23 +58,26 @@ def set_up_jobs(total_jobs):
return jobs, tx_job_map return jobs, tx_job_map
def test_delete_expired_appointment(): def test_delete_expired_appointment(db_manager):
for _ in range(ITERATIONS): for _ in range(ITERATIONS):
appointments, locator_uuid_map = set_up_appointments(MAX_ITEMS) appointments, locator_uuid_map = set_up_appointments(MAX_ITEMS)
expired_appointments = random.sample(list(appointments.keys()), k=ITEMS) expired_appointments = random.sample(list(appointments.keys()), k=ITEMS)
Cleaner.delete_expired_appointment(expired_appointments, appointments, locator_uuid_map) Cleaner.delete_expired_appointment(expired_appointments, appointments, locator_uuid_map, db_manager)
assert not set(expired_appointments).issubset(appointments.keys()) assert not set(expired_appointments).issubset(appointments.keys())
def test_delete_completed_jobs(): def test_delete_completed_jobs(db_manager):
height = 0
for _ in range(ITERATIONS): for _ in range(ITERATIONS):
jobs, tx_job_map = set_up_jobs(MAX_ITEMS) jobs, tx_job_map = set_up_jobs(MAX_ITEMS)
selected_jobs = random.sample(list(jobs.keys()), k=ITEMS) selected_jobs = random.sample(list(jobs.keys()), k=ITEMS)
completed_jobs = [(job, 6) for job in selected_jobs] completed_jobs = [(job, 6) for job in selected_jobs]
Cleaner.delete_completed_jobs(jobs, tx_job_map, completed_jobs, 0) Cleaner.delete_completed_jobs(jobs, tx_job_map, completed_jobs, height, db_manager)
assert not set(completed_jobs).issubset(jobs.keys()) assert not set(completed_jobs).issubset(jobs.keys())

View File

@@ -15,8 +15,8 @@ from pisa.conf import BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def responder(): def responder(db_manager):
return Responder() return Responder(db_manager)
def create_dummy_job_data(random_txid=False, justice_rawtx=None): def create_dummy_job_data(random_txid=False, justice_rawtx=None):
@@ -94,7 +94,9 @@ def test_add_response(responder):
# setting the state to awake. # setting the state to awake.
responder.asleep = False responder.asleep = False
receipt = responder.add_response(uuid, job.dispute_txid, job.justice_txid, job.justice_rawtx, job.appointment_end) # The block_hash passed to add_response does not matter much now. It will in the future to deal with errors
receipt = responder.add_response(uuid, job.dispute_txid, job.justice_txid, job.justice_rawtx, job.appointment_end,
block_hash=get_random_value_hex(32))
assert receipt.delivered is True assert receipt.delivered is True
@@ -235,12 +237,12 @@ def test_get_txs_to_rebroadcast(responder):
assert txs_to_rebroadcast == list(txs_missing_too_many_conf.keys()) assert txs_to_rebroadcast == list(txs_missing_too_many_conf.keys())
def test_get_completed_jobs(): def test_get_completed_jobs(db_manager):
bitcoin_cli = AuthServiceProxy("http://%s:%s@%s:%d" % (BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT)) bitcoin_cli = AuthServiceProxy("http://%s:%s@%s:%d" % (BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT))
initial_height = bitcoin_cli.getblockcount() initial_height = bitcoin_cli.getblockcount()
# Let's use a fresh responder for this to make it easier to compare the results # Let's use a fresh responder for this to make it easier to compare the results
responder = Responder() responder = Responder(db_manager)
# A complete job is a job that has reached the appointment end with enough confirmations (> MIN_CONFIRMATIONS) # A complete job is a job that has reached the appointment end with enough confirmations (> MIN_CONFIRMATIONS)
# We'll create three type of transactions: end reached + enough conf, end reached + no enough conf, end not reached # We'll create three type of transactions: end reached + enough conf, end reached + no enough conf, end not reached
@@ -285,8 +287,8 @@ def test_get_completed_jobs():
assert set(completed_jobs_ids) == set(ended_jobs_keys) assert set(completed_jobs_ids) == set(ended_jobs_keys)
def test_rebroadcast(): def test_rebroadcast(db_manager):
responder = Responder() responder = Responder(db_manager)
responder.asleep = False responder.asleep = False
txs_to_rebroadcast = [] txs_to_rebroadcast = []
@@ -305,7 +307,8 @@ def test_rebroadcast():
if (i % 2) == 0: if (i % 2) == 0:
txs_to_rebroadcast.append(justice_txid) txs_to_rebroadcast.append(justice_txid)
receipts = responder.rebroadcast(txs_to_rebroadcast) # The block_hash passed to rebroadcast does not matter much now. It will in the future to deal with errors
receipts = responder.rebroadcast(txs_to_rebroadcast, get_random_value_hex(32))
# All txs should have been delivered and the missed confirmation reset # All txs should have been delivered and the missed confirmation reset
for txid, receipt in receipts: for txid, receipt in receipts:

View File

@@ -38,8 +38,8 @@ with open(PISA_SECRET_KEY, "r") as key_file:
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def watcher(): def watcher(db_manager):
return Watcher() return Watcher(db_manager)
def generate_dummy_appointment(): def generate_dummy_appointment():