Integrate parse_node_uri with seednode learning entry

pull/618/head
Kieran Prasch 2018-12-17 14:54:21 -08:00 committed by Kieran Prasch
parent b42cb21f4c
commit f6e4d45466
4 changed files with 35 additions and 14 deletions

View File

@ -33,6 +33,8 @@ from cryptography.hazmat.primitives.serialization import Encoding
from cryptography.x509 import load_pem_x509_certificate, Certificate, NameOID
from eth_utils import to_checksum_address
from twisted.internet import threads
from twisted.logger import Logger
from umbral.keys import UmbralPublicKey
from umbral.signing import Signature
@ -667,8 +669,7 @@ class Ursula(Teacher, Character, Miner):
"""
return cls.from_seed_and_stake_info(checksum_public_address=seednode_metadata.checksum_public_address,
host=seednode_metadata.rest_host,
port=seednode_metadata.rest_port,
seed_uri='{}:{}'.format(seednode_metadata.rest_host, seednode_metadata.rest_port),
*args, **kwargs)
@classmethod
@ -679,19 +680,26 @@ class Ursula(Teacher, Character, Miner):
) -> 'Ursula':
hostname, port, checksum_address = parse_node_uri(uri=teacher_uri)
try:
teacher = cls.from_seed_and_stake_info(host=hostname,
port=port,
federated_only=federated_only,
checksum_public_address=checksum_address,
minimum_stake=min_stake)
except (socket.gaierror, requests.exceptions.ConnectionError, ConnectionRefusedError):
# self.log.warn("Can't connect to seed node. Will retry.")
time.sleep(5) # TODO: Move this 5
def __attempt(round=1, interval=10) -> Ursula:
if round > 3:
raise ConnectionRefusedError("Host {} Refused Connection".format(teacher_uri))
else:
return teacher
try:
teacher = cls.from_seed_and_stake_info(seed_uri='{host}:{port}'.format(host=hostname, port=port),
federated_only=federated_only,
checksum_public_address=checksum_address,
minimum_stake=min_stake)
except (socket.gaierror, requests.exceptions.ConnectionError, ConnectionRefusedError):
log = Logger(cls.__name__)
log.warn("Can't connect to seed node (attempt {}). Will retry in {} seconds.".format(round, interval))
time.sleep(interval)
return __attempt(round=round+1)
else:
return teacher
return __attempt()
@classmethod
@validate_checksum_address

View File

@ -39,6 +39,15 @@ def parse_node_uri(uri: str):
parsed_uri = urlparse(uri)
if not parsed_uri.scheme:
try:
parsed_uri = urlparse('https://'+uri)
except Exception:
raise # TODO: Do we need even deeper handling/validation here?
if not parsed_uri.scheme == "https":
raise ValueError("Invalid teacher scheme or protocol. Is the hostname prefixed with 'https://' ?")
hostname = parsed_uri.hostname
port = parsed_uri.port or UrsulaConfiguration.DEFAULT_REST_PORT
return hostname, port, checksum_address

View File

@ -176,17 +176,18 @@ class ProxyRESTRoutes:
def all_known_nodes(self, request: Request):
headers = {'Content-Type': 'application/octet-stream'}
payload = self._node_tracker.snapshot()
ursulas_as_vbytes = (VariableLengthBytestring(n) for n in self._node_tracker)
ursulas_as_bytes = bytes().join(bytes(u) for u in ursulas_as_vbytes)
ursulas_as_bytes += VariableLengthBytestring(self._node_bytes_caster())
payload += ursulas_as_bytes
signature = self._stamp(payload)
return Response(bytes(signature) + payload, headers=headers)
def node_metadata_exchange(self, request: Request, query_params: QueryParams):
# If these nodes already have the same fleet state, no exchange is necessary.
learner_fleet_state = query_params.get('fleet')
if learner_fleet_state == self._node_tracker.checksum:
self.log.debug("Learner already knew fleet state {}; doing nothing.".format(learner_fleet_state))
@ -211,9 +212,11 @@ class ProxyRESTRoutes:
@crosstown_traffic()
def learn_about_announced_nodes():
try:
temp_certificate_filepath = self.__forgetful_node_storage.store_node_certificate(
checksum_address=node.checksum_public_address,
certificate=node.certificate)
node.verify_node(self.network_middleware,
accept_federated_only=self.federated_only, # TODO: 466
certificate_filepath=temp_certificate_filepath)

View File

@ -15,6 +15,7 @@ You should have received a copy of the GNU General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
import datetime
import pathlib