diff --git a/duniterpy/api/client.py b/duniterpy/api/client.py index 3bf6ae8e1adf43066f2ebce5b8811245a10712ad..da524ee6eacf6abb47cc188b8ff78e0cb0a639cf 100644 --- a/duniterpy/api/client.py +++ b/duniterpy/api/client.py @@ -94,6 +94,10 @@ def parse_response(response: str, schema: dict) -> Any: ) from exception +class WSConnectionException(Exception): + pass + + class WSConnection: """ Abstraction layer on websocket library @@ -115,7 +119,7 @@ class WSConnection: :return: """ if self.connection is None: - raise Exception("Connection property is empty") + raise WSConnectionException("Connection property is empty") self.connection.send(data) @@ -127,7 +131,7 @@ class WSConnection: :return: """ if self.connection is None: - raise Exception("Connection property is empty") + raise WSConnectionException("Connection property is empty") if timeout is not None: self.connection.settimeout(timeout) return self.connection.recv() @@ -140,7 +144,7 @@ class WSConnection: :return: """ if self.connection is None: - raise Exception("Connection property is empty") + raise WSConnectionException("Connection property is empty") if timeout is not None: self.connection.settimeout(timeout) return json.loads(self.connection.recv()) @@ -152,7 +156,7 @@ class WSConnection: :return: """ if self.connection is None: - raise Exception("Connection property is empty") + raise WSConnectionException("Connection property is empty") self.connection.close() diff --git a/duniterpy/api/ws2p/requests.py b/duniterpy/api/ws2p/requests.py index 2ca9f166e77dd2705104ac65fa1e36f3daed1ce2..1935805d2ed439b7aa7f62abd2060755ab7c0bd9 100644 --- a/duniterpy/api/ws2p/requests.py +++ b/duniterpy/api/ws2p/requests.py @@ -173,6 +173,10 @@ REQUIREMENTS_RESPONSE_SCHEMA = { } +class WS2PException(Exception): + pass + + def get_current(request_id: str) -> str: """ Return ws2p getCurrent() request as json string @@ -180,7 +184,7 @@ def get_current(request_id: str) -> str: :return: """ if not re.fullmatch("^[0-9a-zA-Z]{8}$", request_id): - raise Exception("Invalid ws2p request unique id") + raise WS2PException("Invalid ws2p request unique id") return json.dumps({"reqId": request_id, "body": {"name": "CURRENT", "params": {}}}) @@ -191,7 +195,7 @@ def get_block(request_id: str, block_number: int) -> str: :return: """ if not re.fullmatch("^[0-9a-zA-Z]{8}$", request_id): - raise Exception("Invalid ws2p request unique id") + raise WS2PException("Invalid ws2p request unique id") return json.dumps( { "reqId": request_id, @@ -207,7 +211,7 @@ def get_blocks(request_id: str, from_number: int, count: int) -> str: :return: """ if not re.fullmatch("^[0-9a-zA-Z]{8}$", request_id): - raise Exception("Invalid ws2p request unique id") + raise WS2PException("Invalid ws2p request unique id") return json.dumps( { "reqId": request_id, @@ -226,7 +230,7 @@ def get_requirements_pending(request_id: str, min_cert: int) -> str: :return: """ if not re.fullmatch("^[0-9a-zA-Z]{8}$", request_id): - raise Exception("Invalid ws2p request unique id") + raise WS2PException("Invalid ws2p request unique id") return json.dumps( { "reqId": request_id, diff --git a/duniterpy/documents/block.py b/duniterpy/documents/block.py index 3580159962dcfd0309effac90340e2d893ebc079..47921682c128a147713509625e0612e5e50a8a2c 100644 --- a/duniterpy/documents/block.py +++ b/duniterpy/documents/block.py @@ -35,6 +35,10 @@ BlockType = TypeVar("BlockType", bound="Block") VERSION = 12 +class SignatureException(Exception): + pass + + class Block(Document): """ The class Block handles Block documents. @@ -701,7 +705,7 @@ PreviousIssuer: {self.prev_issuer}\n" :return: """ if self.signature is None: - raise Exception("Signature is None, can not verify signature") + raise SignatureException("Signature is None, can not verify signature") content_to_verify = f"InnerHash: {self.inner_hash}\nNonce: {self.nonce}\n" verifying_key = VerifyingKey(pubkey) diff --git a/duniterpy/documents/document.py b/duniterpy/documents/document.py index 4611980f2fbd50ab6d01dca6f26c9b7097e3f881..c0e85a232af049293f3e42b75be26adf6200bcb6 100644 --- a/duniterpy/documents/document.py +++ b/duniterpy/documents/document.py @@ -23,6 +23,10 @@ from ..constants import SIGNATURE_REGEX from ..key import SigningKey, VerifyingKey +class SignatureException(Exception): + pass + + class MalformedDocumentError(Exception): """ Malformed document exception @@ -147,7 +151,9 @@ class Document: :return: """ if self.signature is None: - raise Exception("Signature is not defined, can not check signature") + raise SignatureException( + "Signature is not defined, can not check signature" + ) verifying_key = VerifyingKey(pubkey) diff --git a/duniterpy/documents/identity.py b/duniterpy/documents/identity.py index 1437320c44a7618e7d1756ab4f428239242cf2a8..923322d9fffb924b1c71a885ccc4cc58e9216350 100644 --- a/duniterpy/documents/identity.py +++ b/duniterpy/documents/identity.py @@ -34,6 +34,10 @@ IdentityType = TypeVar("IdentityType", bound="Identity") VERSION = 10 +class IdentityException(Exception): + pass + + class Identity(Document): """ A document describing a self certification. @@ -315,6 +319,6 @@ Timestamp: {self.block_id}\n" identity.signature = signature if identity is None: - raise Exception("Identity pubkey not found") + raise IdentityException("Identity pubkey not found") return identity diff --git a/duniterpy/documents/transaction.py b/duniterpy/documents/transaction.py index cc7bcbfb878afe11f67f22b7c05e4267f4a0b2f2..7c7afeb586b35a271a5655bd3ca79643e10d93ae 100644 --- a/duniterpy/documents/transaction.py +++ b/duniterpy/documents/transaction.py @@ -455,6 +455,10 @@ class Unlock: return f"{self.index}:{params}" +class SignatureException(Exception): + pass + + # required to type hint cls in classmethod TransactionType = TypeVar("TransactionType", bound="Transaction") @@ -953,13 +957,15 @@ Currency: {self.currency}\n" :return: """ if not self.signatures: - raise Exception("No signatures, can not check signatures") + raise SignatureException("No signatures, can not check signatures") if isinstance(pubkeys, str): pubkeys = [pubkeys] if len(self.signatures) != len(pubkeys): - raise Exception("Number of pubkeys not equal to number of signatures") + raise SignatureException( + "Number of pubkeys not equal to number of signatures" + ) content_to_verify = self.raw() diff --git a/duniterpy/key/crc_pubkey.py b/duniterpy/key/crc_pubkey.py index 810553bef80df5629837ad1d6b45edbcab625bd3..f30028046b3d245496150e95810530852f98be83 100644 --- a/duniterpy/key/crc_pubkey.py +++ b/duniterpy/key/crc_pubkey.py @@ -26,6 +26,10 @@ from duniterpy.tools import ensure_str CRCPubkeyType = TypeVar("CRCPubkeyType", bound="CRCPubkey") +class CRCPubkeyException(Exception): + pass + + class CRCPubkey: """ Class to implement a crc on a pubkey @@ -53,7 +57,7 @@ class CRCPubkey: """ data = CRCPubkey.re_crc_pubkey.match(crc_pubkey) if data is None: - raise Exception(f"Could not parse CRC public key {crc_pubkey}") + raise CRCPubkeyException(f"Could not parse CRC public key {crc_pubkey}") pubkey = data.group(1) crc = data.group(2) return cls(pubkey, crc) diff --git a/duniterpy/key/signing_key.py b/duniterpy/key/signing_key.py index f825164ee2aaa9f7ef0ea388b90e8ae11f94d5d6..95f23ad21a863d5966e1819546c150fdc9d35f83 100644 --- a/duniterpy/key/signing_key.py +++ b/duniterpy/key/signing_key.py @@ -41,6 +41,10 @@ def opener_user_rw(path, flags): return os.open(path, flags, 0o600) +class SigningKeyException(Exception): + pass + + class SigningKey(libnacl.sign.Signer): def __init__(self, seed: bytes) -> None: """ @@ -136,7 +140,7 @@ class SigningKey(libnacl.sign.Signer): regex_seedhex = re.compile("([0-9a-fA-F]{64})") match = re.search(regex_seedhex, seedhex) if not match: - raise Exception("Error: Bad seed hexadecimal format") + raise SigningKeyException("Error: Bad seed hexadecimal format") seedhex = match.groups()[0] seed = convert_seedhex_to_seed(seedhex) return cls(seed) @@ -194,12 +198,16 @@ class SigningKey(libnacl.sign.Signer): # check public key field match = re.search(regex_pubkey, pubsec_content) if not match: - raise Exception("Error: Bad format PubSec v1 file, missing public key") + raise SigningKeyException( + "Error: Bad format PubSec v1 file, missing public key" + ) # check signkey field match = re.search(regex_signkey, pubsec_content) if not match: - raise Exception("Error: Bad format PubSec v1 file, missing sec key") + raise SigningKeyException( + "Error: Bad format PubSec v1 file, missing sec key" + ) # capture signkey signkey_hex = match.groups()[0] @@ -246,7 +254,7 @@ sec: {base58_signing_key}" regex = re.compile("Data: ([1-9A-HJ-NP-Za-km-z]+)", re.MULTILINE) match = re.search(regex, wif_content) if not match: - raise Exception("Error: Bad format WIF or EWIF v1 file") + raise SigningKeyException("Error: Bad format WIF or EWIF v1 file") # capture hexa wif key wif_hex = match.groups()[0] @@ -271,7 +279,7 @@ sec: {base58_signing_key}" elif fi == b"\x02" and password is not None: result = SigningKey.from_ewif_hex(wif_hex, password) else: - raise Exception("Error: Bad format: not WIF nor EWIF") + raise SigningKeyException("Error: Bad format: not WIF nor EWIF") return result @@ -289,7 +297,7 @@ sec: {base58_signing_key}" regex = re.compile("Data: ([1-9A-HJ-NP-Za-km-z]+)", re.MULTILINE) match = re.search(regex, wif_content) if not match: - raise Exception("Error: Bad format WIF v1 file") + raise SigningKeyException("Error: Bad format WIF v1 file") # capture hexa wif key wif_hex = match.groups()[0] @@ -304,7 +312,7 @@ sec: {base58_signing_key}" """ wif_bytes = Base58Encoder.decode(wif_hex) if len(wif_bytes) != 35: - raise Exception("Error: the size of WIF is invalid") + raise SigningKeyException("Error: the size of WIF is invalid") # extract data checksum_from_wif = wif_bytes[-2:] @@ -314,12 +322,12 @@ sec: {base58_signing_key}" # check WIF format flag if fi != b"\x01": - raise Exception("Error: bad format version, not WIF") + raise SigningKeyException("Error: bad format version, not WIF") # checksum control checksum = libnacl.crypto_hash_sha256(libnacl.crypto_hash_sha256(seed_fi))[0:2] if checksum_from_wif != checksum: - raise Exception("Error: bad checksum of the WIF") + raise SigningKeyException("Error: bad checksum of the WIF") return cls(seed) @@ -364,7 +372,7 @@ Data: {wif_key}" regex = re.compile("Data: ([1-9A-HJ-NP-Za-km-z]+)", re.MULTILINE) match = re.search(regex, wif_content) if not match: - raise Exception("Error: Bad format EWIF v1 file") + raise SigningKeyException("Error: Bad format EWIF v1 file") # capture ewif key ewif_hex = match.groups()[0] @@ -382,7 +390,7 @@ Data: {wif_key}" """ ewif_bytes = Base58Encoder.decode(ewif_hex) if len(ewif_bytes) != 39: - raise Exception("Error: the size of EWIF is invalid") + raise SigningKeyException("Error: the size of EWIF is invalid") # extract data fi = ewif_bytes[0:1] @@ -394,14 +402,14 @@ Data: {wif_key}" # check format flag if fi != b"\x02": - raise Exception("Error: bad format version, not EWIF") + raise SigningKeyException("Error: bad format version, not EWIF") # checksum control checksum = libnacl.crypto_hash_sha256( libnacl.crypto_hash_sha256(ewif_no_checksum) )[0:2] if checksum_from_ewif != checksum: - raise Exception("Error: bad checksum of the EWIF") + raise SigningKeyException("Error: bad checksum of the EWIF") # SCRYPT password_bytes = password.encode("utf-8") @@ -425,7 +433,7 @@ Data: {wif_key}" libnacl.crypto_hash_sha256(Base58Encoder.decode(signer.pubkey)) )[0:4] if salt_from_seed != salt: - raise Exception("Error: bad Password of EWIF address") + raise SigningKeyException("Error: bad Password of EWIF address") return cls(seed) @@ -496,7 +504,7 @@ Data: {ewif_key}" ) match = re.search(regex, ssb_content) if not match: - raise Exception("Error: Bad scuttlebutt secret file") + raise SigningKeyException("Error: Bad scuttlebutt secret file") # capture ssb secret key secret = match.groups()[1]