mirror of https://github.com/nucypher/nucypher.git
removes certificate filepath handling
parent
1ab6e2e121
commit
13758d14a0
|
@ -791,7 +791,6 @@ class Ursula(Teacher, Character, Operator):
|
|||
domain: str,
|
||||
is_me: bool = True,
|
||||
certificate: Optional[Certificate] = None,
|
||||
certificate_filepath: Optional[Path] = None,
|
||||
metadata: Optional[NodeMetadata] = None,
|
||||
# Blockchain
|
||||
checksum_address: Optional[ChecksumAddress] = None,
|
||||
|
@ -859,11 +858,6 @@ class Ursula(Teacher, Character, Operator):
|
|||
|
||||
# Server
|
||||
self.rest_server = self._make_local_server(host=rest_host, port=rest_port)
|
||||
|
||||
# Self-signed TLS certificate of self for Teacher.__init__
|
||||
certificate_filepath = self._crypto_power.power_ups(
|
||||
TLSHostingPower
|
||||
).keypair.certificate_filepath
|
||||
certificate = self._crypto_power.power_ups(
|
||||
TLSHostingPower
|
||||
).keypair.certificate
|
||||
|
@ -884,7 +878,6 @@ class Ursula(Teacher, Character, Operator):
|
|||
Teacher.__init__(
|
||||
self,
|
||||
certificate=certificate,
|
||||
certificate_filepath=certificate_filepath,
|
||||
)
|
||||
|
||||
self._prometheus_metrics_tracker = None
|
||||
|
|
|
@ -25,11 +25,7 @@ from nucypher.blockchain.eth.registry import (
|
|||
from nucypher.blockchain.eth.signers import Signer
|
||||
from nucypher.characters.lawful import Ursula
|
||||
from nucypher.config import constants
|
||||
from nucypher.config.storages import (
|
||||
ForgetfulNodeStorage,
|
||||
LocalFileBasedNodeStorage,
|
||||
NodeStorage,
|
||||
)
|
||||
from nucypher.config.storages import NodeStorage
|
||||
from nucypher.config.util import cast_paths_from
|
||||
from nucypher.crypto.keystore import Keystore
|
||||
from nucypher.crypto.powers import CryptoPower, CryptoPowerUp
|
||||
|
@ -563,20 +559,8 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
def dev_mode(self) -> bool:
|
||||
return self.__dev_mode
|
||||
|
||||
def _setup_node_storage(self, node_storage=None) -> None:
|
||||
# TODO: Disables node metadata persistence
|
||||
# if self.dev_mode:
|
||||
# node_storage = ForgetfulNodeStorage(registry=self.registry)
|
||||
|
||||
# TODO: Forcibly clears the filesystem of any stored node metadata and certificates...
|
||||
local_node_storage = LocalFileBasedNodeStorage(
|
||||
registry=self.registry, config_root=self.config_root
|
||||
)
|
||||
local_node_storage.clear()
|
||||
self.log.info(f'Cleared peer metadata from {local_node_storage.root_dir}')
|
||||
|
||||
# TODO: Always sets up nodes for in-memory node metadata storage
|
||||
node_storage = ForgetfulNodeStorage(registry=self.registry)
|
||||
def _setup_node_storage(self) -> None:
|
||||
node_storage = NodeStorage()
|
||||
self.node_storage = node_storage
|
||||
|
||||
def forget_nodes(self) -> None:
|
||||
|
@ -666,7 +650,6 @@ class CharacterConfiguration(BaseConfiguration):
|
|||
abort_on_learning_error=self.abort_on_learning_error,
|
||||
start_learning_now=self.start_learning_now,
|
||||
save_metadata=self.save_metadata,
|
||||
node_storage=self.node_storage.payload(),
|
||||
lonely=self.lonely,
|
||||
)
|
||||
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
import os
|
||||
import socket
|
||||
import ssl
|
||||
import time
|
||||
from http import HTTPStatus
|
||||
from pathlib import Path
|
||||
from typing import Optional, Sequence, Tuple, Union
|
||||
<<<<<<< HEAD
|
||||
from typing import Tuple, Union
|
||||
=======
|
||||
from typing import Optional, Sequence
|
||||
>>>>>>> 8233d2ce2 (removes certificate filepath handling)
|
||||
|
||||
import requests
|
||||
import time
|
||||
from constant_sorrow.constants import EXEMPT_FROM_VERIFICATION
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from nucypher_core import FleetStateChecksum, MetadataRequest, NodeMetadata
|
||||
from requests.exceptions import SSLError
|
||||
|
||||
from nucypher import characters
|
||||
from nucypher.blockchain.eth.registry import ContractRegistry
|
||||
from nucypher.config.storages import ForgetfulNodeStorage, NodeStorage
|
||||
from nucypher.network.exceptions import NodeSeemsToBeDown
|
||||
from nucypher.config.storages import NodeStorage
|
||||
from nucypher.utilities.logging import Logger
|
||||
from nucypher.utilities.certs import InMemoryCertSession
|
||||
|
||||
SSL_LOGGER = Logger('ssl-middleware')
|
||||
EXEMPT_FROM_VERIFICATION.bool_value(False)
|
||||
|
@ -35,7 +36,7 @@ MIDDLEWARE_DEFAULT_CERTIFICATE_TIMEOUT = os.getenv(
|
|||
|
||||
|
||||
class NucypherMiddlewareClient:
|
||||
library = requests
|
||||
library = InMemoryCertSession()
|
||||
timeout = MIDDLEWARE_DEFAULT_CONNECT_TIMEOUT
|
||||
|
||||
def __init__(
|
||||
|
@ -51,7 +52,7 @@ class NucypherMiddlewareClient:
|
|||
|
||||
self.registry = registry
|
||||
self.eth_endpoint = eth_endpoint
|
||||
self.storage = storage or ForgetfulNodeStorage() # for certificate storage
|
||||
self.storage = storage or NodeStorage() # for certificate storage
|
||||
|
||||
def get_certificate(
|
||||
self,
|
||||
|
@ -175,14 +176,8 @@ class NucypherMiddlewareClient:
|
|||
host, port, http_client = self.verify_and_parse_node_or_host_and_port(node_or_sprout, host, port)
|
||||
endpoint = f"https://{host}:{port}/{path}"
|
||||
method = getattr(http_client, method_name)
|
||||
response = self._execute_method(method, endpoint, *args, **kwargs)
|
||||
|
||||
response = self._execute_method(node_or_sprout,
|
||||
host,
|
||||
port,
|
||||
method,
|
||||
endpoint,
|
||||
*args,
|
||||
**kwargs)
|
||||
# Handle response
|
||||
cleaned_response = self.response_cleaner(response)
|
||||
if cleaned_response.status_code >= 300:
|
||||
|
@ -212,37 +207,11 @@ class NucypherMiddlewareClient:
|
|||
return method_wrapper
|
||||
|
||||
def _execute_method(self,
|
||||
node_or_sprout,
|
||||
host,
|
||||
port,
|
||||
method,
|
||||
endpoint,
|
||||
*args, **kwargs):
|
||||
# Use existing cached SSL certificate or fetch fresh copy and retry
|
||||
cached_cert_filepath = Path(self.storage.generate_certificate_filepath(host=host, port=port))
|
||||
if cached_cert_filepath.exists():
|
||||
# already cached try it
|
||||
try:
|
||||
# Send request
|
||||
response = self.invoke_method(method, endpoint, verify=cached_cert_filepath,
|
||||
*args, **kwargs)
|
||||
|
||||
# successful use of cached certificate
|
||||
return response
|
||||
except SSLError as e:
|
||||
# ignore this exception - probably means that our cached cert may not be up-to-date.
|
||||
SSL_LOGGER.debug(f"Cached cert for {host}:{port} is invalid {e}")
|
||||
|
||||
# Fetch fresh copy of SSL certificate
|
||||
try:
|
||||
certificate, filepath = self.get_certificate(host=host, port=port)
|
||||
except NodeSeemsToBeDown as e:
|
||||
raise RestMiddleware.Unreachable(
|
||||
message=f'Node {node_or_sprout} {host}:{port} is unreachable: {e}')
|
||||
|
||||
# Send request
|
||||
response = self.invoke_method(method, endpoint, verify=filepath,
|
||||
*args, **kwargs)
|
||||
response = self.invoke_method(method, endpoint, *args, **kwargs)
|
||||
return response
|
||||
|
||||
def node_selector(self, node):
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
import time
|
||||
from collections import defaultdict, deque
|
||||
from contextlib import suppress
|
||||
from pathlib import Path
|
||||
from queue import Queue
|
||||
from typing import Callable, List, Optional, Set, Tuple
|
||||
from typing import List, Optional, Set, Tuple
|
||||
|
||||
import maya
|
||||
import requests
|
||||
import time
|
||||
from constant_sorrow.constants import (
|
||||
CERTIFICATE_NOT_SAVED,
|
||||
FLEET_STATES_MATCH,
|
||||
NO_STORAGE_AVAILABLE,
|
||||
NOT_SIGNED,
|
||||
|
@ -32,7 +30,7 @@ from nucypher.blockchain.eth.constants import NULL_ADDRESS
|
|||
from nucypher.blockchain.eth.domains import TACoDomain
|
||||
from nucypher.blockchain.eth.registry import ContractRegistry
|
||||
from nucypher.config.constants import SeednodeMetadata
|
||||
from nucypher.config.storages import ForgetfulNodeStorage
|
||||
from nucypher.config.storages import NodeStorage
|
||||
from nucypher.crypto.powers import (
|
||||
CryptoPower,
|
||||
DecryptingPower,
|
||||
|
@ -186,16 +184,12 @@ class NodeSprout:
|
|||
|
||||
self._is_finishing = True # Prevent reentrance.
|
||||
_finishing_mutex = self._finishing_mutex
|
||||
|
||||
mature_node = self.finish()
|
||||
|
||||
self.__class__ = mature_node.__class__
|
||||
self.__dict__ = mature_node.__dict__
|
||||
|
||||
# As long as we're doing egregious workarounds, here's another one. # TODO: 1481
|
||||
filepath = mature_node._cert_store_function(certificate=mature_node.certificate, port=mature_node.rest_interface.port)
|
||||
mature_node.certificate_filepath = filepath
|
||||
|
||||
_finishing_mutex.put(self)
|
||||
|
||||
return self # To reduce the awkwardity of renaming; this is always the weird part of polymorphism for me.
|
||||
|
||||
|
||||
|
@ -225,7 +219,7 @@ class Learner:
|
|||
_ROUNDS_WITHOUT_NODES_AFTER_WHICH_TO_SLOW_DOWN = 10
|
||||
|
||||
# For Keeps
|
||||
__DEFAULT_NODE_STORAGE = ForgetfulNodeStorage
|
||||
__DEFAULT_NODE_STORAGE = NodeStorage
|
||||
__DEFAULT_MIDDLEWARE_CLASS = RestMiddleware
|
||||
|
||||
_crashed = False # moved from Character - why was this in Character and not Learner before
|
||||
|
@ -298,8 +292,6 @@ class Learner:
|
|||
raise ValueError("Cannot save nodes without a configured node storage")
|
||||
|
||||
self.node_class = node_class or characters.lawful.Ursula
|
||||
self.node_class.set_cert_storage_function(
|
||||
node_storage.store_node_certificate) # TODO: Fix this temporary workaround for on-disk cert storage. #1481
|
||||
|
||||
known_nodes = known_nodes or tuple()
|
||||
self.unresponsive_startup_nodes = list() # TODO: Buckets - Attempt to use these again later #567
|
||||
|
@ -455,18 +447,6 @@ class Learner:
|
|||
|
||||
if eager:
|
||||
node.mature()
|
||||
stranger_certificate = node.certificate
|
||||
|
||||
# Store node's certificate - It has been seen.
|
||||
certificate_filepath = self.node_storage.store_node_certificate(certificate=stranger_certificate, port=node.rest_interface.port)
|
||||
|
||||
# In some cases (seed nodes or other temp stored certs),
|
||||
# this will update the filepath from the temp location to this one.
|
||||
node.certificate_filepath = certificate_filepath
|
||||
|
||||
# Use this to control whether or not this node performs
|
||||
# blockchain calls to determine if stranger nodes are bonded.
|
||||
# Note: self.registry is composed on blockchainy character subclasses.
|
||||
registry = self.registry if self._verify_node_bonding else None
|
||||
|
||||
try:
|
||||
|
@ -794,6 +774,7 @@ class Learner:
|
|||
self._learning_round += 1
|
||||
|
||||
current_teacher = self.current_teacher_node() # Will raise if there's no available teacher.
|
||||
current_teacher.mature()
|
||||
|
||||
if isinstance(self, Teacher):
|
||||
announce_nodes = [self.metadata()]
|
||||
|
@ -821,7 +802,7 @@ class Learner:
|
|||
# Ugh. The teacher is invalid. Rough.
|
||||
# TODO: Bucket separately and report.
|
||||
unresponsive_nodes.add(current_teacher) # This does nothing.
|
||||
self.known_nodes.mark_as(current_teacher.InvalidNode, current_teacher)
|
||||
# self.known_nodes.mark_as(current_teacher.InvalidNode, current_teacher)
|
||||
self.log.warn(f"Teacher {str(current_teacher)} is invalid: {e}.")
|
||||
# TODO (#567): bucket the node as suspicious
|
||||
return
|
||||
|
@ -975,7 +956,6 @@ class Teacher:
|
|||
|
||||
def __init__(self,
|
||||
certificate: Certificate,
|
||||
certificate_filepath: Path,
|
||||
) -> None:
|
||||
|
||||
#
|
||||
|
@ -983,7 +963,6 @@ class Teacher:
|
|||
#
|
||||
|
||||
self.certificate = certificate
|
||||
self.certificate_filepath = certificate_filepath
|
||||
|
||||
# Assume unverified
|
||||
self.verified_stamp = False
|
||||
|
@ -1009,10 +988,6 @@ class Teacher:
|
|||
class UnbondedOperator(InvalidNode):
|
||||
"""Raised when a node fails verification because it is not bonded to a Staker"""
|
||||
|
||||
@classmethod
|
||||
def set_cert_storage_function(cls, node_storage_function: Callable):
|
||||
cls._cert_store_function = node_storage_function
|
||||
|
||||
def mature(self, *args, **kwargs):
|
||||
"""This is the most mature form, so we do nothing."""
|
||||
return self
|
||||
|
@ -1134,7 +1109,6 @@ class Teacher:
|
|||
network_middleware_client,
|
||||
registry: ContractRegistry = None,
|
||||
eth_endpoint: Optional[str] = None,
|
||||
certificate_filepath: Optional[Path] = None,
|
||||
force: bool = False,
|
||||
) -> bool:
|
||||
"""
|
||||
|
@ -1168,14 +1142,10 @@ class Teacher:
|
|||
# This is both the stamp's client signature and interface metadata check; May raise InvalidNode
|
||||
self.validate_metadata(registry=registry, eth_endpoint=eth_endpoint)
|
||||
|
||||
# The node's metadata is valid; let's be sure the interface is in order.
|
||||
if not certificate_filepath:
|
||||
if self.certificate_filepath is CERTIFICATE_NOT_SAVED:
|
||||
self.certificate_filepath = self._cert_store_function(self.certificate, port=self.rest_interface.port)
|
||||
certificate_filepath = self.certificate_filepath
|
||||
|
||||
response_data = network_middleware_client.node_information(host=self.rest_interface.host,
|
||||
port=self.rest_interface.port)
|
||||
response_data = network_middleware_client.node_information(
|
||||
host=self.rest_interface.host,
|
||||
port=self.rest_interface.port
|
||||
)
|
||||
|
||||
try:
|
||||
sprout = self.from_metadata_bytes(response_data)
|
||||
|
|
|
@ -9,9 +9,9 @@ from requests.exceptions import HTTPError, RequestException
|
|||
|
||||
from nucypher.acumen.perception import FleetSensor
|
||||
from nucypher.blockchain.eth.registry import ContractRegistry
|
||||
from nucypher.config.storages import LocalFileBasedNodeStorage
|
||||
from nucypher.network.exceptions import NodeSeemsToBeDown
|
||||
from nucypher.network.middleware import NucypherMiddlewareClient, RestMiddleware
|
||||
from nucypher.network.middleware import NucypherMiddlewareClient
|
||||
from nucypher.network.middleware import RestMiddleware
|
||||
from nucypher.utilities.logging import Logger
|
||||
|
||||
|
||||
|
@ -69,7 +69,7 @@ def _request(url: str, certificate=None) -> Union[str, None]:
|
|||
def _request_from_node(
|
||||
teacher,
|
||||
eth_endpoint: str,
|
||||
client: Optional[NucypherMiddlewareClient] = None,
|
||||
client: Optional['NucypherMiddlewareClient'] = None,
|
||||
timeout: int = 2,
|
||||
log: Logger = IP_DETECTION_LOGGER,
|
||||
) -> Union[str, None]:
|
||||
|
@ -114,9 +114,6 @@ def get_external_ip_from_default_teacher(
|
|||
log.debug(f'{base_error}: Unknown domain "{domain}".')
|
||||
return
|
||||
|
||||
node_storage = LocalFileBasedNodeStorage()
|
||||
Ursula.set_cert_storage_function(node_storage.store_node_certificate)
|
||||
|
||||
external_ip = None
|
||||
for teacher_uri in TEACHER_NODES[domain]:
|
||||
try:
|
||||
|
|
|
@ -32,7 +32,6 @@ class Dummy: # Teacher
|
|||
def __init__(self, canonical_address):
|
||||
self.canonical_address = canonical_address
|
||||
self.checksum_address = to_checksum_address(canonical_address)
|
||||
self.certificate_filepath = None
|
||||
self.domain = MOCK_DOMAIN
|
||||
|
||||
class GoodResponse:
|
||||
|
|
|
@ -61,8 +61,6 @@ class _TestMiddlewareClient(NucypherMiddlewareClient):
|
|||
|
||||
def invoke_method(self, method, url, *args, **kwargs):
|
||||
self.clean_params(kwargs)
|
||||
|
||||
_cert_location = kwargs.pop("verify") # TODO: Is this something that can be meaningfully tested?
|
||||
kwargs.pop("timeout", None) # Just get rid of timeout; not needed for the test client.
|
||||
response = method(url, *args, **kwargs)
|
||||
return response
|
||||
|
|
Loading…
Reference in New Issue