mirror of
https://github.com/aljazceru/python-teos.git
synced 2025-12-17 22:24:23 +01:00
Updates current tests to work with chain_monitor instead of zmq_sub
This commit is contained in:
@@ -10,6 +10,7 @@ from pisa.watcher import Watcher
|
|||||||
from pisa.tools import bitcoin_cli
|
from pisa.tools import bitcoin_cli
|
||||||
from pisa import HOST, PORT
|
from pisa import HOST, PORT
|
||||||
from pisa.conf import MAX_APPOINTMENTS
|
from pisa.conf import MAX_APPOINTMENTS
|
||||||
|
from pisa.chain_monitor import ChainMonitor
|
||||||
|
|
||||||
from test.pisa.unit.conftest import (
|
from test.pisa.unit.conftest import (
|
||||||
generate_block,
|
generate_block,
|
||||||
@@ -37,7 +38,13 @@ def run_api(db_manager):
|
|||||||
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
||||||
encryption_algorithm=serialization.NoEncryption(),
|
encryption_algorithm=serialization.NoEncryption(),
|
||||||
)
|
)
|
||||||
watcher = Watcher(db_manager, sk_der)
|
|
||||||
|
chain_monitor = ChainMonitor()
|
||||||
|
chain_monitor.monitor_chain()
|
||||||
|
|
||||||
|
watcher = Watcher(db_manager, chain_monitor, sk_der)
|
||||||
|
chain_monitor.attach_watcher(watcher.block_queue, watcher.asleep)
|
||||||
|
chain_monitor.attach_responder(watcher.responder.block_queue, watcher.responder.asleep)
|
||||||
|
|
||||||
api_thread = Thread(target=API(watcher).start)
|
api_thread = Thread(target=API(watcher).start)
|
||||||
api_thread.daemon = True
|
api_thread.daemon = True
|
||||||
|
|||||||
@@ -5,15 +5,14 @@ from uuid import uuid4
|
|||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from queue import Queue, Empty
|
|
||||||
|
|
||||||
from pisa.db_manager import DBManager
|
from pisa.db_manager import DBManager
|
||||||
from pisa.responder import Responder, TransactionTracker
|
from pisa.responder import Responder, TransactionTracker
|
||||||
from pisa.block_processor import BlockProcessor
|
from pisa.block_processor import BlockProcessor
|
||||||
|
from pisa.chain_monitor import ChainMonitor
|
||||||
from pisa.tools import bitcoin_cli
|
from pisa.tools import bitcoin_cli
|
||||||
|
|
||||||
from common.constants import LOCATOR_LEN_HEX
|
from common.constants import LOCATOR_LEN_HEX
|
||||||
from common.tools import check_sha256_hex_format
|
|
||||||
|
|
||||||
from bitcoind_mock.utils import sha256d
|
from bitcoind_mock.utils import sha256d
|
||||||
from bitcoind_mock.transaction import TX
|
from bitcoind_mock.transaction import TX
|
||||||
@@ -21,8 +20,19 @@ from test.pisa.unit.conftest import generate_block, generate_blocks, get_random_
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def responder(db_manager):
|
def chain_monitor():
|
||||||
return Responder(db_manager)
|
chain_monitor = ChainMonitor()
|
||||||
|
chain_monitor.monitor_chain()
|
||||||
|
|
||||||
|
return chain_monitor
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def responder(db_manager, chain_monitor):
|
||||||
|
responder = Responder(db_manager, chain_monitor)
|
||||||
|
chain_monitor.attach_responder(responder.block_queue, responder.asleep)
|
||||||
|
|
||||||
|
return responder
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
@@ -145,17 +155,19 @@ def test_tracker_from_dict_invalid_data():
|
|||||||
|
|
||||||
|
|
||||||
def test_init_responder(responder):
|
def test_init_responder(responder):
|
||||||
assert type(responder.trackers) is dict and len(responder.trackers) == 0
|
assert isinstance(responder.trackers, dict) and len(responder.trackers) == 0
|
||||||
assert type(responder.tx_tracker_map) is dict and len(responder.tx_tracker_map) == 0
|
assert isinstance(responder.tx_tracker_map, dict) and len(responder.tx_tracker_map) == 0
|
||||||
assert type(responder.unconfirmed_txs) is list and len(responder.unconfirmed_txs) == 0
|
assert isinstance(responder.unconfirmed_txs, list) and len(responder.unconfirmed_txs) == 0
|
||||||
assert type(responder.missed_confirmations) is dict and len(responder.missed_confirmations) == 0
|
assert isinstance(responder.missed_confirmations, dict) and len(responder.missed_confirmations) == 0
|
||||||
|
assert isinstance(responder.chain_monitor, ChainMonitor)
|
||||||
assert responder.block_queue.empty()
|
assert responder.block_queue.empty()
|
||||||
assert responder.asleep is True
|
assert responder.asleep is True
|
||||||
assert responder.zmq_subscriber is None
|
|
||||||
|
|
||||||
|
|
||||||
def test_handle_breach(db_manager):
|
def test_handle_breach(db_manager, chain_monitor):
|
||||||
responder = Responder(db_manager)
|
responder = Responder(db_manager, chain_monitor)
|
||||||
|
chain_monitor.attach_responder(responder.block_queue, responder.asleep)
|
||||||
|
|
||||||
uuid = uuid4().hex
|
uuid = uuid4().hex
|
||||||
tracker = create_dummy_tracker()
|
tracker = create_dummy_tracker()
|
||||||
|
|
||||||
@@ -172,11 +184,10 @@ def test_handle_breach(db_manager):
|
|||||||
|
|
||||||
assert receipt.delivered is True
|
assert receipt.delivered is True
|
||||||
|
|
||||||
# The responder automatically fires add_tracker on adding a tracker if it is asleep. We need to stop the processes now.
|
# The responder automatically fires add_tracker on adding a tracker if it is asleep. We need to stop the processes
|
||||||
# To do so we delete all the trackers, stop the zmq and create a new fake block to unblock the queue.get method
|
# now. To do so we delete all the trackers, and generate a new block.
|
||||||
responder.trackers = dict()
|
responder.trackers = dict()
|
||||||
responder.zmq_subscriber.terminate = True
|
generate_block()
|
||||||
responder.block_queue.put(get_random_value_hex(32))
|
|
||||||
|
|
||||||
|
|
||||||
def test_add_bad_response(responder):
|
def test_add_bad_response(responder):
|
||||||
@@ -205,7 +216,7 @@ def test_add_bad_response(responder):
|
|||||||
|
|
||||||
|
|
||||||
def test_add_tracker(responder):
|
def test_add_tracker(responder):
|
||||||
responder.asleep = False
|
# Responder is asleep
|
||||||
|
|
||||||
for _ in range(20):
|
for _ in range(20):
|
||||||
uuid = uuid4().hex
|
uuid = uuid4().hex
|
||||||
@@ -237,7 +248,8 @@ def test_add_tracker(responder):
|
|||||||
|
|
||||||
|
|
||||||
def test_add_tracker_same_penalty_txid(responder):
|
def test_add_tracker_same_penalty_txid(responder):
|
||||||
# Create the same tracker using two different uuids
|
# Responder is asleep
|
||||||
|
|
||||||
confirmations = 0
|
confirmations = 0
|
||||||
locator, dispute_txid, penalty_txid, penalty_rawtx, appointment_end = create_dummy_tracker_data(random_txid=True)
|
locator, dispute_txid, penalty_txid, penalty_rawtx, appointment_end = create_dummy_tracker_data(random_txid=True)
|
||||||
uuid_1 = uuid4().hex
|
uuid_1 = uuid4().hex
|
||||||
@@ -264,7 +276,7 @@ def test_add_tracker_same_penalty_txid(responder):
|
|||||||
|
|
||||||
|
|
||||||
def test_add_tracker_already_confirmed(responder):
|
def test_add_tracker_already_confirmed(responder):
|
||||||
responder.asleep = False
|
# Responder is asleep
|
||||||
|
|
||||||
for i in range(20):
|
for i in range(20):
|
||||||
uuid = uuid4().hex
|
uuid = uuid4().hex
|
||||||
@@ -278,29 +290,10 @@ def test_add_tracker_already_confirmed(responder):
|
|||||||
assert penalty_txid not in responder.unconfirmed_txs
|
assert penalty_txid not in responder.unconfirmed_txs
|
||||||
|
|
||||||
|
|
||||||
def test_do_subscribe(responder):
|
def test_do_watch(temp_db_manager, chain_monitor):
|
||||||
responder.block_queue = Queue()
|
# Create a fresh responder to simplify the test
|
||||||
|
responder = Responder(temp_db_manager, chain_monitor)
|
||||||
zmq_thread = Thread(target=responder.do_subscribe)
|
chain_monitor.attach_responder(responder.block_queue, False)
|
||||||
zmq_thread.daemon = True
|
|
||||||
zmq_thread.start()
|
|
||||||
|
|
||||||
try:
|
|
||||||
generate_block()
|
|
||||||
block_hash = responder.block_queue.get()
|
|
||||||
assert check_sha256_hex_format(block_hash)
|
|
||||||
|
|
||||||
except Empty:
|
|
||||||
assert False
|
|
||||||
|
|
||||||
|
|
||||||
def test_do_watch(temp_db_manager):
|
|
||||||
responder = Responder(temp_db_manager)
|
|
||||||
responder.block_queue = Queue()
|
|
||||||
|
|
||||||
zmq_thread = Thread(target=responder.do_subscribe)
|
|
||||||
zmq_thread.daemon = True
|
|
||||||
zmq_thread.start()
|
|
||||||
|
|
||||||
trackers = [create_dummy_tracker(penalty_rawtx=TX.create_dummy_transaction()) for _ in range(20)]
|
trackers = [create_dummy_tracker(penalty_rawtx=TX.create_dummy_transaction()) for _ in range(20)]
|
||||||
|
|
||||||
@@ -314,9 +307,7 @@ def test_do_watch(temp_db_manager):
|
|||||||
responder.unconfirmed_txs.append(tracker.penalty_txid)
|
responder.unconfirmed_txs.append(tracker.penalty_txid)
|
||||||
|
|
||||||
# Let's start to watch
|
# Let's start to watch
|
||||||
watch_thread = Thread(target=responder.do_watch)
|
Thread(target=responder.do_watch, daemon=True).start()
|
||||||
watch_thread.daemon = True
|
|
||||||
watch_thread.start()
|
|
||||||
|
|
||||||
# And broadcast some of the transactions
|
# And broadcast some of the transactions
|
||||||
broadcast_txs = []
|
broadcast_txs = []
|
||||||
@@ -324,8 +315,10 @@ def test_do_watch(temp_db_manager):
|
|||||||
bitcoin_cli().sendrawtransaction(tracker.penalty_rawtx)
|
bitcoin_cli().sendrawtransaction(tracker.penalty_rawtx)
|
||||||
broadcast_txs.append(tracker.penalty_txid)
|
broadcast_txs.append(tracker.penalty_txid)
|
||||||
|
|
||||||
|
print(responder.unconfirmed_txs)
|
||||||
# Mine a block
|
# Mine a block
|
||||||
generate_block()
|
generate_block()
|
||||||
|
print(responder.unconfirmed_txs)
|
||||||
|
|
||||||
# The transactions we sent shouldn't be in the unconfirmed transaction list anymore
|
# The transactions we sent shouldn't be in the unconfirmed transaction list anymore
|
||||||
assert not set(broadcast_txs).issubset(responder.unconfirmed_txs)
|
assert not set(broadcast_txs).issubset(responder.unconfirmed_txs)
|
||||||
@@ -350,13 +343,9 @@ def test_do_watch(temp_db_manager):
|
|||||||
assert responder.asleep is True
|
assert responder.asleep is True
|
||||||
|
|
||||||
|
|
||||||
def test_check_confirmations(temp_db_manager):
|
def test_check_confirmations(temp_db_manager, chain_monitor):
|
||||||
responder = Responder(temp_db_manager)
|
responder = Responder(temp_db_manager, chain_monitor)
|
||||||
responder.block_queue = Queue()
|
chain_monitor.attach_responder(responder.block_queue, responder.asleep)
|
||||||
|
|
||||||
zmq_thread = Thread(target=responder.do_subscribe)
|
|
||||||
zmq_thread.daemon = True
|
|
||||||
zmq_thread.start()
|
|
||||||
|
|
||||||
# check_confirmations checks, given a list of transaction for a block, what of the known penalty transaction have
|
# check_confirmations checks, given a list of transaction for a block, what of the known penalty transaction have
|
||||||
# been confirmed. To test this we need to create a list of transactions and the state of the responder
|
# been confirmed. To test this we need to create a list of transactions and the state of the responder
|
||||||
@@ -386,7 +375,7 @@ def test_check_confirmations(temp_db_manager):
|
|||||||
assert responder.missed_confirmations[tx] == 1
|
assert responder.missed_confirmations[tx] == 1
|
||||||
|
|
||||||
|
|
||||||
# WIP: Check this properly, a bug pass unnoticed!
|
# TODO: Check this properly, a bug pass unnoticed!
|
||||||
def test_get_txs_to_rebroadcast(responder):
|
def test_get_txs_to_rebroadcast(responder):
|
||||||
# Let's create a few fake txids and assign at least 6 missing confirmations to each
|
# Let's create a few fake txids and assign at least 6 missing confirmations to each
|
||||||
txs_missing_too_many_conf = {get_random_value_hex(32): 6 + i for i in range(10)}
|
txs_missing_too_many_conf = {get_random_value_hex(32): 6 + i for i in range(10)}
|
||||||
@@ -410,13 +399,13 @@ 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_trackers(db_manager):
|
def test_get_completed_trackers(db_manager, chain_monitor):
|
||||||
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
|
responder = Responder(db_manager, chain_monitor)
|
||||||
responder = Responder(db_manager)
|
chain_monitor.attach_responder(responder.block_queue, responder.asleep)
|
||||||
|
|
||||||
# A complete tracker is a tracker that has reached the appointment end with enough confirmations (> MIN_CONFIRMATIONS)
|
# A complete tracker is a tracker that has reached the appointment end with enough confs (> 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
|
||||||
trackers_end_conf = {
|
trackers_end_conf = {
|
||||||
uuid4().hex: create_dummy_tracker(penalty_rawtx=TX.create_dummy_transaction()) for _ in range(10)
|
uuid4().hex: create_dummy_tracker(penalty_rawtx=TX.create_dummy_transaction()) for _ in range(10)
|
||||||
@@ -461,9 +450,10 @@ def test_get_completed_trackers(db_manager):
|
|||||||
assert set(completed_trackers_ids) == set(ended_trackers_keys)
|
assert set(completed_trackers_ids) == set(ended_trackers_keys)
|
||||||
|
|
||||||
|
|
||||||
def test_rebroadcast(db_manager):
|
def test_rebroadcast(db_manager, chain_monitor):
|
||||||
responder = Responder(db_manager)
|
responder = Responder(db_manager, chain_monitor)
|
||||||
responder.asleep = False
|
responder.asleep = False
|
||||||
|
chain_monitor.attach_responder(responder.block_queue, responder.asleep)
|
||||||
|
|
||||||
txs_to_rebroadcast = []
|
txs_to_rebroadcast = []
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,15 @@
|
|||||||
import pytest
|
import pytest
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from queue import Queue, Empty
|
|
||||||
from cryptography.hazmat.primitives import serialization
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
|
||||||
from pisa.watcher import Watcher
|
from pisa.watcher import Watcher
|
||||||
from pisa.responder import Responder
|
from pisa.responder import Responder
|
||||||
from pisa.tools import bitcoin_cli
|
from pisa.tools import bitcoin_cli
|
||||||
from test.pisa.unit.conftest import (
|
from test.pisa.unit.conftest import generate_blocks, generate_dummy_appointment, get_random_value_hex, generate_keypair
|
||||||
generate_block,
|
from pisa.chain_monitor import ChainMonitor
|
||||||
generate_blocks,
|
|
||||||
generate_dummy_appointment,
|
|
||||||
get_random_value_hex,
|
|
||||||
generate_keypair,
|
|
||||||
)
|
|
||||||
from pisa.conf import EXPIRY_DELTA, MAX_APPOINTMENTS
|
from pisa.conf import EXPIRY_DELTA, MAX_APPOINTMENTS
|
||||||
|
|
||||||
from common.tools import check_sha256_hex_format
|
|
||||||
from common.cryptographer import Cryptographer
|
from common.cryptographer import Cryptographer
|
||||||
|
|
||||||
|
|
||||||
@@ -35,8 +28,20 @@ sk_der = signing_key.private_bytes(
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def watcher(db_manager):
|
def chain_monitor():
|
||||||
return Watcher(db_manager, sk_der)
|
chain_monitor = ChainMonitor()
|
||||||
|
chain_monitor.monitor_chain()
|
||||||
|
|
||||||
|
return chain_monitor
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def watcher(db_manager, chain_monitor):
|
||||||
|
watcher = Watcher(db_manager, chain_monitor, sk_der)
|
||||||
|
chain_monitor.attach_watcher(watcher.block_queue, watcher.asleep)
|
||||||
|
chain_monitor.attach_responder(watcher.responder.block_queue, watcher.responder.asleep)
|
||||||
|
|
||||||
|
return watcher
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
@@ -67,17 +72,18 @@ def create_appointments(n):
|
|||||||
return appointments, locator_uuid_map, dispute_txs
|
return appointments, locator_uuid_map, dispute_txs
|
||||||
|
|
||||||
|
|
||||||
def test_init(watcher):
|
def test_init(run_bitcoind, watcher):
|
||||||
assert type(watcher.appointments) is dict and len(watcher.appointments) == 0
|
assert isinstance(watcher.appointments, dict) and len(watcher.appointments) == 0
|
||||||
assert type(watcher.locator_uuid_map) is dict and len(watcher.locator_uuid_map) == 0
|
assert isinstance(watcher.locator_uuid_map, dict) and len(watcher.locator_uuid_map) == 0
|
||||||
|
assert isinstance(watcher.chain_monitor, ChainMonitor)
|
||||||
assert watcher.block_queue.empty()
|
assert watcher.block_queue.empty()
|
||||||
assert watcher.asleep is True
|
assert watcher.asleep is True
|
||||||
|
|
||||||
assert watcher.max_appointments == MAX_APPOINTMENTS
|
assert watcher.max_appointments == MAX_APPOINTMENTS
|
||||||
assert watcher.zmq_subscriber is None
|
|
||||||
assert type(watcher.responder) is Responder
|
assert type(watcher.responder) is Responder
|
||||||
|
|
||||||
|
|
||||||
def test_add_appointment(run_bitcoind, watcher):
|
def test_add_appointment(watcher):
|
||||||
# The watcher automatically fires do_watch and do_subscribe on adding an appointment if it is asleep (initial state)
|
# The watcher automatically fires do_watch and do_subscribe on adding an appointment if it is asleep (initial state)
|
||||||
# Avoid this by setting the state to awake.
|
# Avoid this by setting the state to awake.
|
||||||
watcher.asleep = False
|
watcher.asleep = False
|
||||||
@@ -121,36 +127,18 @@ def test_add_too_many_appointments(watcher):
|
|||||||
assert sig is None
|
assert sig is None
|
||||||
|
|
||||||
|
|
||||||
def test_do_subscribe(watcher):
|
|
||||||
watcher.block_queue = Queue()
|
|
||||||
|
|
||||||
zmq_thread = Thread(target=watcher.do_subscribe)
|
|
||||||
zmq_thread.daemon = True
|
|
||||||
zmq_thread.start()
|
|
||||||
|
|
||||||
try:
|
|
||||||
generate_block()
|
|
||||||
block_hash = watcher.block_queue.get()
|
|
||||||
assert check_sha256_hex_format(block_hash)
|
|
||||||
|
|
||||||
except Empty:
|
|
||||||
assert False
|
|
||||||
|
|
||||||
|
|
||||||
def test_do_watch(watcher):
|
def test_do_watch(watcher):
|
||||||
# We will wipe all the previous data and add 5 appointments
|
# We will wipe all the previous data and add 5 appointments
|
||||||
watcher.appointments, watcher.locator_uuid_map, dispute_txs = create_appointments(APPOINTMENTS)
|
watcher.appointments, watcher.locator_uuid_map, dispute_txs = create_appointments(APPOINTMENTS)
|
||||||
|
watcher.chain_monitor.watcher_asleep = False
|
||||||
|
|
||||||
watch_thread = Thread(target=watcher.do_watch)
|
Thread(target=watcher.do_watch, daemon=True).start()
|
||||||
watch_thread.daemon = True
|
|
||||||
watch_thread.start()
|
|
||||||
|
|
||||||
# Broadcast the first two
|
# Broadcast the first two
|
||||||
for dispute_tx in dispute_txs[:2]:
|
for dispute_tx in dispute_txs[:2]:
|
||||||
bitcoin_cli().sendrawtransaction(dispute_tx)
|
bitcoin_cli().sendrawtransaction(dispute_tx)
|
||||||
|
|
||||||
# After leaving some time for the block to be mined and processed, the number of appointments should have reduced
|
# After generating enough blocks, the number of appointments should have reduced by two
|
||||||
# by two
|
|
||||||
generate_blocks(START_TIME_OFFSET + END_TIME_OFFSET)
|
generate_blocks(START_TIME_OFFSET + END_TIME_OFFSET)
|
||||||
|
|
||||||
assert len(watcher.appointments) == APPOINTMENTS - 2
|
assert len(watcher.appointments) == APPOINTMENTS - 2
|
||||||
|
|||||||
Reference in New Issue
Block a user