Shifting things around a bit, introducing ProxyRESTRoutes, and starting to implmenet rest_information().

pull/424/head
jMyles 2018-08-30 17:12:37 +02:00
parent a6baa8c2c7
commit d2250b2a84
4 changed files with 63 additions and 61 deletions

View File

@ -1092,12 +1092,12 @@ class Ursula(Character, VerifiableNode, Miner):
blockchain_power = BlockchainPower(blockchain=self.blockchain, account=self.checksum_public_address)
self._crypto_power.consume_power_up(blockchain_power)
rest_server = ProxyRESTServer(
rest_host=rest_host,
rest_port=rest_port,
db_name=db_name,
tls_private_key=tls_private_key,
tls_curve=tls_curve,
)
tls_hosting_keypair = HostingKeypair(
@ -1117,9 +1117,18 @@ class Ursula(Character, VerifiableNode, Miner):
if not federated_only:
self.substantiate_stamp()
def rest_information(self):
hosting_power = self._crypto_power.power_ups(TLSHostingPower)
return (
hosting_power.rest_server.rest_interface,
hosting_power.keypair.certificate,
hosting_power.keypair.pubkey
)
def __bytes__(self):
interface_info = VariableLengthBytestring(self.rest_interface)
interface_info = VariableLengthBytestring(self.rest_information()[0])
if self.dht_interface:
interface_info += VariableLengthBytestring(self.dht_interface)
@ -1218,11 +1227,13 @@ class Ursula(Character, VerifiableNode, Miner):
@property
def rest_app(self):
if not self._rest_app:
rest_app_on_server = self._crypto_power.power_ups(TLSHostingPower).rest_server._rest_app
if not rest_app_on_server:
m = "This Ursula doesn't have a REST app attached. If you want one, init with is_me and attach_server."
raise AttributeError(m)
else:
return self._rest_app
return rest_app_on_server
def interface_info_with_metadata(self):
# TODO: Do we ever actually use this without using the rest of the serialized Ursula? 337

View File

@ -87,8 +87,8 @@ class VerifiableNode:
self.validate_metadata(accept_federated_only) # This is both the stamp and interface check.
# The node's metadata is valid; let's be sure the interface is in order.
response = network_middleware.node_information(host=self.rest_interface.host,
port=self.rest_interface.port)
response = network_middleware.node_information(host=self.rest_information()[0].host,
port=self.rest_information()[0].port)
if not response.status_code == 200:
raise RuntimeError("Or something.") # TODO: Raise an error here? Or return False? Or something?
signature, identity_evidence, verifying_key, encrypting_key, public_address, rest_info, dht_info = self._internal_splitter(response.content)
@ -112,7 +112,7 @@ class VerifiableNode:
self._evidence_of_decentralized_identity = signature
def _signable_interface_info_message(self):
message = self.canonical_public_address + self.rest_interface + self.dht_interface
message = self.canonical_public_address + self.rest_information()[0] + self.dht_interface
return message
def _sign_interface_info(self):

View File

@ -1,7 +1,7 @@
import asyncio
import binascii
import random
from typing import ClassVar
from logging import getLogger
import kademlia
from apistar import http, Route, App
@ -101,33 +101,47 @@ class NucypherSeedOnlyDHTServer(NucypherDHTServer):
class ProxyRESTServer:
log = getLogger("characters")
def __init__(self,
rest_host=None,
rest_port=None,
db_name=None,
tls_private_key=None,
tls_curve=None,
certificate=None,
common_name=None,
*args, ** kwargs) -> None:
rest_host,
rest_port,
routes,
) -> None:
self.rest_interface = InterfaceInfo(host=rest_host, port=rest_port)
def start_datastore(self, db_name):
if not db_name:
raise TypeError("In order to start a datastore, you need to supply a db_name.")
from nucypher.keystore import keystore
from nucypher.keystore.db import Base
from sqlalchemy.engine import create_engine
self.log.info("Starting datastore {}".format(db_name))
engine = create_engine('sqlite:///{}'.format(db_name))
Base.metadata.create_all(engine)
self.datastore = keystore.KeyStore(engine)
self.db_engine = engine
def rest_url(self):
return "{}:{}".format(self.rest_information()[0].host, self.rest_information()[0].port)
#####################################
# Actual REST Endpoints and utilities
#####################################
def get_deployer(self):
deployer = self._crypto_power.power_ups(TLSHostingPower).get_deployer(rest_app=self._rest_app,
port=self.rest_information()[0].port)
return deployer
class ProxyRESTRoutes:
def __init__(self, db_name=None):
self.db_name = db_name
self._rest_app = None
def public_material(self, power_class: ClassVar):
"""Implemented on Ursula"""
raise NotImplementedError
def canonical_public_address(self):
"""Implemented on Ursula"""
raise NotImplementedError
def stamp(self, *args, **kwargs):
"""Implemented on Ursula"""
raise NotImplementedError
def attach_rest_server(self):
routes = [
Route('/kFrag/{id_as_hex}',
@ -156,27 +170,6 @@ class ProxyRESTServer:
self._rest_app = App(routes=routes)
self.start_datastore(self.db_name)
def start_datastore(self, db_name):
if not db_name:
raise TypeError("In order to start a datastore, you need to supply a db_name.")
from nucypher.keystore import keystore
from nucypher.keystore.db import Base
from sqlalchemy.engine import create_engine
self.log.info("Starting datastore {}".format(db_name))
engine = create_engine('sqlite:///{}'.format(db_name))
Base.metadata.create_all(engine)
self.datastore = keystore.KeyStore(engine)
self.db_engine = engine
def rest_url(self):
return "{}:{}".format(self.rest_interface.host, self.rest_interface.port)
#####################################
# Actual REST Endpoints and utilities
#####################################
def public_information(self):
"""
REST endpoint for public keys and address..
@ -331,11 +324,6 @@ class ProxyRESTServer:
self.log.info("Bad TreasureMap ID; not storing {}".format(treasure_map_id))
assert False
def get_deployer(self):
deployer = self._crypto_power.power_ups(TLSHostingPower).get_deployer(rest_app=self._rest_app,
port=self.rest_interface.port)
return deployer
class TLSHostingPower(KeyPairBasedPower):
_keypair_class = HostingKeypair

View File

@ -96,7 +96,10 @@ def make_ursulas(ether_addresses: list,
ursula.federated_only = True
ursulas.add(ursula)
_TEST_KNOWN_URSULAS_CACHE[ursula.rest_information().port] = ursula
# Store this Ursula in our global cache.
port = ursula.rest_information()[0].port
_TEST_KNOWN_URSULAS_CACHE[port] = ursula
if know_each_other and not bare:
@ -108,7 +111,7 @@ def make_ursulas(ether_addresses: list,
event_loop.run_until_complete(
ursula.dht_server.bootstrap(
[("localhost", starting_port + _c) for _c in range(len(ursulas))]))
ursula.publish_dht_information()
# ursula.publish_dht_information()
return ursulas