def test_add_appointment_trigger_on_cache_cannot_decrypt(teosd): _, teos_id = teosd commitment_tx, _, penalty_tx = create_txs() # Let's send the commitment to the network and mine a block generate_block_with_transactions(commitment_tx) sleep(1) # The appointment data is built using a random 32-byte value. appointment_data = build_appointment_data(get_random_value_hex(32), penalty_tx) # We cannot use teos_client.add_appointment here since it computes the locator internally, so let's do it manually. appointment_data["locator"] = compute_locator(bitcoin_cli.decoderawtransaction(commitment_tx).get("txid")) appointment_data["encrypted_blob"] = Cryptographer.encrypt(penalty_tx, get_random_value_hex(32)) appointment = Appointment.from_dict(appointment_data) signature = Cryptographer.sign(appointment.serialize(), user_sk) data = {"appointment": appointment.to_dict(), "signature": signature} # Send appointment to the server. response = teos_client.post_request(data, teos_add_appointment_endpoint) response_json = teos_client.process_post_response(response) # Check that the server has accepted the appointment tower_signature = response_json.get("signature") appointment_receipt = receipts.create_appointment_receipt(signature, response_json.get("start_block")) rpk = Cryptographer.recover_pk(appointment_receipt, tower_signature) assert teos_id == Cryptographer.get_compressed_pk(rpk) assert response_json.get("locator") == appointment.locator # The appointment should should have been immediately dropped with pytest.raises(TowerResponseError): get_appointment_info(teos_id, appointment_data["locator"])
def _generate_dummy_tracker(): tracker_data = dict( locator=get_random_value_hex(16), dispute_txid=get_random_value_hex(32), penalty_txid=get_random_value_hex(32), penalty_rawtx=get_random_value_hex(150), user_id="02" + get_random_value_hex(32), ) return TransactionTracker.from_dict(tracker_data)
def _generate_dummy_appointment(): appointment_data = { "locator": get_random_value_hex(16), "to_self_delay": 20, "encrypted_blob": get_random_value_hex(150), "user_id": get_random_value_hex(16), "user_signature": get_random_value_hex(50), "start_block": 200, } return ExtendedAppointment.from_dict(appointment_data)
def _generate_dummy_appointment(): commitment_txid = get_random_value_hex(32) penalty_tx = get_random_value_hex(150) appointment_data = { "locator": compute_locator(commitment_txid), "to_self_delay": 20, "encrypted_blob": Cryptographer.encrypt(penalty_tx, commitment_txid), "user_id": get_random_value_hex(16), "user_signature": get_random_value_hex(50), "start_block": 200, } return ExtendedAppointment.from_dict(appointment_data), commitment_txid
def test_appointment_wrong_decryption_key(teosd): _, teos_id = teosd # This tests an appointment encrypted with a key that has not been derived from the same source as the locator. # Therefore the tower won't be able to decrypt the blob once the appointment is triggered. commitment_tx, _, penalty_tx = create_txs() # The appointment data is built using a random 32-byte value. appointment_data = build_appointment_data(get_random_value_hex(32), penalty_tx) # We cannot use teos_client.add_appointment here since it computes the locator internally, so let's do it manually. # We will encrypt the blob using the random value and derive the locator from the commitment tx. appointment_data["locator"] = compute_locator(bitcoin_cli.decoderawtransaction(commitment_tx).get("txid")) appointment_data["encrypted_blob"] = Cryptographer.encrypt(penalty_tx, get_random_value_hex(32)) appointment = Appointment.from_dict(appointment_data) signature = Cryptographer.sign(appointment.serialize(), user_sk) data = {"appointment": appointment.to_dict(), "signature": signature} # Send appointment to the server. response = teos_client.post_request(data, teos_add_appointment_endpoint) response_json = teos_client.process_post_response(response) # Check that the server has accepted the appointment tower_signature = response_json.get("signature") appointment_receipt = receipts.create_appointment_receipt(signature, response_json.get("start_block")) rpk = Cryptographer.recover_pk(appointment_receipt, tower_signature) assert teos_id == Cryptographer.get_compressed_pk(rpk) assert response_json.get("locator") == appointment.locator # Trigger the appointment generate_block_with_transactions(commitment_tx) # The appointment should have been removed since the decryption failed. with pytest.raises(TowerResponseError): get_appointment_info(teos_id, appointment.locator)
def _generate_dummy_tracker(commitment_tx=None): if not commitment_tx: commitment_tx = create_commitment_tx() decoded_commitment_tx = bitcoin_cli.decoderawtransaction(commitment_tx) penalty_tx = create_penalty_tx(decoded_commitment_tx) locator = decoded_commitment_tx.get("txid")[:LOCATOR_LEN_HEX] tracker_data = dict( locator=locator, dispute_txid=bitcoin_cli.decoderawtransaction(commitment_tx).get( "txid"), penalty_txid=bitcoin_cli.decoderawtransaction(penalty_tx).get( "txid"), penalty_rawtx=penalty_tx, user_id="02" + get_random_value_hex(32), ) return TransactionTracker.from_dict(tracker_data)
import sys import json from test.teos.conftest import get_random_value_hex from contrib.client.teos_client import main as teos_client appointment_data = { "tx": "4615a58815475ab8145b6bb90b1268a0dbb02e344ddd483f45052bec1f15b1951c1ee7f070a0993da395a5ee92ea3a1c184b5ffdb250" "7164bf1f8c1364155d48bdbc882eee0868ca69864a807f213f538990ad16f56d7dfb28a18e69e3f31ae9adad229e3244073b7d643b4597ec88" "bf247b9f73f301b0f25ae8207b02b7709c271da98af19f1db276ac48ba64f099644af1ae2c90edb7def5e8589a1bb17cc72ac42ecf07dd29cf" "f91823938fd0d772c2c92b7ab050f8837efd46197c9b2b3f", "tx_id": "0af510d92a50c1d67c6f7fc5d47908d96b3eccdea093d89bcbaf05bcfebdd982", "to_self_delay": 20, } # Add too many appointment by changing the tx_id (100 is the default max) for _ in range(int(sys.argv[1])): appointment_data["tx_id"] = get_random_value_hex(32) teos_client("add_appointment", [json.dumps(appointment_data)], {})