mirror of https://github.com/nucypher/nucypher.git
Implementing InterfaceInfo.
parent
0c7646fa94
commit
36b86eb6bb
|
@ -16,7 +16,7 @@ from nucypher.network.middleware import RestMiddleware
|
|||
from umbral.keys import UmbralPublicKey
|
||||
|
||||
URSULA = Ursula.from_rest_url(network_middleware=RestMiddleware(),
|
||||
ip_address="localhost",
|
||||
host="localhost",
|
||||
port=3601)
|
||||
|
||||
network_middleware = SandboxRestMiddleware([URSULA])
|
||||
|
|
|
@ -12,7 +12,7 @@ class SandboxRestMiddleware(RestMiddleware):
|
|||
def consider_arrangement(self, contract=None):
|
||||
ursula = Ursula.from_rest_url(
|
||||
self,
|
||||
ip_address="localhost",
|
||||
host="localhost",
|
||||
port=3601,
|
||||
)
|
||||
response = requests.post("https://localhost:3601/consider_arrangement", bytes(contract), verify=False)
|
||||
|
|
|
@ -248,8 +248,8 @@ class Character:
|
|||
"""
|
||||
if rest_address is None:
|
||||
current_teacher = self.current_teacher_node()
|
||||
rest_address = current_teacher.ip_address
|
||||
port = current_teacher.rest_port
|
||||
rest_address = current_teacher.rest_interface.host
|
||||
port = current_teacher.rest_interface.port
|
||||
|
||||
response = self.network_middleware.get_nodes_via_rest(rest_address,
|
||||
port, node_ids=self._node_ids_to_learn_about_immediately)
|
||||
|
@ -262,20 +262,16 @@ class Character:
|
|||
split_nodes = ursula_interface_splitter.repeat(nodes)
|
||||
|
||||
for node_meta in split_nodes:
|
||||
header, sig, pubkey, ether_address, interface_info = node_meta
|
||||
header, sig, pubkey, ether_address, rest_info, dht_info = node_meta
|
||||
message = ether_address + rest_info + dht_info
|
||||
|
||||
if not pubkey in self._known_nodes:
|
||||
if sig.verify(keccak_digest(interface_info), pubkey):
|
||||
|
||||
# GARBAGE GARBAGE GARBAGE
|
||||
rest_address, dht_port, rest_port = msgpack.loads(interface_info)
|
||||
# ENDGARBAGE
|
||||
|
||||
if sig.verify(message, pubkey):
|
||||
|
||||
# TOOD: Is this too eager? Does it make sense to only learn later, when we want to make an Arrangement with this node?
|
||||
ursula = Ursula.from_rest_url(network_middleware=self.network_middleware,
|
||||
ip_address=rest_address.decode("utf-8"),
|
||||
port=rest_port)
|
||||
host=rest_info.host,
|
||||
port=rest_info.port)
|
||||
|
||||
self.remember_node(ursula)
|
||||
|
||||
|
@ -283,7 +279,6 @@ class Character:
|
|||
self._node_ids_to_learn_about_immediately.discard(pubkey)
|
||||
|
||||
else:
|
||||
|
||||
message = "Suspicious Activity: Discovered node with bad signature: {}. " \
|
||||
"Propagated by: {}:{}".format(node_meta, rest_address, port)
|
||||
self.log.warning(message)
|
||||
|
@ -736,18 +731,25 @@ class Ursula(Character, ProxyRESTServer, Miner):
|
|||
pass
|
||||
|
||||
# TODO: 289
|
||||
def __init__(self, is_me=True,
|
||||
def __init__(self,
|
||||
rest_host,
|
||||
rest_port,
|
||||
is_me=True,
|
||||
dht_host=None,
|
||||
dht_port=None,
|
||||
federated_only=False,
|
||||
*args,
|
||||
**kwargs):
|
||||
self.dht_port = dht_port
|
||||
if dht_host:
|
||||
self.dht_interface = InterfaceInfo(host=dht_host, port=dht_port)
|
||||
else:
|
||||
self.dht_interface = constants.NO_INTERFACE.bool_value(False)
|
||||
self._work_orders = []
|
||||
|
||||
Character.__init__(self, is_me=is_me, *args, **kwargs)
|
||||
if not federated_only:
|
||||
Miner.__init__(self, is_me=is_me, *args, **kwargs)
|
||||
ProxyRESTServer.__init__(self, *args, **kwargs)
|
||||
ProxyRESTServer.__init__(self, host=rest_host, port=rest_port, *args, **kwargs)
|
||||
|
||||
if is_me is True:
|
||||
self.attach_dht_server()
|
||||
|
|
|
@ -114,3 +114,30 @@ class NucypherSeedOnlyProtocol(NucypherHashProtocol):
|
|||
"got a store request from %s, but THIS VALUE WILL NOT BE STORED as this is a seed-only node." % str(
|
||||
sender))
|
||||
return True
|
||||
|
||||
|
||||
class InterfaceInfo:
|
||||
|
||||
expected_bytes_length = lambda: VariableLengthBytestring
|
||||
|
||||
def __init__(self, host, port):
|
||||
self.host = host
|
||||
self.port = port
|
||||
|
||||
@classmethod
|
||||
def from_bytes(cls, url_string):
|
||||
host_bytes, port_bytes = url_string.split(b":")
|
||||
port = int.from_bytes(port_bytes, "big")
|
||||
host = host_bytes.decode("utf-8")
|
||||
return cls(host=host, port=port)
|
||||
|
||||
def __bytes__(self):
|
||||
return bytes(self.host, encoding="utf-8") + b":" + self.port.to_bytes(4, "big")
|
||||
|
||||
def __add__(self, other):
|
||||
return bytes(self) + bytes(other)
|
||||
|
||||
def __radd__(self, other):
|
||||
return bytes(other) + bytes(self)
|
||||
|
||||
ursula_interface_splitter = dht_value_splitter + BytestringSplitter(InterfaceInfo) * 2
|
||||
|
|
|
@ -18,7 +18,7 @@ from nucypher.crypto.kits import UmbralMessageKit
|
|||
from nucypher.crypto.powers import EncryptingPower, SigningPower
|
||||
from nucypher.keystore.threading import ThreadedSession
|
||||
from nucypher.network.protocols import NucypherSeedOnlyProtocol, NucypherHashProtocol, \
|
||||
dht_with_hrac_splitter
|
||||
dht_with_hrac_splitter, InterfaceInfo
|
||||
from nucypher.network.storage import SeedOnlyStorage
|
||||
|
||||
|
||||
|
@ -84,10 +84,9 @@ class NucypherSeedOnlyDHTServer(NucypherDHTServer):
|
|||
|
||||
class ProxyRESTServer:
|
||||
|
||||
def __init__(self, ip_address=None, rest_port=None, db_name=None, *args, **kwargs):
|
||||
"""TODO: A server with no uri...? """
|
||||
self.ip_address = ip_address
|
||||
self.rest_port = rest_port
|
||||
def __init__(self, host=None, port=None, db_name=None, *args, **kwargs):
|
||||
self.rest_interface = InterfaceInfo(host=host, port=port)
|
||||
|
||||
self.db_name = db_name
|
||||
self._rest_app = None
|
||||
|
||||
|
@ -99,7 +98,15 @@ class ProxyRESTServer:
|
|||
instance = cls()
|
||||
|
||||
def public_key(self, power_class: ClassVar):
|
||||
"""Implemented on Ursula subclass"""
|
||||
"""Implemented on Ursula"""
|
||||
raise NotImplementedError
|
||||
|
||||
def public_address(self):
|
||||
"""Implemented on Ursula"""
|
||||
raise NotImplementedError
|
||||
|
||||
def stamp(self, *args, **kwargs):
|
||||
"""Implemented on Ursula"""
|
||||
raise NotImplementedError
|
||||
|
||||
def attach_rest_server(self, db_name):
|
||||
|
@ -112,7 +119,7 @@ class ProxyRESTServer:
|
|||
'POST',
|
||||
self.reencrypt_via_rest),
|
||||
Route('/public_keys', 'GET',
|
||||
self.get_signing_and_encrypting_public_keys),
|
||||
self.public_information),
|
||||
Route('/list_nodes', 'GET',
|
||||
self.list_all_active_nodes_about_which_we_know),
|
||||
Route('/consider_arrangement',
|
||||
|
@ -150,20 +157,25 @@ class ProxyRESTServer:
|
|||
# Actual REST Endpoints and utilities
|
||||
#####################################
|
||||
|
||||
def get_signing_and_encrypting_public_keys(self):
|
||||
def public_information(self):
|
||||
"""
|
||||
REST endpoint for getting both signing and encrypting public keys.
|
||||
REST endpoint for public keys and address..
|
||||
"""
|
||||
|
||||
headers = {'Content-Type': 'application/octet-stream'}
|
||||
# TODO: Calling public_address() works here because this is mixed in with Character, but it's not really right.
|
||||
message = bytes(self.public_key(SigningPower)) + bytes(self.public_key(EncryptingPower)) + self.public_address
|
||||
signature = self.stamp(message)
|
||||
|
||||
response = Response(
|
||||
content=bytes(self.public_key(SigningPower)) + bytes(self.public_key(EncryptingPower)),
|
||||
content=signature + message,
|
||||
headers=headers)
|
||||
|
||||
return response
|
||||
|
||||
def list_all_active_nodes_about_which_we_know(self):
|
||||
headers = {'Content-Type': 'application/octet-stream'}
|
||||
# TODO: mm hmmph *slowly exhales* fffff. Some 227 right here.
|
||||
ursulas_as_bytes = bytes().join(self.dht_server.protocol.ursulas.values())
|
||||
ursulas_as_bytes += self.interface_info_with_metadata()
|
||||
signature = self.stamp(ursulas_as_bytes)
|
||||
|
@ -279,4 +291,3 @@ class ProxyRESTServer:
|
|||
else:
|
||||
# TODO: Make this a proper 500 or whatever.
|
||||
assert False
|
||||
|
||||
|
|
|
@ -61,3 +61,4 @@ def test_alice_can_get_ursulas_keys_via_rest(ursulas):
|
|||
public_keys = {SigningPower: signing_key, EncryptingPower: encrypting_key}
|
||||
stranger_ursula_from_public_keys = Ursula.from_public_keys(public_keys)
|
||||
assert stranger_ursula_from_public_keys == ursulas[0]
|
||||
|
||||
|
|
|
@ -36,9 +36,10 @@ def make_ursulas(ether_addresses: list, ursula_starting_port: int, miners=False)
|
|||
for port, ether_address in enumerate(ether_addresses, start=ursula_starting_port):
|
||||
ursula = Ursula(is_me=True,
|
||||
ether_address=ether_address,
|
||||
dht_host="127.0.0.1",
|
||||
dht_port=port,
|
||||
db_name="test-{}".format(port),
|
||||
ip_address="127.0.0.1",
|
||||
rest_host="127.0.0.1",
|
||||
rest_port=port+100,
|
||||
always_be_learning=False
|
||||
)
|
||||
|
@ -64,7 +65,7 @@ def make_ursulas(ether_addresses: list, ursula_starting_port: int, miners=False)
|
|||
pass
|
||||
|
||||
ursulas.add(ursula)
|
||||
_ALL_URSULAS[ursula.rest_port] = ursula
|
||||
_ALL_URSULAS[ursula.rest_interface.port] = ursula
|
||||
|
||||
for ursula_to_teach in ursulas:
|
||||
# Add other Ursulas as known nodes.
|
||||
|
|
Loading…
Reference in New Issue