mirror of
https://github.com/aljazceru/python-teos.git
synced 2025-12-17 22:24:23 +01:00
Last formatting details troughout the codebase
This commit is contained in:
25
pisa/api.py
25
pisa/api.py
@@ -26,9 +26,9 @@ def add_appointment():
|
||||
encoded and contain an ``appointment`` field and optionally a ``signature`` and ``public_key`` fields.
|
||||
|
||||
Returns:
|
||||
``tuple``: A tuple containing the response (``json``) and response code (``int``). For accepted appointments, the
|
||||
``rcode`` is always 0 and the response contains the signed receipt. For rejected appointments, the ``rcode`` is
|
||||
a negative value and the response contains the error message. Error messages can be found at
|
||||
:obj:`tuple`: A tuple containing the response (``json``) and response code (``int``). For accepted appointments,
|
||||
the ``rcode`` is always 0 and the response contains the signed receipt. For rejected appointments, the ``rcode``
|
||||
is a negative value and the response contains the error message. Error messages can be found at
|
||||
:mod:`Errors <pisa.errors>`.
|
||||
"""
|
||||
|
||||
@@ -90,13 +90,13 @@ def get_appointment():
|
||||
The information is requested by ``locator``.
|
||||
|
||||
Returns:
|
||||
``dict``: A json formatted dictionary containing information about the requested appointment.
|
||||
:obj:`dict`: A json formatted dictionary containing information about the requested appointment.
|
||||
|
||||
A ``status`` flag is added to the data provided by either the :mod:`Watcher <pisa.watcher>` or the
|
||||
:mod:`Responder <pisa.responder>` that signals the status of the appointment.
|
||||
A ``status`` flag is added to the data provided by either the :obj:`Watcher <pisa.watcher.Watcher>` or the
|
||||
:obj:`Responder <pisa.responder.Responder>` that signals the status of the appointment.
|
||||
|
||||
- Appointments hold by the :mod:`Watcher <pisa.watcher>` are flagged as ``being_watched``.
|
||||
- Appointments hold by the :mod:`Responder <pisa.responder>` are flagged as ``dispute_triggered``.
|
||||
- Appointments hold by the :obj:`Watcher <pisa.watcher.Watcher>` are flagged as ``being_watched``.
|
||||
- Appointments hold by the :obj:`Responder <pisa.responder.Responder>` are flagged as ``dispute_triggered``.
|
||||
- Unknown appointments are flagged as ``not_found``.
|
||||
"""
|
||||
|
||||
@@ -143,8 +143,9 @@ def get_all_appointments():
|
||||
This endpoint should only be accessible by the administrator. Requests are only allowed from localhost.
|
||||
|
||||
Returns:
|
||||
``dict``: A json formatted dictionary containing all the appointments hold by the :mod:`Watcher <pisa.watcher>`
|
||||
(``watcher_appointments``) and by the :mod:`Responder <pisa.responder>` (``responder_trackers``).
|
||||
:obj:`dict`: A json formatted dictionary containing all the appointments hold by the
|
||||
:obj:`Watcher <pisa.watcher.Watcher>` (``watcher_appointments``) and by the
|
||||
:obj:`Responder <pisa.responder.Responder>` (``responder_trackers``).
|
||||
|
||||
"""
|
||||
|
||||
@@ -172,7 +173,7 @@ def get_block_count():
|
||||
testers about the current block so they can define a dummy appointment without having to run a bitcoin node.
|
||||
|
||||
Returns:
|
||||
``dict``: A json encoded dictionary containing the block height.
|
||||
:obj:`dict`: A json encoded dictionary containing the block height.
|
||||
|
||||
"""
|
||||
|
||||
@@ -184,7 +185,7 @@ def start_api(w):
|
||||
This function starts the Flask server used to run the API.
|
||||
|
||||
Args:
|
||||
w (Watcher): A :mod:`Watcher <pisa.watcher>` object.
|
||||
w (:obj:`Watcher <pisa.watcher.Watcher>`): A ``Watcher`` object.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -5,18 +5,18 @@ from pisa.encrypted_blob import EncryptedBlob
|
||||
|
||||
class Appointment:
|
||||
"""
|
||||
The ``Appointment`` contains the information regarding an appointment between a client and the Watchtower.
|
||||
The :class:`Appointment` contains the information regarding an appointment between a client and the Watchtower.
|
||||
|
||||
Args:
|
||||
locator (str): A 16-byte hex-encoded value used by the tower to detect channel breaches. It serves as a trigger
|
||||
locator (:mod:`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 (int): The block height at which the tower is hired to start watching for breaches.
|
||||
end_time (int): The block height at which the tower will stop watching for breaches.
|
||||
to_self_delay (int): The ``to_self_delay`` encoded in the ``csv`` of the ``htlc`` that this appointment is
|
||||
start_time (:mod:`int`): The block height where the tower is hired to start watching for breaches.
|
||||
end_time (:mod:`int`): The block height where the tower will stop watching for breaches.
|
||||
to_self_delay (:mod:`int`): The ``to_self_delay`` encoded in the ``csv`` of the ``htlc`` that this appointment is
|
||||
covering.
|
||||
encrypted_blob (EncryptedBlob): An :mod:`EncryptedBlob <pisa.encrypted_blob>` object containing an encrypted
|
||||
penalty transaction. The tower will decrypt it and broadcast the penalty transaction upon seeing a breach on
|
||||
the blockchain.
|
||||
encrypted_blob (:obj:`EncryptedBlob <pisa.encrypted_blob.EncryptedBlob>`): An ``EncryptedBlob`` object
|
||||
containing an encrypted penalty transaction. The tower will decrypt it and broadcast the penalty transaction
|
||||
upon seeing a breach on the blockchain.
|
||||
"""
|
||||
|
||||
# DISCUSS: 35-appointment-checks
|
||||
@@ -35,11 +35,11 @@ class Appointment:
|
||||
This method is useful to load data from a database.
|
||||
|
||||
Args:
|
||||
appointment_data (dict): a dictionary containing the following keys:
|
||||
appointment_data (:mod:`dict`): a dictionary containing the following keys:
|
||||
``{locator, start_time, end_time, to_self_delay, encrypted_blob}``
|
||||
|
||||
Returns:
|
||||
``Appointment``: An appointment initialized using the provided data.
|
||||
:obj:`Appointment <pisa.appointment.Appointment>`: An appointment initialized using the provided data.
|
||||
|
||||
Raises:
|
||||
ValueError: If one of the mandatory keys is missing in ``appointment_data``.
|
||||
@@ -64,7 +64,7 @@ class Appointment:
|
||||
Exports an appointment as a dictionary.
|
||||
|
||||
Returns:
|
||||
``dict``: A dictionary containing the appointment attributes.
|
||||
:obj:`dict`: A dictionary containing the appointment attributes.
|
||||
|
||||
"""
|
||||
|
||||
@@ -87,13 +87,13 @@ class Appointment:
|
||||
to store appointments in the database.
|
||||
|
||||
Args:
|
||||
triggered (bool): Whether the dispute has been triggered or not. When an appointment passes from the
|
||||
triggered (:mod:`bool`): Whether the dispute has been triggered or not. When an appointment passes from the
|
||||
:mod:`Watcher <pisa.watcher>` to the :mod:`Responder <pisa.responder>` it is not deleted straightaway.
|
||||
Instead, the appointment is stored in the DB flagged as ``triggered``. This aims to ease handling block
|
||||
reorgs in the future.
|
||||
|
||||
Returns:
|
||||
``str``: A json-encoded str representing the appointment.
|
||||
:obj:`str`: A json-encoded str representing the appointment.
|
||||
"""
|
||||
|
||||
appointment = self.to_dict()
|
||||
|
||||
@@ -7,8 +7,8 @@ logger = Logger("BlockProcessor")
|
||||
|
||||
class BlockProcessor:
|
||||
"""
|
||||
The ``BlockProcessor`` contains methods related to the blockchain. Most of its methods required communication with
|
||||
``bitcoind``.
|
||||
The :class:`BlockProcessor` contains methods related to the blockchain. Most of its methods require communication
|
||||
with ``bitcoind``.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
@@ -17,10 +17,10 @@ class BlockProcessor:
|
||||
Gives a block given a block hash by querying ``bitcoind``.
|
||||
|
||||
Args:
|
||||
block_hash (str): The block hash to be queried.
|
||||
block_hash (:obj:`str`): The block hash to be queried.
|
||||
|
||||
Returns:
|
||||
``dict`` or ``None``: A dictionary containing the requested block data if the block is found.
|
||||
:obj:`dict` or :obj:`None`: A dictionary containing the requested block data if the block is found.
|
||||
|
||||
Returns ``None`` otherwise.
|
||||
"""
|
||||
@@ -40,7 +40,7 @@ class BlockProcessor:
|
||||
Returns the hash of the current best chain tip.
|
||||
|
||||
Returns:
|
||||
``str`` or ``None``: The hash of the block if it can be found.
|
||||
:obj:`str` or :obj:`None`: The hash of the block if it can be found.
|
||||
|
||||
Returns ``None`` otherwise (not even sure this can actually happen).
|
||||
"""
|
||||
@@ -60,7 +60,7 @@ class BlockProcessor:
|
||||
Returns the block height of the best chain.
|
||||
|
||||
Returns:
|
||||
``int`` or ``None``: The block height if it can be computed.
|
||||
:obj:`int` or :obj:`None`: The block height if it can be computed.
|
||||
|
||||
Returns ``None`` otherwise (not even sure this can actually happen).
|
||||
"""
|
||||
@@ -81,10 +81,10 @@ class BlockProcessor:
|
||||
associated metadata given by ``bitcoind`` (e.g. confirmation count).
|
||||
|
||||
Args:
|
||||
raw_tx (str): The hex representation of the transaction.
|
||||
raw_tx (:obj:`str`): The hex representation of the transaction.
|
||||
|
||||
Returns:
|
||||
``dict`` or ``None``: The decoding of the given ``raw_tx`` if the transaction is well formatted.
|
||||
:obj:`dict` or :obj:`None`: The decoding of the given ``raw_tx`` if the transaction is well formatted.
|
||||
|
||||
Returns ``None`` otherwise.
|
||||
"""
|
||||
@@ -105,16 +105,16 @@ class BlockProcessor:
|
||||
This method is used to fetch all the missed information when recovering from a crash. Note that if the two
|
||||
blocks are not part of the same chain, it would return all the blocks up to genesis.
|
||||
|
||||
FIXME: This needs to be integrated with the ChainMaester (soon TM) to allow dealing with forks.
|
||||
|
||||
Args:
|
||||
last_know_block_hash (hex): the hash of the last known block.
|
||||
last_know_block_hash (:obj:`str`): the hash of the last known block.
|
||||
|
||||
Returns:
|
||||
``list``: A list of blocks between the last given block and the current best chain tip, starting from the
|
||||
:obj:`list`: A list of blocks between the last given block and the current best chain tip, starting from the
|
||||
child of ``last_know_block_hash``.
|
||||
"""
|
||||
|
||||
# FIXME: This needs to be integrated with the ChainMaester (soon TM) to allow dealing with forks.
|
||||
|
||||
current_block_hash = self.get_best_block_hash()
|
||||
missed_blocks = []
|
||||
|
||||
@@ -131,11 +131,11 @@ class BlockProcessor:
|
||||
Compute the distance between a given block hash and the best chain tip.
|
||||
|
||||
Args:
|
||||
target_block_hash (str): the hash of the target block (the one to compute the distance form the tip).
|
||||
target_block_hash (:obj:`str`): the hash of the target block (the one to compute the distance form the tip).
|
||||
|
||||
Returns:
|
||||
``int`` or ``None``: The distance between the target and the best chain tip is the target block can be found
|
||||
on the blockchain.
|
||||
:obj:`int` or :obj:`None`: The distance between the target and the best chain tip is the target block can be
|
||||
found on the blockchain.
|
||||
|
||||
Returns ``None`` otherwise.
|
||||
"""
|
||||
|
||||
@@ -6,8 +6,8 @@ from pisa.appointment import Appointment
|
||||
|
||||
class Builder:
|
||||
"""
|
||||
The ``Builder`` class is in charge or reconstructing data loaded from the database and build the data structures
|
||||
of the :mod:`Watcher <pisa.watcher>` and the :mod:`Responder <pisa.responder>`.
|
||||
The :class:`Builder` class is in charge or reconstructing data loaded from the database and build the data
|
||||
structures of the :obj:`Watcher <pisa.watcher.Watcher>` and the :obj:`Responder <pisa.responder.Responder>`.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
@@ -17,15 +17,15 @@ class Builder:
|
||||
dictionary of appointments from the database.
|
||||
|
||||
Args:
|
||||
appointments_data (dict): a dictionary of dictionaries representing all the :mod:`Watcher <pisa.watcher>`
|
||||
appointments stored in the database. The structure is as follows:
|
||||
appointments_data (:obj:`dict`): a dictionary of dictionaries representing all the
|
||||
:obj:`Watcher <pisa.watcher.Watcher>` appointments stored in the database. The structure is as follows:
|
||||
|
||||
``{uuid: {locator: str, start_time: int, ...}, uuid: {locator:...}}``
|
||||
|
||||
Returns:
|
||||
``tuple``: A tuple with two dictionaries. ``appointments`` containing the appointment information in
|
||||
:mod:`Appointment <pisa.appointment>` objects and ``locator_uuid_map`` containing a map of appointment
|
||||
(``uuid:locator``).
|
||||
:obj:`tuple`: A tuple with two dictionaries. ``appointments`` containing the appointment information in
|
||||
:obj:`Appointment <pisa.appointment.Appointment>` objects and ``locator_uuid_map`` containing a map of
|
||||
appointment (``uuid:locator``).
|
||||
"""
|
||||
|
||||
appointments = {}
|
||||
@@ -50,14 +50,15 @@ class Builder:
|
||||
a dictionary of trackers from the database.
|
||||
|
||||
Args:
|
||||
tracker_data (dict): a dictionary of dictionaries representing all the :mod:`Responder <pisa.responder>`
|
||||
trackers stored in the database. The structure is as follows:
|
||||
tracker_data (:obj:`dict`): a dictionary of dictionaries representing all the
|
||||
:mod:`Responder <pisa.responder.Responder>` trackers stored in the database.
|
||||
The structure is as follows:
|
||||
|
||||
``{uuid: {locator: str, dispute_txid: str, ...}, uuid: {locator:...}}``
|
||||
|
||||
Returns:
|
||||
``tuple``: A tuple with two dictionaries. ``trackers`` containing the trackers' information in
|
||||
:class:`TransactionTracker <pisa.responder.TransactionTracker>` objects and a ``tx_tracker_map`` containing
|
||||
:obj:`tuple`: A tuple with two dictionaries. ``trackers`` containing the trackers' information in
|
||||
:obj:`TransactionTracker <pisa.responder.TransactionTracker>` objects and a ``tx_tracker_map`` containing
|
||||
the map of trackers (``penalty_txid: uuid``).
|
||||
|
||||
"""
|
||||
@@ -80,14 +81,14 @@ class Builder:
|
||||
@staticmethod
|
||||
def build_block_queue(missed_blocks):
|
||||
"""
|
||||
Builds a ``Queue`` of block hashes to initialize the :mod:`Watcher <pisa.watcher>` or the
|
||||
:mod:`Responder <pisa.responder>` using backed up data.
|
||||
Builds a ``Queue`` of block hashes to initialize the :mod:`Watcher <pisa.watcher.Watcher>` or the
|
||||
:mod:`Responder <pisa.responder.Responder>` using backed up data.
|
||||
|
||||
Args:
|
||||
missed_blocks (list): list of block hashes missed by the Watchtower (do to a crash or shutdown).
|
||||
missed_blocks (:obj:`list`): list of block hashes missed by the Watchtower (do to a crash or shutdown).
|
||||
|
||||
Returns:
|
||||
``Queue``: A `Queue` containing all the missed blocks hashes.
|
||||
:obj:`Queue`: A ``Queue`` containing all the missed blocks hashes.
|
||||
"""
|
||||
|
||||
block_queue = Queue()
|
||||
|
||||
@@ -11,18 +11,18 @@ logger = Logger("Carrier")
|
||||
|
||||
class Receipt:
|
||||
"""
|
||||
The ``Receipt`` class represent the interaction between the ``Carrier`` and ``bitcoind`` when broadcasting
|
||||
The :class:`Receipt` class represent the interaction between the :obj:`Carrier` and ``bitcoind`` when broadcasting
|
||||
transactions. It is used to signal whether or not a transaction has been successfully broadcast and why.
|
||||
|
||||
Args:
|
||||
delivered (bool): whether or not the transaction has been successfully broadcast.
|
||||
confirmations (int): the number of confirmations of the transaction to broadcast. In certain situations the
|
||||
``Carrier`` may fail to broadcast a transaction because it was already in the blockchain. This attribute
|
||||
signals those situations.
|
||||
reason (int): an error code describing why the transaction broadcast failed.
|
||||
delivered (:obj:`bool`): whether or not the transaction has been successfully broadcast.
|
||||
confirmations (:obj:`int`): the number of confirmations of the transaction to broadcast. In certain situations
|
||||
the :obj:`Carrier` may fail to broadcast a transaction because it was already in the blockchain.
|
||||
This attribute signals those situations.
|
||||
reason (:obj:`int`): an error code describing why the transaction broadcast failed.
|
||||
|
||||
Returns:
|
||||
``Receipt``: A receipt describing whether or not the transaction was delivered. Notice that transactions
|
||||
:obj:`Receipt`: A receipt describing whether or not the transaction was delivered. Notice that transactions
|
||||
that are already on chain are flagged as delivered with a ``confirmations > 0`` whereas new transactions are so
|
||||
with ``confirmations = 0``.
|
||||
"""
|
||||
@@ -35,8 +35,8 @@ class Receipt:
|
||||
|
||||
class Carrier:
|
||||
"""
|
||||
The ``Carrier`` is the class in charge of interacting with ``bitcoind`` to send/get transactions. It uses
|
||||
``Receipt`` objects to report about sending transactions.
|
||||
The :class:`Carrier` is the class in charge of interacting with ``bitcoind`` to send/get transactions. It uses
|
||||
:obj:`Receipt` objects to report about the sending outcome.
|
||||
"""
|
||||
|
||||
# NOTCOVERED
|
||||
@@ -45,11 +45,11 @@ class Carrier:
|
||||
Tries to send a given raw transaction to the Bitcoin network using ``bitcoind``.
|
||||
|
||||
Args:
|
||||
rawtx (str): a (potentially) signed raw transaction ready to be broadcast.
|
||||
txid (str): the transaction id corresponding to ``rawtx``.
|
||||
rawtx (:obj:`str`): a (potentially) signed raw transaction ready to be broadcast.
|
||||
txid (:obj:`str`): the transaction id corresponding to ``rawtx``.
|
||||
|
||||
Returns:
|
||||
``Receipt``: A receipt reporting whether the transaction was successfully delivered or not and why.
|
||||
:obj:`Receipt`: A receipt reporting whether the transaction was successfully delivered or not and why.
|
||||
"""
|
||||
|
||||
try:
|
||||
@@ -108,10 +108,11 @@ class Carrier:
|
||||
Queries transaction data to ``bitcoind`` given a transaction id.
|
||||
|
||||
Args:
|
||||
txid (str): a 32-byte hex-formatted string representing the transaction id.
|
||||
txid (:obj:`str`): a 32-byte hex-formatted string representing the transaction id.
|
||||
|
||||
Returns:
|
||||
``dict`` or ``None``: A dictionary with the transaction data if the transaction can be found on the chain.
|
||||
:obj:`dict` or :obj:`None`: A dictionary with the transaction data if the transaction can be found on the
|
||||
chain.
|
||||
Returns ``None`` otherwise.
|
||||
"""
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ logger = Logger("Cleaner")
|
||||
|
||||
class Cleaner:
|
||||
"""
|
||||
The ``Cleaner`` is the class in charge of removing expired / completed data from the tower.
|
||||
The :class:`Cleaner` is the class in charge of removing expired/completed data from the tower.
|
||||
|
||||
Mutable objects (like dicts) are passed-by-reference in Python, so no return is needed for the Cleaner.
|
||||
"""
|
||||
@@ -14,13 +14,16 @@ class Cleaner:
|
||||
def delete_expired_appointment(expired_appointments, appointments, locator_uuid_map, db_manager):
|
||||
"""
|
||||
Deletes appointments which ``end_time`` has been reached (with no trigger) both from memory
|
||||
(:mod:`Watcher <pisa.watcher>`) and disk.
|
||||
(:obj:`Watcher <pisa.watcher.Watcher>`) and disk.
|
||||
|
||||
Args:
|
||||
expired_appointments (list): a list of appointments to be deleted.
|
||||
appointments (dict): a dictionary containing all the :mod:`Watcher <pisa.watcher>` appointments.
|
||||
locator_uuid_map (dict): a ``locator:uuid`` map for the :mod:`Watcher <pisa.watcher>` appointments.
|
||||
db_manager (DBManager): a :mod:`DBManager <pisa.db_manager>` instance to interact with the database.
|
||||
expired_appointments (:obj:`list`): a list of appointments to be deleted.
|
||||
appointments (:obj:`dict`): a dictionary containing all the :mod:`Watcher <pisa.watcher.Watcher>`
|
||||
appointments.
|
||||
locator_uuid_map (:obj:`dict`): a ``locator:uuid`` map for the :obj:`Watcher <pisa.watcher.Watcher>`
|
||||
appointments.
|
||||
db_manager (:obj:`DBManager <pisa.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
database.
|
||||
"""
|
||||
|
||||
for uuid in expired_appointments:
|
||||
@@ -34,7 +37,7 @@ class Cleaner:
|
||||
else:
|
||||
locator_uuid_map[locator].remove(uuid)
|
||||
|
||||
logger.info("End time reached with no match. Deleting appointment.", locator=locator, uuid=uuid)
|
||||
logger.info("End time reached with no breach. Deleting appointment.", locator=locator, uuid=uuid)
|
||||
|
||||
# Delete appointment from the db
|
||||
db_manager.delete_watcher_appointment(uuid)
|
||||
@@ -42,13 +45,17 @@ class Cleaner:
|
||||
@staticmethod
|
||||
def delete_completed_appointment(uuid, appointments, locator_uuid_map, db_manager):
|
||||
"""
|
||||
Deletes a triggered appointment from memory (:mod:`Watcher <pisa.watcher>`) and flags it as triggered in disk.
|
||||
Deletes a triggered appointment from memory (:obj:`Watcher <pisa.watcher.Watcher>`) and flags it as triggered in
|
||||
disk.
|
||||
|
||||
Args:
|
||||
uuid (str): a unique 16-byte hex-encoded str that identifies the appointment.
|
||||
appointments (dict): a dictionary containing all the :mod:`Watcher <pisa.watcher>` appointments.
|
||||
locator_uuid_map (dict): a ``locator:uuid`` map for the :mod:`Watcher <pisa.watcher>` appointments.
|
||||
db_manager (DBManager): a :mod:`DBManager <pisa.db_manager>` instance to interact with the database.
|
||||
uuid (:obj:`str`): a unique 16-byte hex-encoded str that identifies the appointment.
|
||||
appointments (:obj:`dict`): a dictionary containing all the :obj:`Watcher <pisa.watcher.Watcher>`
|
||||
appointments.
|
||||
locator_uuid_map (:obj:`dict`): a ``locator:uuid`` map for the :obj:`Watcher <pisa.watcher.Watcher>`
|
||||
appointments.
|
||||
db_manager (:obj:`DBManager <pisa.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
database.
|
||||
"""
|
||||
|
||||
# Delete the appointment
|
||||
@@ -69,15 +76,18 @@ class Cleaner:
|
||||
@staticmethod
|
||||
def delete_completed_trackers(completed_trackers, height, trackers, tx_tracker_map, db_manager):
|
||||
"""
|
||||
Deletes a completed tracker both from memory (:mod:`Responder <pisa.responder>`) and disk (from the
|
||||
:mod:`Responder <pisa.responder>` and :mod:`Watcher <pisa.watcher>` databases).
|
||||
Deletes a completed tracker both from memory (:obj:`Responder <pisa.responder.Responder>`) and disk (from the
|
||||
Responder's and Watcher's databases).
|
||||
|
||||
Args:
|
||||
trackers (dict): a dictionary containing all the :mod:`Responder <pisa.responder>` trackers.
|
||||
tx_tracker_map (dict): a ``penalty_txid:uuid`` map for the :mod:`Responder <pisa.responder>` trackers.
|
||||
completed_trackers (list): a list of completed trackers to be deleted.
|
||||
height (int): the block height at which the trackers were completed.
|
||||
db_manager (DBManager): a :mod:`DBManager <pisa.db_manager>` instance to interact with the database.
|
||||
trackers (:obj:`dict`): a dictionary containing all the :obj:`Responder <pisa.responder.Responder>`
|
||||
trackers.
|
||||
tx_tracker_map (:obj:`dict`): a ``penalty_txid:uuid`` map for the :obj:`Responder
|
||||
<pisa.responder.Responder>` trackers.
|
||||
completed_trackers (:obj:`list`): a list of completed trackers to be deleted.
|
||||
height (:obj:`int`): the block height at which the trackers were completed.
|
||||
db_manager (:obj:`DBManager <pisa.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
database.
|
||||
"""
|
||||
|
||||
for uuid, confirmations in completed_trackers:
|
||||
|
||||
@@ -14,19 +14,19 @@ LOCATOR_MAP_PREFIX = "m"
|
||||
|
||||
class DBManager:
|
||||
"""
|
||||
The ``DBManager`` is the class in charge of interacting with the appointments database (``LevelDB``).
|
||||
The :class:`DBManager` is the class in charge of interacting with the appointments database (``LevelDB``).
|
||||
Keys and values are stored as bytes in the database but processed as strings by the manager.
|
||||
|
||||
The database is split in five prefixes:
|
||||
|
||||
- ``WATCHER_PREFIX``, defined as ``b'w``, is used to store :mod:`Watcher <pisa.watcher>` appointments.
|
||||
- ``RESPONDER_PREFIX``, defines as ``b'r``, is used to store :mod:`Responder <pisa.responder>` trackers.
|
||||
- ``WATCHER_LAST_BLOCK_KEY``, defined as ``b'bw``, is used to store the last block hash known by the :mod:`Watcher <pisa.watcher>`.
|
||||
- ``RESPONDER_LAST_BLOCK_KEY``, defined as ``b'br``, is used to store the last block hash known by the :mod:`Responder <pisa.responder>`.
|
||||
- ``WATCHER_PREFIX``, defined as ``b'w``, is used to store :obj:`Watcher <pisa.watcher.Watcher>` appointments.
|
||||
- ``RESPONDER_PREFIX``, defines as ``b'r``, is used to store :obj:`Responder <pisa.responder.Responder>` trackers.
|
||||
- ``WATCHER_LAST_BLOCK_KEY``, defined as ``b'bw``, is used to store the last block hash known by the :obj:`Watcher <pisa.watcher.Watcher>`.
|
||||
- ``RESPONDER_LAST_BLOCK_KEY``, defined as ``b'br``, is used to store the last block hash known by the :obj:`Responder <pisa.responder.Responder>`.
|
||||
- ``LOCATOR_MAP_PREFIX``, defined as ``b'm``, is used to store the ``locator:uuid`` maps.
|
||||
|
||||
Args:
|
||||
db_path (str): the path (relative or absolute) to the system folder containing the database. A fresh new
|
||||
db_path (:obj:`str`): the path (relative or absolute) to the system folder containing the database. A fresh
|
||||
database will be create if the specified path does not contain one.
|
||||
"""
|
||||
|
||||
@@ -48,10 +48,10 @@ class DBManager:
|
||||
``RESPONDER_PREFIX``.
|
||||
|
||||
Args:
|
||||
prefix (str): the prefix of the data to load.
|
||||
prefix (:obj:`str`): the prefix of the data to load.
|
||||
|
||||
Returns:
|
||||
(``dict``): A dictionary containing the requested data (appointments or trackers) indexed by ``uuid``.
|
||||
:obj:`dict`: A dictionary containing the requested data (appointments or trackers) indexed by ``uuid``.
|
||||
|
||||
Returns an empty dictionary if no data is found.
|
||||
"""
|
||||
@@ -70,7 +70,7 @@ class DBManager:
|
||||
Loads the last known block given a key (either ``WATCHER_LAST_BLOCK_KEY`` or ``RESPONDER_LAST_BLOCK_KEY``).
|
||||
|
||||
Returns:
|
||||
(``str`` or ``None``): A 16-byte hex-encoded str representing the last known block hash.
|
||||
:obj:`str` or :obj:`None`: A 16-byte hex-encoded str representing the last known block hash.
|
||||
|
||||
Returns ``None`` if the entry is not found.
|
||||
"""
|
||||
@@ -87,9 +87,9 @@ class DBManager:
|
||||
Creates a new entry in the database.
|
||||
|
||||
Args:
|
||||
key (str): the key of the new entry, used to identify it.
|
||||
value (str): the data stored under the given ``key``.
|
||||
prefix (str): an optional prefix added to the ``key``.
|
||||
key (:obj:`str`): the key of the new entry, used to identify it.
|
||||
value (:obj:`str`): the data stored under the given ``key``.
|
||||
prefix (:obj:`str`): an optional prefix added to the ``key``.
|
||||
"""
|
||||
|
||||
if isinstance(prefix, str):
|
||||
@@ -105,10 +105,10 @@ class DBManager:
|
||||
Loads an entry from the database given a ``key``.
|
||||
|
||||
Args:
|
||||
key (str): the key that identifies the entry to be loaded.
|
||||
key (:obj:`str`): the key that identifies the entry to be loaded.
|
||||
|
||||
Returns:
|
||||
(``dict`` or ``None``): A dictionary containing the requested data (an appointment or a tracker).
|
||||
:obj:`dict` or :obj:`None`: A dictionary containing the requested data (an appointment or a tracker).
|
||||
|
||||
Returns ``None`` if the entry is not found.
|
||||
"""
|
||||
@@ -122,8 +122,8 @@ class DBManager:
|
||||
Deletes an entry from the database given an ``key`` (and optionally a ``prefix``)
|
||||
|
||||
Args:
|
||||
key (str): the key that identifies the data to be deleted.
|
||||
prefix (str): an optional prefix to be prepended to the ``key``.
|
||||
key (:obj:`str`): the key that identifies the data to be deleted.
|
||||
prefix (:obj:`str`): an optional prefix to be prepended to the ``key``.
|
||||
"""
|
||||
|
||||
if isinstance(prefix, str):
|
||||
@@ -138,7 +138,7 @@ class DBManager:
|
||||
Loads an appointment from the database using ``WATCHER_PREFIX`` as prefix to the given ``key``.
|
||||
|
||||
Returns:
|
||||
(``dict``): A dictionary containing the appointment data if they ``key`` is found.
|
||||
:obj:`dict`: A dictionary containing the appointment data if they ``key`` is found.
|
||||
|
||||
Returns ``None`` otherwise.
|
||||
"""
|
||||
@@ -150,7 +150,7 @@ class DBManager:
|
||||
Loads a tracker from the database using ``RESPONDER_PREFIX`` as a prefix to the given ``key``.
|
||||
|
||||
Returns:
|
||||
(``dict``): A dictionary containing the tracker data if they ``key`` is found.
|
||||
:obj:`dict`: A dictionary containing the tracker data if they ``key`` is found.
|
||||
|
||||
Returns ``None`` otherwise.
|
||||
"""
|
||||
@@ -162,12 +162,12 @@ class DBManager:
|
||||
Loads all the appointments from the database (all entries with the ``WATCHER_PREFIX`` prefix).
|
||||
|
||||
Args:
|
||||
include_triggered (bool): Whether to include the appointments flagged as triggered or not. ``False`` by
|
||||
default.
|
||||
include_triggered (:obj:`bool`): Whether to include the appointments flagged as triggered or not. ``False`` by
|
||||
default.
|
||||
|
||||
Returns:
|
||||
(``dict``): A dictionary with all the appointments stored in the database. An empty dictionary is there are
|
||||
none.
|
||||
:obj:`dict`: A dictionary with all the appointments stored in the database. An empty dictionary is there
|
||||
are none.
|
||||
"""
|
||||
|
||||
appointments = self.load_appointments_db(prefix=WATCHER_PREFIX)
|
||||
@@ -184,7 +184,7 @@ class DBManager:
|
||||
Loads all the trackers from the database (all entries with the ``RESPONDER_PREFIX`` prefix).
|
||||
|
||||
Returns:
|
||||
(``dict``): A dictionary with all the trackers stored in the database. An empty dictionary is there are
|
||||
:obj:`dict`: A dictionary with all the trackers stored in the database. An empty dictionary is there are
|
||||
none.
|
||||
"""
|
||||
|
||||
@@ -211,10 +211,10 @@ class DBManager:
|
||||
Loads the ``locator:uuid`` map of a given ``locator`` from the database.
|
||||
|
||||
Args:
|
||||
locator (str): a 16-byte hex-encoded string representing the appointment locator.
|
||||
locator (:obj:`str`): a 16-byte hex-encoded string representing the appointment locator.
|
||||
|
||||
Returns:
|
||||
(``dict`` or ``None``): The requested ``locator:uuid`` map if found.
|
||||
:obj:`dict` or :obj:`None`: The requested ``locator:uuid`` map if found.
|
||||
|
||||
Returns ``None`` otherwise.
|
||||
"""
|
||||
@@ -237,8 +237,8 @@ class DBManager:
|
||||
If the map already exists, the new ``uuid`` is appended to the existing ones (if it is not already there).
|
||||
|
||||
Args:
|
||||
locator (str): a 16-byte hex-encoded string used as the key of the map.
|
||||
uuid (str): a 16-byte hex-encoded unique id to create (or add to) the map.
|
||||
locator (:obj:`str`): a 16-byte hex-encoded string used as the key of the map.
|
||||
uuid (:obj:`str`): a 16-byte hex-encoded unique id to create (or add to) the map.
|
||||
"""
|
||||
|
||||
locator_map = self.load_locator_map(locator)
|
||||
@@ -263,7 +263,7 @@ class DBManager:
|
||||
Deletes a ``locator:uuid`` map.
|
||||
|
||||
Args:
|
||||
locator (str): a 16-byte hex-encoded string identifying the map to delete.
|
||||
locator (:obj:`str`): a 16-byte hex-encoded string identifying the map to delete.
|
||||
"""
|
||||
|
||||
self.delete_entry(locator, prefix=LOCATOR_MAP_PREFIX)
|
||||
@@ -274,7 +274,7 @@ class DBManager:
|
||||
Deletes an appointment from the database.
|
||||
|
||||
Args:
|
||||
uuid (str): a 16-byte hex-encoded string identifying the appointment to be deleted.
|
||||
uuid (:obj:`str`): a 16-byte hex-encoded string identifying the appointment to be deleted.
|
||||
"""
|
||||
|
||||
self.delete_entry(uuid, prefix=WATCHER_PREFIX)
|
||||
@@ -285,7 +285,7 @@ class DBManager:
|
||||
Deletes a tracker from the database.
|
||||
|
||||
Args:
|
||||
uuid (str): a 16-byte hex-encoded string identifying the tracker to be deleted.
|
||||
uuid (:obj:`str`): a 16-byte hex-encoded string identifying the tracker to be deleted.
|
||||
"""
|
||||
|
||||
self.delete_entry(uuid, prefix=RESPONDER_PREFIX)
|
||||
@@ -293,10 +293,10 @@ class DBManager:
|
||||
|
||||
def load_last_block_hash_watcher(self):
|
||||
"""
|
||||
Loads the last known block hash of the :mod:`Watcher <pisa.watcher>` from the database.
|
||||
Loads the last known block hash of the :obj:`Watcher <pisa.watcher.Watcher>` from the database.
|
||||
|
||||
Returns:
|
||||
(``str`` or ``None``): A 32-byte hex-encoded string representing the last known block hash if found.
|
||||
:obj:`str` or :obj:`None`: A 32-byte hex-encoded string representing the last known block hash if found.
|
||||
|
||||
Returns ``None`` otherwise.
|
||||
"""
|
||||
@@ -304,10 +304,10 @@ class DBManager:
|
||||
|
||||
def load_last_block_hash_responder(self):
|
||||
"""
|
||||
Loads the last known block hash of the :mod:`Responder <pisa.responder>` from the database.
|
||||
Loads the last known block hash of the :obj:`Responder <pisa.responder.Responder>` from the database.
|
||||
|
||||
Returns:
|
||||
(``str`` or ``None``): A 32-byte hex-encoded string representing the last known block hash if found.
|
||||
:obj:`str` or :obj:`None`: A 32-byte hex-encoded string representing the last known block hash if found.
|
||||
|
||||
Returns ``None`` otherwise.
|
||||
"""
|
||||
@@ -315,20 +315,20 @@ class DBManager:
|
||||
|
||||
def store_last_block_hash_watcher(self, block_hash):
|
||||
"""
|
||||
Stores a block hash as the last known block of the :mod:`Watcher <pisa.watcher>`.
|
||||
Stores a block hash as the last known block of the :obj:`Watcher <pisa.watcher.Watcher>`.
|
||||
|
||||
Args:
|
||||
block_hash (str): the block hash to be stored (32-byte hex-encoded)
|
||||
block_hash (:obj:`str`): the block hash to be stored (32-byte hex-encoded)
|
||||
"""
|
||||
|
||||
self.create_entry(WATCHER_LAST_BLOCK_KEY, block_hash)
|
||||
|
||||
def store_last_block_hash_responder(self, block_hash):
|
||||
"""
|
||||
Stores a block hash as the last known block of the :mod:`Responder <pisa.responder>`.
|
||||
Stores a block hash as the last known block of the :obj:`Responder <pisa.responder.Responder>`.
|
||||
|
||||
Args:
|
||||
block_hash (str): the block hash to be stored (32-byte hex-encoded)
|
||||
block_hash (:obj:`str`): the block hash to be stored (32-byte hex-encoded)
|
||||
"""
|
||||
|
||||
self.create_entry(RESPONDER_LAST_BLOCK_KEY, block_hash)
|
||||
|
||||
@@ -20,7 +20,7 @@ logger = Logger("Inspector")
|
||||
|
||||
class Inspector:
|
||||
"""
|
||||
The ``Inspector`` class is in charge of verifying that the appointment data provided by the user is correct.
|
||||
The :class:`Inspector` class is in charge of verifying that the appointment data provided by the user is correct.
|
||||
"""
|
||||
|
||||
def inspect(self, appointment_data, signature, public_key):
|
||||
@@ -28,16 +28,17 @@ class Inspector:
|
||||
Inspects whether the data provided by the user is correct.
|
||||
|
||||
Args:
|
||||
appointment_data (dict): a dictionary containing the appointment data.
|
||||
signature (str): the appointment signature provided by the user (hex encoded).
|
||||
public_key (str): the user's public key (hex encoded).
|
||||
appointment_data (:obj:`dict`): a dictionary containing the appointment data.
|
||||
signature (:obj:`str`): the appointment signature provided by the user (hex encoded).
|
||||
public_key (:obj:`str`): the user's public key (hex encoded).
|
||||
|
||||
Returns:
|
||||
``Appointment`` or ``tuple``: An appointment initialized with the provided data if it is correct.
|
||||
:obj:`Appointment <pisa.appointment.Appointment>` or :obj:`tuple`: An appointment initialized with the
|
||||
provided data if it is correct.
|
||||
|
||||
Returns a tuple (`return code`, `message`) describing the error otherwise.
|
||||
Returns a tuple ``(return code, message)`` describing the error otherwise.
|
||||
|
||||
Errors are defined in :mod:`errors <pisa.errors>`.
|
||||
Errors are defined in :mod:`Errors <pisa.errors>`.
|
||||
"""
|
||||
|
||||
block_height = BlockProcessor.get_block_count()
|
||||
@@ -77,10 +78,10 @@ class Inspector:
|
||||
Locators must be 16-byte hex encoded strings.
|
||||
|
||||
Args:
|
||||
locator (str): the locator to be checked.
|
||||
locator (:obj:`str`): the locator to be checked.
|
||||
|
||||
Returns:
|
||||
``tuple``: A tuple (return code, message) as follows:
|
||||
:obj:`tuple`: A tuple (return code, message) as follows:
|
||||
|
||||
- ``(0, None)`` if the ``locator`` is correct.
|
||||
- ``!= (0, None)`` otherwise.
|
||||
@@ -122,11 +123,11 @@ class Inspector:
|
||||
Start times must be ahead the current best chain tip.
|
||||
|
||||
Args:
|
||||
start_time (int): the block height at which the tower is requested to start watching for breaches.
|
||||
block_height (int): the chain height.
|
||||
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.
|
||||
|
||||
Returns:
|
||||
``tuple``: A tuple (return code, message) as follows:
|
||||
:obj:`tuple`: A tuple (return code, message) as follows:
|
||||
|
||||
- ``(0, None)`` if the ``start_time`` is correct.
|
||||
- ``!= (0, None)`` otherwise.
|
||||
@@ -171,12 +172,12 @@ class Inspector:
|
||||
End times must be ahead both the ``start_time`` and the current best chain tip.
|
||||
|
||||
Args:
|
||||
end_time (int): the block height at which the tower is requested to stop watching for breaches.
|
||||
start_time (int): the block height at which the tower is requested to start watching for breaches.
|
||||
block_height (int): the chain height.
|
||||
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.
|
||||
|
||||
Returns:
|
||||
``tuple``: A tuple (return code, message) as follows:
|
||||
:obj:`tuple`: A tuple (return code, message) as follows:
|
||||
|
||||
- ``(0, None)`` if the ``end_time`` is correct.
|
||||
- ``!= (0, None)`` otherwise.
|
||||
@@ -228,11 +229,11 @@ class Inspector:
|
||||
To self delays must be greater or equal to ``MIN_TO_SELF_DELAY``.
|
||||
|
||||
Args:
|
||||
to_self_delay (int): The ``to_self_delay`` encoded in the ``csv`` of the ``htlc`` that this appointment is
|
||||
covering.
|
||||
to_self_delay (:obj:`int`): The ``to_self_delay`` encoded in the ``csv`` of the ``htlc`` that this
|
||||
appointment is covering.
|
||||
|
||||
Returns:
|
||||
``tuple``: A tuple (return code, message) as follows:
|
||||
:obj:`tuple`: A tuple (return code, message) as follows:
|
||||
|
||||
- ``(0, None)`` if the ``to_self_delay`` is correct.
|
||||
- ``!= (0, None)`` otherwise.
|
||||
@@ -271,13 +272,11 @@ class Inspector:
|
||||
"""
|
||||
Checks if the provided ``encrypted_blob`` may be correct.
|
||||
|
||||
FIXME: Currently this only checks format and not empty. It must be improved.
|
||||
|
||||
Args:
|
||||
encrypted_blob (str): the encrypted blob to be checked (hex encoded).
|
||||
encrypted_blob (:obj:`str`): the encrypted blob to be checked (hex encoded).
|
||||
|
||||
Returns:
|
||||
``tuple``: A tuple (return code, message) as follows:
|
||||
:obj:`tuple`: A tuple (return code, message) as follows:
|
||||
|
||||
- ``(0, None)`` if the ``encrypted_blob`` is correct.
|
||||
- ``!= (0, None)`` otherwise.
|
||||
@@ -315,12 +314,12 @@ class Inspector:
|
||||
Checks if the provided user signature is correct.
|
||||
|
||||
Args:
|
||||
appointment (dict): the appointment that was signed by the user.
|
||||
signature (str): the user's signature (hex encoded).
|
||||
pk_der (str): the user's public key (hex encoded, DER format).
|
||||
appointment (:obj:`dict`): the appointment that was signed by the user.
|
||||
signature (:obj:`str`): the user's signature (hex encoded).
|
||||
pk_der (:obj:`str`): the user's public key (hex encoded, DER format).
|
||||
|
||||
Returns:
|
||||
``tuple``: A tuple (return code, message) as follows:
|
||||
:obj:`tuple`: A tuple (return code, message) as follows:
|
||||
|
||||
- ``(0, None)`` if the ``signature`` is correct.
|
||||
- ``!= (0, None)`` otherwise.
|
||||
|
||||
@@ -16,10 +16,10 @@ class _StructuredMessage:
|
||||
|
||||
class Logger:
|
||||
"""
|
||||
The ``Logger`` is the class in charge of logging events into the log file.
|
||||
The :class:`Logger` is the class in charge of logging events into the log file.
|
||||
|
||||
Args:
|
||||
actor (str): the system actor that is logging the event (e.g. ``Watcher``, ``Cryptographer``, ...).
|
||||
actor (:obj:`str`): the system actor that is logging the event (e.g. ``Watcher``, ``Cryptographer``, ...).
|
||||
"""
|
||||
|
||||
def __init__(self, actor=None):
|
||||
@@ -39,7 +39,7 @@ class Logger:
|
||||
Logs an ``INFO`` level message to stdout and file.
|
||||
|
||||
Args:
|
||||
msg (str): the message to be logged.
|
||||
msg (:obj:`str`): the message to be logged.
|
||||
kwargs: a ``key:value`` collection parameters to be added to the output.
|
||||
"""
|
||||
|
||||
@@ -51,7 +51,7 @@ class Logger:
|
||||
Logs an ``DEBUG`` level message to stdout and file.
|
||||
|
||||
Args:
|
||||
msg (str): the message to be logged.
|
||||
msg (:obj:`str`): the message to be logged.
|
||||
kwargs: a ``key:value`` collection parameters to be added to the output.
|
||||
"""
|
||||
|
||||
@@ -63,7 +63,7 @@ class Logger:
|
||||
Logs an ``ERROR`` level message to stdout and file.
|
||||
|
||||
Args:
|
||||
msg (str): the message to be logged.
|
||||
msg (:obj:`str`): the message to be logged.
|
||||
kwargs: a ``key:value`` collection parameters to be added to the output.
|
||||
"""
|
||||
|
||||
@@ -75,7 +75,7 @@ class Logger:
|
||||
Logs an ``WARNING`` level message to stdout and file.
|
||||
|
||||
Args:
|
||||
msg (str): the message to be logged.
|
||||
msg (:obj:`str`): the message to be logged.
|
||||
kwargs: a ``key:value`` collection parameters to be added to the output.
|
||||
"""
|
||||
|
||||
|
||||
@@ -16,20 +16,21 @@ logger = Logger("Responder")
|
||||
|
||||
class TransactionTracker:
|
||||
"""
|
||||
A ``TransactionTracker`` is used to monitor a ``penalty_tx``. Once the dispute is seen by the
|
||||
:mod:`Watcher <pisa.watcher>` the penalty transaction is decrypted and the relevant appointment data is passed
|
||||
along to the ``Responder``.
|
||||
A :class:`TransactionTracker` is used to monitor a ``penalty_tx``. Once the dispute is seen by the
|
||||
:obj:`Watcher <pisa.watcher.Watcher>` the penalty transaction is decrypted and the relevant appointment data is
|
||||
passed along to the :obj:`Responder`.
|
||||
|
||||
Once the ``Responder`` has succeeded on broadcasting the penalty transaction it will create a ``TransactionTracker``
|
||||
and monitor the blockchain until the end of the appointment.
|
||||
Once the :obj:`Responder` has succeeded on broadcasting the penalty transaction it will create a
|
||||
:obj:`TransactionTracker` and monitor the blockchain until the end of the appointment.
|
||||
|
||||
Args:
|
||||
locator (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.
|
||||
dispute_txid (str): the id of the transaction that created the channel breach and triggered the penalty.
|
||||
penalty_txid (str): the id of the transaction that was encrypted under ``dispute_txid``.
|
||||
penalty_rawtx (str): the raw transaction that was broadcast as a consequence of the channel breach.
|
||||
appointment_end (int): the block at which the tower will stop monitoring the blockchain for this appointment.
|
||||
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.
|
||||
dispute_txid (:obj:`str`): the id of the transaction that created the channel breach and triggered the penalty.
|
||||
penalty_txid (:obj:`str`): the id of the transaction that was encrypted under ``dispute_txid``.
|
||||
penalty_rawtx (:obj:`str`): the raw transaction that was broadcast as a consequence of the channel breach.
|
||||
appointment_end (:obj:`int`): the block at which the tower will stop monitoring the blockchain for this
|
||||
appointment.
|
||||
"""
|
||||
|
||||
def __init__(self, locator, dispute_txid, penalty_txid, penalty_rawtx, appointment_end):
|
||||
@@ -42,17 +43,17 @@ class TransactionTracker:
|
||||
@classmethod
|
||||
def from_dict(cls, tx_tracker_data):
|
||||
"""
|
||||
Constructs a ``TransactionTracker`` instance from a dictionary. Requires that all the fields are populated
|
||||
Constructs a :obj:`TransactionTracker` instance from a dictionary. Requires that all the fields are populated
|
||||
(``not None``).
|
||||
|
||||
Useful to load data from the database.
|
||||
|
||||
Args:
|
||||
tx_tracker_data (dict): a dictionary with an entry per each field required to create the
|
||||
``TransactionTracker``.
|
||||
tx_tracker_data (:obj:`dict`): a dictionary with an entry per each field required to create the
|
||||
:obj:`TransactionTracker`.
|
||||
|
||||
Returns:
|
||||
``TransactionTracker``: A ``TransactionTracker`` instantiated with the provided data.
|
||||
:obj:`TransactionTracker`: A ``TransactionTracker`` instantiated with the provided data.
|
||||
|
||||
Raises:
|
||||
ValueError: if any of the required fields is missing.
|
||||
@@ -74,10 +75,10 @@ class TransactionTracker:
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
Exports a ``TransactionTracker`` as a dictionary.
|
||||
Exports a :obj:`TransactionTracker` as a dictionary.
|
||||
|
||||
Returns:
|
||||
``dict``: A dictionary containing the ``TransactionTracker`` data.
|
||||
:obj:`dict`: A dictionary containing the :obj:`TransactionTracker` data.
|
||||
"""
|
||||
|
||||
tx_tracker = {
|
||||
@@ -92,10 +93,10 @@ class TransactionTracker:
|
||||
|
||||
def to_json(self):
|
||||
"""
|
||||
Exports a ``TransactionTracker`` as a json-encoded dictionary.
|
||||
Exports a :obj:`TransactionTracker` as a json-encoded dictionary.
|
||||
|
||||
Returns:
|
||||
``str``: A json-encoded dictionary containing the ``TransactionTracker`` data.
|
||||
:obj:`str`: A json-encoded dictionary containing the :obj:`TransactionTracker` data.
|
||||
"""
|
||||
|
||||
return json.dumps(self.to_dict())
|
||||
@@ -103,29 +104,34 @@ class TransactionTracker:
|
||||
|
||||
class Responder:
|
||||
"""
|
||||
The ``Responder`` is the class in charge of ensuring that channel breaches are dealt with. It does so handling the
|
||||
decrypted ``penalty_txs`` handed by the :mod:`Watcher <pisa.watcher>` and ensuring the they make it to the
|
||||
blockchain.
|
||||
The :class:`Responder` is the class in charge of ensuring that channel breaches are dealt with. It does so handling
|
||||
the decrypted ``penalty_txs`` handed by the :obj:`Watcher <pisa.watcher.Watcher>` and ensuring the they make it to
|
||||
the blockchain.
|
||||
|
||||
The :class:`Responder` can be in two states:
|
||||
|
||||
The ``Responder`` can be in two states:
|
||||
- Asleep (``self.asleep = True)`` when there are no trackers to take care of (``self.trackers`` is empty).
|
||||
- Awake (``self.asleep = False)`` when there are trackers to take care of (actively monitoring the blockchain).
|
||||
|
||||
Args:
|
||||
db_manager (DBManager): a :mod:`DBManager <pisa.db_manager>` instance to interact with the database.
|
||||
db_manager (:obj:`DBManager <pisa.db_manager.DBManager>`): a ``DBManager`` instance to interact with the
|
||||
database.
|
||||
|
||||
Attributes:
|
||||
trackers (``dict``): A dictionary containing all the ``TransactionTrackers`` handled by the ``Responder``.
|
||||
Each entry is identified by a ``uuid``.
|
||||
tx_tracker_map (``dict``): A ``penalty_txid:uuid`` map used to allow the ``Responder`` to deal with several
|
||||
trackers triggered by the same ``penalty_txid``.
|
||||
unconfirmed_txs (``list``): A list that keeps track of all unconfirmed ``penalty_txs``.
|
||||
missed_confirmations (``dict``): a dictionary that keeps count of how many confirmations each ``penalty_tx`` has
|
||||
missed. Used to trigger rebroadcast if needed.
|
||||
asleep (``bool``): A flag that signals whether the ``Responder`` is asleep or awake.
|
||||
block_queue (``Queue``): A queue used by the ``Responder`` to receive block hashes from ``bitcoind``. It is
|
||||
populated by the ``ZMQSubscriber``.
|
||||
db_manager (``DBManager``): A :mod:`DBManager <pisa.db_manager>` instance to interact with the database.
|
||||
trackers (:obj:`dict`): A dictionary containing all the :obj:`TransactionTracker` handled by the
|
||||
:obj:`Responder`. Each entry is identified by a ``uuid``.
|
||||
tx_tracker_map (:obj:`dict`): A ``penalty_txid:uuid`` map used to allow the :obj:`Responder` to deal with
|
||||
several trackers triggered by the same ``penalty_txid``.
|
||||
unconfirmed_txs (:obj:`list`): A list that keeps track of all unconfirmed ``penalty_txs``.
|
||||
missed_confirmations (:obj:`dict`): A dictionary that keeps count of how many confirmations each ``penalty_tx``
|
||||
has missed. Used to trigger rebroadcast if needed.
|
||||
asleep (:obj:`bool`): A flag that signals whether the :obj:`Responder` is asleep or awake.
|
||||
block_queue (:obj:`Queue`): A queue used by the :obj:`Responder` to receive block hashes from ``bitcoind``. It
|
||||
is populated by the :obj:`ZMQSubscriber <pisa.utils.zmq_subscriber.ZMQSubscriber>`.
|
||||
zmq_subscriber (:obj:`ZMQSubscriber <pisa.utils.zmq_subscriber.ZMQSubscriber>`): a ``ZMQSubscriber`` instance
|
||||
used to receive new block notifications from ``bitcoind``.
|
||||
db_manager (:obj:`DBManager <pisa.db_manager.DBManager>`): A ``DBManager`` instance to interact with the
|
||||
database.
|
||||
|
||||
"""
|
||||
|
||||
@@ -142,22 +148,22 @@ class Responder:
|
||||
@staticmethod
|
||||
def on_sync(block_hash):
|
||||
"""
|
||||
Whether the ``Responder`` is on sync with ``bitcoind`` or not. Used when recovering from a crash.
|
||||
Whether the :obj:`Responder` is on sync with ``bitcoind`` or not. Used when recovering from a crash.
|
||||
|
||||
The Watchtower can be instantiated with fresh or with backed up data. In the later, some triggers may have been
|
||||
missed. In order to go back on sync both the ``Watcher`` and the ``Responder`` need to perform the state
|
||||
transitions until they catch up.
|
||||
missed. In order to go back on sync both the :obj:`Watcher <pisa.watcher.Watcher>` and the :obj:`Responder`
|
||||
need to perform the state transitions until they catch up.
|
||||
|
||||
If a transaction is broadcast by the ``Responder`` and it is rejected (due to a double-spending for example)
|
||||
and the ``Responder`` is off-sync then the ``TransactionTracker`` is abandoned.
|
||||
If a transaction is broadcast by the :obj:`Responder` and it is rejected (due to a double-spending for example)
|
||||
and the :obj:`Responder` is off-sync then the :obj:`TransactionTracker` is abandoned.
|
||||
|
||||
This method helps making that decision.
|
||||
|
||||
Args:
|
||||
block_hash (str): the block hash passed to the ``Responder`` in the ``handle_breach`` request.
|
||||
block_hash (:obj:`str`): the block hash passed to the :obj:`Responder` in the ``handle_breach`` request.
|
||||
|
||||
Returns:
|
||||
``bool``: Whether or not the ``Responder`` and ``bitcoind`` are on sync.
|
||||
:obj:`bool`: Whether or not the :obj:`Responder` and ``bitcoind`` are on sync.
|
||||
"""
|
||||
|
||||
block_processor = BlockProcessor()
|
||||
@@ -173,20 +179,20 @@ class Responder:
|
||||
|
||||
def handle_breach(self, uuid, locator, dispute_txid, penalty_txid, penalty_rawtx, appointment_end, block_hash):
|
||||
"""
|
||||
Requests the ``Responder`` to handle a channel breach. This is the entry point of the ``Responder``.
|
||||
Requests the :obj:`Responder` to handle a channel breach. This is the entry point of the :obj:`Responder`.
|
||||
|
||||
Args:
|
||||
uuid (str): a unique identifier for the appointment.
|
||||
locator (str): the appointment locator provided by the user (16-byte hex-encoded).
|
||||
dispute_txid (str): the id of the transaction that created the channel breach.
|
||||
penalty_txid (str): the id of the decrypted transaction included in the appointment.
|
||||
penalty_rawtx (str): the raw transaction to be broadcast in response of the breach.
|
||||
appointment_end (int): the block height at which the ``Responder`` will stop monitoring for this penalty
|
||||
transaction.
|
||||
block_hash (str): the block hash at which the breach was seen (used to see if we are on sync).
|
||||
uuid (:obj:`str`): a unique identifier for the appointment.
|
||||
locator (:obj:`str`): the appointment locator provided by the user (16-byte hex-encoded).
|
||||
dispute_txid (:obj:`str`): the id of the transaction that created the channel breach.
|
||||
penalty_txid (:obj:`str`): the id of the decrypted transaction included in the appointment.
|
||||
penalty_rawtx (:obj:`str`): the raw transaction to be broadcast in response of the breach.
|
||||
appointment_end (:obj:`int`): the block height at which the :obj:`Responder` will stop monitoring for this
|
||||
penalty transaction.
|
||||
block_hash (:obj:`str`): the block hash at which the breach was seen (used to see if we are on sync).
|
||||
|
||||
Returns:
|
||||
``Receipt``: A :mod:`Receipt <pisa.carrier.Receipt>` indicating whether or not the ``penalty_tx`` made it
|
||||
:obj:`Receipt <pisa.carrier.Receipt>`: A ``Receipt`` indicating whether or not the ``penalty_tx`` made it
|
||||
into the blockchain.
|
||||
"""
|
||||
|
||||
@@ -213,22 +219,24 @@ class Responder:
|
||||
|
||||
def add_tracker(self, uuid, locator, dispute_txid, penalty_txid, penalty_rawtx, appointment_end, confirmations=0):
|
||||
"""
|
||||
Creates a ``TransactionTracker`` after successfully broadcasting a ``penalty_tx``.
|
||||
Creates a :obj:`TransactionTracker` after successfully broadcasting a ``penalty_tx``.
|
||||
|
||||
The ``TransactionTracker`` is stored in ``trackers`` and ``tx_tracker_map`` and the ``penalty_txid`` added to
|
||||
The :obj:`TransactionTracker` is stored in ``trackers`` and ``tx_tracker_map`` and the ``penalty_txid`` added to
|
||||
``unconfirmed_txs`` if ``confirmations=0``. Finally, the data is also stored in the database.
|
||||
|
||||
``add_tracker`` awakes the ``Responder`` and creates a connection with the ``ZMQSubscriber`` if he is asleep.
|
||||
``add_tracker`` awakes the :obj:`Responder` and creates a connection with the
|
||||
:obj:`ZMQSubscriber <pisa.utils.zmq_subscriber.ZMQSubscriber>` if he is asleep.
|
||||
|
||||
Args:
|
||||
uuid (str): a unique identifier for the appointment.
|
||||
locator (str): the appointment locator provided by the user (16-byte hex-encoded).
|
||||
dispute_txid (str): the id of the transaction that created the channel breach.
|
||||
penalty_txid (str): the id of the decrypted transaction included in the appointment.
|
||||
penalty_rawtx (str): the raw transaction to be broadcast.
|
||||
appointment_end (int): the block height at which the ``Responder`` will stop monitoring for the tracker.
|
||||
confirmations (int): the confirmation count of the ``penalty_tx``. In normal conditions it will be zero, but
|
||||
if the transaction is already on the blockchain this won't be the case.
|
||||
uuid (:obj:`str`): a unique identifier for the appointment.
|
||||
locator (:obj:`str`): the appointment locator provided by the user (16-byte hex-encoded).
|
||||
dispute_txid (:obj:`str`): the id of the transaction that created the channel breach.
|
||||
penalty_txid (:obj:`str`): the id of the decrypted transaction included in the appointment.
|
||||
penalty_rawtx (:obj:`str`): the raw transaction to be broadcast.
|
||||
appointment_end (:obj:`int`): the block height at which the :obj:`Responder` will stop monitoring for the
|
||||
tracker.
|
||||
confirmations (:obj:`int`): the confirmation count of the ``penalty_tx``. In normal conditions it will be
|
||||
zero, but if the transaction is already on the blockchain this won't be the case.
|
||||
"""
|
||||
|
||||
tracker = TransactionTracker(locator, dispute_txid, penalty_txid, penalty_rawtx, appointment_end)
|
||||
@@ -259,8 +267,8 @@ class Responder:
|
||||
|
||||
def do_subscribe(self):
|
||||
"""
|
||||
Initializes a ``ZMQSubscriber`` instance to listen to new blocks from ``bitcoind``. Block ids are received
|
||||
trough the ``block_queue``.
|
||||
Initializes a :obj:`ZMQSubscriber <pisa.utils.zmq_subscriber.ZMQSubscriber>` instance to listen to new blocks
|
||||
from ``bitcoind``. Block ids are received trough the ``block_queue``.
|
||||
"""
|
||||
|
||||
self.zmq_subscriber = ZMQSubscriber(parent="Responder")
|
||||
@@ -270,7 +278,8 @@ class Responder:
|
||||
"""
|
||||
Monitors the blockchain whilst there are pending trackers.
|
||||
|
||||
This is the main method of the ``Responder`` and triggers tracker cleaning, rebroadcasting, reorg managing, etc.
|
||||
This is the main method of the :obj:`Responder` and triggers tracker cleaning, rebroadcasting, reorg managing,
|
||||
etc.
|
||||
"""
|
||||
|
||||
# ToDo: change prev_block_hash to the last known tip when bootstrapping
|
||||
@@ -316,7 +325,7 @@ class Responder:
|
||||
|
||||
prev_block_hash = block.get("hash")
|
||||
|
||||
# Go back to sleep if there are no more pendong trackers
|
||||
# Go back to sleep if there are no more pending trackers
|
||||
self.asleep = True
|
||||
self.zmq_subscriber.terminate = True
|
||||
self.block_queue = Queue()
|
||||
@@ -330,7 +339,8 @@ class Responder:
|
||||
This method manages ``unconfirmed_txs`` and ``missed_confirmations``.
|
||||
|
||||
Args:
|
||||
txs (list): A list of confirmed tx ids (the list of transactions included in the last received block).
|
||||
txs (:obj:`list`): A list of confirmed tx ids (the list of transactions included in the last received
|
||||
block).
|
||||
"""
|
||||
|
||||
# If a new confirmed tx matches a tx we are watching, then we remove it from the unconfirmed txs map
|
||||
@@ -356,7 +366,7 @@ class Responder:
|
||||
Gets the transactions to be rebroadcast based on their ``missed_confirmation`` count.
|
||||
|
||||
Returns:
|
||||
``list``: A list with all the ids of the transaction that have to be rebroadcast.
|
||||
:obj:`list`: A list with all the ids of the transaction that have to be rebroadcast.
|
||||
"""
|
||||
|
||||
txs_to_rebroadcast = []
|
||||
@@ -374,10 +384,10 @@ class Responder:
|
||||
minimum confirmation count).
|
||||
|
||||
Args:
|
||||
height (int): the height of the last received block.
|
||||
height (:obj:`int`): the height of the last received block.
|
||||
|
||||
Returns:
|
||||
``list``: a list of tuples ``uuid:confirmations`` for the completed trackers.
|
||||
:obj:`list`: a list of tuples ``uuid:confirmations`` for the completed trackers.
|
||||
"""
|
||||
|
||||
completed_trackers = []
|
||||
@@ -402,14 +412,14 @@ class Responder:
|
||||
forever si the transaction keeps not getting it.
|
||||
|
||||
Potentially the fees could be bumped here if the transaction has some tower dedicated outputs (or allows it
|
||||
trough ``ANYONECANSPEND`` or something similar).
|
||||
trough ``ANYONECANPAY`` or something similar).
|
||||
|
||||
Args:
|
||||
txs_to_rebroadcast (list): a list of transactions to be rebroadcast.
|
||||
txs_to_rebroadcast (:obj:`list`): a list of transactions to be rebroadcast.
|
||||
|
||||
Returns:
|
||||
``list``: A list of ``Receipts`` with information about whether or not every transaction made it trough the
|
||||
network.
|
||||
:obj:`list`: A list of :obj:`Receipts <pisa.carrier.Receipt>` with information about whether or not every
|
||||
transaction made it trough the network.
|
||||
"""
|
||||
|
||||
# DISCUSS: #22-discuss-confirmations-before-retry
|
||||
@@ -442,10 +452,10 @@ class Responder:
|
||||
def handle_reorgs(self, block_hash):
|
||||
"""
|
||||
Basic reorg handle. It deals with situations where a reorg has been found but the ``dispute_tx`` is still
|
||||
on the chain. If the ``dispute_tx`` is reverted, it need to call the ``ReorgManager`` (not implemented yet).
|
||||
on the chain. If the ``dispute_tx`` is reverted, it need to call the :obj:`ReorgManager` (Soon TM).
|
||||
|
||||
Args:
|
||||
block_hash (str): the hash of the last block received (which triggered the reorg).
|
||||
block_hash (:obj:`str`): the hash of the last block received (which triggered the reorg).
|
||||
|
||||
"""
|
||||
carrier = Carrier()
|
||||
|
||||
@@ -14,8 +14,8 @@ def bitcoin_cli():
|
||||
An ``http`` connection with ``bitcoind`` using the ``json-rpc`` interface.
|
||||
|
||||
Returns:
|
||||
``AuthServiceProxy``: An authenticated service proxy to ``bitcoind`` that can be used to send ``json-rpc``
|
||||
commands.
|
||||
:obj:`AuthServiceProxy <pisa.utils.auth_proxy.AuthServiceProxy>`: An authenticated service proxy to ``bitcoind``
|
||||
that can be used to send ``json-rpc`` commands.
|
||||
"""
|
||||
|
||||
return AuthServiceProxy(
|
||||
@@ -29,7 +29,7 @@ def can_connect_to_bitcoind():
|
||||
Checks if the tower has connection to ``bitcoind``.
|
||||
|
||||
Returns:
|
||||
``bool``: ``True`` if the connection can be established. ``False`` otherwise.
|
||||
:obj:`bool`: ``True`` if the connection can be established. ``False`` otherwise.
|
||||
"""
|
||||
|
||||
can_connect = True
|
||||
@@ -48,7 +48,7 @@ def in_correct_network(network):
|
||||
``regtest``)
|
||||
|
||||
Returns:
|
||||
``bool``: ``True`` if the network configuration matches. ``False`` otherwise.
|
||||
:obj:`bool`: ``True`` if the network configuration matches. ``False`` otherwise.
|
||||
"""
|
||||
|
||||
mainnet_genesis_block_hash = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
|
||||
|
||||
@@ -17,17 +17,18 @@ logger = Logger("Watcher")
|
||||
|
||||
class Watcher:
|
||||
"""
|
||||
The ``Watcher`` is the class in charge to watch for channel breaches for the appointments accepted by the tower.
|
||||
The :class:`Watcher` is the class in charge to watch for channel breaches for the appointments accepted by the
|
||||
tower.
|
||||
|
||||
The ``Watcher`` keeps track of the accepted appointments in ``appointments`` and, for new received block, checks
|
||||
if any breach has happened by comparing the txids with the appointment locators. If a breach is seen, the
|
||||
:mod:`EncryptedBlob <pisa.encrypted_blob>` of the corresponding appointment is decrypted and the data is passed
|
||||
to the :mod:`Responder <pisa.responder>`.
|
||||
The :class:`Watcher` keeps track of the accepted appointments in ``appointments`` and, for new received block,
|
||||
checks if any breach has happened by comparing the txids with the appointment locators. If a breach is seen, the
|
||||
:obj:`EncryptedBlob <pisa.encrypted_blob.EncryptedBlob>` of the corresponding appointment is decrypted and the data
|
||||
is passed to the :obj:`Responder <pisa.responder.Responder>`.
|
||||
|
||||
If an appointment reaches its end with no breach, the data is simply deleted.
|
||||
|
||||
The ``Watcher`` receives information about new received blocks via the ``block_queue`` that is populated by the
|
||||
:mod:`ZMQSubscriber <pisa.utils.zmq_subscriber>`.
|
||||
The :class:`Watcher` receives information about new received blocks via the ``block_queue`` that is populated by the
|
||||
:obj:`ZMQSubscriber <pisa.utils.zmq_subscriber>`.
|
||||
|
||||
Args:
|
||||
db_manager (:obj:`DBManager <pisa.db_manager>`): a ``DBManager`` instance to interact with the database.
|
||||
@@ -99,8 +100,8 @@ class Watcher:
|
||||
It will go back to sleep once there are no more pending appointments.
|
||||
|
||||
Once a breach is seen on the blockchain, the :obj:`Watcher` will decrypt the corresponding
|
||||
:mod:`EncryptedBlob <pisa.encrypted_blob.EncryptedBlob` and pass the information to the
|
||||
:mod:`Responder <pisa.responder.Responder>`.
|
||||
:obj:`EncryptedBlob <pisa.encrypted_blob.EncryptedBlob>` and pass the information to the
|
||||
:obj:`Responder <pisa.responder.Responder>`.
|
||||
|
||||
The tower may store multiple appointments with the same ``locator`` to avoid DoS attacks based on data
|
||||
rewriting. `locators`` should be derived from the ``dispute_txid``, but that task is performed by the user, and
|
||||
|
||||
Reference in New Issue
Block a user