def test_check_confirmations(db_manager, carrier, block_processor): responder = Responder(db_manager, carrier, block_processor) chain_monitor = ChainMonitor(Queue(), responder.block_queue, block_processor, bitcoind_feed_params) chain_monitor.monitor_chain() # 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 txs = [get_random_value_hex(32) for _ in range(20)] # The responder has a list of unconfirmed transaction, let make that some of them are the ones we've received responder.unconfirmed_txs = [get_random_value_hex(32) for _ in range(10)] txs_subset = random.sample(txs, k=10) responder.unconfirmed_txs.extend(txs_subset) # We also need to add them to the tx_tracker_map since they would be there in normal conditions responder.tx_tracker_map = { txid: TransactionTracker(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 assert len(responder.missed_confirmations) == 0 responder.check_confirmations(txs) # After checking confirmations the txs in txs_subset should be confirmed (not part of unconfirmed_txs anymore) # and the rest should have a missing confirmation for tx in txs_subset: assert tx not in responder.unconfirmed_txs for tx in responder.unconfirmed_txs: assert responder.missed_confirmations[tx] == 1
def test_check_confirmations(responder, monkeypatch): # 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 # The responder has a list of unconfirmed transaction, let make that some of them are the ones we've received txs = [get_random_value_hex(32) for _ in range(20)] unconfirmed_txs = [get_random_value_hex(32) for _ in range(10)] txs_subset = random.sample(txs, k=10) unconfirmed_txs.extend(txs_subset) # We also need to add them to the tx_tracker_map since they would be there in normal conditions tx_tracker_map = { txid: TransactionTracker(txid[:LOCATOR_LEN_HEX], txid, None, None, None) for txid in unconfirmed_txs } # Mock the structures monkeypatch.setattr(responder, "unconfirmed_txs", unconfirmed_txs) monkeypatch.setattr(responder, "tx_tracker_map", tx_tracker_map) # Let's make sure that there are no txs with missed confirmations yet assert len(responder.missed_confirmations) == 0 # After checking confirmations the txs in txs_subset should be confirmed (not part of unconfirmed_txs anymore) # and the rest should have a missing confirmation responder.check_confirmations(txs) for tx in txs_subset: assert tx not in responder.unconfirmed_txs for tx in responder.unconfirmed_txs: assert responder.missed_confirmations[tx] == 1
def test_tracker_init(run_bitcoind): locator, dispute_txid, penalty_txid, penalty_rawtx, appointment_end = create_dummy_tracker_data( ) tracker = TransactionTracker(locator, dispute_txid, penalty_txid, penalty_rawtx, appointment_end) assert (tracker.dispute_txid == dispute_txid and tracker.penalty_txid == penalty_txid and tracker.penalty_rawtx == penalty_rawtx and tracker.appointment_end == appointment_end)
def test_tracker_init(run_bitcoind): locator, dispute_txid, penalty_txid, penalty_rawtx, user_id = create_dummy_tracker_data( ) tracker = TransactionTracker(locator, dispute_txid, penalty_txid, penalty_rawtx, user_id) assert (tracker.locator == locator and tracker.dispute_txid == dispute_txid and tracker.penalty_txid == penalty_txid and tracker.penalty_rawtx == penalty_rawtx and tracker.user_id == user_id)
def test_tracker_init(): locator = get_random_value_hex(32) dispute_txid = get_random_value_hex(32) penalty_txid = get_random_value_hex(32) penalty_tx = get_random_value_hex(200) user_id = get_random_value_hex(16) tracker = TransactionTracker(locator, dispute_txid, penalty_txid, penalty_tx, user_id) assert (tracker.locator == locator and tracker.dispute_txid == dispute_txid and tracker.penalty_txid == penalty_txid and tracker.penalty_rawtx == penalty_tx and tracker.user_id == user_id)
def test_tracker_init(): # Simple test to check that creating a Tracker works locator = get_random_value_hex(32) dispute_txid = get_random_value_hex(32) penalty_txid = get_random_value_hex(32) penalty_tx = get_random_value_hex(200) user_id = get_random_value_hex(16) tracker = TransactionTracker(locator, dispute_txid, penalty_txid, penalty_tx, user_id) assert (tracker.locator == locator and tracker.dispute_txid == dispute_txid and tracker.penalty_txid == penalty_txid and tracker.penalty_rawtx == penalty_tx and tracker.user_id == user_id)
def set_up_trackers(db_manager, total_trackers): trackers = dict() tx_tracker_map = dict() for i in range(total_trackers): uuid = uuid4().hex # We use the same txid for penalty and dispute here, it shouldn't matter penalty_txid = get_random_value_hex(32) dispute_txid = get_random_value_hex(32) locator = dispute_txid[:LOCATOR_LEN_HEX] # Appointment data appointment = Appointment(locator, None, None) # Store the data in the database and create a flag db_manager.store_watcher_appointment(uuid, appointment.to_dict()) db_manager.create_triggered_appointment_flag(uuid) # Assign both penalty_txid and dispute_txid the same id (it shouldn't matter) tracker = TransactionTracker(locator, dispute_txid, penalty_txid, None, None) trackers[uuid] = { "locator": tracker.locator, "penalty_txid": tracker.penalty_txid } tx_tracker_map[penalty_txid] = [uuid] db_manager.store_responder_tracker(uuid, tracker.to_dict()) # Each penalty_txid can have more than one uuid assigned to it. if i % 2: uuid = uuid4().hex trackers[uuid] = { "locator": tracker.locator, "penalty_txid": tracker.penalty_txid } tx_tracker_map[penalty_txid].append(uuid) db_manager.store_responder_tracker(uuid, tracker.to_dict()) # Add them to the Watcher's db too db_manager.store_watcher_appointment(uuid, appointment.to_dict()) db_manager.create_triggered_appointment_flag(uuid) return trackers, tx_tracker_map
def test_rebroadcast(db_manager, carrier, block_processor): responder = Responder(db_manager, carrier, block_processor) chain_monitor = ChainMonitor(Queue(), responder.block_queue, block_processor, bitcoind_feed_params) chain_monitor.monitor_chain() txs_to_rebroadcast = [] # Rebroadcast calls add_response with retry=True. The tracker data is already in trackers. for i in range(20): uuid = uuid4().hex locator, dispute_txid, penalty_txid, penalty_rawtx, appointment_end = create_dummy_tracker_data( penalty_rawtx=create_dummy_transaction().hex()) tracker = TransactionTracker(locator, dispute_txid, penalty_txid, penalty_rawtx, appointment_end) responder.trackers[uuid] = { "locator": locator, "penalty_txid": penalty_txid, "appointment_end": appointment_end, } # We need to add it to the db too responder.db_manager.create_triggered_appointment_flag(uuid) responder.db_manager.store_responder_tracker(uuid, tracker.to_json()) responder.tx_tracker_map[penalty_txid] = [uuid] responder.unconfirmed_txs.append(penalty_txid) # Let's add some of the txs in the rebroadcast list if (i % 2) == 0: txs_to_rebroadcast.append(penalty_txid) # 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) # All txs should have been delivered and the missed confirmation reset for txid, receipt in receipts: # Sanity check assert txid in txs_to_rebroadcast assert receipt.delivered is True assert responder.missed_confirmations[txid] == 0
def set_up_trackers(db_manager, total_trackers): trackers = dict() tx_tracker_map = dict() for i in range(total_trackers): uuid = uuid4().hex # We use the same txid for penalty and dispute here, it shouldn't matter penalty_txid = get_random_value_hex(32) dispute_txid = get_random_value_hex(32) locator = dispute_txid[:LOCATOR_LEN_HEX] # Assign both penalty_txid and dispute_txid the same id (it shouldn't matter) tracker = TransactionTracker(locator, dispute_txid, penalty_txid, None, None) trackers[uuid] = { "locator": tracker.locator, "penalty_txid": tracker.penalty_txid } tx_tracker_map[penalty_txid] = [uuid] db_manager.store_responder_tracker(uuid, tracker.to_json()) db_manager.create_append_locator_map(tracker.locator, uuid) # Each penalty_txid can have more than one uuid assigned to it. if i % 2: uuid = uuid4().hex trackers[uuid] = { "locator": tracker.locator, "penalty_txid": tracker.penalty_txid } tx_tracker_map[penalty_txid].append(uuid) db_manager.store_responder_tracker(uuid, tracker.to_json()) db_manager.create_append_locator_map(tracker.locator, uuid) return trackers, tx_tracker_map
def create_dummy_tracker(random_txid=False, penalty_rawtx=None): locator, dispute_txid, penalty_txid, penalty_rawtx, appointment_end = create_dummy_tracker_data( random_txid, penalty_rawtx) return TransactionTracker(locator, dispute_txid, penalty_txid, penalty_rawtx, appointment_end)