コード例 #1
0
def test_deserialize_ursulas_version_1():
    """
    DON'T 'FIX' THIS TEST IF FAILING, UNLESS YOU KNOW WHAT YOU'RE DOING.
    The goal of this test is to show incompatibility of current Discovery Loop version wrt to version 1.
    See issue #1869 "Test with a hard-coded, versioned node metadata bytestring"
    https://github.com/nucypher/nucypher/issues/1869
    """

    expected_version = 1
    ursulas_matrix = versioned_ursulas[expected_version]
    for fossilized_ursula in ursulas_matrix:
        fossilized_ursula = bytes.fromhex(fossilized_ursula)

        version, _ = Ursula.version_splitter(fossilized_ursula,
                                             return_remainder=True)
        assert version == expected_version
        assert version != Ursula.LEARNER_VERSION

        with pytest.raises(Teacher.AreYouFromThePast,
                           match=f"purported to be of version 1, "
                           f"but we're version {Ursula.LEARNER_VERSION}"):
            _resurrected_ursula = Ursula.from_bytes(fossilized_ursula,
                                                    fail_fast=True)

        assert UNKNOWN_VERSION == Ursula.from_bytes(fossilized_ursula,
                                                    fail_fast=False)
コード例 #2
0
    def from_target_ursula(cls,
                           target_ursula: Ursula,
                           claim_signing_key: bool = False,
                           attach_transacting_key: bool = True
                           ) -> 'Vladimir':
        """
        Sometimes Vladimir seeks to attack or imitate a *specific* target Ursula.

        TODO: This is probably a more instructive method if it takes a bytes representation instead of the entire Ursula.
        """
        crypto_power = CryptoPower(power_ups=target_ursula._default_crypto_powerups)

        if claim_signing_key:
            crypto_power.consume_power_up(SigningPower(pubkey=target_ursula.stamp.as_umbral_pubkey()))

        if attach_transacting_key:
            cls.attach_transacting_key(blockchain=target_ursula.blockchain)

        vladimir = cls(is_me=True,
                       crypto_power=crypto_power,
                       db_filepath=cls.db_filepath,
                       rest_host=target_ursula.rest_information()[0].host,
                       rest_port=target_ursula.rest_information()[0].port,
                       certificate=target_ursula.rest_server_certificate(),
                       network_middleware=cls.network_middleware,
                       checksum_address = cls.fraud_address,
                       ######### Asshole.
                       timestamp=target_ursula._timestamp,
                       interface_signature=target_ursula._interface_signature,
                       ######### 
                       )

        cls.attach_transacting_key(blockchain=target_ursula.blockchain)

        return vladimir
コード例 #3
0
def test_refund(click_runner, testerchain, agency_local_registry,
                token_economics):

    bidder = testerchain.client.accounts[2]
    worker_address = testerchain.unassigned_accounts[-1]

    #
    # WorkLock Staker-Worker
    #

    worklock_agent = ContractAgency.get_agent(WorkLockAgent,
                                              registry=agency_local_registry)

    # Bidder is now STAKER. Bond a worker.
    staker = Staker(is_me=True,
                    checksum_address=bidder,
                    registry=agency_local_registry)
    receipt = staker.bond_worker(worker_address=worker_address)
    assert receipt['status'] == 1

    worker = Ursula(is_me=True,
                    registry=agency_local_registry,
                    checksum_address=bidder,
                    worker_address=worker_address,
                    rest_host=MOCK_IP_ADDRESS,
                    rest_port=select_test_port(),
                    db_filepath=tempfile.mkdtemp())

    # Ensure there is work to do
    remaining_work = worklock_agent.get_remaining_work(checksum_address=bidder)
    assert remaining_work > 0

    # Unlock
    transacting_power = worker._crypto_power.power_ups(TransactingPower)
    transacting_power.activate(password=INSECURE_DEVELOPMENT_PASSWORD)

    # Do some work
    for i in range(3):
        txhash = worker.commit_to_next_period()
        testerchain.wait_for_receipt(txhash)
        assert receipt['status'] == 1
        testerchain.time_travel(periods=1)

    command = ('refund', '--participant-address', bidder,
               '--registry-filepath', agency_local_registry.filepath,
               '--provider', TEST_PROVIDER_URI, '--network', TEMPORARY_DOMAIN,
               '--force')

    user_input = f'{INSECURE_DEVELOPMENT_PASSWORD}\n' + 'Y\n'
    result = click_runner.invoke(worklock,
                                 command,
                                 input=user_input,
                                 catch_exceptions=False)
    assert result.exit_code == 0

    # Less work to do...
    new_remaining_work = worklock_agent.get_remaining_work(
        checksum_address=bidder)
    assert new_remaining_work < remaining_work
コード例 #4
0
def test_refund(click_runner, testerchain, agency_local_registry,
                token_economics):

    bidder = testerchain.unassigned_accounts[1]
    worker_address = testerchain.unassigned_accounts[-1]

    #
    # WorkLock Staker-Worker
    #

    worklock_agent = ContractAgency.get_agent(WorkLockAgent,
                                              registry=agency_local_registry)

    # Bidder is now STAKER. Bond a worker.
    staker = Staker(is_me=True,
                    checksum_address=bidder,
                    registry=agency_local_registry)
    receipt = staker.set_worker(worker_address=worker_address)
    assert receipt['status'] == 1

    worker = Ursula(is_me=True,
                    registry=agency_local_registry,
                    checksum_address=bidder,
                    worker_address=worker_address,
                    rest_host=MOCK_IP_ADDRESS,
                    rest_port=select_test_port())

    # Ensure there is work to do
    remaining_work = worklock_agent.get_remaining_work(checksum_address=bidder)
    assert remaining_work > 0

    # Do some work
    for i in range(3):
        receipt = worker.confirm_activity()
        assert receipt['status'] == 1
        testerchain.time_travel(periods=1)

    command = ('refund', '--bidder-address', bidder, '--registry-filepath',
               agency_local_registry.filepath, '--provider', TEST_PROVIDER_URI,
               '--poa', '--force')

    user_input = f'{INSECURE_DEVELOPMENT_PASSWORD}\n' + 'Y\n'
    result = click_runner.invoke(worklock,
                                 command,
                                 input=user_input,
                                 catch_exceptions=False)
    assert result.exit_code == 0

    # Less work to do...
    new_remaining_work = worklock_agent.get_remaining_work(
        checksum_address=bidder)
    assert new_remaining_work < remaining_work
コード例 #5
0
ファイル: networking.py プロジェクト: KPrasch/nucypher
def get_external_ip_from_default_teacher(
        network: str,
        federated_only: bool = False,
        registry: Optional[BaseContractRegistry] = None,
        log: Logger = IP_DETECTION_LOGGER) -> Union[str, None]:

    # Prevents circular imports
    from nucypher.characters.lawful import Ursula
    from nucypher.network.nodes import TEACHER_NODES

    if federated_only and registry:
        raise ValueError(
            'Federated mode must not be true if registry is provided.')

    base_error = 'Cannot determine IP using default teacher'

    if network not in TEACHER_NODES:
        log.debug(f'{base_error}: Unknown network "{network}".')
        return

    ####
    # TODO: Clean this mess #1481 (Federated Mode)
    node_storage = LocalFileBasedNodeStorage(federated_only=federated_only)
    Ursula.set_cert_storage_function(node_storage.store_node_certificate)
    Ursula.set_federated_mode(federated_only)
    #####

    external_ip = None
    for teacher_uri in TEACHER_NODES[network]:
        try:
            teacher = Ursula.from_teacher_uri(
                teacher_uri=teacher_uri,
                federated_only=federated_only,
                min_stake=0)  # TODO: Handle customized min stake here.
            # TODO: Pass registry here to verify stake (not essential here since it's a hardcoded node)
            external_ip = _request_from_node(teacher=teacher)
            # Found a reachable teacher, return from loop
            if external_ip:
                break
        except NodeSeemsToBeDown:
            # Teacher is unreachable, try next one
            continue

    if not external_ip:
        log.debug(
            f'{base_error}: No teacher available for network "{network}".')
        return

    return external_ip
コード例 #6
0
def initialize_bob(bob_privkeys):
    ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URI,
                                             federated_only=True,
                                             minimum_stake=0)
    TEMP_DOCTOR_DIR = "{}/listener-files".format(
        os.path.dirname(os.path.abspath(__file__)))

    # Remove previous demo files and create new ones
    shutil.rmtree(TEMP_DOCTOR_DIR, ignore_errors=True)

    bob_enc_keypair = DecryptingKeypair(private_key=bob_privkeys["enc"])
    bob_sig_keypair = SigningKeypair(private_key=bob_privkeys["sig"])
    enc_power = DecryptingPower(keypair=bob_enc_keypair)
    sig_power = SigningPower(keypair=bob_sig_keypair)
    power_ups = [enc_power, sig_power]

    print("Creating the Listener ...")

    listener = Bob(
        domains={TEMPORARY_DOMAIN},
        federated_only=True,
        crypto_power_ups=power_ups,
        start_learning_now=True,
        abort_on_learning_error=True,
        known_nodes=[ursula],
        save_metadata=False,
        network_middleware=RestMiddleware(),
    )

    print("Listener = ", listener)
    return listener
コード例 #7
0
    def connect(self, nucypher_network, ipfs_api_gateway): 
        """
        client = ncipfs.Connect(
            nucypher_network="localhost:11500",
            ipfs_api_gateway="localhost:5001"
        )
        """
        self.nucypher_network = nucypher_network
        self.ipfs_api_gateway = ipfs_api_gateway

        try:
            self.ipfs_gateway_api = ipfsapi.connect('127.0.0.1', 5001)
        except Exception as e: # should be more specific ConnectionRefusedError, NewConnectionError, MaxRetryError not sure
            print("Automatic Mode A Public Gateway will be used as a fallback")
            self.ipfs_gateway_api = ipfsapi.connect('https://ipfs.infura.io', 5001)


        # SEEDNODE_URL = self.nucypher_network
        POLICY_FILENAME = "policy-metadata.json"

        # # FOR LOCAL RUNNING NET
        # self.ursula = Ursula.from_seed_and_stake_info(
        #     seed_uri=SEEDNODE_URL,
        #     federated_only=True,
        #     minimum_stake=0
        # )

        self.ursula =urs = Ursula.from_teacher_uri(
            teacher_uri=self.nucypher_network,
            federated_only=True,
            min_stake=0
        )
        return True
コード例 #8
0
    def _read_and_write_metadata(self, ursula, node_storage):
        # Write Node
        node_storage.store_node_metadata(node=ursula)

        # Read Node
        node_from_storage = node_storage.get(checksum_address=ursula.checksum_address,
                                             federated_only=True)
        assert ursula == node_from_storage, "Node storage {} failed".format(node_storage)

        # Save more nodes
        all_known_nodes = set()
        for port in range(MOCK_URSULA_STARTING_PORT, MOCK_URSULA_STARTING_PORT+100):
            node = Ursula(rest_host='127.0.0.1', db_filepath=MOCK_URSULA_DB_FILEPATH, rest_port=port,
                          federated_only=True)
            node_storage.store_node_metadata(node=node)
            all_known_nodes.add(node)

        # Read all nodes from storage
        all_stored_nodes = node_storage.all(federated_only=True)
        all_known_nodes.add(ursula)
        assert len(all_known_nodes) == len(all_stored_nodes)
        assert all_stored_nodes == all_known_nodes

        # Read random nodes
        for i in range(3):
            random_node = all_known_nodes.pop()
            random_node_from_storage = node_storage.get(checksum_address=random_node.checksum_address,
                                                        federated_only=True)
            assert random_node.checksum_address == random_node_from_storage.checksum_address

        return True
コード例 #9
0
    def check_availability():
        """Asks this node: Can you access my public information endpoint?"""
        try:
            requesting_ursula = Ursula.from_metadata_bytes(request.data)
            requesting_ursula.mature()
        except ValueError:
            return Response({'error': 'Invalid Ursula'}, status=HTTPStatus.BAD_REQUEST)
        else:
            initiator_address, initiator_port = tuple(requesting_ursula.rest_interface)

        # Compare requester and posted Ursula information
        request_address = request.remote_addr
        if request_address != initiator_address:
            message = f'Origin address mismatch: Request origin is {request_address} but metadata claims {initiator_address}.'
            return Response({'error': message}, status=HTTPStatus.BAD_REQUEST)

        # Make a Sandwich
        try:
            requesting_ursula_metadata = this_node.network_middleware.client.node_information(
                host=initiator_address,
                port=initiator_port,
            )
        except NodeSeemsToBeDown:
            return Response({'error': 'Unreachable node'}, status=HTTPStatus.BAD_REQUEST)  # ... toasted

        # Compare the results of the outer POST with the inner GET... yum
        if requesting_ursula_metadata == request.data:
            return Response(status=HTTPStatus.OK)
        else:
            return Response({'error': 'Suspicious node'}, status=HTTPStatus.BAD_REQUEST)
コード例 #10
0
def test_alice_does_not_update_with_old_ursula_info(federated_alice,
                                                    federated_ursulas):
    ursula = list(federated_ursulas)[0]
    old_metadata = bytes(ursula)

    # Alice has remembered Ursula.
    assert federated_alice.known_nodes[
        ursula.checksum_public_address] == ursula

    # But now, Ursula wants to sign and date her interface info again.  This causes a new timestamp.
    ursula._sign_and_date_interface_info()

    # Indeed, her metadata is not the same now.
    assert bytes(ursula) != old_metadata

    old_ursula = Ursula.from_bytes(old_metadata, federated_only=True)

    # Once Alice learns about Ursula's updated info...
    federated_alice.remember_node(ursula)

    # ...she can't learn about old ursula anymore.
    federated_alice.remember_node(old_ursula)

    new_metadata = bytes(
        federated_alice.known_nodes[ursula.checksum_public_address])
    assert new_metadata != old_metadata
コード例 #11
0
ファイル: test_storages.py プロジェクト: sriharikapu/nucypher
    def _read_and_write_to_storage(self, ursula, node_storage):
        # Write Node
        node_storage.save(node=ursula)

        # Read Node
        node_from_storage = node_storage.get(checksum_address=ursula.checksum_public_address,
                                             federated_only=True)
        assert ursula == node_from_storage, "Node storage {} failed".format(node_storage)

        # Save more nodes
        all_known_nodes = set()
        for port in range(10152, 10251):
            node = Ursula(rest_host='127.0.0.1', rest_port=port, federated_only=True)
            node_storage.save(node=node)
            all_known_nodes.add(node)

        # Read all nodes from storage
        all_stored_nodes = node_storage.all(federated_only=True)
        all_known_nodes.add(ursula)
        assert len(all_known_nodes) == len(all_stored_nodes)
        assert all_stored_nodes == all_known_nodes

        # Read random nodes
        for i in range(3):
            random_node = all_known_nodes.pop()
            random_node_from_storage = node_storage.get(checksum_address=random_node.checksum_public_address,
                                                        federated_only=True)
            assert random_node.checksum_public_address == random_node_from_storage.checksum_public_address

        return True
コード例 #12
0
def initialize_alice():
    ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URI,
                                         federated_only=True,
                                         minimum_stake=0)

    # If anything fails, let's create Alicia from scratch
    # Remove previous demo files and create new ones
    shutil.rmtree(TEMP_ALICE_DIR, ignore_errors=True)
    
    alice_config = AliceConfiguration(
        config_root=os.path.join(TEMP_ALICE_DIR),
        domains={TEMPORARY_DOMAIN},
        known_nodes={ursula},
        start_learning_now=False,
        federated_only=True,
        learn_on_same_thread=True,
    )

    alice_config.initialize(password=passphrase)
    alice_config.keyring.unlock(password=passphrase)
    
    # We will save Alicia's config to a file for later use
    alice_config_file = alice_config.to_configuration_file()
    
    with open(os.path.join(TEMP_ALICE_DIR, 'alice.config.json'), 'w') as f:
        f.write(open(alice_config_file).read())
    
    alicia = alice_config.produce()
    
    # Let's get to learn about the NuCypher network
    alicia.start_learning_loop(now=True)
    return alicia, alice_config_file
コード例 #13
0
 def light_ursula(temp_dir_path):
     node = Ursula(rest_host=LOOPBACK_ADDRESS,
                   rest_port=MOCK_URSULA_STARTING_PORT,
                   db_filepath=MOCK_URSULA_DB_FILEPATH,
                   federated_only=True,
                   domain=TEMPORARY_DOMAIN)
     yield node
コード例 #14
0
def createGenericAlicia(passphrase):
    print('createGenericAlicia')
    TEMP_ALICE_DIR = os.path.join('/', 'tmp', 'zkDonationFlaskApp')
    shutil.rmtree(TEMP_ALICE_DIR, ignore_errors=True)

    ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URI,
                                             federated_only=True,
                                             minimum_stake=0)

    alice_config = AliceConfiguration(
        config_root=os.path.join(TEMP_ALICE_DIR),
        domains={TEMPORARY_DOMAIN},
        known_nodes={ursula},
        start_learning_now=False,
        federated_only=True,
        learn_on_same_thread=True,
    )

    alice_config.initialize(password=passphrase)

    alice_config.keyring.unlock(password=passphrase)
    alicia = alice_config.produce()

    alice_config.to_configuration_file()

    alicia.start_learning_loop(now=True)

    return alicia
コード例 #15
0
def load_seednodes(min_stake: int,
                   federated_only: bool,
                   network_domains: set,
                   network_middleware: RestMiddleware = None,
                   teacher_uris: list = None
                   ) -> List[Ursula]:

    # Set domains
    if network_domains is None:
        from nucypher.config.node import CharacterConfiguration
        network_domains = {CharacterConfiguration.DEFAULT_DOMAIN, }

    teacher_nodes = list()  # Ursula
    if teacher_uris is None:
        teacher_uris = list()

    for domain in network_domains:
        try:
            teacher_uris = TEACHER_NODES[domain]
        except KeyError:
            # TODO: If this is a unknown domain, require the caller to pass a teacher URI explicitly?
            if not teacher_uris:
                console_emitter(message=f"No default teacher nodes exist for the specified network: {domain}")

        for uri in teacher_uris:
            teacher_node = Ursula.from_teacher_uri(teacher_uri=uri,
                                                   min_stake=min_stake,
                                                   federated_only=federated_only,
                                                   network_middleware=network_middleware)
            teacher_nodes.append(teacher_node)

    if not teacher_nodes:
        console_emitter(message=f'WARNING - No Bootnodes Available')

    return teacher_nodes
コード例 #16
0
def aggregate_nodes() -> Tuple[Set[Ursula], Set[Ursula]]:
    """generates ursulas from URIs used in grant metrics collection"""

    seednodes = set()
    if DEFAULT_SEEDNODE_URIS:
        for uri in DEFAULT_SEEDNODE_URIS:
            ursula = Ursula.from_seed_and_stake_info(seed_uri=uri, federated_only=False)
            seednodes.add(ursula)

    handpicked_ursulas = set()
    if HANDPICKED_URSULA_URIS:
        for uri in HANDPICKED_URSULA_URIS:
            ursula = Ursula.from_seed_and_stake_info(seed_uri=uri, federated_only=False)
            handpicked_ursulas.add(ursula)

    return seednodes, handpicked_ursulas
コード例 #17
0
ファイル: main.py プロジェクト: derekpierre/nucypher-monitor
def crawl(
    general_config,
    teacher_uri,
    registry_filepath,
    min_stake,
    network,
    learn_on_launch,
    provider_uri,
    influx_host,
    influx_port,
    http_port,
    dry_run,
    eager,
    poa,
):
    """
    Gather NuCypher network information.
    """

    # Banner
    emitter = general_config.emitter
    emitter.clear()
    emitter.banner(MONITOR_BANNER.format(CRAWLER))

    # Setup
    BlockchainInterfaceFactory.initialize_interface(provider_uri=provider_uri,
                                                    poa=poa)
    registry = _get_registry(registry_filepath, network)
    middleware = RestMiddleware()

    # Teacher Ursula
    sage_node = None
    if teacher_uri:
        sage_node = Ursula.from_teacher_uri(
            teacher_uri=teacher_uri,
            min_stake=0,  # TODO: Where to get this?
            federated_only=False,  # always False
            network_middleware=middleware,
            registry=registry)

    crawler = Crawler(domain=network if network else None,
                      network_middleware=middleware,
                      known_nodes=[sage_node] if teacher_uri else None,
                      registry=registry,
                      start_learning_now=eager,
                      learn_on_same_thread=learn_on_launch,
                      influx_host=influx_host,
                      influx_port=influx_port)

    emitter.message(f"Network: {network.capitalize()}", color='blue')
    emitter.message(f"InfluxDB: {influx_host}:{influx_port}", color='blue')
    emitter.message(f"Provider: {provider_uri}", color='blue')
    emitter.message(f"Refresh Rate: {crawler._refresh_rate}s", color='blue')
    message = f"Running Nucypher Crawler JSON endpoint at http://localhost:{http_port}/stats"
    emitter.message(message, color='green', bold=True)
    if not dry_run:
        crawler.start(eager=eager)
        reactor.run()
コード例 #18
0
    def ping():
        """
        GET: Asks this node: "What is my IP address?"
        POST: Asks this node: "Can you access my public information endpoint?"
        """

        if request.method == 'GET':
            requester_ip_address = request.remote_addr
            return Response(requester_ip_address, status=200)

        elif request.method == 'POST':
            try:
                requesting_ursula = Ursula.from_bytes(request.data)
                requesting_ursula.mature()
            except ValueError:
                return Response({'error': 'Invalid Ursula'}, status=400)
            else:
                initiator_address, initiator_port = tuple(
                    requesting_ursula.rest_interface)

            # Compare requester and posted Ursula information
            request_address = request.remote_addr
            if request_address != initiator_address:
                message = f'Origin address mismatch: Request origin is {request_address} but metadata claims {initiator_address}.'
                return Response({'error': message}, status=400)

            #
            # Make a Sandwich
            #

            try:
                # Fetch and store initiator's teacher certificate.
                certificate = this_node.network_middleware.get_certificate(
                    host=initiator_address, port=initiator_port)
                certificate_filepath = this_node.node_storage.store_node_certificate(
                    certificate=certificate)
                requesting_ursula_bytes = this_node.network_middleware.client.node_information(
                    host=initiator_address,
                    port=initiator_port,
                    certificate_filepath=certificate_filepath)
            except NodeSeemsToBeDown:
                return Response({'error': 'Unreachable node'},
                                status=400)  # ... toasted

            except InvalidNodeCertificate:
                return Response(
                    {
                        'error':
                        'Invalid TLS certificate - missing checksum address'
                    },
                    status=400)  # ... invalid

            # Compare the results of the outer POST with the inner GET... yum
            if requesting_ursula_bytes == request.data:
                return Response(status=200)
            else:
                return Response({'error': 'Suspicious node'}, status=400)
コード例 #19
0
ファイル: test_bob.py プロジェクト: p2p-org/nucypher-old
 def substitute_bob(*args, **kwargs):
     log.info("Substituting the Policy's Bob in CLI runtime.")
     this_fuckin_guy = enacted_federated_policy.bob
     somebody_else = Ursula.from_teacher_uri(teacher_uri=kwargs['teacher_uri'],
                                             min_stake=0,
                                             federated_only=True,
                                             network_middleware=this_fuckin_guy.network_middleware)
     this_fuckin_guy.remember_node(somebody_else)
     this_fuckin_guy.controller.emitter = JSONRPCStdoutEmitter()
     return this_fuckin_guy
コード例 #20
0
ファイル: storages.py プロジェクト: ryanleecode/nucypher
 def __read_metadata(self, filepath: str, federated_only: bool):
     from nucypher.characters.lawful import Ursula
     try:
         with open(filepath, "rb") as seed_file:
             seed_file.seek(0)
             node_bytes = self.deserializer(seed_file.read())
             node = Ursula.from_bytes(node_bytes, federated_only=federated_only)
     except FileNotFoundError:
         raise self.UnknownNode
     return node
コード例 #21
0
    def load_seednodes(self,
                       read_storages: bool = True,
                       retry_attempts: int = 3):  # TODO: why are these unused?
        """
        Engage known nodes from storages and pre-fetch hardcoded seednode certificates for node learning.
        """
        if self.done_seeding:
            sendMessage(
                encodeMessage(
                    "log:Level:Debug, Date:{}, Message:Already done seeding; won't try again."
                    .format(get_sysdate())))
            #self.log.debug("Already done seeding; won't try again.")
            return

        from nucypher.characters.lawful import Ursula
        for seednode_metadata in self._seed_nodes:
            sendMessage(
                encodeMessage(
                    "log:Level:Debug, Date:{}, Message:Seeding from: {}|{}:{}".
                    format(get_sysdate(), seednode_metadata.checksum_address,
                           seednode_metadata.rest_host,
                           seednode_metadata.rest_port)))
            #self.log.debug(
            #    "Seeding from: {}|{}:{}".format(seednode_metadata.checksum_public_address,
            #                                    seednode_metadata.rest_host,
            #                                    seednode_metadata.rest_port))

            seed_node = Ursula.from_seednode_metadata(
                seednode_metadata=seednode_metadata,
                network_middleware=self.network_middleware,
                federated_only=self.federated_only)  # TODO: 466
            if seed_node is False:
                self.unresponsive_seed_nodes.add(seednode_metadata)
            else:
                self.unresponsive_seed_nodes.discard(seednode_metadata)
                self.remember_node(seed_node)

        if not self.unresponsive_seed_nodes:
            sendMessage(
                encodeMessage(
                    "log:Level:Info, Date:{}, Message: Finished learning about all seednodes."
                    .format(get_sysdate())))
            #self.log.info("Finished learning about all seednodes.")

        self.done_seeding = True

        if read_storages is True:
            self.read_nodes_from_storage()

        if not self.known_nodes:
            sendMessage(
                encodeMessage(
                    "log:Level:Warn, Date:{}, Message: No seednodes were available after {} attempts"
                    .format(get_sysdate(), retry_attempts)))
コード例 #22
0
ファイル: test_storages.py プロジェクト: sriharikapu/nucypher
def light_ursula(temp_dir_path):
    db_name = 'ursula-{}.db'.format(10151)

    node = Ursula(rest_host='127.0.0.1',
                  rest_port=10151,
                  db_filepath=db_name,  # TODO: Needs cleanup
                  db_name=db_name,
                  federated_only=True)
    yield node
    with contextlib.suppress(Exception):
        os.remove(db_name)
コード例 #23
0
def load_seednodes(
    emitter,
    min_stake: int,
    federated_only: bool,
    network_domains: set,
    network_middleware: RestMiddleware = None,
    teacher_uris: list = None,
    registry: BaseContractRegistry = None,
) -> List:
    """
    Aggregates seednodes URI sources into a list or teacher URIs ordered
    by connection priority in the following order:

    1. --teacher CLI flag
    2. static-nodes.json
    3. Hardcoded teachers
    """

    # Heads up
    emitter.message("Connecting to preferred teacher nodes...", color='yellow')
    from nucypher.characters.lawful import Ursula

    # Aggregate URIs (Ordered by Priority)
    teacher_nodes = list()  # type: List[Ursula]
    teacher_uris = aggregate_seednode_uris(domains=network_domains,
                                           highest_priority=teacher_uris)
    if not teacher_uris:
        emitter.message(
            f"No teacher nodes available for domains: {','.join(network_domains)}"
        )
        return teacher_nodes

    # Construct Ursulas
    for uri in teacher_uris:
        try:
            teacher_node = Ursula.from_teacher_uri(
                teacher_uri=uri,
                min_stake=min_stake,
                federated_only=federated_only,
                network_middleware=network_middleware,
                registry=registry)
        except NodeSeemsToBeDown:
            LOG.info(f"Failed to connect to teacher: {uri}")
            continue
        except Teacher.NotStaking:
            LOG.info(f"Teacher: {uri} is not actively staking, skipping")
            continue
        teacher_nodes.append(teacher_node)

    if not teacher_nodes:
        emitter.message(
            f"WARNING - No Peers Available for domains: {','.join(network_domains)}"
        )
    return teacher_nodes
コード例 #24
0
def test_tls_hosting_certificate_remains_the_same(tmpdir, mocker):
    keyring = NucypherKeyring.generate(checksum_address=FEDERATED_ADDRESS,
                                       password=INSECURE_DEVELOPMENT_PASSWORD,
                                       encrypting=True,
                                       rest=True,
                                       host=LOOPBACK_ADDRESS,
                                       keyring_root=tmpdir)
    keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)

    rest_port = 12345
    db_filepath = tempfile.mkdtemp()

    ursula = Ursula(federated_only=True,
                    start_learning_now=False,
                    keyring=keyring,
                    rest_host=LOOPBACK_ADDRESS,
                    rest_port=rest_port,
                    db_filepath=db_filepath,
                    domain=TEMPORARY_DOMAIN)

    assert ursula.keyring is keyring
    assert ursula.certificate == ursula._crypto_power.power_ups(
        TLSHostingPower).keypair.certificate

    original_certificate_bytes = ursula.certificate.public_bytes(
        encoding=Encoding.PEM)
    ursula.disenchant()
    del ursula

    spy_rest_server_init = mocker.spy(ProxyRESTServer, '__init__')
    recreated_ursula = Ursula(federated_only=True,
                              start_learning_now=False,
                              keyring=keyring,
                              rest_host=LOOPBACK_ADDRESS,
                              rest_port=rest_port,
                              db_filepath=db_filepath,
                              domain=TEMPORARY_DOMAIN)

    assert recreated_ursula.keyring is keyring
    assert recreated_ursula.certificate.public_bytes(
        encoding=Encoding.PEM) == original_certificate_bytes
    tls_hosting_power = recreated_ursula._crypto_power.power_ups(
        TLSHostingPower)
    spy_rest_server_init.assert_called_once_with(
        ANY,  # self
        rest_host=LOOPBACK_ADDRESS,
        rest_port=rest_port,
        rest_app=IsType(Flask),
        datastore=IsType(Datastore),
        hosting_power=tls_hosting_power)
    recreated_ursula.disenchant()
コード例 #25
0
def test_deserialize_ursulas_version_2():
    """
    DON'T 'FIX' THIS TEST IF FAILING, UNLESS YOU KNOW WHAT YOU'RE DOING.
    The goal of this test is to show compatibility of a hard-coded version 2 bytestring.
    See issue #1869 "Test with a hard-coded, versioned node metadata bytestring"
    https://github.com/nucypher/nucypher/issues/1869
    """

    expected_version = 2
    ursulas_matrix = versioned_ursulas[expected_version]
    for fossilized_ursula in ursulas_matrix:
        fossilized_ursula = bytes.fromhex(fossilized_ursula)

        version, _ = Ursula.version_splitter(fossilized_ursula,
                                             return_remainder=True)
        assert version == expected_version
        assert version == Ursula.LEARNER_VERSION

        resurrected_ursula = Ursula.from_bytes(fossilized_ursula,
                                               fail_fast=True)
        assert TEMPORARY_DOMAIN.encode('utf-8') == resurrected_ursula.domain
コード例 #26
0
ファイル: seednodes.py プロジェクト: ronmnm/nucypher
def load_seednodes(
    emitter,
    min_stake: int,
    federated_only: bool,
    network_domains: set,
    network_middleware: RestMiddleware = None,
    teacher_uris: list = None,
    registry: BaseContractRegistry = None,
) -> List:
    """
    Aggregates seednodes URI sources into a list or teacher URIs ordered
    by connection priority in the following order:

    1. --teacher CLI flag
    2. static-nodes.json
    3. Hardcoded teachers
    """

    # Heads up
    emitter.message(START_LOADING_SEEDNODES, color='yellow')
    from nucypher.characters.lawful import Ursula

    # Aggregate URIs (Ordered by Priority)
    teacher_nodes = list()  # type: List[Ursula]
    teacher_uris = aggregate_seednode_uris(domains=network_domains,
                                           highest_priority=teacher_uris)
    if not teacher_uris:
        emitter.message(
            NO_DOMAIN_PEERS.format(domains=','.join(network_domains)))
        return teacher_nodes

    # Construct Ursulas
    for uri in teacher_uris:
        try:
            teacher_node = Ursula.from_teacher_uri(
                teacher_uri=uri,
                min_stake=min_stake,
                federated_only=federated_only,
                network_middleware=network_middleware,
                registry=registry)
        except NodeSeemsToBeDown:
            emitter.message(UNREADABLE_SEEDNODE_ADVISORY.format(uri=uri))
            continue
        except Teacher.NotStaking:
            emitter.message(SEEDNODE_NOT_STAKING_WARNING.format(uri=uri))
            continue
        teacher_nodes.append(teacher_node)

    if not teacher_nodes:
        emitter.message(
            NO_DOMAIN_PEERS.format(domains=','.join(network_domains)))
    return teacher_nodes
コード例 #27
0
ファイル: server.py プロジェクト: wiki-wang/nucypher
    def ping():
        """
        Asks this node: "Can you access my public information endpoint"?
        """

        try:
            requesting_ursula = Ursula.from_bytes(request.data,
                                                  registry=this_node.registry)
            requesting_ursula.mature()
        except ValueError:  # (ValueError)
            return Response({'error': 'Invalid Ursula'}, status=400)
        else:
            initiator_address, initiator_port = tuple(
                requesting_ursula.rest_interface)

        # Compare requester and posted Ursula information
        request_address = request.environ['REMOTE_ADDR']
        if request_address != initiator_address:
            return Response({'error': 'Suspicious origin address'}, status=400)

        #
        # Make a Sandwich
        #

        try:
            # Fetch and store initiator's teacher certificate.
            certificate = this_node.network_middleware.get_certificate(
                host=initiator_address, port=initiator_port)
            certificate_filepath = this_node.node_storage.store_node_certificate(
                certificate=certificate)
            requesting_ursula_bytes = this_node.network_middleware.client.node_information(
                host=initiator_address,
                port=initiator_port,
                certificate_filepath=certificate_filepath)
        except NodeSeemsToBeDown:
            return Response({'error': 'Unreachable node'},
                            status=400)  # ... toasted

        except InvalidNodeCertificate:
            return Response(
                {
                    'error':
                    'Invalid TLS certificate - missing checksum address'
                },
                status=400)  # ... invalid

        # Compare the results of the outer POST with the inner GET... yum
        if requesting_ursula_bytes == request.data:
            return Response(status=200)
        else:
            return Response({'error': 'Suspicious node'}, status=400)
コード例 #28
0
    def load_known_nodes(self, known_metadata_dir=None) -> None:

        if known_metadata_dir is None:
            known_metadata_dir = self.known_metadata_dir

        glob_pattern = os.path.join(known_metadata_dir, '*.node')
        metadata_paths = sorted(glob(glob_pattern), key=os.path.getctime)

        for metadata_path in metadata_paths:
            from nucypher.characters.lawful import Ursula
            node = Ursula.from_metadata_file(
                filepath=abspath(metadata_path),
                federated_only=self.federated_only)
            self.known_nodes.add(node)
コード例 #29
0
def start_pytest_ursula_services(ursula: Ursula) -> Certificate:
    """
    Takes an ursula and starts its learning
    services when running tests with pytest twisted.
    """

    node_deployer = ursula.get_deployer()

    node_deployer.addServices()
    node_deployer.catalogServers(node_deployer.hendrix)
    node_deployer.start()

    certificate_as_deployed = node_deployer.cert.to_cryptography()
    return certificate_as_deployed
コード例 #30
0
ファイル: test_keyring.py プロジェクト: p2p-org/nucypher-old
def test_characters_use_keyring(tmpdir):
    keyring = NucypherKeyring.generate(checksum_address=FEDERATED_ADDRESS,
                                       password=INSECURE_DEVELOPMENT_PASSWORD,
                                       encrypting=True,
                                       rest=False,
                                       keyring_root=tmpdir)
    keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
    Alice(federated_only=True, start_learning_now=False, keyring=keyring)
    Bob(federated_only=True, start_learning_now=False, keyring=keyring)
    Ursula(federated_only=True,
           start_learning_now=False,
           keyring=keyring,
           rest_host='127.0.0.1',
           rest_port=12345)