Fixes comments, docstrings and some renamings

This commit is contained in:
Sergi Delgado Segura
2020-04-02 15:20:04 +02:00
parent 39f2628b79
commit fe73ee7298
20 changed files with 213 additions and 233 deletions

View File

@@ -9,18 +9,17 @@ class Appointment:
The :class:`Appointment` contains the information regarding an appointment between a client and the Watchtower.
Args:
locator (:mod:`str`): A 16-byte hex-encoded value used by the tower to detect channel breaches. It serves as a
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 (: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.
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:`EncryptedBlob <common.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
def __init__(self, locator, start_time, end_time, to_self_delay, encrypted_blob):
self.locator = locator
self.start_time = start_time # ToDo: #4-standardize-appointment-fields
@@ -36,7 +35,7 @@ class Appointment:
This method is useful to load data from a database.
Args:
appointment_data (:mod:`dict`): a dictionary containing the following keys:
appointment_data (:obj:`dict`): a dictionary containing the following keys:
``{locator, start_time, end_time, to_self_delay, encrypted_blob}``
Returns:
@@ -62,11 +61,10 @@ class Appointment:
def to_dict(self):
"""
Exports an appointment as a dictionary.
Encodes an appointment as a dictionary.
Returns:
:obj:`dict`: A dictionary containing the appointment attributes.
"""
# ToDO: #3-improve-appointment-structure
@@ -90,7 +88,7 @@ class Appointment:
All values are big endian.
Returns:
:mod:`bytes`: The serialized data to be signed.
:obj:`bytes`: The serialized data to be signed.
"""
return (
unhexlify(self.locator)

View File

@@ -21,14 +21,14 @@ class ConfigLoader:
data_dir (:obj:`str`): the path to the data directory where the configuration file may be found.
conf_file_path (:obj:`str`): the path to the config file (the file may not exist).
conf_fields (:obj:`dict`): a dictionary populated with the configuration params and the expected types.
follows the same format as default_conf.
It follows the same format as default_conf.
command_line_conf (:obj:`dict`): a dictionary containing the command line parameters that may replace the
ones in default / config file.
"""
def __init__(self, data_dir, conf_file_name, default_conf, command_line_conf):
self.data_dir = data_dir
self.conf_file_path = self.data_dir + conf_file_name
self.conf_file_path = os.path.join(self.data_dir, conf_file_name)
self.conf_fields = default_conf
self.command_line_conf = command_line_conf
@@ -36,13 +36,13 @@ class ConfigLoader:
"""
Builds a config dictionary from command line, config file and default configuration parameters.
The priority if as follows:
The priority is as follows:
- command line
- config file
- defaults
Returns:
obj:`dict`: a dictionary containing all the configuration parameters.
:obj:`dict`: a dictionary containing all the configuration parameters.
"""
@@ -50,6 +50,7 @@ class ConfigLoader:
file_config = configparser.ConfigParser()
file_config.read(self.conf_file_path)
# Load parameters and cast them to int if necessary
if file_config:
for sec in file_config.sections():
for k, v in file_config.items(sec):
@@ -82,10 +83,10 @@ class ConfigLoader:
Returns:
:obj:`dict`: A dictionary with the same keys as the provided one, but containing only the "value" field as
value if the provided ``conf_fields`` where correct.
value if the provided ``conf_fields`` are correct.
Raises:
ValueError: If any of the dictionary elements does not have the expected type
:obj:`ValueError`: If any of the dictionary elements does not have the expected type.
"""
conf_dict = {}
@@ -104,11 +105,11 @@ class ConfigLoader:
def extend_paths(self):
"""
Extends the relative paths of the ``conf_fields`` dictionary with ``data_dir``.
Extends the relative paths of the ``conf_fields`` dictionary with ``data_dir``.
If an absolute path is given, it'll remain the same.
"""
for key, field in self.conf_fields.items():
if field.get("path") is True and isinstance(field.get("value"), str):
if field.get("path") and isinstance(field.get("value"), str):
self.conf_fields[key]["value"] = os.path.join(self.data_dir, self.conf_fields[key]["value"])

View File

@@ -6,14 +6,14 @@ from coincurve import PrivateKey, PublicKey
from cryptography.exceptions import InvalidTag
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
from common.tools import check_sha256_hex_format
from common.tools import is_256b_hex_str
LN_MESSAGE_PREFIX = b"Lightning Signed Message:"
def sha256d(message):
"""
Compute the sha245d (double sha256) of a given by message.
Compute the sha256 (double sha256) of a given by message.
Args:
message(:obj:`bytes`): the message to be used as input to the hash function.
@@ -46,10 +46,9 @@ def hash_160(message):
# NOTCOVERED
def sigrec_encode(rsig_rid):
"""
Encodes a pk-recoverable signature to be used in LN. ```rsig_rid`` can be obtained trough
Encodes a pk-recoverable signature to be used in LN. ``rsig_rid`` can be obtained trough
``PrivateKey.sign_recoverable``. The required format has the recovery id as the last byte, and for signing LN
messages we need it as the first.
From: https://twitter.com/rusty_twit/status/1182102005914800128
messages we need it as the first. From: https://twitter.com/rusty_twit/status/1182102005914800128
Args:
rsig_rid(:obj:`bytes`): the signature to be encoded.
@@ -94,7 +93,7 @@ logger = None
class Cryptographer:
"""
The :class:`Cryptographer` is the class in charge of all the cryptography in the tower.
The :class:`Cryptographer` is in charge of all the cryptography in the tower.
"""
@staticmethod
@@ -104,21 +103,21 @@ class Cryptographer:
formatted.
Args:
data(:mod:`str`): the data to be encrypted.
secret(:mod:`str`): the secret used to derive the encryption key.
data(:obj:`str`): the data to be encrypted.
secret(:obj:`str`): the secret used to derive the encryption key.
Returns:
:obj:`bool`: Whether or not the ``key`` and ``data`` are properly formatted.
Raises:
ValueError: if either the ``key`` or ``data`` is not properly formatted.
:obj:`ValueError`: if either the ``key`` or ``data`` is not properly formatted.
"""
if len(data) % 2:
error = "Incorrect (Odd-length) value"
raise ValueError(error)
if not check_sha256_hex_format(secret):
if not is_256b_hex_str(secret):
error = "Secret must be a 32-byte hex value (64 hex chars)"
raise ValueError(error)
@@ -127,16 +126,19 @@ class Cryptographer:
@staticmethod
def encrypt(blob, secret):
"""
Encrypts a given :mod:`Blob <common.cli.blob.Blob>` data using ``CHACHA20POLY1305``.
Encrypts a given :obj:`Blob <common.cli.blob.Blob>` data using ``CHACHA20POLY1305``.
``SHA256(secret)`` is used as ``key``, and ``0 (12-byte)`` as ``iv``.
Args:
blob (:mod:`Blob <common.cli.blob.Blob>`): a ``Blob`` object containing a raw penalty transaction.
secret (:mod:`str`): a value to used to derive the encryption key. Should be the dispute txid.
blob (:obj:`Blob <common.cli.blob.Blob>`): a ``Blob`` object containing a raw penalty transaction.
secret (:obj:`str`): a value to used to derive the encryption key. Should be the dispute txid.
Returns:
:obj:`str`: The encrypted data (hex encoded).
Raises:
:obj:`ValueError`: if either the ``secret`` or ``blob`` is not properly formatted.
"""
Cryptographer.check_data_key_format(blob.data, secret)
@@ -162,17 +164,20 @@ class Cryptographer:
# ToDo: #20-test-tx-decrypting-edge-cases
def decrypt(encrypted_blob, secret):
"""
Decrypts a given :mod:`EncryptedBlob <common.encrypted_blob.EncryptedBlob>` using ``CHACHA20POLY1305``.
Decrypts a given :obj:`EncryptedBlob <common.encrypted_blob.EncryptedBlob>` using ``CHACHA20POLY1305``.
``SHA256(secret)`` is used as ``key``, and ``0 (12-byte)`` as ``iv``.
Args:
encrypted_blob(:mod:`EncryptedBlob <common.encrypted_blob.EncryptedBlob>`): an ``EncryptedBlob``
encrypted_blob(:obj:`EncryptedBlob <common.encrypted_blob.EncryptedBlob>`): an ``EncryptedBlob``
potentially containing a penalty transaction.
secret (:mod:`str`): a value to used to derive the decryption key. Should be the dispute txid.
secret (:obj:`str`): a value to used to derive the decryption key. Should be the dispute txid.
Returns:
:obj:`str`: The decrypted data (hex encoded).
Raises:
:obj:`ValueError`: if either the ``secret`` or ``encrypted_blob`` is not properly formatted.
"""
Cryptographer.check_data_key_format(encrypted_blob.data, secret)
@@ -234,17 +239,14 @@ class Cryptographer:
@staticmethod
def load_private_key_der(sk_der):
"""
Creates a :mod:`PrivateKey` object from a given ``DER`` encoded private key.
Creates a :obj:`PrivateKey` from a given ``DER`` encoded private key.
Args:
sk_der(:mod:`str`): a private key encoded in ``DER`` format.
sk_der(:obj:`str`): a private key encoded in ``DER`` format.
Returns:
:mod:`PrivateKey`: A ``PrivateKey`` object.
Raises:
ValueError: if the provided ``pk_der`` data cannot be deserialized (wrong size or format).
TypeError: if the provided ``pk_der`` data is not a string.
:obj:`PrivateKey` or :obj:`None`: A ``PrivateKey`` object. if the private key can be loaded. `None`
otherwise.
"""
try:
sk = PrivateKey.from_der(sk_der)
@@ -261,14 +263,14 @@ class Cryptographer:
@staticmethod
def sign(message, sk):
"""
Signs a given data using a given secret key using ECDSA.
Signs a given data using a given secret key using ECDSA over secp256k1.
Args:
message(:obj:`bytes`): the data to be signed.
sk(:obj:`PrivateKey`): the ECDSA secret key used to signed the data.
Returns:
:obj:`str`: The zbase32 signature of the given message.
:obj:`str` or :obj:`None`: The zbase32 signature of the given message is it can be signed. `None` otherwise.
"""
if not isinstance(message, bytes):
@@ -295,7 +297,7 @@ class Cryptographer:
zb32_sig(:obj:`str`): the zbase32 signature of the message.
Returns:
:obj:`PublicKey`: The recovered public key.
:obj:`PublicKey` or :obj:`None`: The recovered public key if it can be recovered. `None` otherwise.
"""
if not isinstance(message, bytes):
@@ -345,13 +347,14 @@ class Cryptographer:
@staticmethod
def get_compressed_pk(pk):
"""
Computes a compressed, hex encoded, public key given a ``PublicKey`` object.
Computes a compressed, hex-encoded, public key given a ``PublicKey``.
Args:
pk(:obj:`PublicKey`): a given public key.
Returns:
:obj:`str`: A compressed, hex encoded, public key (33-byte long)
:obj:`str` or :obj:`None`: A compressed, hex-encoded, public key (33-byte long) if it can be compressed.
`None` oterwise.
"""
if not isinstance(pk, PublicKey):

View File

@@ -15,9 +15,10 @@ class _StructuredMessage:
class Logger:
"""
The :class:`Logger` is the class in charge of logging events into the log file.
The :class:`Logger` is in charge of logging events into the log file.
Args:
log_name_prefix (:obj:`str`): the prefix of the logger where the data will be stored in (server, client, ...).
actor (:obj:`str`): the system actor that is logging the event (e.g. ``Watcher``, ``Cryptographer``, ...).
"""
@@ -52,7 +53,7 @@ class Logger:
Args:
msg (:obj:`str`): the message to be logged.
kwargs: a ``key:value`` collection parameters to be added to the output.
kwargs (:obj:`dict`): a ``key:value`` collection parameters to be added to the output.
"""
self.f_logger.info(self._create_file_message(msg, **kwargs))
@@ -64,7 +65,7 @@ class Logger:
Args:
msg (:obj:`str`): the message to be logged.
kwargs: a ``key:value`` collection parameters to be added to the output.
kwargs (:obj:`dict`): a ``key:value`` collection parameters to be added to the output.
"""
self.f_logger.debug(self._create_file_message(msg, **kwargs))
@@ -76,7 +77,7 @@ class Logger:
Args:
msg (:obj:`str`): the message to be logged.
kwargs: a ``key:value`` collection parameters to be added to the output.
kwargs (:obj:`dict`): a ``key:value`` collection parameters to be added to the output.
"""
self.f_logger.error(self._create_file_message(msg, **kwargs))
@@ -88,7 +89,7 @@ class Logger:
Args:
msg (:obj:`str`): the message to be logged.
kwargs: a ``key:value`` collection parameters to be added to the output.
kwargs (:obj:`dict`): a ``key:value`` collection parameters to be added to the output.
"""
self.f_logger.warning(self._create_file_message(msg, **kwargs))

View File

@@ -4,21 +4,21 @@ from pathlib import Path
from common.constants import LOCATOR_LEN_HEX
def check_compressed_pk_format(compressed_pk):
def is_compressed_pk(value):
"""
Checks if a given value is a 33-byte hex encoded string.
Checks if a given value is a 33-byte hex-encoded string starting by 02 or 03.
Args:
compressed_pk(:obj:`str`): the value to be checked.
value(:obj:`str`): the value to be checked.
Returns:
:obj:`bool`: Whether or not the value matches the format.
"""
return isinstance(compressed_pk, str) and re.match(r"^0[2-3][0-9A-Fa-f]{64}$", compressed_pk) is not None
return isinstance(value, str) and re.match(r"^0[2-3][0-9A-Fa-f]{64}$", value) is not None
def check_sha256_hex_format(value):
def is_256b_hex_str(value):
"""
Checks if a given value is a 32-byte hex encoded string.
@@ -31,7 +31,7 @@ def check_sha256_hex_format(value):
return isinstance(value, str) and re.match(r"^[0-9A-Fa-f]{64}$", value) is not None
def check_locator_format(value):
def is_locator(value):
"""
Checks if a given value is a 16-byte hex encoded string.
@@ -61,7 +61,7 @@ def setup_data_folder(data_folder):
Create a data folder for either the client or the server side if the folder does not exists.
Args:
data_folder (:obj:`str`): the path of the folder
data_folder (:obj:`str`): the path of the folder.
"""
Path(data_folder).mkdir(parents=True, exist_ok=True)
@@ -69,9 +69,12 @@ def setup_data_folder(data_folder):
def setup_logging(log_file_path, log_name_prefix):
"""
Setups a couple of loggers (console and file) given a prefix and a file path. The log names are:
Setups a couple of loggers (console and file) given a prefix and a file path.
prefix | _file_log and prefix | _console_log
The log names are:
prefix | _file_log
prefix | _console_log
Args:
log_file_path (:obj:`str`): the path of the file to output the file log.
@@ -80,10 +83,10 @@ def setup_logging(log_file_path, log_name_prefix):
if not isinstance(log_file_path, str):
print(log_file_path)
raise ValueError("Wrong log file path.")
raise ValueError("Wrong log file path")
if not isinstance(log_name_prefix, str):
raise ValueError("Wrong log file name.")
raise ValueError("Wrong log file name")
# Create the file logger
f_logger = logging.getLogger("{}_file_log".format(log_name_prefix))