def info(
    private_key: str,
    web3: Web3,
    contracts: Dict[str, Contract],
    start_block: BlockNumber,
) -> None:
    log.info("Using RPC endpoint", rpc_url=get_web3_provider_info(web3))
    service_registry_contract = contracts[CONTRACT_SERVICE_REGISTRY]
    deposit_token_address = service_registry_contract.functions.token().call()
    deposit_token_contract = web3.eth.contract(
        address=deposit_token_address,
        abi=CONTRACT_MANAGER.get_contract_abi(CONTRACT_CUSTOM_TOKEN),
    )
    caller_address = private_key_to_address(private_key)
    fmt_amount = get_token_formatter(deposit_token_contract)

    deposits = find_deposits(
        web3=web3,
        service_address=caller_address,
        service_registry_contract=service_registry_contract,
        start_block=start_block,
    )
    if not deposits:
        print("No deposits were made from this account.")
        return

    print("Deposits:")
    for dep in deposits:
        print(f" * block {dep['block_number']}", end=", ")
        print(f"amount: {fmt_amount(dep['amount'])}", end=", ")
        if dep["withdrawn"]:
            print("WITHDRAWN")
        else:
            print("increased validity till " + dep["valid_till"])
예제 #2
0
def withdraw(
    private_key: str,
    web3: Web3,
    contracts: Dict[str, Contract],
    start_block: BlockNumber,
    to: Optional[Address],
) -> None:
    log.info("Using RPC endpoint", rpc_url=get_web3_provider_info(web3))
    service_registry_contract = contracts[CONTRACT_SERVICE_REGISTRY]
    caller_address = private_key_to_address(private_key)

    # Find deposit contract address
    caller_address = private_key_to_address(private_key)
    deposit_contract_address = find_withdrawable_deposit(
        web3=web3,
        service_address=caller_address,
        service_registry_contract=service_registry_contract,
        start_block=start_block,
    )
    deposit_contract = web3.eth.contract(
        abi=CONTRACT_MANAGER.get_contract_abi(CONTRACT_DEPOSIT),
        address=deposit_contract_address)

    # Check usage of correct key
    withdrawer = deposit_contract.functions.withdrawer().call()
    if to_canonical_address(withdrawer) != caller_address:
        log.error(
            "You must use the key used to deposit when withdrawing",
            expected=withdrawer,
            actual=to_checksum_address(caller_address),
        )
        sys.exit(1)

    # Can we withdraw already?
    release_at = deposit_contract.functions.release_at().call()
    deprecated = service_registry_contract.functions.deprecated().call()
    if web3.eth.getBlock(
            "latest")["timestamp"] < release_at and not deprecated:
        log.error(
            "Too early to withdraw",
            released_at_utc=datetime.utcfromtimestamp(release_at).isoformat(),
        )
        sys.exit(1)

    receiver = to or private_key_to_address(private_key)
    checked_transact(
        web3=web3,
        sender_address=caller_address,
        function_call=deposit_contract.functions.withdraw(receiver),
        task_name="withdraw",
        wait_confirmation_interval=False,
    )
def register_account(
    private_key: str,
    web3: Web3,
    contracts: Dict[str, Contract],
    start_block: BlockNumber,
    service_url: Optional[str],
    accept_disclaimer: bool,
    accept_all: bool,
    extend: bool = False,
) -> None:
    click.secho(DISCLAIMER, fg="yellow")
    if not accept_disclaimer and not accept_all:
        click.confirm(CONFIRMATION_OF_UNDERSTANDING, abort=True)

    def maybe_prompt(query: str) -> None:
        if not accept_all:
            click.confirm(query, abort=True)

    chain_id = web3.eth.chainId
    log.info("Using RPC endpoint", rpc_url=get_web3_provider_info(web3))
    hex_addresses = {
        name: to_checksum_address(contract.address) for name, contract in contracts.items()
    }
    log.info("Contract information", addresses=hex_addresses, start_block=start_block)

    # Add middleware to sign transactions by default
    web3.middleware_onion.add(construct_sign_and_send_raw_middleware(private_key))

    service_address = private_key_to_address(private_key)
    log.info("Running service registration script", account_address=service_address)
    click.secho(
        f"\nThis will run the registration with the address {to_checksum_address(service_address)}"
        f"\n\tSee {etherscan_url_for_address(chain_id, service_address)}"
    )
    maybe_prompt("I have checked that the address is correct and want to continue")

    # Create contract proxies
    service_registry_contract = contracts[CONTRACT_SERVICE_REGISTRY]
    service_registry_address = to_canonical_address(service_registry_contract.address)
    deposit_token_address = service_registry_contract.functions.token().call()
    deposit_token_contract = web3.eth.contract(
        address=deposit_token_address,
        abi=CONTRACT_MANAGER.get_contract_abi(CONTRACT_CUSTOM_TOKEN),
    )

    click.secho(
        "\nThe address of the service registry contract used is "
        f"{to_checksum_address(service_registry_contract.address)}"
        f"\n\tSee {etherscan_url_for_address(chain_id, service_registry_address)}"
    )
    maybe_prompt("I have checked that the address is correct and want to continue")

    # Check current token balance
    fmt_amount = get_token_formatter(deposit_token_contract)
    account_balance = deposit_token_contract.functions.balanceOf(service_address).call()
    log.info("Current account balance", balance=account_balance)
    click.secho(
        "\nThe address of the token used is "
        f"{to_checksum_address(deposit_token_address)}"
        f"\n\tSee {etherscan_url_for_address(chain_id, deposit_token_address)}"
        f"\nThe account balance of that token is {fmt_amount(account_balance)}."
    )
    maybe_prompt("I have checked that the address and my balance are correct and want to continue")

    # check if already registered
    currently_registered = service_registry_contract.functions.hasValidRegistration(
        service_address
    ).call()
    current_url = service_registry_contract.functions.urls(service_address).call()
    log.info(
        "Current ServiceRegistry information for service address",
        service_address=service_address,
        currently_registered=currently_registered,
        current_url=current_url,
    )

    # Register if not yet done or extension is requested
    if extend and currently_registered:
        log.info("Registration found. Preparing to extend registration.")
        send_registration_transaction(
            web3=web3,
            service_registry_contract=service_registry_contract,
            deposit_token_contract=deposit_token_contract,
            maybe_prompt=maybe_prompt,
            account_balance=account_balance,
            service_address=service_address,
            fmt_amount=fmt_amount,
        )
    elif not currently_registered:
        log.info("Address not registered in ServiceRegistry")
        send_registration_transaction(
            web3=web3,
            service_registry_contract=service_registry_contract,
            deposit_token_contract=deposit_token_contract,
            maybe_prompt=maybe_prompt,
            account_balance=account_balance,
            service_address=service_address,
            fmt_amount=fmt_amount,
        )
    else:
        log.info(
            "Already registered. If you want to extend your registration, "
            "use the 'extend' command."
        )

    if service_url and service_url != current_url:
        click.secho(f'\nNew Url to be registered "{service_url}"')
        hostname = service_url.split("//")[1]
        reachable = not subprocess.run(
            ["ping", "-c", "1", hostname], capture_output=True, check=False
        ).returncode
        if not reachable:
            click.secho(f"`ping {hostname}` fails. Are you sure the URL is correct?", fg="yellow")
        maybe_prompt("I have checked the URL and it is correct")

        checked_transact(
            web3=web3,
            sender_address=service_address,
            function_call=service_registry_contract.functions.setURL(service_url),
            task_name="Registering new URL",
        )

    current_url = service_registry_contract.functions.urls(service_address).call()

    click.secho("\nThank you for registering your services!", fg="green")
    log.info("Updated infos", current_url=current_url)
예제 #4
0
def main(  # pylint: disable=too-many-arguments,too-many-locals
    private_key: PrivateKey,
    state_db: str,
    web3: Web3,
    contracts: Dict[str, Contract],
    start_block: BlockNumber,
    confirmations: BlockTimeout,
    host: str,
    port: int,
    service_fee: TokenAmount,
    operator: str,
    info_message: str,
    enable_debug: bool,
    matrix_server: List[str],
    accept_disclaimer: bool,
    enable_tracing: bool,
    tracing_sampler: str,
    tracing_param: str,
) -> int:
    """The Pathfinding service for the Raiden Network."""
    log.info("Starting Raiden Pathfinding Service")
    click.secho(PFS_DISCLAIMER, fg="yellow")
    if not accept_disclaimer:
        click.confirm(CONFIRMATION_OF_UNDERSTANDING, abort=True)

    if not confirmations:
        chain_id = ChainID(web3.eth.chain_id)
        confirmations = (BlockTimeout(0) if "arbitrum" in ID_TO_CHAINNAME.get(
            chain_id, "") else DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS)
        log.info("Setting number of confirmation blocks",
                 confirmations=confirmations)

    log.info("Using RPC endpoint", rpc_url=get_web3_provider_info(web3))
    hex_addresses = {
        name: to_checksum_address(contract.address)
        for name, contract in contracts.items()
    }
    log.info("Contract information",
             addresses=hex_addresses,
             start_block=start_block)

    if enable_tracing:
        tracing_config = Config(
            config={
                "sampler": {
                    "type": tracing_sampler,
                    "param": tracing_param
                },
                "logging": True
            },
            service_name="pfs",
            scope_manager=GeventScopeManager(),
            validate=True,
        )
        # Tracer is stored in `opentracing.tracer`
        tracing_config.initialize_tracer()

        assert isinstance(web3.provider, HTTPProvider), MYPY_ANNOTATION
        assert web3.provider.endpoint_uri is not None, MYPY_ANNOTATION
        # Set `Web3` requests Session to use `SessionTracing`
        cache_session(
            web3.provider.endpoint_uri,
            SessionTracing(propagate=False, span_tags={"target": "ethnode"}),
        )

    service = None
    api = None
    try:
        service = PathfindingService(
            web3=web3,
            contracts=contracts,
            sync_start_block=start_block,
            required_confirmations=confirmations,
            private_key=private_key,
            poll_interval=DEFAULT_POLL_INTERVALL,
            db_filename=state_db,
            matrix_servers=matrix_server,
            enable_tracing=enable_tracing,
        )
        service.start()
        log.debug("Waiting for service to start before accepting API requests")
        try:
            service.startup_finished.get(timeout=PFS_START_TIMEOUT)
        except gevent.Timeout:
            raise Exception("PFS did not start within time.")

        log.debug("Starting API")
        api = PFSApi(
            pathfinding_service=service,
            service_fee=service_fee,
            debug_mode=enable_debug,
            one_to_n_address=to_canonical_address(
                contracts[CONTRACT_ONE_TO_N].address),
            operator=operator,
            info_message=info_message,
            enable_tracing=enable_tracing,
        )
        api.run(host=host, port=port)

        service.get()
    except (KeyboardInterrupt, SystemExit):
        print("Exiting...")
    finally:
        log.info("Stopping Pathfinding Service...")
        if api:
            api.stop()
        if service:
            service.stop()

    return 0
예제 #5
0
def main(  # pylint: disable=too-many-arguments,too-many-locals
    private_key: PrivateKey,
    state_db: str,
    web3: Web3,
    contracts: Dict[str, Contract],
    start_block: BlockNumber,
    host: str,
    port: int,
    min_reward: int,
    confirmations: BlockTimeout,
    operator: str,
    info_message: str,
    debug_shell: bool,
    accept_disclaimer: bool,
) -> int:
    """The Monitoring service for the Raiden Network."""
    log.info("Starting Raiden Monitoring Service")
    click.secho(MS_DISCLAIMER, fg="yellow")
    if not accept_disclaimer:
        click.confirm(CONFIRMATION_OF_UNDERSTANDING, abort=True)

    if not confirmations:
        chain_id = ChainID(web3.eth.chain_id)
        confirmations = (BlockTimeout(0) if "arbitrum" in ID_TO_CHAINNAME.get(
            chain_id, "") else DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS)
        log.info("Setting number of confirmation blocks",
                 confirmations=confirmations)

    log.info("Using RPC endpoint", rpc_url=get_web3_provider_info(web3))
    hex_addresses = {
        name: to_checksum_address(contract.address)
        for name, contract in contracts.items()
    }
    log.info("Contract information",
             addresses=hex_addresses,
             start_block=start_block)

    task = None
    api = None
    try:
        service = MonitoringService(
            web3=web3,
            private_key=private_key,
            contracts=contracts,
            sync_start_block=start_block,
            required_confirmations=confirmations,
            poll_interval=DEFAULT_POLL_INTERVALL,
            db_filename=state_db,
            min_reward=min_reward,
        )

        if debug_shell:
            import IPython

            IPython.embed()
            return 0

        task = spawn_named("MonitoringService", service.start)

        log.debug("Starting API")
        api = MSApi(monitoring_service=service,
                    operator=operator,
                    info_message=info_message)
        api.run(host=host, port=port)

        task.get()
    finally:
        log.info("Stopping Monitoring Service...")
        if api:
            api.stop()
        if task:
            task.kill()
            task.get()

    return 0
예제 #6
0
def main(  # pylint: disable=too-many-arguments,too-many-locals
    private_key: PrivateKey,
    state_db: str,
    web3: Web3,
    contracts: Dict[str, Contract],
    start_block: BlockNumber,
    confirmations: BlockTimeout,
    host: str,
    port: int,
    service_fee: TokenAmount,
    operator: str,
    info_message: str,
    enable_debug: bool,
    matrix_server: List[str],
    accept_disclaimer: bool,
) -> int:
    """The Pathfinding service for the Raiden Network."""
    log.info("Starting Raiden Pathfinding Service")
    click.secho(PFS_DISCLAIMER, fg="yellow")
    if not accept_disclaimer:
        click.confirm(CONFIRMATION_OF_UNDERSTANDING, abort=True)
    log.info("Using RPC endpoint", rpc_url=get_web3_provider_info(web3))
    hex_addresses = {
        name: to_checksum_address(contract.address)
        for name, contract in contracts.items()
    }
    log.info("Contract information",
             addresses=hex_addresses,
             start_block=start_block)

    service = None
    api = None
    try:
        service = PathfindingService(
            web3=web3,
            contracts=contracts,
            sync_start_block=start_block,
            required_confirmations=confirmations,
            private_key=private_key,
            poll_interval=DEFAULT_POLL_INTERVALL,
            db_filename=state_db,
            matrix_servers=matrix_server,
        )
        service.start()
        log.debug("Waiting for service to start before accepting API requests")
        try:
            service.startup_finished.get(timeout=PFS_START_TIMEOUT)
        except gevent.Timeout:
            raise Exception("PFS did not start within time.")

        log.debug("Starting API")
        api = PFSApi(
            pathfinding_service=service,
            service_fee=service_fee,
            debug_mode=enable_debug,
            one_to_n_address=to_canonical_address(
                contracts[CONTRACT_ONE_TO_N].address),
            operator=operator,
            info_message=info_message,
        )
        api.run(host=host, port=port)

        service.get()
    except (KeyboardInterrupt, SystemExit):
        print("Exiting...")
    finally:
        log.info("Stopping Pathfinding Service...")
        if api:
            api.stop()
        if service:
            service.stop()

    return 0