-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from ggleszczynski/features/implementation
Implementing logic
- Loading branch information
Showing
26 changed files
with
3,532 additions
and
440 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,98 @@ | ||
from abc import ABC, abstractmethod | ||
from dataclasses import dataclass | ||
from enum import Enum | ||
|
||
|
||
class AddressType(Enum): | ||
""" | ||
Possible types of address. | ||
""" | ||
IP = "ip" # IPv4 address | ||
IPV6 = "ipv6" # IPv6 address | ||
DOMAIN = "domain" # domain name | ||
IP = "ip" # IPv4 address | ||
IPV6 = "ipv6" # IPv6 address | ||
DOMAIN = "domain" # domain name | ||
S3 = "s3" # address identifies S3 object (id is object name) | ||
EC2 = "ec2" # address identifies EC2 instance (id is instance id) | ||
|
||
|
||
class Address(ABC): | ||
@dataclass | ||
class Address: | ||
""" | ||
Class describing address, which redirects to original miner's server. | ||
Class describing some address - domain or IP. | ||
""" | ||
|
||
def __init__(self, address_id, address_type: AddressType, address: str, port: int): | ||
""" | ||
Args: | ||
address_id: Identifier (used by AddressManager) of the address. Type depends on the implementation. | ||
address_type: Type of the address. | ||
address: Address. | ||
port: Port of the address. | ||
""" | ||
self.address_id = address_id | ||
self.address_type = address_type | ||
self.address = address | ||
self.port = port | ||
address_id: str | ||
""" identifier (used by AbstractAddressManager implementation) of the address """ | ||
address_type: AddressType | ||
address: str | ||
port: int | ||
|
||
def __repr__(self): | ||
return f"Address(id={self.address_id}, type={self.address_type}, address={self.address}:{self.port})" | ||
|
||
|
||
class AddressSerializerException(Exception): | ||
pass | ||
|
||
|
||
class AddressDeserializationException(AddressSerializerException): | ||
""" | ||
Exception thrown when deserialization of address data fails. | ||
""" | ||
pass | ||
|
||
|
||
class AbstractAddressSerializer(ABC): | ||
""" | ||
Class used to serialize and deserialize addresses. | ||
""" | ||
|
||
@abstractmethod | ||
def encrypt(self) -> bytes: | ||
def serialize(self, address: Address) -> bytes: | ||
""" | ||
Encrypts address data. | ||
Returns: | ||
bytes: Encrypted address data. | ||
Serialize address data. Output format depends on the implementation. | ||
""" | ||
pass | ||
|
||
@classmethod | ||
@abstractmethod | ||
def decrypt(cls, encrypted_data: bytes) -> Address: | ||
def deserialize(self, serialized_data: bytes) -> Address: | ||
""" | ||
Create address from encrypted address data. | ||
Deserialize address data. Throws AddressDeserializationException if data format is not recognized. | ||
Args: | ||
encrypted_data: Encrypted address data. | ||
Returns: | ||
Address: Created address. | ||
serialized_data: Data serialized before by serialize method. | ||
""" | ||
pass | ||
|
||
|
||
class DefaultAddressSerializer(AbstractAddressSerializer): | ||
""" | ||
Address serializer implementation which serialize address to string. | ||
""" | ||
|
||
encoding: str | ||
|
||
def __init__(self, encoding: str = "utf-8"): | ||
""" | ||
Args: | ||
encoding: Encoding used for transforming generated address string to bytes. | ||
""" | ||
self.encoding = encoding | ||
|
||
def serialize(self, address: Address) -> bytes: | ||
assert address.address.find(":") == -1, "Address should not contain colon character" | ||
address_str: str = f"{address.address_type.value}:{address.address}:{address.port}:{address.address_id}" | ||
return address_str.encode(self.encoding) | ||
|
||
def deserialize(self, serialized_data: bytes) -> Address: | ||
try: | ||
address_str: str = serialized_data.decode(self.encoding) | ||
parts = address_str.split(":") | ||
if len(parts) < 4: | ||
raise AddressDeserializationException(f"Invalid number of parts, address_str='{address_str}'") | ||
address_type: AddressType = AddressType(parts[0]) | ||
address: str = parts[1] | ||
port: int = int(parts[2]) | ||
address_id: str = ":".join(parts[3:]) # there can possibly be some colons in address_id | ||
return Address(address_id=address_id, address_type=address_type, address=address, port=port) | ||
except Exception as e: | ||
raise AddressDeserializationException(f"Failed to deserialize address, error='{e}'") from e |
Oops, something went wrong.