コード例 #1
0
ファイル: status.py プロジェクト: existentializm/nucypher
def _get_staking_agent(click_config, emitter, geth, poa, provider_uri,
                       registry_filepath):
    try:
        ETH_NODE = None
        if geth:
            ETH_NODE = get_provider_process()

        # Note: For test compatibility.
        if not BlockchainInterfaceFactory.is_interface_initialized(
                provider_uri=provider_uri):
            BlockchainInterfaceFactory.initialize_interface(
                provider_uri=provider_uri,
                provider_process=ETH_NODE,
                poa=poa,
                sync=False,
                show_sync_progress=False)

        blockchain = BlockchainInterfaceFactory.get_interface(
            provider_uri=provider_uri)

        emitter.echo(message="Reading Latest Chaindata...")
        blockchain.connect()
    except Exception as e:
        if click_config.debug:
            raise
        click.secho(str(e), bold=True, fg='red')
        raise click.Abort
    if registry_filepath:
        registry = LocalContractRegistry(filepath=registry_filepath)
    else:
        registry = InMemoryContractRegistry.from_latest_publication()

    staking_agent = ContractAgency.get_agent(StakingEscrowAgent,
                                             registry=registry)
    return staking_agent
コード例 #2
0
ファイル: status.py プロジェクト: p2p-org/nucypher-old
    def get_registry(self, emitter, debug):
        try:
            eth_node = None
            if self.geth:
                eth_node = get_provider_process()

            # Note: For test compatibility.
            if not BlockchainInterfaceFactory.is_interface_initialized(
                    provider_uri=self.provider_uri):
                BlockchainInterfaceFactory.initialize_interface(
                    provider_uri=self.provider_uri,
                    provider_process=eth_node,
                    poa=self.poa,
                    light=self.light,
                    sync=False,
                    emitter=emitter)

            blockchain = BlockchainInterfaceFactory.get_interface(
                provider_uri=self.provider_uri)

            emitter.echo(message="Reading Latest Chaindata...")
            blockchain.connect()
        except Exception as e:
            if debug:
                raise
            click.secho(str(e), bold=True, fg='red')
            raise click.Abort
        if self.registry_filepath:
            registry = LocalContractRegistry(filepath=self.registry_filepath)
        else:
            registry = InMemoryContractRegistry.from_latest_publication(
                network=self.network)

        return registry
コード例 #3
0
ファイル: ursula.py プロジェクト: renaynay/nucypher
    def __init__(self, geth, provider_uri, worker_address, federated_only,
                 rest_host, rest_port, db_filepath, network, registry_filepath,
                 dev, poa, light):

        if federated_only:
            # TODO: consider rephrasing in a more universal voice.
            if geth:
                raise click.BadOptionUsage(
                    option_name="--geth",
                    message="--geth cannot be used in federated mode.")

            if registry_filepath:
                raise click.BadOptionUsage(
                    option_name="--registry-filepath",
                    message=
                    f"--registry-filepath cannot be used in federated mode.")

        eth_node = NO_BLOCKCHAIN_CONNECTION
        provider_uri = provider_uri
        if geth:
            eth_node = actions.get_provider_process()
            provider_uri = eth_node.provider_uri(scheme='file')

        self.eth_node = eth_node
        self.provider_uri = provider_uri
        self.worker_address = worker_address
        self.federated_only = federated_only
        self.rest_host = rest_host
        self.rest_port = rest_port  # FIXME: not used in generate()
        self.db_filepath = db_filepath
        self.domains = {network} if network else None  # TODO: #1580
        self.registry_filepath = registry_filepath
        self.dev = dev
        self.poa = poa
        self.light = light
コード例 #4
0
ファイル: alice.py プロジェクト: xbee/nucypher
    def __init__(self, dev, network, provider_uri, geth, federated_only,
                 discovery_port, pay_with, registry_filepath, middleware,
                 gas_strategy, signer_uri):

        if federated_only and geth:
            raise click.BadOptionUsage(
                option_name="--geth",
                message="--federated-only cannot be used with the --geth flag")

        # Managed Ethereum Client
        eth_node = NO_BLOCKCHAIN_CONNECTION
        if geth:
            eth_node = actions.get_provider_process()
            provider_uri = eth_node.provider_uri(scheme='file')

        self.dev = dev
        self.domains = {network} if network else None
        self.provider_uri = provider_uri
        self.signer_uri = signer_uri
        self.gas_strategy = gas_strategy
        self.geth = geth
        self.federated_only = federated_only
        self.eth_node = eth_node
        self.pay_with = pay_with
        self.discovery_port = discovery_port
        self.registry_filepath = registry_filepath
        self.middleware = middleware
コード例 #5
0
    def connect_blockchain(self, emitter, debug):
        try:
            eth_node = None
            if self.geth:
                eth_node = get_provider_process()

            # Note: For test compatibility.
            if not BlockchainInterfaceFactory.is_interface_initialized(
                    provider_uri=self.provider_uri):
                BlockchainInterfaceFactory.initialize_interface(
                    provider_uri=self.provider_uri,
                    provider_process=eth_node,
                    poa=self.poa,
                    light=self.light,
                    sync=False,
                    emitter=emitter)

            blockchain = BlockchainInterfaceFactory.get_interface(
                provider_uri=self.provider_uri)

            emitter.echo(message="Reading Latest Chaindata...")
            blockchain.connect()
            return blockchain
        except Exception as e:
            if debug:
                raise
            click.secho(str(e), bold=True, fg='red')
            raise click.Abort
コード例 #6
0
def destroy(
        click_config,

        # Admin Options
        checksum_address,
        geth,
        dev,
        network,
        registry_filepath,
        provider_uri,
        host,
        db_filepath,
        poa,

        # Other
        config_file,
        port,
        force):
    """
    Destroy Felix Configuration.
    """
    emitter = _setup_emitter(click_config, checksum_address)

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process(dev)
        provider_uri = ETH_NODE.provider_uri

    felix_config = _get_config(emitter, network, config_file,
                               registry_filepath, ETH_NODE, provider_uri, host,
                               port, db_filepath, poa)
    actions.destroy_configuration(emitter,
                                  character_config=felix_config,
                                  force=force)
コード例 #7
0
ファイル: status.py プロジェクト: vepkenez/nucypher
def status(click_config, provider_uri, sync, geth, poa):
    """
    Echo a snapshot of live network metadata.
    """

    emitter = click_config.emitter
    click.clear()
    emitter.banner(NU_BANNER)
    emitter.echo(message="Reading Latest Chaindata...")

    try:
        ETH_NODE = None
        if geth:
            ETH_NODE = get_provider_process()
        blockchain = BlockchainInterface(provider_uri=provider_uri,
                                         provider_process=ETH_NODE,
                                         poa=poa)
        blockchain.connect(sync_now=sync, fetch_registry=True)
        paint_contract_status(blockchain=blockchain, emitter=emitter)
        return  # Exit

    except Exception as e:
        if click_config.debug:
            raise
        click.secho(str(e), bold=True, fg='red')
        return  # Exit
コード例 #8
0
def init(
        click_config,

        # Admin Options
        checksum_address,
        geth,
        dev,
        network,
        registry_filepath,
        provider_uri,
        host,
        db_filepath,
        poa,

        # Other
        config_root,
        discovery_port):
    """
    Create a brand-new Felix.
    """
    emitter = _setup_emitter(click_config, checksum_address)

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process(dev)
        provider_uri = ETH_NODE.provider_uri

    if not config_root:  # Flag
        config_root = DEFAULT_CONFIG_ROOT  # Envvar or init-only default

    try:
        new_felix_config = FelixConfiguration.generate(
            password=get_nucypher_password(confirm=True),
            config_root=config_root,
            rest_host=host,
            rest_port=discovery_port,
            db_filepath=db_filepath,
            domains={network} if network else None,
            checksum_address=checksum_address,
            registry_filepath=registry_filepath,
            provider_uri=provider_uri,
            provider_process=ETH_NODE,
            poa=poa)
    except Exception as e:
        if click_config.debug:
            raise
        else:
            emitter.echo(str(e), color='red', bold=True)
            raise click.Abort

    # Paint Help
    painting.paint_new_installation_help(emitter,
                                         new_configuration=new_felix_config)
コード例 #9
0
ファイル: ursula.py プロジェクト: itsencrypted/nucypher
def init(click_config,

         # Admin Options
         geth, provider_uri, network, registry_filepath, staker_address, worker_address, federated_only, rest_host,
         rest_port, db_filepath, poa, light,

         # Other
         force, config_root):
    """
    Create a new Ursula node configuration.
    """

    ### Setup ###
    _validate_args(geth, federated_only, staker_address, registry_filepath)

    emitter = _setup_emitter(click_config, worker_address)

    _pre_launch_warnings(emitter, dev=None, force=force)

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process()
        provider_uri = ETH_NODE.provider_uri(scheme='file')
    #############

    if (not staker_address or not worker_address) and not federated_only:
        if not staker_address:
            prompt = "Select staker account"
            staker_address = select_client_account(emitter=emitter, prompt=prompt, provider_uri=provider_uri)

        if not worker_address:
            prompt = "Select worker account"
            worker_address = select_client_account(emitter=emitter, prompt=prompt, provider_uri=provider_uri)
    if not config_root:  # Flag
        config_root = click_config.config_file  # Envvar
    if not rest_host:
        rest_host = actions.determine_external_ip_address(emitter, force=force)
    ursula_config = UrsulaConfiguration.generate(password=get_nucypher_password(confirm=True),
                                                 config_root=config_root,
                                                 rest_host=rest_host,
                                                 rest_port=rest_port,
                                                 db_filepath=db_filepath,
                                                 domains={network} if network else None,
                                                 federated_only=federated_only,
                                                 checksum_address=staker_address,
                                                 worker_address=worker_address,
                                                 registry_filepath=registry_filepath,
                                                 provider_process=ETH_NODE,
                                                 provider_uri=provider_uri,
                                                 poa=poa,
                                                 light=light)
    painting.paint_new_installation_help(emitter, new_configuration=ursula_config)
コード例 #10
0
ファイル: alice.py プロジェクト: gs455/nucypher
def _get_alice_config(click_config, config_file, dev, discovery_port, federated_only, geth, network, pay_with,
                      provider_uri, registry_filepath):
    if federated_only and geth:
        raise click.BadOptionUsage(option_name="--geth", message="Federated only cannot be used with the --geth flag")
    #
    # Managed Ethereum Client
    #
    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process()
        provider_uri = ETH_NODE.provider_uri(scheme='file')

    # Get config
    alice_config = _get_or_create_alice_config(click_config, dev, network, ETH_NODE, provider_uri,
                                               config_file, discovery_port, pay_with, registry_filepath)
    return alice_config, provider_uri
コード例 #11
0
ファイル: ursula.py プロジェクト: existentializm/nucypher
def _get_ursula_config(emitter, geth, provider_uri, network, registry_filepath,
                       dev, config_file, staker_address, worker_address,
                       federated_only, rest_host, rest_port, db_filepath, poa):

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process()
        provider_uri = ETH_NODE.provider_uri(scheme='file')

    if dev:
        ursula_config = UrsulaConfiguration(
            dev_mode=True,
            domains={TEMPORARY_DOMAIN},
            poa=poa,
            registry_filepath=registry_filepath,
            provider_process=ETH_NODE,
            provider_uri=provider_uri,
            checksum_address=staker_address,
            worker_address=worker_address,
            federated_only=federated_only,
            rest_host=rest_host,
            rest_port=rest_port,
            db_filepath=db_filepath)
    else:
        try:
            ursula_config = UrsulaConfiguration.from_configuration_file(
                filepath=config_file,
                domains={network} if network else None,
                registry_filepath=registry_filepath,
                provider_process=ETH_NODE,
                provider_uri=provider_uri,
                rest_host=rest_host,
                rest_port=rest_port,
                db_filepath=db_filepath,
                poa=poa,
                federated_only=federated_only)
        except FileNotFoundError:
            return actions.handle_missing_configuration_file(
                character_config_class=UrsulaConfiguration,
                config_file=config_file)
        except NucypherKeyring.AuthenticationFailed as e:
            emitter.echo(str(e), color='red', bold=True)
            # TODO: Exit codes (not only for this, but for other exceptions)
            return click.get_current_context().exit(1)

    return ursula_config, provider_uri
コード例 #12
0
def createdb(
        click_config,

        # API Options
        checksum_address,
        geth,
        dev,
        network,
        registry_filepath,
        provider_uri,
        host,
        db_filepath,
        poa,
        config_file,
        port,
        teacher_uri,
        min_stake,

        # Other
        force):
    """
    Create Felix DB.
    """
    emitter = _setup_emitter(click_config, checksum_address)

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process(dev)
        provider_uri = ETH_NODE.provider_uri

    felix_config = _get_config(emitter, network, config_file,
                               registry_filepath, ETH_NODE, provider_uri, host,
                               port, db_filepath, poa)
    FELIX = _create_felix(emitter, click_config, felix_config, teacher_uri,
                          min_stake, network)

    if os.path.isfile(FELIX.db_filepath):
        if not force:
            click.confirm("Overwrite existing database?", abort=True)
        os.remove(FELIX.db_filepath)
        emitter.echo(f"Destroyed existing database {FELIX.db_filepath}")

    FELIX.create_tables()
    emitter.echo(f"\nCreated new database at {FELIX.db_filepath}",
                 color='green')
コード例 #13
0
    def __init__(self, geth, dev, network, provider_uri, host, db_filepath,
                 checksum_address, registry_filepath, poa, port):

        eth_node = NO_BLOCKCHAIN_CONNECTION
        if geth:
            eth_node = actions.get_provider_process(dev)
            provider_uri = eth_node.provider_uri

        self.eth_node = eth_node
        self.provider_uri = provider_uri
        self.domains = {network} if network else None
        self.dev = dev
        self.host = host
        self.db_filepath = db_filepath
        self.checksum_address = checksum_address
        self.registry_filepath = registry_filepath
        self.poa = poa
        self.port = port
コード例 #14
0
def run(
        click_config,

        # API Options
        checksum_address,
        geth,
        dev,
        network,
        registry_filepath,
        provider_uri,
        host,
        db_filepath,
        poa,
        config_file,
        port,
        teacher_uri,
        min_stake,

        # Other
        dry_run):
    """
    Run Felix service.
    """
    emitter = _setup_emitter(click_config, checksum_address)

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process(dev)
        provider_uri = ETH_NODE.provider_uri

    felix_config = _get_config(emitter, network, config_file,
                               registry_filepath, ETH_NODE, provider_uri, host,
                               port, db_filepath, poa)
    FELIX = _create_felix(emitter, click_config, felix_config, teacher_uri,
                          min_stake, network)

    emitter.echo("Waiting for blockchain sync...", color='yellow')
    emitter.message(f"Running Felix on {host}:{port}")
    FELIX.start(host=host,
                port=port,
                web_services=not dry_run,
                distribution=True,
                crash_on_error=click_config.debug)
コード例 #15
0
def view(
        click_config,

        # API Options
        checksum_address,
        geth,
        dev,
        network,
        registry_filepath,
        provider_uri,
        host,
        db_filepath,
        poa,
        config_file,
        port,
        teacher_uri,
        min_stake):
    """
    View Felix token balance.
    """
    emitter = _setup_emitter(click_config, checksum_address)

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process(dev)
        provider_uri = ETH_NODE.provider_uri

    felix_config = _get_config(emitter, network, config_file,
                               registry_filepath, ETH_NODE, provider_uri, host,
                               port, db_filepath, poa)
    FELIX = _create_felix(emitter, click_config, felix_config, teacher_uri,
                          min_stake, network)

    token_balance = FELIX.token_balance
    eth_balance = FELIX.eth_balance
    emitter.echo(f"""
        Address .... {FELIX.checksum_address}
        NU ......... {str(token_balance)}
        ETH ........ {str(eth_balance)}
    """)
コード例 #16
0
def accounts(
        click_config,

        # API Options
        checksum_address,
        geth,
        dev,
        network,
        registry_filepath,
        provider_uri,
        host,
        db_filepath,
        poa,
        config_file,
        port,
        teacher_uri,
        min_stake):
    """
    View Felix known accounts.
    """
    emitter = _setup_emitter(click_config, checksum_address)

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process(dev)
        provider_uri = ETH_NODE.provider_uri

    felix_config = _get_config(emitter, network, config_file,
                               registry_filepath, ETH_NODE, provider_uri, host,
                               port, db_filepath, poa)
    FELIX = _create_felix(emitter, click_config, felix_config, teacher_uri,
                          min_stake, network)

    accounts = FELIX.blockchain.client.accounts
    for account in accounts:
        emitter.echo(account)
コード例 #17
0
def felix(click_config, action, teacher_uri, enode, min_stake, network, host,
          dry_run, port, discovery_port, provider_uri, geth, config_root,
          checksum_address, poa, config_file, db_filepath, registry_filepath,
          dev, force):
    """
    "Felix the Faucet" management commands.
    """

    emitter = click_config.emitter

    # Intro
    emitter.clear()
    emitter.banner(FELIX_BANNER.format(checksum_address or ''))

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process(dev=dev)
        provider_uri = ETH_NODE.provider_uri

    if action == "init":
        """Create a brand-new Felix"""

        if not config_root:  # Flag
            config_root = DEFAULT_CONFIG_ROOT  # Envvar or init-only default

        try:
            new_felix_config = FelixConfiguration.generate(
                password=get_nucypher_password(confirm=True),
                config_root=config_root,
                rest_host=host,
                rest_port=discovery_port,
                db_filepath=db_filepath,
                domains={network} if network else None,
                checksum_address=checksum_address,
                registry_filepath=registry_filepath,
                provider_uri=provider_uri,
                provider_process=ETH_NODE,
                poa=poa)
        except Exception as e:
            if click_config.debug:
                raise
            else:
                emitter.echo(str(e), color='red', bold=True)
                raise click.Abort

        # Paint Help
        painting.paint_new_installation_help(
            emitter, new_configuration=new_felix_config)

        return  # <-- do not remove (conditional flow control)

    # Domains -> bytes | or default
    domains = [network] if network else None

    # Load Felix from Configuration File with overrides
    try:
        felix_config = FelixConfiguration.from_configuration_file(
            filepath=config_file,
            domains=domains,
            registry_filepath=registry_filepath,
            provider_process=ETH_NODE,
            provider_uri=provider_uri,
            rest_host=host,
            rest_port=port,
            db_filepath=db_filepath,
            poa=poa)

    except FileNotFoundError:
        emitter.echo(
            f"No Felix configuration file found at {config_file}. "
            f"Check the filepath or run 'nucypher felix init' to create a new system configuration."
        )
        raise click.Abort

    if action == "destroy":
        """Delete all configuration files from the disk"""
        if dev:
            message = "'nucypher felix destroy' cannot be used in --dev mode"
            raise click.BadOptionUsage(option_name='--dev', message=message)
        actions.destroy_configuration(emitter,
                                      character_config=felix_config,
                                      force=force)
        return

    try:

        # Authenticate
        unlock_nucypher_keyring(emitter,
                                character_configuration=felix_config,
                                password=get_nucypher_password(confirm=False))

        # Produce Teacher Ursulas
        teacher_nodes = actions.load_seednodes(
            emitter,
            teacher_uris=[teacher_uri] if teacher_uri else None,
            min_stake=min_stake,
            federated_only=felix_config.federated_only,
            network_domains=felix_config.domains,
            network_middleware=click_config.middleware)

        # Produce Felix
        FELIX = felix_config.produce(domains=network,
                                     known_nodes=teacher_nodes)
        FELIX.make_web_app()  # attach web application, but dont start service

    except Exception as e:
        if click_config.debug:
            raise
        else:
            emitter.echo(str(e), color='red', bold=True)
            raise click.Abort

    if action == "createdb":  # Initialize Database
        if os.path.isfile(FELIX.db_filepath):
            if not force:
                click.confirm("Overwrite existing database?", abort=True)
            os.remove(FELIX.db_filepath)
            emitter.echo(f"Destroyed existing database {FELIX.db_filepath}")

        FELIX.create_tables()
        emitter.echo(f"\nCreated new database at {FELIX.db_filepath}",
                     color='green')

    elif action == 'view':
        token_balance = FELIX.token_balance
        eth_balance = FELIX.eth_balance
        emitter.echo(f"""
Address .... {FELIX.checksum_address}
NU ......... {str(token_balance)}
ETH ........ {str(eth_balance)}
        """)

    elif action == "accounts":
        accounts = FELIX.blockchain.client.accounts
        for account in accounts:
            emitter.echo(account)

    elif action == 'run':  # Start web services

        emitter.echo("Waiting for blockchain sync...", color='yellow')
        emitter.message(f"Running Felix on {host}:{port}")
        FELIX.start(host=host,
                    port=port,
                    web_services=not dry_run,
                    distribution=True,
                    crash_on_error=click_config.debug)

    else:
        raise click.BadArgumentUsage("No such argument {}".format(action))
コード例 #18
0
def alice(
    click_config,
    action,

    # Mode
    dev,
    force,
    dry_run,

    # Network
    teacher_uri,
    min_stake,
    federated_only,
    network,
    discovery_port,
    controller_port,

    # Filesystem
    config_root,
    config_file,

    # Blockchain
    pay_with,
    provider_uri,
    geth,
    sync,
    poa,
    registry_filepath,
    hw_wallet,

    # Alice
    bob_encrypting_key,
    bob_verifying_key,
    label,
    m,
    n,
    value,
    rate,
    duration_periods,
    expiration,
    message_kit,
):
    """
    "Alice the Policy Authority" management commands.

    \b
    Actions
    -------------------------------------------------
    \b
    init                  Create a brand new persistent Alice
    view                  View existing Alice's configuration.
    run                   Start Alice's controller.
    destroy               Delete existing Alice's configuration.
    public-keys           Obtain Alice's public verification and encryption keys.
    derive-policy-pubkey  Get a policy public key from a policy label.
    grant                 Create and enact an access policy for some Bob.
    revoke                Revoke a policy.
    decrypt               Decrypt data encrypted under an Alice's policy public key.

    """

    #
    # Validate
    #

    if federated_only and geth:
        raise click.BadOptionUsage(
            option_name="--geth",
            message="Federated only cannot be used with the --geth flag")

    # Banner
    emitter = click_config.emitter
    emitter.clear()
    emitter.banner(ALICE_BANNER)

    #
    # Managed Ethereum Client
    #

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process()
        provider_uri = ETH_NODE.provider_uri(scheme='file')

    #
    # Eager Actions (No Authentication Required)
    #

    if action == 'init':
        """Create a brand-new persistent Alice"""

        if dev:
            raise click.BadArgumentUsage(
                "Cannot create a persistent development character")

        if not provider_uri and not federated_only:
            raise click.BadOptionUsage(
                option_name='--provider',
                message=
                "--provider is required to create a new decentralized alice.")

        if not config_root:  # Flag
            config_root = click_config.config_file  # Envvar

        if not pay_with and not federated_only:
            pay_with = select_client_account(emitter=emitter,
                                             provider_uri=provider_uri)

        new_alice_config = AliceConfiguration.generate(
            password=get_nucypher_password(confirm=True),
            config_root=config_root,
            checksum_address=pay_with,
            domains={network} if network else None,
            federated_only=federated_only,
            registry_filepath=registry_filepath,
            provider_process=ETH_NODE,
            poa=poa,
            provider_uri=provider_uri,
            m=m,
            n=n,
            duration_periods=duration_periods,
            rate=rate)

        painting.paint_new_installation_help(
            emitter, new_configuration=new_alice_config)
        return  # Exit

    elif action == "view":
        """Paint an existing configuration to the console"""
        configuration_file_location = config_file or AliceConfiguration.default_filepath(
        )
        response = AliceConfiguration._read_configuration_file(
            filepath=configuration_file_location)
        return emitter.ipc(
            response=response, request_id=0,
            duration=0)  # FIXME: what are request_id and duration here?

    #
    # Get Alice Configuration
    #

    if dev:
        alice_config = AliceConfiguration(
            dev_mode=True,
            network_middleware=click_config.middleware,
            domains={network},
            provider_process=ETH_NODE,
            provider_uri=provider_uri,
            federated_only=True)

    else:
        try:
            alice_config = AliceConfiguration.from_configuration_file(
                dev_mode=False,
                filepath=config_file,
                domains={network} if network else None,
                network_middleware=click_config.middleware,
                rest_port=discovery_port,
                checksum_address=pay_with,
                provider_process=ETH_NODE,
                provider_uri=provider_uri,
                registry_filepath=registry_filepath)
        except FileNotFoundError:
            return actions.handle_missing_configuration_file(
                character_config_class=AliceConfiguration,
                config_file=config_file)

    if action == "destroy":
        """Delete all configuration files from the disk"""
        if dev:
            message = "'nucypher alice destroy' cannot be used in --dev mode"
            raise click.BadOptionUsage(option_name='--dev', message=message)
        return actions.destroy_configuration(emitter,
                                             character_config=alice_config,
                                             force=force)

    #
    # Produce Alice
    #

    # TODO: OH MY.
    client_password = None
    if not alice_config.federated_only:
        if (not hw_wallet or not dev) and not click_config.json_ipc:
            client_password = get_client_password(
                checksum_address=alice_config.checksum_address)

    try:
        ALICE = actions.make_cli_character(character_config=alice_config,
                                           click_config=click_config,
                                           dev=dev,
                                           teacher_uri=teacher_uri,
                                           min_stake=min_stake,
                                           client_password=client_password)
    except NucypherKeyring.AuthenticationFailed as e:
        emitter.echo(str(e), color='red', bold=True)
        click.get_current_context().exit(1)
        # TODO: Exit codes (not only for this, but for other exceptions)

    #
    # Admin Actions
    #

    if action == "run":
        """Start Alice Controller"""

        try:

            # RPC
            if click_config.json_ipc:
                rpc_controller = ALICE.make_rpc_controller()
                _transport = rpc_controller.make_control_transport()
                rpc_controller.start()
                return

            # HTTP
            else:
                emitter.message(
                    f"Alice Verifying Key {bytes(ALICE.stamp).hex()}",
                    color="green",
                    bold=True)
                controller = ALICE.make_web_controller(
                    crash_on_error=click_config.debug)
                ALICE.log.info('Starting HTTP Character Web Controller')
                emitter.message(
                    f'Running HTTP Alice Controller at http://localhost:{controller_port}'
                )
                return controller.start(http_port=controller_port,
                                        dry_run=dry_run)

        # Handle Crash
        except Exception as e:
            alice_config.log.critical(str(e))
            emitter.message(f"{e.__class__.__name__} {e}",
                            color='red',
                            bold=True)
            if click_config.debug:
                raise  # Crash :-(
            return

    #
    # Alice API
    #

    elif action == "public-keys":
        response = ALICE.controller.public_keys()
        return response

    elif action == "derive-policy-pubkey":

        # Validate
        if not label:
            raise click.BadOptionUsage(
                option_name='label',
                message=
                "--label is required for deriving a policy encrypting key.")

        # Request
        return ALICE.controller.derive_policy_encrypting_key(label=label)

    elif action == "grant":

        # Validate
        if not all((bob_verifying_key, bob_encrypting_key, label)):
            raise click.BadArgumentUsage(
                message=
                "--bob-verifying-key, --bob-encrypting-key, and --label are "
                "required options to grant (optionally --m, --n, and --expiration)."
            )

        # Request
        grant_request = {
            'bob_encrypting_key': bob_encrypting_key,
            'bob_verifying_key': bob_verifying_key,
            'label': label,
            'm': m,
            'n': n,
            'expiration': expiration,
        }

        if not ALICE.federated_only:
            grant_request.update({'value': value})
        return ALICE.controller.grant(request=grant_request)

    elif action == "revoke":

        # Validate
        if not label and bob_verifying_key:
            raise click.BadArgumentUsage(
                message=
                f"--label and --bob-verifying-key are required options for revoke."
            )

        # Request
        revoke_request = {
            'label': label,
            'bob_verifying_key': bob_verifying_key
        }
        return ALICE.controller.revoke(request=revoke_request)

    elif action == "decrypt":

        # Validate
        if not all((label, message_kit)):
            input_specification, output_specification = ALICE.controller.get_specifications(
                interface_name=action)
            required_fields = ', '.join(input_specification)
            raise click.BadArgumentUsage(
                f'{required_fields} are required flags to decrypt')

        # Request
        request_data = {'label': label, 'message_kit': message_kit}
        response = ALICE.controller.decrypt(request=request_data)
        return response

    else:
        raise click.BadArgumentUsage(f"No such argument {action}")
コード例 #19
0
def ursula(
    click_config,
    action,
    dev,
    dry_run,
    force,
    lonely,
    network,
    teacher_uri,
    min_stake,
    rest_host,
    rest_port,
    db_filepath,
    staker_address,
    worker_address,
    federated_only,
    poa,
    config_root,
    config_file,
    provider_uri,
    geth,
    registry_filepath,
    interactive,
    sync,
) -> None:
    """
    "Ursula the Untrusted" PRE Re-encryption node management commands.

    \b
    Actions
    -------------------------------------------------
    \b
    init              Create a new Ursula node configuration.
    view              View the Ursula node's configuration.
    run               Run an "Ursula" node.
    save-metadata     Manually write node metadata to disk without running
    forget            Forget all known nodes.
    destroy           Delete Ursula node configuration.
    confirm-activity  Manually confirm-activity for the current period.

    """

    emitter = click_config.emitter

    #
    # Validate
    #

    if federated_only:
        if geth:
            raise click.BadOptionUsage(
                option_name="--geth",
                message="Federated only cannot be used with the --geth flag")

        if staker_address:
            raise click.BadOptionUsage(
                option_name='--federated-only',
                message="Staking address cannot be used in federated mode.")

    # Banner
    emitter.banner(URSULA_BANNER.format(worker_address or ''))

    #
    # Pre-Launch Warnings
    #

    if dev:
        emitter.echo("WARNING: Running in Development mode",
                     color='yellow',
                     verbosity=1)
    if force:
        emitter.echo("WARNING: Force is enabled", color='yellow', verbosity=1)

    #
    # Internal Ethereum Client
    #

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process()
        provider_uri = ETH_NODE.provider_uri(scheme='file')

    #
    # Eager Actions
    #

    if action == "init":
        """Create a brand-new persistent Ursula"""

        if dev:
            raise click.BadArgumentUsage(
                "Cannot create a persistent development character")

        if (not staker_address or not worker_address) and not federated_only:

            # Connect to Blockchain
            fetch_registry = registry_filepath is None and not click_config.no_registry
            registry = None
            if registry_filepath:
                registry = EthereumContractRegistry(
                    registry_filepath=registry_filepath)
            blockchain = BlockchainInterface(provider_uri=provider_uri,
                                             registry=registry,
                                             poa=poa)
            blockchain.connect(fetch_registry=fetch_registry,
                               sync_now=sync,
                               emitter=emitter)

            if not staker_address:
                prompt = "Select staker account"
                staker_address = select_client_account(emitter=emitter,
                                                       blockchain=blockchain,
                                                       prompt=prompt)

            if not worker_address:
                prompt = "Select worker account"
                worker_address = select_client_account(emitter=emitter,
                                                       blockchain=blockchain,
                                                       prompt=prompt)

        if not config_root:  # Flag
            config_root = click_config.config_file  # Envvar

        if not rest_host:
            rest_host = actions.determine_external_ip_address(emitter,
                                                              force=force)

        download_registry = not federated_only and not click_config.no_registry
        ursula_config = UrsulaConfiguration.generate(
            password=get_nucypher_password(confirm=True),
            config_root=config_root,
            rest_host=rest_host,
            rest_port=rest_port,
            db_filepath=db_filepath,
            domains={network} if network else None,
            federated_only=federated_only,
            checksum_address=staker_address,
            worker_address=worker_address,
            download_registry=download_registry,
            registry_filepath=registry_filepath,
            provider_process=ETH_NODE,
            provider_uri=provider_uri,
            poa=poa)

        painting.paint_new_installation_help(emitter,
                                             new_configuration=ursula_config)
        return

    #
    # Make Ursula
    #

    if dev:
        ursula_config = UrsulaConfiguration(
            dev_mode=True,
            domains={TEMPORARY_DOMAIN},
            poa=poa,
            download_registry=False,
            registry_filepath=registry_filepath,
            provider_process=ETH_NODE,
            provider_uri=provider_uri,
            checksum_address=staker_address,
            worker_address=worker_address,
            federated_only=federated_only,
            rest_host=rest_host,
            rest_port=rest_port,
            db_filepath=db_filepath)
    else:
        try:
            ursula_config = UrsulaConfiguration.from_configuration_file(
                filepath=config_file,
                domains={network} if network else None,
                registry_filepath=registry_filepath,
                provider_process=ETH_NODE,
                provider_uri=provider_uri,
                rest_host=rest_host,
                rest_port=rest_port,
                db_filepath=db_filepath,
                poa=poa,
                federated_only=federated_only)
        except FileNotFoundError:
            return actions.handle_missing_configuration_file(
                character_config_class=UrsulaConfiguration,
                config_file=config_file)
        except NucypherKeyring.AuthenticationFailed as e:
            emitter.echo(str(e), color='red', bold=True)
            click.get_current_context().exit(1)
            # TODO: Exit codes (not only for this, but for other exceptions)

    #
    # Configured Pre-Authentication Actions
    #

    # Handle destruction and forget *before* network bootstrap and character initialization below
    if action == "destroy":
        """Delete all configuration files from the disk"""
        if dev:
            message = "'nucypher ursula destroy' cannot be used in --dev mode - There is nothing to destroy."
            raise click.BadOptionUsage(option_name='--dev', message=message)
        actions.destroy_configuration(emitter,
                                      character_config=ursula_config,
                                      force=force)
        return

    elif action == "forget":
        actions.forget(emitter, configuration=ursula_config)
        return

    #
    # Make Ursula
    #
    client_password = None
    if not ursula_config.federated_only:
        if not dev and not click_config.json_ipc:
            client_password = get_client_password(
                checksum_address=ursula_config.worker_address,
                envvar="NUCYPHER_WORKER_ETH_PASSWORD")

    try:
        URSULA = actions.make_cli_character(character_config=ursula_config,
                                            click_config=click_config,
                                            min_stake=min_stake,
                                            teacher_uri=teacher_uri,
                                            dev=dev,
                                            lonely=lonely,
                                            client_password=client_password)
    except NucypherKeyring.AuthenticationFailed as e:
        emitter.echo(str(e), color='red', bold=True)
        click.get_current_context().exit(1)
        # TODO: Exit codes (not only for this, but for other exceptions)

    #
    # Authenticated Action Switch
    #

    if action == 'run':
        """Seed, Produce, Run!"""

        # GO!
        try:

            # Ursula Deploy Warnings
            emitter.message(f"Starting Ursula on {URSULA.rest_interface}",
                            color='green',
                            bold=True)

            emitter.message(f"Connecting to {','.join(ursula_config.domains)}",
                            color='green',
                            bold=True)

            emitter.message("Working ~ Keep Ursula Online!",
                            color='blue',
                            bold=True)

            if interactive:
                stdio.StandardIO(
                    UrsulaCommandProtocol(ursula=URSULA, emitter=emitter))

            if dry_run:
                return  # <-- ABORT - (Last Chance)

            # Run - Step 3
            node_deployer = URSULA.get_deployer()
            node_deployer.addServices()
            node_deployer.catalogServers(node_deployer.hendrix)
            node_deployer.run()  # <--- Blocking Call (Reactor)

        # Handle Crash
        except Exception as e:
            ursula_config.log.critical(str(e))
            emitter.message(f"{e.__class__.__name__} {e}",
                            color='red',
                            bold=True)
            raise  # Crash :-(

        # Graceful Exit
        finally:
            emitter.message("Stopping Ursula", color='green')
            ursula_config.cleanup()
            emitter.message("Ursula Stopped", color='red')
        return

    elif action == "save-metadata":
        """Manually save a node self-metadata file"""
        metadata_path = ursula.write_node_metadata(node=URSULA)
        emitter.message(
            f"Successfully saved node metadata to {metadata_path}.",
            color='green')
        return

    elif action == "view":
        """Paint an existing configuration to the console"""

        if not URSULA.federated_only:
            emitter.echo("BLOCKCHAIN ----------\n")
            painting.paint_contract_status(emitter=emitter,
                                           blockchain=URSULA.blockchain)
            current_block = URSULA.blockchain.w3.eth.blockNumber
            emitter.echo(f'Block # {current_block}')
            # TODO: 1231
            emitter.echo(f'NU Balance (staker): {URSULA.token_balance}')
            emitter.echo(
                f'ETH Balance (worker): {URSULA.blockchain.client.get_balance(URSULA.worker_address)}'
            )
            emitter.echo(
                f'Current Gas Price {URSULA.blockchain.client.gas_price}')

        emitter.echo("CONFIGURATION --------")
        response = UrsulaConfiguration._read_configuration_file(
            filepath=config_file or ursula_config.config_file_location)
        return emitter.ipc(
            response=response, request_id=0, duration=0
        )  # FIXME: #1216 - what are request_id and duration here?

    elif action == 'confirm-activity':
        receipt = URSULA.confirm_activity()

        confirmed_period = URSULA.staking_agent.get_current_period() + 1
        date = datetime_at_period(period=confirmed_period)

        # TODO: Double-check dates here
        emitter.echo(
            f'\nActivity confirmed for period #{confirmed_period} '
            f'(starting at {date})',
            bold=True,
            color='blue')
        painting.paint_receipt_summary(
            emitter=emitter,
            receipt=receipt,
            chain_name=URSULA.blockchain.client.chain_name)

        # TODO: Check ActivityConfirmation event (see #1193)
        return

    else:
        raise click.BadArgumentUsage("No such argument {}".format(action))
コード例 #20
0
ファイル: alice.py プロジェクト: Howlla/nucypher
def alice(
        click_config,
        action,

        # Mode
        dev,
        force,
        dry_run,

        # Network
        teacher_uri,
        min_stake,
        federated_only,
        network,
        discovery_port,
        controller_port,

        # Filesystem
        config_root,
        config_file,

        # Blockchain
        pay_with,
        provider_uri,
        geth,
        sync,
        poa,
        no_registry,
        registry_filepath,

        # Alice
        bob_encrypting_key,
        bob_verifying_key,
        label,
        m,
        n,
        value,
        rate,
        duration,
        expiration,
        message_kit):

    #
    # Validate
    #

    if federated_only and geth:
        raise click.BadOptionUsage(
            option_name="--geth",
            message="Federated only cannot be used with the --geth flag")

    # Banner
    click.clear()
    if not click_config.json_ipc and not click_config.quiet:
        click.secho(ALICE_BANNER)

    #
    # Managed Ethereum Client
    #

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process()
        provider_uri = ETH_NODE.provider_uri(scheme='file')

    #
    # Eager Actions (No Authentication Required)
    #

    if action == 'init':
        """Create a brand-new persistent Alice"""

        if dev:
            raise click.BadArgumentUsage(
                "Cannot create a persistent development character")

        if not config_root:  # Flag
            config_root = click_config.config_file  # Envvar

        new_alice_config = AliceConfiguration.generate(
            password=click_config.get_password(confirm=True),
            config_root=config_root,
            checksum_address=pay_with,
            rest_host="localhost",
            domains={network} if network else None,
            federated_only=federated_only,
            download_registry=no_registry,
            registry_filepath=registry_filepath,
            provider_process=ETH_NODE,
            poa=poa,
            provider_uri=provider_uri,
            m=m,
            n=n,
            duration=duration,
            rate=rate)

        painting.paint_new_installation_help(
            new_configuration=new_alice_config,
            config_root=config_root,
            config_file=config_file)
        return  # Exit

    elif action == "view":
        """Paint an existing configuration to the console"""
        configuration_file_location = config_file or AliceConfiguration.DEFAULT_CONFIG_FILE_LOCATION
        response = AliceConfiguration._read_configuration_file(
            filepath=configuration_file_location)
        click_config.emit(response)
        return  # Exit

    #
    # Make Alice
    #

    if dev:
        alice_config = AliceConfiguration(
            dev_mode=True,
            network_middleware=click_config.middleware,
            domains={network},
            provider_process=ETH_NODE,
            provider_uri=provider_uri,
            federated_only=True)

    else:
        try:
            alice_config = AliceConfiguration.from_configuration_file(
                filepath=config_file,
                domains={network} if network else None,
                network_middleware=click_config.middleware,
                rest_port=discovery_port,
                checksum_address=pay_with,
                provider_process=ETH_NODE,
                provider_uri=provider_uri)
        except FileNotFoundError:
            return actions.handle_missing_configuration_file(
                character_config_class=AliceConfiguration,
                config_file=config_file)

    ALICE = actions.make_cli_character(character_config=alice_config,
                                       click_config=click_config,
                                       dev=dev,
                                       teacher_uri=teacher_uri,
                                       min_stake=min_stake,
                                       sync=sync)

    #
    # Admin Actions
    #

    if action == "run":
        """Start Alice Web Controller"""
        ALICE.controller.emitter(
            message=f"Alice Verifying Key {bytes(ALICE.stamp).hex()}",
            color="green",
            bold=True)
        controller = ALICE.make_web_controller(
            crash_on_error=click_config.debug)
        ALICE.log.info('Starting Alice Web Controller')
        return controller.start(http_port=controller_port
                                or alice_config.controller_port,
                                dry_run=dry_run)

    elif action == "destroy":
        """Delete all configuration files from the disk"""
        if dev:
            message = "'nucypher alice destroy' cannot be used in --dev mode"
            raise click.BadOptionUsage(option_name='--dev', message=message)
        return actions.destroy_configuration(character_config=alice_config,
                                             force=force)

    #
    # Alice API
    #

    elif action == "public-keys":
        response = ALICE.controller.public_keys()
        return response

    elif action == "derive-policy-pubkey":

        # Validate
        if not label:
            raise click.BadOptionUsage(
                option_name='label',
                message=
                "--label is required for deriving a policy encrypting key.")

        # Request
        return ALICE.controller.derive_policy_encrypting_key(label=label)

    elif action == "grant":

        # Validate
        if not all((bob_verifying_key, bob_encrypting_key, label)):
            raise click.BadArgumentUsage(
                message=
                "--bob-verifying-key, --bob-encrypting-key, and --label are "
                "required options to grant (optionally --m, --n, and --expiration)."
            )

        # Request
        grant_request = {
            'bob_encrypting_key': bob_encrypting_key,
            'bob_verifying_key': bob_verifying_key,
            'label': label,
            'm': m,
            'n': n,
            'expiration': expiration,
        }

        if not ALICE.federated_only:
            grant_request.update({'value': value})

        return ALICE.controller.grant(request=grant_request)

    elif action == "revoke":

        # Validate
        if not label and bob_verifying_key:
            raise click.BadArgumentUsage(
                message=
                f"--label and --bob-verifying-key are required options for revoke."
            )

        # Request
        revoke_request = {
            'label': label,
            'bob_verifying_key': bob_verifying_key
        }
        return ALICE.controller.revoke(request=revoke_request)

    elif action == "decrypt":

        # Validate
        if not all((label, message_kit)):
            input_specification, output_specification = ALICE.controller.get_specifications(
                interface_name=action)
            required_fields = ', '.join(input_specification)
            raise click.BadArgumentUsage(
                f'{required_fields} are required flags to decrypt')

        # Request
        request_data = {'label': label, 'message_kit': message_kit}
        response = ALICE.controller.decrypt(request=request_data)
        return response

    else:
        raise click.BadArgumentUsage(f"No such argument {action}")
コード例 #21
0
def felix(click_config, action, teacher_uri, enode, min_stake, network, host,
          dry_run, port, discovery_port, provider_uri, geth, config_root,
          checksum_address, poa, config_file, db_filepath, no_registry,
          registry_filepath, dev, force):

    # Intro
    click.clear()
    if not click_config.quiet:
        click.secho(FELIX_BANNER.format(checksum_address or ''))

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process(dev=dev)
        provider_uri = ETH_NODE.provider_uri

    if action == "init":
        """Create a brand-new Felix"""

        if not config_root:  # Flag
            config_root = DEFAULT_CONFIG_ROOT  # Envvar or init-only default

        # Acquire Keyring Password
        new_password = click_config.get_password(confirm=True)

        try:
            new_felix_config = FelixConfiguration.generate(
                password=new_password,
                config_root=config_root,
                rest_host=host,
                rest_port=discovery_port,
                db_filepath=db_filepath,
                domains={network} if network else None,
                checksum_address=checksum_address,
                download_registry=not no_registry,
                registry_filepath=registry_filepath,
                provider_uri=provider_uri,
                provider_process=ETH_NODE,
                poa=poa)
        except Exception as e:
            if click_config.debug:
                raise
            else:
                click.secho(str(e), fg='red', bold=True)
                raise click.Abort

        # Paint Help
        painting.paint_new_installation_help(
            new_configuration=new_felix_config,
            config_root=config_root,
            config_file=config_file)

        return  # <-- do not remove (conditional flow control)

    # Domains -> bytes | or default
    domains = [network] if network else None

    # Load Felix from Configuration File with overrides
    try:
        felix_config = FelixConfiguration.from_configuration_file(
            filepath=config_file,
            domains=domains,
            registry_filepath=registry_filepath,
            provider_process=ETH_NODE,
            provider_uri=provider_uri,
            rest_host=host,
            rest_port=port,
            db_filepath=db_filepath,
            poa=poa)

    except FileNotFoundError:
        click.secho(
            f"No Felix configuration file found at {config_file}. "
            f"Check the filepath or run 'nucypher felix init' to create a new system configuration."
        )
        raise click.Abort

    try:

        # Connect to Blockchain
        felix_config.connect_to_blockchain()

        # Authenticate
        password = click_config.get_password(confirm=False)
        click_config.unlock_keyring(character_configuration=felix_config,
                                    password=password)

        # Produce Teacher Ursulas
        teacher_nodes = actions.load_seednodes(
            teacher_uris=[teacher_uri] if teacher_uri else None,
            min_stake=min_stake,
            federated_only=felix_config.federated_only,
            network_domains=felix_config.domains,
            network_middleware=click_config.middleware)

        # Add ETH Bootnode or Peer
        if enode:
            if geth:
                felix_config.blockchain.interface.w3.geth.admin.addPeer(enode)
                click.secho(f"Added ethereum peer {enode}")
            else:
                raise NotImplemented  # TODO: other backends

        # Produce Felix
        FELIX = felix_config.produce(domains=network,
                                     known_nodes=teacher_nodes)
        FELIX.make_web_app()  # attach web application, but dont start service

    except Exception as e:
        if click_config.debug:
            raise
        else:
            click.secho(str(e), fg='red', bold=True)
            raise click.Abort

    if action == "createdb":  # Initialize Database
        if os.path.isfile(FELIX.db_filepath):
            if not force:
                click.confirm("Overwrite existing database?", abort=True)
            os.remove(FELIX.db_filepath)
            click.secho(f"Destroyed existing database {FELIX.db_filepath}")

        FELIX.create_tables()
        click.secho(f"\nCreated new database at {FELIX.db_filepath}",
                    fg='green')

    elif action == 'view':
        token_balance = FELIX.token_balance
        eth_balance = FELIX.eth_balance
        click.secho(f"""
Address .... {FELIX.checksum_address}
NU ......... {str(token_balance)}
ETH ........ {str(eth_balance)}
        """)

    elif action == "accounts":
        accounts = FELIX.blockchain.interface.w3.eth.accounts
        for account in accounts:
            click.secho(account)

    elif action == "destroy":
        """Delete all configuration files from the disk"""
        actions.destroy_configuration(character_config=felix_config,
                                      force=force)

    elif action == 'run':  # Start web services

        try:
            click.secho("Waiting for blockchain sync...", fg='yellow')
            FELIX.blockchain.sync()
            FELIX.start(host=host,
                        port=port,
                        web_services=not dry_run,
                        distribution=True,
                        crash_on_error=click_config.debug)
        finally:
            FELIX.blockchain.disconnect()

    else:
        raise click.BadArgumentUsage("No such argument {}".format(action))
コード例 #22
0
ファイル: alice.py プロジェクト: existentializm/nucypher
def init(
        click_config,

        # Admin Options
        geth,
        provider_uri,
        federated_only,
        dev,
        pay_with,
        network,
        registry_filepath,

        # Other
        config_root,
        poa,
        m,
        n,
        rate,
        duration_periods):
    """
    Create a brand new persistent Alice.
    """

    ### Setup ###
    emitter = _setup_emitter(click_config)

    if federated_only and geth:
        raise click.BadOptionUsage(
            option_name="--geth",
            message="Federated only cannot be used with the --geth flag")

    #
    # Managed Ethereum Client
    #

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process()
        provider_uri = ETH_NODE.provider_uri(scheme='file')

    #############

    if dev:
        raise click.BadArgumentUsage(
            "Cannot create a persistent development character")

    if not provider_uri and not federated_only:
        raise click.BadOptionUsage(
            option_name='--provider',
            message=
            "--provider is required to create a new decentralized alice.")

    if not config_root:  # Flag
        config_root = click_config.config_file  # Envvar

    if not pay_with and not federated_only:
        pay_with = select_client_account(emitter=emitter,
                                         provider_uri=provider_uri)

    new_alice_config = AliceConfiguration.generate(
        password=get_nucypher_password(confirm=True),
        config_root=config_root,
        checksum_address=pay_with,
        domains={network} if network else None,
        federated_only=federated_only,
        registry_filepath=registry_filepath,
        provider_process=ETH_NODE,
        poa=poa,
        provider_uri=provider_uri,
        m=m,
        n=n,
        duration_periods=duration_periods,
        rate=rate)

    painting.paint_new_installation_help(emitter,
                                         new_configuration=new_alice_config)
コード例 #23
0
ファイル: status.py プロジェクト: zaxayn/nucypher
def status(click_config, action, provider_uri, sync, geth, poa, periods, staking_address, registry_filepath):
    """
    Echo a snapshot of live NuCypher Network metadata.

    \b
    Actions
    -------------------------------------------------
    network        Overall information of the NuCypher Network
    stakers        Show relevant information about stakers
    locked-tokens  Display a graph of evolution of locked tokens

    """

    emitter = click_config.emitter
    click.clear()
    emitter.banner(NU_BANNER)

    #
    # Connect to Blockchain
    #

    try:
        ETH_NODE = None
        if geth:
            ETH_NODE = get_provider_process()

        # Note: For test compatibility.
        if not BlockchainInterfaceFactory.is_interface_initialized(provider_uri=provider_uri):
            BlockchainInterfaceFactory.initialize_interface(provider_uri=provider_uri,
                                                            provider_process=ETH_NODE,
                                                            poa=poa,
                                                            sync=False,
                                                            show_sync_progress=False)

        blockchain = BlockchainInterfaceFactory.get_interface(provider_uri=provider_uri)

        emitter.echo(message="Reading Latest Chaindata...")
        blockchain.connect()
    except Exception as e:
        if click_config.debug:
            raise
        click.secho(str(e), bold=True, fg='red')
        raise click.Abort

    if registry_filepath:
        registry = LocalContractRegistry(filepath=registry_filepath)
    else:
        registry = InMemoryContractRegistry.from_latest_publication()

    staking_agent = ContractAgency.get_agent(StakingEscrowAgent, registry=registry)

    if action == 'network':
        paint_contract_status(registry, emitter=emitter)
        return  # Exit

    elif action == 'stakers':
        stakers = [staking_address] if staking_address else staking_agent.get_stakers()
        paint_stakers(emitter=emitter, stakers=stakers, agent=staking_agent)
        return  # Exit

    elif action == 'locked-tokens':
        paint_locked_tokens_status(emitter=emitter, agent=staking_agent, periods=periods)
        return  # Exit

    else:
        ctx = click.get_current_context()
        raise click.UsageError(message=f"Unknown action '{action}'.", ctx=ctx)
コード例 #24
0
ファイル: ursula.py プロジェクト: pranav-singhal/nucypher
def ursula(
    click_config,
    action,
    dev,
    quiet,
    dry_run,
    force,
    lonely,
    network,
    teacher_uri,
    min_stake,
    rest_host,
    rest_port,
    db_filepath,
    checksum_address,
    withdraw_address,
    federated_only,
    poa,
    config_root,
    config_file,
    provider_uri,
    geth,
    no_registry,
    registry_filepath,
    value,
    duration,
    index,
    list_,
    divide,
    sync,
    device,
    interactive,
) -> None:
    """
    Manage and run an "Ursula" PRE node.

    \b
    Actions
    -------------------------------------------------
    \b
    init              Create a new Ursula node configuration.
    view              View the Ursula node's configuration.
    run               Run an "Ursula" node.
    save-metadata     Manually write node metadata to disk without running
    forget            Forget all known nodes.
    destroy           Delete Ursula node configuration.
    stake             Manage stakes for this node.
    confirm-activity  Manually confirm-activity for the current period.
    collect-reward    Withdraw staking reward.

    """

    #
    # Validate
    #

    if federated_only and geth:
        raise click.BadOptionUsage(
            option_name="--geth",
            message="Federated only cannot be used with the --geth flag")

    if click_config.debug and quiet:
        raise click.BadOptionUsage(
            option_name="quiet",
            message="--debug and --quiet cannot be used at the same time.")

    # Banner
    if not click_config.json_ipc and not click_config.quiet:
        click.secho(URSULA_BANNER.format(checksum_address or ''))

    #
    # Pre-Launch Warnings
    #

    if not click_config.quiet:
        if dev:
            click.secho("WARNING: Running in Development mode", fg='yellow')
        if force:
            click.secho("WARNING: Force is enabled", fg='yellow')

    #
    # Internal Ethereum Client
    #

    ETH_NODE = NO_BLOCKCHAIN_CONNECTION
    if geth:
        ETH_NODE = actions.get_provider_process()
        provider_uri = ETH_NODE.provider_uri(scheme='file')

    #
    # Eager Actions
    #

    if action == "init":
        """Create a brand-new persistent Ursula"""

        if dev:
            raise click.BadArgumentUsage(
                "Cannot create a persistent development character")

        if not config_root:  # Flag
            config_root = click_config.config_file  # Envvar

        if not rest_host:
            rest_host = actions.determine_external_ip_address(force=force)

        ursula_config = UrsulaConfiguration.generate(
            password=get_password(confirm=True),
            config_root=config_root,
            rest_host=rest_host,
            rest_port=rest_port,
            db_filepath=db_filepath,
            domains={network} if network else None,
            federated_only=federated_only,
            checksum_address=checksum_address,
            download_registry=federated_only or no_registry,
            registry_filepath=registry_filepath,
            provider_process=ETH_NODE,
            provider_uri=provider_uri,
            poa=poa)

        painting.paint_new_installation_help(new_configuration=ursula_config)
        return

    #
    # Make Ursula
    #

    if dev:
        ursula_config = UrsulaConfiguration(
            dev_mode=True,
            domains={TEMPORARY_DOMAIN},
            poa=poa,
            download_registry=False,
            registry_filepath=registry_filepath,
            provider_process=ETH_NODE,
            provider_uri=provider_uri,
            checksum_address=checksum_address,
            federated_only=federated_only,
            rest_host=rest_host,
            rest_port=rest_port,
            db_filepath=db_filepath)
    else:
        try:
            ursula_config = UrsulaConfiguration.from_configuration_file(
                filepath=config_file,
                domains={network} if network else None,
                registry_filepath=registry_filepath,
                provider_process=ETH_NODE,
                provider_uri=provider_uri,
                rest_host=rest_host,
                rest_port=rest_port,
                db_filepath=db_filepath,
                poa=poa,
                federated_only=federated_only)
        except FileNotFoundError:
            return actions.handle_missing_configuration_file(
                character_config_class=UrsulaConfiguration,
                config_file=config_file)
        except Exception as e:
            if click_config.debug:
                raise
            else:
                click.secho(str(e), fg='red', bold=True)
                raise click.Abort

    #
    # Configured Pre-Authentication Actions
    #

    # Handle destruction *before* network bootstrap and character initialization below
    if action == "destroy":
        """Delete all configuration files from the disk"""
        if dev:
            message = "'nucypher ursula destroy' cannot be used in --dev mode - There is nothing to destroy."
            raise click.BadOptionUsage(option_name='--dev', message=message)
        return actions.destroy_configuration(character_config=ursula_config,
                                             force=force)

    #
    # Make Ursula
    #

    URSULA = actions.make_cli_character(character_config=ursula_config,
                                        click_config=click_config,
                                        min_stake=min_stake,
                                        teacher_uri=teacher_uri,
                                        dev=dev,
                                        lonely=lonely)

    #
    # Authenticated Action Switch
    #

    if action == 'run':
        """Seed, Produce, Run!"""

        # GO!
        try:

            # Ursula Deploy Warnings
            click_config.emit(message="Starting Ursula on {}".format(
                URSULA.rest_interface),
                              color='green',
                              bold=True)

            click_config.emit(message="Connecting to {}".format(','.join(
                ursula_config.domains)),
                              color='green',
                              bold=True)

            if not URSULA.federated_only and URSULA.stakes:
                click_config.emit(
                    message=
                    f"Staking {str(URSULA.current_stake)} ~ Keep Ursula Online!",
                    color='blue',
                    bold=True)

            if interactive:
                stdio.StandardIO(UrsulaCommandProtocol(ursula=URSULA))

            if dry_run:
                return  # <-- ABORT - (Last Chance)

            # Run - Step 3
            node_deployer = URSULA.get_deployer()
            node_deployer.addServices()
            node_deployer.catalogServers(node_deployer.hendrix)
            node_deployer.run()  # <--- Blocking Call (Reactor)

        # Handle Crash
        except Exception as e:
            ursula_config.log.critical(str(e))
            click_config.emit(message="{} {}".format(e.__class__.__name__,
                                                     str(e)),
                              color='red',
                              bold=True)
            raise  # Crash :-(

        # Graceful Exit
        finally:
            click_config.emit(message="Stopping Ursula", color='green')
            ursula_config.cleanup()
            click_config.emit(message="Ursula Stopped", color='red')
        return

    elif action == "save-metadata":
        """Manually save a node self-metadata file"""
        metadata_path = ursula.write_node_metadata(node=URSULA)
        return click_config.emit(
            message="Successfully saved node metadata to {}.".format(
                metadata_path),
            color='green')

    elif action == "view":
        """Paint an existing configuration to the console"""

        if not URSULA.federated_only:
            click.secho("BLOCKCHAIN ----------\n")
            painting.paint_contract_status(click_config=click_config,
                                           ursula_config=ursula_config)
            current_block = URSULA.blockchain.w3.eth.blockNumber
            click.secho(f'Block # {current_block}')
            click.secho(f'NU Balance: {URSULA.token_balance}')
            click.secho(f'ETH Balance: {URSULA.eth_balance}')
            click.secho(
                f'Current Gas Price {URSULA.blockchain.client.gasPrice}')

        click.secho("CONFIGURATION --------")
        response = UrsulaConfiguration._read_configuration_file(
            filepath=config_file or ursula_config.config_file_location)
        return click_config.emit(response=response)

    elif action == "forget":
        actions.forget(configuration=ursula_config)
        return

    elif action == 'stake':

        # List Only
        if list_:
            if not URSULA.stakes:
                click.echo(
                    f"There are no active stakes for {URSULA.checksum_address}"
                )
            else:
                painting.paint_stakes(stakes=URSULA.stakes)
            return

        # Divide Only
        if divide:
            """Divide an existing stake by specifying the new target value and end period"""

            # Validate
            if not URSULA.stakes:
                click.echo(
                    f"There are no active stakes for {URSULA.checksum_address}"
                )
                return

            # Selection
            if index is None:
                painting.paint_stakes(stakes=URSULA.stakes)
                index = click.prompt("Select a stake to divide",
                                     type=click.IntRange(
                                         min=0, max=len(URSULA.stakes) - 1))

            # Lookup the stake
            current_stake = URSULA.stakes[index]

            # Value
            if not value:
                value = click.prompt(
                    f"Enter target value (must be less than {str(current_stake.value)})",
                    type=STAKE_VALUE)
            value = NU(value, 'NU')

            # Duration
            if not duration:
                extension = click.prompt("Enter number of periods to extend",
                                         type=STAKE_EXTENSION)
            else:
                extension = duration

            if not force:
                painting.paint_staged_stake_division(
                    ursula=URSULA,
                    original_index=index,
                    original_stake=current_stake,
                    target_value=value,
                    extension=extension)

                click.confirm("Is this correct?", abort=True)

            modified_stake, new_stake = URSULA.divide_stake(
                stake_index=index,
                target_value=value,
                additional_periods=extension)

            if not quiet:
                click.secho('Successfully divided stake', fg='green')
                click.secho(
                    f'Transaction Hash ........... {new_stake.receipt}')

            # Show the resulting stake list
            painting.paint_stakes(stakes=URSULA.stakes)

            return

        # Confirm new stake init
        if not force:
            click.confirm("Stage a new stake?", abort=True)

        # Validate balance
        balance = URSULA.token_balance
        if balance == 0:
            click.secho(f"{URSULA.checksum_address} has 0 NU.")
            raise click.Abort
        if not quiet:
            click.echo(f"Current balance: {balance}")

        # Gather stake value
        if not value:
            min_locked = NU(URSULA.economics.minimum_allowed_locked, 'NuNit')
            value = click.prompt(f"Enter stake value",
                                 type=STAKE_VALUE,
                                 default=min_locked)
        else:
            value = NU(int(value), 'NU')

        # Duration
        if not quiet:
            message = f"Minimum duration: {URSULA.economics.minimum_allowed_locked} | " \
                      f"Maximum Duration: {URSULA.economics.maximum_allowed_locked}"
            click.echo(message)
        if not duration:
            duration = click.prompt(
                "Enter stake duration in periods (1 Period = 24 Hours)",
                type=STAKE_DURATION)
        start_period = URSULA.staking_agent.get_current_period()
        end_period = start_period + duration

        # Review
        if not force:
            painting.paint_staged_stake(ursula=URSULA,
                                        stake_value=value,
                                        duration=duration,
                                        start_period=start_period,
                                        end_period=end_period)

            if not dev:
                actions.confirm_staged_stake(ursula=URSULA,
                                             value=value,
                                             duration=duration)

        # Last chance to bail
        if not force:
            click.confirm("Publish staged stake to the blockchain?",
                          abort=True)

        stake = URSULA.initialize_stake(amount=int(value),
                                        lock_periods=duration)
        # TODO temporary fix to not break backward compatibility
        URSULA.set_worker(worker_address=URSULA.checksum_address)
        painting.paint_staking_confirmation(ursula=URSULA,
                                            transactions=stake.transactions)
        return

    elif action == 'confirm-activity':
        if not URSULA.stakes:
            click.secho("There are no active stakes for {}".format(
                URSULA.checksum_address))
            return
        URSULA.staking_agent.confirm_activity(
            node_address=URSULA.checksum_address)
        return

    elif action == 'collect-reward':
        """Withdraw staking reward to the specified wallet address"""
        if not force:
            click.confirm(
                f"Send {URSULA.calculate_reward()} to {URSULA.checksum_address}?"
            )
        inflation_reward = URSULA.calculate_reward()
        if inflation_reward:
            URSULA.collect_staking_reward()
        URSULA.collect_policy_reward(
            collector_address=withdraw_address or checksum_address)

    else:
        raise click.BadArgumentUsage("No such argument {}".format(action))