Replaces locator with common/constants value

This commit is contained in:
Sergi Delgado Segura
2019-12-05 11:03:36 +01:00
parent ac912aea69
commit bd08b151df
5 changed files with 72 additions and 36 deletions

View File

@@ -15,28 +15,26 @@ logger = Logger("Responder")
class Job: class Job:
def __init__(self, dispute_txid, justice_txid, justice_rawtx, appointment_end): def __init__(self, locator, dispute_txid, justice_txid, justice_rawtx, appointment_end):
self.locator = locator
self.dispute_txid = dispute_txid self.dispute_txid = dispute_txid
self.justice_txid = justice_txid self.justice_txid = justice_txid
self.justice_rawtx = justice_rawtx self.justice_rawtx = justice_rawtx
self.appointment_end = appointment_end self.appointment_end = appointment_end
# FIXME: locator is here so we can give info about jobs for now. It can be either passed from watcher or info
# can be directly got from DB
self.locator = dispute_txid[:32]
@classmethod @classmethod
def from_dict(cls, job_data): def from_dict(cls, job_data):
locator = job_data.get("locator")
dispute_txid = job_data.get("dispute_txid") dispute_txid = job_data.get("dispute_txid")
justice_txid = job_data.get("justice_txid") justice_txid = job_data.get("justice_txid")
justice_rawtx = job_data.get("justice_rawtx") justice_rawtx = job_data.get("justice_rawtx")
appointment_end = job_data.get("appointment_end") appointment_end = job_data.get("appointment_end")
if any(v is None for v in [dispute_txid, justice_txid, justice_rawtx, appointment_end]): if any(v is None for v in [locator, dispute_txid, justice_txid, justice_rawtx, appointment_end]):
raise ValueError("Wrong job data, some fields are missing") raise ValueError("Wrong job data, some fields are missing")
else: else:
job = cls(dispute_txid, justice_txid, justice_rawtx, appointment_end) job = cls(locator, dispute_txid, justice_txid, justice_rawtx, appointment_end)
return job return job
@@ -79,7 +77,9 @@ class Responder:
return synchronized return synchronized
def add_response(self, uuid, dispute_txid, justice_txid, justice_rawtx, appointment_end, block_hash, retry=False): def add_response(
self, uuid, locator, dispute_txid, justice_txid, justice_rawtx, appointment_end, block_hash, retry=False
):
if self.asleep: if self.asleep:
logger.info("Waking up") logger.info("Waking up")
@@ -90,7 +90,9 @@ class Responder:
# retry holds that information. If retry is true the job already exists # retry holds that information. If retry is true the job already exists
if receipt.delivered: if receipt.delivered:
if not retry: if not retry:
self.create_job(uuid, dispute_txid, justice_txid, justice_rawtx, appointment_end, receipt.confirmations) self.create_job(
uuid, locator, dispute_txid, justice_txid, justice_rawtx, appointment_end, receipt.confirmations
)
else: else:
# TODO: Add the missing reasons (e.g. RPC_VERIFY_REJECTED) # TODO: Add the missing reasons (e.g. RPC_VERIFY_REJECTED)
@@ -100,8 +102,8 @@ class Responder:
return receipt return receipt
def create_job(self, uuid, dispute_txid, justice_txid, justice_rawtx, appointment_end, confirmations=0): def create_job(self, uuid, locator, dispute_txid, justice_txid, justice_rawtx, appointment_end, confirmations=0):
job = Job(dispute_txid, justice_txid, justice_rawtx, appointment_end) job = Job(locator, dispute_txid, justice_txid, justice_rawtx, appointment_end)
self.jobs[uuid] = job self.jobs[uuid] = job
if justice_txid in self.tx_job_map: if justice_txid in self.tx_job_map:
@@ -240,6 +242,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( receipt = self.add_response(
job.locator,
uuid, uuid,
job.dispute_txid, job.dispute_txid,
job.justice_txid, job.justice_txid,
@@ -288,7 +291,13 @@ class Responder:
# FIXME: Whether we decide to increase the retried counter or not, the current counter should be # FIXME: Whether we decide to increase the retried counter or not, the current counter should be
# maintained. There is no way of doing so with the current approach. Update if required # maintained. There is no way of doing so with the current approach. Update if required
self.add_response( self.add_response(
uuid, job.dispute_txid, job.justice_txid, job.justice_rawtx, job.appointment_end, block_hash job.locator,
uuid,
job.dispute_txid,
job.justice_txid,
job.justice_rawtx,
job.appointment_end,
block_hash,
) )
logger.warning("Justice transaction banished. Resetting the job", justice_tx=job.justice_txid) logger.warning("Justice transaction banished. Resetting the job", justice_tx=job.justice_txid)

View File

@@ -7,10 +7,12 @@ from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.serialization import load_pem_private_key from cryptography.hazmat.primitives.serialization import load_pem_private_key
from common.cryptographer import Cryptographer
from common.constants import LOCATOR_LEN_HEX
from pisa.logger import Logger from pisa.logger import Logger
from pisa.cleaner import Cleaner from pisa.cleaner import Cleaner
from pisa.responder import Responder from pisa.responder import Responder
from pisa.cryptographer import Cryptographer
from pisa.block_processor import BlockProcessor from pisa.block_processor import BlockProcessor
from pisa.utils.zmq_subscriber import ZMQHandler from pisa.utils.zmq_subscriber import ZMQHandler
from pisa.conf import EXPIRY_DELTA, MAX_APPOINTMENTS, PISA_SECRET_KEY from pisa.conf import EXPIRY_DELTA, MAX_APPOINTMENTS, PISA_SECRET_KEY
@@ -40,7 +42,7 @@ class Watcher:
@staticmethod @staticmethod
def compute_locator(tx_id): def compute_locator(tx_id):
return tx_id[:32] return tx_id[:LOCATOR_LEN_HEX]
def sign_appointment(self, appointment): def sign_appointment(self, appointment):
data = appointment.serialize() data = appointment.serialize()
@@ -134,6 +136,7 @@ class Watcher:
self.responder.add_response( self.responder.add_response(
uuid, uuid,
filtered_match["locator"],
filtered_match["dispute_txid"], filtered_match["dispute_txid"],
filtered_match["justice_txid"], filtered_match["justice_txid"],
filtered_match["justice_rawtx"], filtered_match["justice_rawtx"],

View File

@@ -18,10 +18,13 @@ from pisa.watcher import Watcher
from pisa.tools import bitcoin_cli from pisa.tools import bitcoin_cli
from pisa.db_manager import DBManager from pisa.db_manager import DBManager
from pisa.appointment import Appointment from pisa.appointment import Appointment
from test.simulator.utils import sha256d from test.simulator.utils import sha256d
from test.simulator.transaction import TX from test.simulator.transaction import TX
from test.simulator.bitcoind_sim import run_simulator, HOST, PORT from test.simulator.bitcoind_sim import run_simulator, HOST, PORT
from common.constants import LOCATOR_LEN_HEX
@pytest.fixture(scope="session") @pytest.fixture(scope="session")
def run_bitcoind(): def run_bitcoind():
@@ -139,9 +142,14 @@ def generate_dummy_job():
dispute_txid = get_random_value_hex(32) dispute_txid = get_random_value_hex(32)
justice_txid = get_random_value_hex(32) justice_txid = get_random_value_hex(32)
justice_rawtx = get_random_value_hex(100) justice_rawtx = get_random_value_hex(100)
locator = dispute_txid[:LOCATOR_LEN_HEX]
job_data = dict( job_data = dict(
dispute_txid=dispute_txid, justice_txid=justice_txid, justice_rawtx=justice_rawtx, appointment_end=100 locator=locator,
dispute_txid=dispute_txid,
justice_txid=justice_txid,
justice_rawtx=justice_rawtx,
appointment_end=100,
) )
return Job.from_dict(job_data) return Job.from_dict(job_data)

View File

@@ -6,8 +6,11 @@ from pisa.responder import Job
from pisa.cleaner import Cleaner from pisa.cleaner import Cleaner
from pisa.appointment import Appointment from pisa.appointment import Appointment
from pisa.db_manager import WATCHER_PREFIX from pisa.db_manager import WATCHER_PREFIX
from test.unit.conftest import get_random_value_hex from test.unit.conftest import get_random_value_hex
from common.constants import LOCATOR_LEN_BYTES, LOCATOR_LEN_HEX
CONFIRMATIONS = 6 CONFIRMATIONS = 6
ITEMS = 10 ITEMS = 10
MAX_ITEMS = 100 MAX_ITEMS = 100
@@ -23,7 +26,7 @@ def set_up_appointments(db_manager, total_appointments):
for i in range(total_appointments): for i in range(total_appointments):
uuid = uuid4().hex uuid = uuid4().hex
locator = get_random_value_hex(32) locator = get_random_value_hex(LOCATOR_LEN_BYTES)
appointment = Appointment(locator, None, None, None, None, None) appointment = Appointment(locator, None, None, None, None, None)
appointments[uuid] = appointment appointments[uuid] = appointment
@@ -55,9 +58,10 @@ def set_up_jobs(db_manager, total_jobs):
# We use the same txid for justice and dispute here, it shouldn't matter # We use the same txid for justice and dispute here, it shouldn't matter
justice_txid = get_random_value_hex(32) justice_txid = get_random_value_hex(32)
dispute_txid = get_random_value_hex(32) dispute_txid = get_random_value_hex(32)
locator = dispute_txid[:LOCATOR_LEN_HEX]
# Assign both justice_txid and dispute_txid the same id (it shouldn't matter) # Assign both justice_txid and dispute_txid the same id (it shouldn't matter)
job = Job(dispute_txid, justice_txid, None, None) job = Job(locator, dispute_txid, justice_txid, None, None)
jobs[uuid] = job jobs[uuid] = job
tx_job_map[justice_txid] = [uuid] tx_job_map[justice_txid] = [uuid]
@@ -131,9 +135,10 @@ def test_delete_completed_jobs_no_db_match(db_manager):
for uuid in selected_jobs[: ITEMS // 2]: for uuid in selected_jobs[: ITEMS // 2]:
justice_txid = jobs[uuid].justice_txid justice_txid = jobs[uuid].justice_txid
dispute_txid = get_random_value_hex(32) dispute_txid = get_random_value_hex(32)
locator = dispute_txid[:LOCATOR_LEN_HEX]
new_uuid = uuid4().hex new_uuid = uuid4().hex
jobs[new_uuid] = Job(dispute_txid, justice_txid, None, None) jobs[new_uuid] = Job(locator, dispute_txid, justice_txid, None, None)
tx_job_map[justice_txid].append(new_uuid) tx_job_map[justice_txid].append(new_uuid)
selected_jobs.append(new_uuid) selected_jobs.append(new_uuid)
@@ -142,8 +147,9 @@ def test_delete_completed_jobs_no_db_match(db_manager):
uuid = uuid4().hex uuid = uuid4().hex
justice_txid = get_random_value_hex(32) justice_txid = get_random_value_hex(32)
dispute_txid = get_random_value_hex(32) dispute_txid = get_random_value_hex(32)
locator = dispute_txid[:LOCATOR_LEN_HEX]
jobs[uuid] = Job(dispute_txid, justice_txid, None, None) jobs[uuid] = Job(locator, dispute_txid, justice_txid, None, None)
tx_job_map[justice_txid] = [uuid] tx_job_map[justice_txid] = [uuid]
selected_jobs.append(uuid) selected_jobs.append(uuid)

View File

@@ -9,11 +9,14 @@ from queue import Queue, Empty
from pisa import c_logger from pisa import c_logger
from pisa.db_manager import DBManager from pisa.db_manager import DBManager
from test.simulator.utils import sha256d
from pisa.responder import Responder, Job from pisa.responder import Responder, Job
from test.simulator.bitcoind_sim import TX
from pisa.block_processor import BlockProcessor from pisa.block_processor import BlockProcessor
from pisa.tools import check_txid_format, bitcoin_cli from pisa.tools import check_txid_format, bitcoin_cli
from common.constants import LOCATOR_LEN_HEX
from test.simulator.utils import sha256d
from test.simulator.bitcoind_sim import TX
from test.unit.conftest import generate_block, generate_blocks, get_random_value_hex from test.unit.conftest import generate_block, generate_blocks, get_random_value_hex
c_logger.disabled = True c_logger.disabled = True
@@ -58,18 +61,21 @@ def create_dummy_job_data(random_txid=False, justice_rawtx=None):
justice_txid = get_random_value_hex(32) justice_txid = get_random_value_hex(32)
appointment_end = bitcoin_cli().getblockcount() + 2 appointment_end = bitcoin_cli().getblockcount() + 2
locator = dispute_txid[:LOCATOR_LEN_HEX]
return dispute_txid, justice_txid, justice_rawtx, appointment_end return locator, dispute_txid, justice_txid, justice_rawtx, appointment_end
def create_dummy_job(random_txid=False, justice_rawtx=None): def create_dummy_job(random_txid=False, justice_rawtx=None):
dispute_txid, justice_txid, justice_rawtx, appointment_end = create_dummy_job_data(random_txid, justice_rawtx) locator, dispute_txid, justice_txid, justice_rawtx, appointment_end = create_dummy_job_data(
return Job(dispute_txid, justice_txid, justice_rawtx, appointment_end) random_txid, justice_rawtx
)
return Job(locator, dispute_txid, justice_txid, justice_rawtx, appointment_end)
def test_job_init(run_bitcoind): def test_job_init(run_bitcoind):
dispute_txid, justice_txid, justice_rawtx, appointment_end = create_dummy_job_data() locator, dispute_txid, justice_txid, justice_rawtx, appointment_end = create_dummy_job_data()
job = Job(dispute_txid, justice_txid, justice_rawtx, appointment_end) job = Job(locator, dispute_txid, justice_txid, justice_rawtx, appointment_end)
assert ( assert (
job.dispute_txid == dispute_txid job.dispute_txid == dispute_txid
@@ -157,6 +163,7 @@ def test_add_response(db_manager):
# The block_hash passed to add_response does not matter much now. It will in the future to deal with errors # 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( receipt = responder.add_response(
job.locator,
uuid, uuid,
job.dispute_txid, job.dispute_txid,
job.justice_txid, job.justice_txid,
@@ -187,6 +194,7 @@ def test_add_bad_response(responder):
# The block_hash passed to add_response does not matter much now. It will in the future to deal with errors # 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( receipt = responder.add_response(
job.locator,
uuid, uuid,
job.dispute_txid, job.dispute_txid,
job.justice_txid, job.justice_txid,
@@ -204,7 +212,7 @@ def test_create_job(responder):
for _ in range(20): for _ in range(20):
uuid = uuid4().hex uuid = uuid4().hex
confirmations = 0 confirmations = 0
dispute_txid, justice_txid, justice_rawtx, appointment_end = create_dummy_job_data(random_txid=True) locator, dispute_txid, justice_txid, justice_rawtx, appointment_end = create_dummy_job_data(random_txid=True)
# Check the job is not within the responder jobs before adding it # Check the job is not within the responder jobs before adding it
assert uuid not in responder.jobs assert uuid not in responder.jobs
@@ -212,7 +220,7 @@ def test_create_job(responder):
assert justice_txid not in responder.unconfirmed_txs assert justice_txid not in responder.unconfirmed_txs
# And that it is afterwards # And that it is afterwards
responder.create_job(uuid, dispute_txid, justice_txid, justice_rawtx, appointment_end, confirmations) responder.create_job(uuid, locator, dispute_txid, justice_txid, justice_rawtx, appointment_end, confirmations)
assert uuid in responder.jobs assert uuid in responder.jobs
assert justice_txid in responder.tx_job_map assert justice_txid in responder.tx_job_map
assert justice_txid in responder.unconfirmed_txs assert justice_txid in responder.unconfirmed_txs
@@ -231,12 +239,12 @@ def test_create_job(responder):
def test_create_job_same_justice_txid(responder): def test_create_job_same_justice_txid(responder):
# Create the same job using two different uuids # Create the same job using two different uuids
confirmations = 0 confirmations = 0
dispute_txid, justice_txid, justice_rawtx, appointment_end = create_dummy_job_data(random_txid=True) locator, dispute_txid, justice_txid, justice_rawtx, appointment_end = create_dummy_job_data(random_txid=True)
uuid_1 = uuid4().hex uuid_1 = uuid4().hex
uuid_2 = uuid4().hex uuid_2 = uuid4().hex
responder.create_job(uuid_1, dispute_txid, justice_txid, justice_rawtx, appointment_end, confirmations) responder.create_job(uuid_1, locator, dispute_txid, justice_txid, justice_rawtx, appointment_end, confirmations)
responder.create_job(uuid_2, dispute_txid, justice_txid, justice_rawtx, appointment_end, confirmations) responder.create_job(uuid_2, locator, dispute_txid, justice_txid, justice_rawtx, appointment_end, confirmations)
# Check that both jobs have been added # Check that both jobs have been added
assert uuid_1 in responder.jobs and uuid_2 in responder.jobs assert uuid_1 in responder.jobs and uuid_2 in responder.jobs
@@ -261,11 +269,11 @@ def test_create_job_already_confirmed(responder):
for i in range(20): for i in range(20):
uuid = uuid4().hex uuid = uuid4().hex
confirmations = i + 1 confirmations = i + 1
dispute_txid, justice_txid, justice_rawtx, appointment_end = create_dummy_job_data( locator, dispute_txid, justice_txid, justice_rawtx, appointment_end = create_dummy_job_data(
justice_rawtx=TX.create_dummy_transaction() justice_rawtx=TX.create_dummy_transaction()
) )
responder.create_job(uuid, dispute_txid, justice_txid, justice_rawtx, appointment_end, confirmations) responder.create_job(uuid, locator, dispute_txid, justice_txid, justice_rawtx, appointment_end, confirmations)
assert justice_txid not in responder.unconfirmed_txs assert justice_txid not in responder.unconfirmed_txs
@@ -360,7 +368,9 @@ def test_check_confirmations(temp_db_manager):
responder.unconfirmed_txs.extend(txs_subset) responder.unconfirmed_txs.extend(txs_subset)
# We also need to add them to the tx_job_map since they would be there in normal conditions # We also need to add them to the tx_job_map since they would be there in normal conditions
responder.tx_job_map = {txid: Job(txid, None, None, None) for txid in responder.unconfirmed_txs} responder.tx_job_map = {
txid: Job(txid[:LOCATOR_LEN_HEX], txid, None, None, None) for txid in responder.unconfirmed_txs
}
# Let's make sure that there are no txs with missed confirmations yet # Let's make sure that there are no txs with missed confirmations yet
assert len(responder.missed_confirmations) == 0 assert len(responder.missed_confirmations) == 0
@@ -457,11 +467,11 @@ def test_rebroadcast(db_manager):
# Rebroadcast calls add_response with retry=True. The job data is already in jobs. # Rebroadcast calls add_response with retry=True. The job data is already in jobs.
for i in range(20): for i in range(20):
uuid = uuid4().hex uuid = uuid4().hex
dispute_txid, justice_txid, justice_rawtx, appointment_end = create_dummy_job_data( locator, dispute_txid, justice_txid, justice_rawtx, appointment_end = create_dummy_job_data(
justice_rawtx=TX.create_dummy_transaction() justice_rawtx=TX.create_dummy_transaction()
) )
responder.jobs[uuid] = Job(dispute_txid, justice_txid, justice_rawtx, appointment_end) responder.jobs[uuid] = Job(locator, dispute_txid, justice_txid, justice_rawtx, appointment_end)
responder.tx_job_map[justice_txid] = [uuid] responder.tx_job_map[justice_txid] = [uuid]
responder.unconfirmed_txs.append(justice_txid) responder.unconfirmed_txs.append(justice_txid)