From 86e97e37bff99b54714f0b4e778fe4aaf81e6ced Mon Sep 17 00:00:00 2001 From: Sergi Delgado Segura Date: Tue, 14 Apr 2020 16:53:35 +0200 Subject: [PATCH] Removes start/end time from appointment --- CONTRIBUTING.md | 8 ++--- cli/README.md | 15 ++------ common/appointment.py | 26 ++++---------- teos/inspector.py | 83 ------------------------------------------- 4 files changed, 12 insertions(+), 120 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c3c1280..85b74fe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -49,10 +49,10 @@ for opt, arg in opts: ``` ```python -if rcode == 0: - rcode, message = self.check_start_time(start_time, block_height) -if rcode == 0: - rcode, message = self.check_end_time(end_time, start_time, block_height) +if appointment_data is None: + raise InspectionFailed(errors.APPOINTMENT_EMPTY_FIELD, "empty appointment received") +elif not isinstance(appointment_data, dict): + raise InspectionFailed(errors.APPOINTMENT_WRONG_FIELD, "wrong appointment format") ``` ## Dev Requirements diff --git a/cli/README.md b/cli/README.md index 266e0fc..b04f9df 100644 --- a/cli/README.md +++ b/cli/README.md @@ -44,8 +44,6 @@ This command is used to send appointments to the watchtower. Appointments **must { "tx": tx, "tx_id": tx_id, - "start_time": s, - "end_time": e, "to_self_delay": d } `tx` **must** be the raw penalty transaction that will be encrypted before sent to the watchtower. `type(tx) = hex encoded str` @@ -60,12 +58,6 @@ This command is used to send appointments to the watchtower. Appointments **must The API will return a `application/json` HTTP response code `200/OK` if the appointment is accepted, with the locator encoded in the response text, or a `400/Bad Request` if the appointment is rejected, with the rejection reason encoded in the response text. -### Alpha release restrictions -The alpha release does not have authentication, payments nor rate limiting, therefore some self imposed restrictions apply: - -- `start_time` should be within the next 6 blocks `[current_time+1, current_time+6]`. -- `end_time` cannot be bigger than (roughly) a month. That is `4320` blocks on top of `start_time`. - #### Usage @@ -103,9 +95,7 @@ if `-f, --file` **is** specified, then the command expects a path to a json file "appointment": { "encrypted_blob": eb, - "end_time": e, "locator": appointment_locator, - "start_time": s, "status": "being_watched", "to_self_delay": d } @@ -118,7 +108,6 @@ if `-f, --file` **is** specified, then the command expects a path to a json file "status": "dispute_responded", "appointment": { - "appointment_end": e, "dispute_txid": dispute_txid, "locator": appointment_locator, "penalty_rawtx": penalty_rawtx, @@ -164,10 +153,10 @@ python teos_cli.py register 2. Generate a new dummy appointment. **Note:** this appointment will never be fulfilled (it will eventually expire) since it does not correspond to a valid transaction. However it can be used to interact with the Eye of Satoshi's API. ``` - echo '{"tx": "4615a58815475ab8145b6bb90b1268a0dbb02e344ddd483f45052bec1f15b1951c1ee7f070a0993da395a5ee92ea3a1c184b5ffdb2507164bf1f8c1364155d48bdbc882eee0868ca69864a807f213f538990ad16f56d7dfb28a18e69e3f31ae9adad229e3244073b7d643b4597ec88bf247b9f73f301b0f25ae8207b02b7709c271da98af19f1db276ac48ba64f099644af1ae2c90edb7def5e8589a1bb17cc72ac42ecf07dd29cff91823938fd0d772c2c92b7ab050f8837efd46197c9b2b3f", "tx_id": "0b9510d92a50c1d67c6f7fc5d47908d96b3eccdea093d89bcbaf05bcfebdd951", "start_time": 0, "end_time": 0, "to_self_delay": 20}' > dummy_appointment_data.json + echo '{"tx": "4615a58815475ab8145b6bb90b1268a0dbb02e344ddd483f45052bec1f15b1951c1ee7f070a0993da395a5ee92ea3a1c184b5ffdb2507164bf1f8c1364155d48bdbc882eee0868ca69864a807f213f538990ad16f56d7dfb28a18e69e3f31ae9adad229e3244073b7d643b4597ec88bf247b9f73f301b0f25ae8207b02b7709c271da98af19f1db276ac48ba64f099644af1ae2c90edb7def5e8589a1bb17cc72ac42ecf07dd29cff91823938fd0d772c2c92b7ab050f8837efd46197c9b2b3f", "tx_id": "0b9510d92a50c1d67c6f7fc5d47908d96b3eccdea093d89bcbaf05bcfebdd951", "to_self_delay": 20}' > dummy_appointment_data.json ``` - That will create a json file that follows the appointment data structure filled with dummy data and store it in `dummy_appointment_data.json`. **Note**: You'll need to update the `start_time` and `end_time` to match valid block heights. + That will create a json file that follows the appointment data structure filled with dummy data and store it in `dummy_appointment_data.json`. 3. Send the appointment to the tower API. Which will then start monitoring for matching transactions. diff --git a/common/appointment.py b/common/appointment.py index e4a0050..232ed14 100644 --- a/common/appointment.py +++ b/common/appointment.py @@ -9,18 +9,14 @@ class Appointment: Args: locator (:obj:`str`): A 16-byte hex-encoded value used by the tower to detect channel breaches. It serves as a trigger for the tower to decrypt and broadcast the penalty transaction. - start_time (:obj:`int`): The block height where the tower is hired to start watching for breaches. - end_time (:obj:`int`): The block height where the tower will stop watching for breaches. to_self_delay (:obj:`int`): The ``to_self_delay`` encoded in the ``csv`` of the ``to_remote`` output of the commitment transaction that this appointment is covering. encrypted_blob (:obj:`str`): An encrypted blob of data containing a penalty transaction. The tower will decrypt it and broadcast the penalty transaction upon seeing a breach on the blockchain. """ - def __init__(self, locator, start_time, end_time, to_self_delay, encrypted_blob): + def __init__(self, locator, to_self_delay, encrypted_blob): self.locator = locator - self.start_time = start_time # ToDo: #4-standardize-appointment-fields - self.end_time = end_time # ToDo: #4-standardize-appointment-fields self.to_self_delay = to_self_delay self.encrypted_blob = encrypted_blob @@ -33,7 +29,7 @@ class Appointment: Args: appointment_data (:obj:`dict`): a dictionary containing the following keys: - ``{locator, start_time, end_time, to_self_delay, encrypted_blob}`` + ``{locator, to_self_delay, encrypted_blob}`` Returns: :obj:`Appointment `: An appointment initialized using the provided data. @@ -43,16 +39,14 @@ class Appointment: """ locator = appointment_data.get("locator") - start_time = appointment_data.get("start_time") # ToDo: #4-standardize-appointment-fields - end_time = appointment_data.get("end_time") # ToDo: #4-standardize-appointment-fields to_self_delay = appointment_data.get("to_self_delay") encrypted_blob_data = appointment_data.get("encrypted_blob") - if any(v is None for v in [locator, start_time, end_time, to_self_delay, encrypted_blob_data]): + if any(v is None for v in [locator, to_self_delay, encrypted_blob_data]): raise ValueError("Wrong appointment data, some fields are missing") else: - appointment = cls(locator, start_time, end_time, to_self_delay, encrypted_blob_data) + appointment = cls(locator, to_self_delay, encrypted_blob_data) return appointment @@ -67,8 +61,6 @@ class Appointment: # ToDO: #3-improve-appointment-structure appointment = { "locator": self.locator, - "start_time": self.start_time, - "end_time": self.end_time, "to_self_delay": self.to_self_delay, "encrypted_blob": self.encrypted_blob, } @@ -80,17 +72,11 @@ class Appointment: Serializes an appointment to be signed. The serialization follows the same ordering as the fields in the appointment: - locator:start_time:end_time:to_self_delay:encrypted_blob + locator:to_self_delay:encrypted_blob All values are big endian. Returns: :obj:`bytes`: The serialized data to be signed. """ - return ( - unhexlify(self.locator) - + struct.pack(">I", self.start_time) - + struct.pack(">I", self.end_time) - + struct.pack(">I", self.to_self_delay) - + unhexlify(self.encrypted_blob) - ) + return unhexlify(self.locator) + struct.pack(">I", self.to_self_delay) + unhexlify(self.encrypted_blob) diff --git a/teos/inspector.py b/teos/inspector.py index caf87d7..8effcf4 100644 --- a/teos/inspector.py +++ b/teos/inspector.py @@ -65,8 +65,6 @@ class Inspector: raise InspectionFailed(errors.UNKNOWN_JSON_RPC_EXCEPTION, "unexpected error occurred") self.check_locator(appointment_data.get("locator")) - self.check_start_time(appointment_data.get("start_time"), block_height) - self.check_end_time(appointment_data.get("end_time"), appointment_data.get("start_time"), block_height) self.check_to_self_delay(appointment_data.get("to_self_delay")) self.check_blob(appointment_data.get("encrypted_blob")) @@ -100,87 +98,6 @@ class Inspector: elif not is_locator(locator): raise InspectionFailed(errors.APPOINTMENT_WRONG_FIELD_FORMAT, "wrong locator format ({})".format(locator)) - @staticmethod - def check_start_time(start_time, block_height): - """ - Checks if the provided ``start_time`` is correct. - - Start times must be ahead the current best chain tip. - - Args: - start_time (:obj:`int`): the block height at which the tower is requested to start watching for breaches. - block_height (:obj:`int`): the chain height. - - Raises: - :obj:`InspectionFailed`: if any of the fields is wrong. - """ - - if start_time is None: - raise InspectionFailed(errors.APPOINTMENT_EMPTY_FIELD, "empty start_time received") - - elif type(start_time) != int: - raise InspectionFailed( - errors.APPOINTMENT_WRONG_FIELD_TYPE, "wrong start_time data type ({})".format(type(start_time)) - ) - - elif start_time < block_height: - raise InspectionFailed(errors.APPOINTMENT_FIELD_TOO_SMALL, "start_time is in the past") - - elif start_time == block_height: - raise InspectionFailed( - errors.APPOINTMENT_FIELD_TOO_SMALL, - "start_time is too close to current height. Accepted times are: [current_height+1, current_height+6]", - ) - - elif start_time > block_height + 6: - raise InspectionFailed( - errors.APPOINTMENT_FIELD_TOO_BIG, - "start_time is too far in the future. Accepted start times are up to 6 blocks in the future", - ) - - @staticmethod - def check_end_time(end_time, start_time, block_height): - """ - Checks if the provided ``end_time`` is correct. - - End times must be ahead both the ``start_time`` and the current best chain tip. - - Args: - end_time (:obj:`int`): the block height at which the tower is requested to stop watching for breaches. - start_time (:obj:`int`): the block height at which the tower is requested to start watching for breaches. - block_height (:obj:`int`): the chain height. - - Raises: - :obj:`InspectionFailed`: if any of the fields is wrong. - """ - - # TODO: What's too close to the current height is not properly defined. Right now any appointment that ends in - # the future will be accepted (even if it's only one block away). - - if end_time is None: - raise InspectionFailed(errors.APPOINTMENT_EMPTY_FIELD, "empty end_time received") - - elif type(end_time) != int: - raise InspectionFailed( - errors.APPOINTMENT_WRONG_FIELD_TYPE, "wrong end_time data type ({})".format(type(end_time)) - ) - - elif end_time > block_height + BLOCKS_IN_A_MONTH: # 4320 = roughly a month in blocks - raise InspectionFailed( - errors.APPOINTMENT_FIELD_TOO_BIG, "end_time should be within the next month (<= current_height + 4320)" - ) - elif start_time > end_time: - raise InspectionFailed(errors.APPOINTMENT_FIELD_TOO_SMALL, "end_time is smaller than start_time") - - elif start_time == end_time: - raise InspectionFailed(errors.APPOINTMENT_FIELD_TOO_SMALL, "end_time is equal to start_time") - - elif block_height > end_time: - raise InspectionFailed(errors.APPOINTMENT_FIELD_TOO_SMALL, "end_time is in the past") - - elif block_height == end_time: - raise InspectionFailed(errors.APPOINTMENT_FIELD_TOO_SMALL, "end_time is too close to current height") - def check_to_self_delay(self, to_self_delay): """ Checks if the provided ``to_self_delay`` is correct.