def make_ursulas(how_many_ursulas: int, ursula_starting_port: int, config: NucypherConfig) -> list: """ :param how_many_ursulas: How many Ursulas to create. :param ursula_starting_port: The port of the first created Ursula; subsequent Ursulas will increment the port number by 1. :return: A list of created Ursulas """ event_loop = asyncio.get_event_loop() URSULAS = [] for _u in range(how_many_ursulas): port = ursula_starting_port + _u _URSULA = Ursula( dht_port=port, ip_address="127.0.0.1", db_name="test-{}".format(port), rest_port=port + 100, config=config) # TODO: Make ports unstupid and more clear. class MockDatastoreThreadPool(object): def callInThread(self, f, *args, **kwargs): return f(*args, **kwargs) _URSULA.datastore_threadpool = MockDatastoreThreadPool() _URSULA.dht_listen() URSULAS.append(_URSULA) for _counter, ursula in enumerate(URSULAS): event_loop.run_until_complete( ursula.server.bootstrap([("127.0.0.1", ursula_starting_port + _c) for _c in range(how_many_ursulas)])) ursula.publish_dht_information() return URSULAS
def spin_up_ursula(dht_port, rest_port, db_name, teachers=()): metadata_file = "examples-runtime-cruft/node-metadata-{}".format(rest_port) asyncio.set_event_loop(asyncio.new_event_loop() ) # Ugh. Awful. But needed until we shed the DHT. _URSULA = Ursula( dht_port=dht_port, rest_port=rest_port, rest_host="localhost", dht_host="localhost", db_name=db_name, federated_only=True, known_nodes=teachers, ) _URSULA.dht_listen() try: with open(metadata_file, "w") as f: f.write(bytes(_URSULA).hex()) _URSULA.start_learning_loop() _URSULA.get_deployer().run() finally: os.remove(db_name) os.remove(metadata_file)
def make_ursulas(ether_addresses: list, miner_agent=None, miners=False, bare=False, know_each_other=True, **ursula_kwargs) -> Set[Ursula]: """ :param ether_addresses: Ethereum addresses to create ursulas with. :param ursula_starting_port: The port of the first created Ursula; subsequent Ursulas will increment the port number by 1. :param miner_agent: A miner agent instance to use when creating ursulas. :param miners: If True, create staking ursulas on the blockchain from the addresses :param bare: If True, Create an non-learning Ursula without a rest app, dht server or database attached, for testing mining functionality when network transport is not needed. "Just a miner" :return: A list of created Ursulas """ if isinstance(ether_addresses, int): ether_addresses = [to_checksum_address(secure_random(20)) for _ in range(ether_addresses)] event_loop = asyncio.get_event_loop() if not _TEST_KNOWN_URSULAS_CACHE: starting_port = constants.URSULA_PORT_SEED else: starting_port = max(_TEST_KNOWN_URSULAS_CACHE.keys()) + 1 ursulas = set() for port, ether_address in enumerate(ether_addresses, start=starting_port): if bare: ursula = Ursula(is_me=False, # do not attach dht server rest_host="localhost", # TODO: remove rest interface rest_port=port + 100, checksum_address=ether_address, always_be_learning=False, miner_agent=miner_agent, abort_on_learning_error=True, **ursula_kwargs) ursula.is_me = True # Patch to allow execution of transacting methods in tests else: federated_only = not miners if federated_only: ether_address = None ursula = Ursula(is_me=True, checksum_address=ether_address, dht_host="localhost", dht_port=port, db_name="test-{}".format(port), rest_host="localhost", rest_port=port+100, always_be_learning=False, miner_agent=miner_agent, federated_only=federated_only, **ursula_kwargs) ursula.attach_rest_server() class MockDatastoreThreadPool(object): def callInThread(self, f, *args, **kwargs): return f(*args, **kwargs) ursula.datastore_threadpool = MockDatastoreThreadPool() ursula.dht_listen() if miners is True: # TODO: 309 # stake a random amount min_stake, balance = constants.MIN_ALLOWED_LOCKED, ursula.token_balance amount = random.randint(min_stake, balance) # for a random lock duration min_locktime, max_locktime = constants.MIN_LOCKED_PERIODS, constants.MAX_MINTING_PERIODS periods = random.randint(min_locktime, max_locktime) ursula.initialize_stake(amount=amount, lock_periods=periods) else: ursula.federated_only = True ursulas.add(ursula) _TEST_KNOWN_URSULAS_CACHE[ursula.rest_interface.port] = ursula if know_each_other and not bare: for ursula_to_teach in ursulas: # Add other Ursulas as known nodes. for ursula_to_learn_about in ursulas: ursula_to_teach.remember_node(ursula_to_learn_about) event_loop.run_until_complete( ursula.dht_server.bootstrap( [("localhost", starting_port + _c) for _c in range(len(ursulas))])) ursula.publish_dht_information() return ursulas
from hendrix.deploy.tls import HendrixDeployTLS from hendrix.facilities.services import ExistingKeyTLSContextFactory from nucypher.characters import Ursula from OpenSSL.crypto import X509 from OpenSSL.SSL import TLSv1_2_METHOD from nucypher.crypto.api import generate_self_signed_certificate DB_NAME = "non-mining-proxy-node" _URSULA = Ursula(dht_port=3501, rest_port=3601, ip_address="localhost", db_name=DB_NAME) _URSULA.dht_listen() CURVE = ec.SECP256R1 cert, private_key = generate_self_signed_certificate( _URSULA.stamp.fingerprint().decode(), CURVE) deployer = HendrixDeployTLS("start", { "wsgi": _URSULA.rest_app, "https_port": _URSULA.rest_port }, key=private_key, cert=X509.from_cryptography(cert), context_factory=ExistingKeyTLSContextFactory, context_factory_kwargs={ "curve_name": "prime256v1", "sslmethod": TLSv1_2_METHOD