removes certificate filepath handling

remotes/origin/v7.4.x
Kieran Prasch 2023-10-21 23:18:19 +02:00 committed by Derek Pierre
parent 1ab6e2e121
commit 13758d14a0
7 changed files with 30 additions and 121 deletions

View File

@ -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

View File

@ -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,
)

View File

@ -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):

View File

@ -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)

View File

@ -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:

View File

@ -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:

View File

@ -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