Пример #1
0
def verify_deployed_service_contracts_in_filesystem(
    web3: Web3,
    contract_manager: ContractManager,
    token_address: str,
    user_deposit_whole_balance_limit: int,
):
    chain_id = int(web3.version.network)

    deployment_data = get_contracts_deployed(
        chain_id=chain_id,
        version=contract_manager.contracts_version,
        services=True,
    )
    deployment_file_path = contracts_deployed_path(
        chain_id=chain_id,
        version=contract_manager.contracts_version,
        services=True,
    )
    assert deployment_data is not None

    if verify_service_contracts_deployment_data(
            web3=web3,
            contract_manager=contract_manager,
            token_address=token_address,
            user_deposit_whole_balance_limit=user_deposit_whole_balance_limit,
            deployment_data=deployment_data,
    ):
        print(
            f'Deployment info from {deployment_file_path} has been verified and it is CORRECT.'
        )
Пример #2
0
def get_deployment_infos(
    chain_id: ChainID,
    contracts_version: str = None,
) -> Dict[str, Any]:
    try:
        core_contract_data = get_contracts_deployed(
            chain_id=chain_id,
            version=contracts_version,
        )
        service_contract_data = get_contracts_deployed(
            chain_id=chain_id,
            version=contracts_version,
            services=True,
        )
        token_network_registry_info = core_contract_data['contracts'][
            CONTRACT_TOKEN_NETWORK_REGISTRY]  # noqa
        monitor_contract_info = service_contract_data['contracts'][
            CONTRACT_MONITORING_SERVICE]
        user_deposit_contract_info = service_contract_data['contracts'][
            CONTRACT_USER_DEPOSIT]

        contracts_start_block = max(
            0,
            min(
                token_network_registry_info['block_number'],
                monitor_contract_info['block_number'],
                user_deposit_contract_info['block_number'],
            ),
        )
        return {
            CONTRACT_TOKEN_NETWORK_REGISTRY:
            token_network_registry_info['address'],
            CONTRACT_MONITORING_SERVICE: monitor_contract_info['address'],
            CONTRACT_USER_DEPOSIT: user_deposit_contract_info['address'],
            START_BLOCK_ID: contracts_start_block,
        }
    except ValueError:
        log.info('No deployed contracts were found at the default registry')

        return {
            CONTRACT_TOKEN_NETWORK_REGISTRY: None,
            CONTRACT_MONITORING_SERVICE: None,
            CONTRACT_USER_DEPOSIT: None,
            START_BLOCK_ID: 0,
        }
Пример #3
0
def test_deploy_data_all(
    version: Optional[str],
    chain_id: int,
):
    data_services = get_contracts_deployed(chain_id, version, services=True)
    data_raiden = get_contracts_deployed(chain_id, version, services=False)
    data_all_computed = merge_deployment_data(data_services, data_raiden)
    data_all = get_contracts_deployment_info(chain_id,
                                             version,
                                             module=DeploymentModule.ALL)
    data_default = get_contracts_deployment_info(chain_id,
                                                 version,
                                                 module=DeploymentModule.ALL)
    assert data_all == data_all_computed
    assert data_all == data_default

    for name in RAIDEN_CONTRACT_NAMES + SERVICE_CONTRACT_NAMES:
        deployed = data_all['contracts'][name]
        reasonable_deployment_of_a_contract(deployed)
def test_deploy_data_has_fields_raiden(
        version: Optional[str],
        chain_id: int,
):
    data = get_contracts_deployed(chain_id, version, services=False)
    assert data['contracts_version'] == version if version else CONTRACTS_VERSION
    assert data['chain_id'] == chain_id
    contracts = data['contracts']
    for name in {'EndpointRegistry', 'TokenNetworkRegistry', 'SecretRegistry'}:
        deployed = contracts[name]
        reasonable_deployment_of_a_contract(deployed)
def test_deploy_data_has_fields_services(
        version: Optional[str],
        chain_id: int,
):
    data = get_contracts_deployed(chain_id, version, services=True)
    assert data['contracts_version'] == version if version else CONTRACTS_VERSION
    assert data['chain_id'] == chain_id
    contracts = data['contracts']
    for name in {'ServiceRegistry', 'MonitoringService', 'OneToN', 'UserDeposit'}:
        deployed = contracts[name]
        reasonable_deployment_of_a_contract(deployed)
def get_default_registry_and_start_block(
    net_version: int,
    contracts_version: str,
):
    try:
        contract_data = get_contracts_deployed(net_version, contracts_version)
        token_network_registry_info = contract_data['contracts'][CONTRACT_TOKEN_NETWORK_REGISTRY]
        registry_address = token_network_registry_info['address']
        start_block = max(0, token_network_registry_info['block_number'] - 100)
        return registry_address, start_block
    except ValueError:
        log.error('No deployed contracts were found at the default registry')
        sys.exit(1)
Пример #7
0
def test_deploy_data_has_fields_services(
    version: Optional[str],
    chain_id: int,
):
    data = get_contracts_deployed(chain_id, version, services=True)
    data2 = get_contracts_deployment_info(chain_id,
                                          version,
                                          module=DeploymentModule.SERVICES)
    assert data2 == data
    assert data[
        'contracts_version'] == version if version else CONTRACTS_VERSION
    assert data['chain_id'] == chain_id
    contracts = data['contracts']
    for name in SERVICE_CONTRACT_NAMES:
        deployed = contracts[name]
        reasonable_deployment_of_a_contract(deployed)
Пример #8
0
    def verify_deployed_contracts_in_filesystem(self):
        chain_id = int(self.web3.version.network)

        deployment_data = get_contracts_deployed(
            chain_id=chain_id,
            version=self.contract_manager.contracts_version,
        )
        deployment_file_path = contracts_deployed_path(
            chain_id=chain_id,
            version=self.contract_manager.contracts_version,
        )
        assert deployment_data is not None

        if self._verify_deployment_data(deployment_data):
            print(
                f'Deployment info from {deployment_file_path} has been verified'
                'and it is CORRECT.')
Пример #9
0
def verify_deployed_contracts_in_filesystem(
    web3: Web3,
    contract_manager: ContractManager,
):
    chain_id = int(web3.version.network)

    deployment_data = get_contracts_deployed(
        chain_id=chain_id,
        version=contract_manager.contracts_version,
    )
    deployment_file_path = contracts_deployed_path(
        chain_id=chain_id,
        version=contract_manager.contracts_version,
    )
    assert deployment_data is not None

    if verify_deployment_data(web3, contract_manager, deployment_data):
        print(
            f'Deployment info from {deployment_file_path} has been verified and it is CORRECT.'
        )
Пример #10
0
def run_app(
    address,
    keystore_path,
    gas_price,
    eth_rpc_endpoint,
    tokennetwork_registry_contract_address,
    secret_registry_contract_address,
    endpoint_registry_contract_address,
    listen_address,
    mapped_socket,
    max_unresponsive_time,
    api_address,
    rpc,
    sync_check,
    console,
    password_file,
    web_ui,
    datadir,
    transport,
    matrix_server,
    network_id,
    environment_type,
    unrecoverable_error_should_crash,
    pathfinding_service_address,
    config=None,
    extra_config=None,
    **kwargs,
):
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements,unused-argument

    from raiden.app import App

    _assert_sql_version()

    if transport == 'udp' and not mapped_socket:
        raise RuntimeError('Missing socket')

    if datadir is None:
        datadir = os.path.join(os.path.expanduser('~'), '.raiden')

    address_hex = to_normalized_address(address) if address else None
    address_hex, privatekey_bin = prompt_account(address_hex, keystore_path,
                                                 password_file)
    address = to_canonical_address(address_hex)

    (listen_host, listen_port) = split_endpoint(listen_address)
    (api_host, api_port) = split_endpoint(api_address)

    config['transport']['udp']['host'] = listen_host
    config['transport']['udp']['port'] = listen_port
    config['console'] = console
    config['rpc'] = rpc
    config['web_ui'] = rpc and web_ui
    config['api_host'] = api_host
    config['api_port'] = api_port
    if mapped_socket:
        config['socket'] = mapped_socket.socket
        config['transport']['udp']['external_ip'] = mapped_socket.external_ip
        config['transport']['udp'][
            'external_port'] = mapped_socket.external_port
    config['transport_type'] = transport
    config['transport']['matrix']['server'] = matrix_server
    config['transport']['udp'][
        'nat_keepalive_retries'] = DEFAULT_NAT_KEEPALIVE_RETRIES
    timeout = max_unresponsive_time / DEFAULT_NAT_KEEPALIVE_RETRIES
    config['transport']['udp']['nat_keepalive_timeout'] = timeout
    config['privatekey_hex'] = encode_hex(privatekey_bin)
    config[
        'unrecoverable_error_should_crash'] = unrecoverable_error_should_crash
    config['services'][
        'pathfinding_service_address'] = pathfinding_service_address

    parsed_eth_rpc_endpoint = urlparse(eth_rpc_endpoint)
    if not parsed_eth_rpc_endpoint.scheme:
        eth_rpc_endpoint = f'http://{eth_rpc_endpoint}'

    web3 = _setup_web3(eth_rpc_endpoint)

    rpc_client = JSONRPCClient(
        web3,
        privatekey_bin,
        gas_price_strategy=gas_price,
        block_num_confirmations=DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS,
        uses_infura='infura.io' in eth_rpc_endpoint,
    )

    blockchain_service = BlockChainService(
        privatekey_bin=privatekey_bin,
        jsonrpc_client=rpc_client,
        # Not giving the contract manager here, but injecting it later
        # since we first need blockchain service to calculate the network id
    )

    given_network_id = network_id
    node_network_id = blockchain_service.network_id
    known_given_network_id = given_network_id in ID_TO_NETWORKNAME
    known_node_network_id = node_network_id in ID_TO_NETWORKNAME

    if node_network_id != given_network_id:
        if known_given_network_id and known_node_network_id:
            click.secho(
                f"The chosen ethereum network '{ID_TO_NETWORKNAME[given_network_id]}' "
                f"differs from the ethereum client '{ID_TO_NETWORKNAME[node_network_id]}'. "
                "Please update your settings.",
                fg='red',
            )
        else:
            click.secho(
                f"The chosen ethereum network id '{given_network_id}' differs "
                f"from the ethereum client '{node_network_id}'. "
                "Please update your settings.",
                fg='red',
            )
        sys.exit(1)

    config['chain_id'] = given_network_id

    # interpret the provided string argument
    if environment_type == Environment.PRODUCTION:
        # Safe configuration: restrictions for mainnet apply and matrix rooms have to be private
        config['environment_type'] = Environment.PRODUCTION
        config['transport']['matrix']['private_rooms'] = True
    else:
        config['environment_type'] = Environment.DEVELOPMENT

    environment_type = config['environment_type']
    print(f'Raiden is running in {environment_type.value.lower()} mode')

    chain_config = {}
    contract_addresses_known = False
    contracts = dict()
    contracts_version = 'pre_limits' if environment_type == Environment.DEVELOPMENT else None
    config['contracts_path'] = contracts_precompiled_path(contracts_version)
    if node_network_id in ID_TO_NETWORKNAME and ID_TO_NETWORKNAME[
            node_network_id] != 'smoketest':
        deployment_data = get_contracts_deployed(node_network_id,
                                                 contracts_version)
        not_allowed = (  # for now we only disallow mainnet with test configuration
            network_id == 1 and environment_type == Environment.DEVELOPMENT)
        if not_allowed:
            click.secho(
                f'The chosen network ({ID_TO_NETWORKNAME[node_network_id]}) is not a testnet, '
                'but the "development" environment was selected.\n'
                'This is not allowed. Please start again with a safe environment setting '
                '(--environment production).',
                fg='red',
            )
            sys.exit(1)

        contracts = deployment_data['contracts']
        contract_addresses_known = True

    blockchain_service.inject_contract_manager(
        ContractManager(config['contracts_path']))

    if sync_check:
        check_synced(blockchain_service, known_node_network_id)

    contract_addresses_given = (
        tokennetwork_registry_contract_address is not None
        and secret_registry_contract_address is not None
        and endpoint_registry_contract_address is not None)

    if not contract_addresses_given and not contract_addresses_known:
        click.secho(
            f"There are no known contract addresses for network id '{given_network_id}'. "
            "Please provide them on the command line or in the configuration file.",
            fg='red',
        )
        sys.exit(1)

    try:
        token_network_registry = blockchain_service.token_network_registry(
            tokennetwork_registry_contract_address or to_canonical_address(
                contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['address'], ), )
    except ContractVersionMismatch as e:
        handle_contract_version_mismatch(e)
    except AddressWithoutCode:
        handle_contract_no_code('token network registry',
                                tokennetwork_registry_contract_address)
    except AddressWrongContract:
        handle_contract_wrong_address(
            'token network registry',
            tokennetwork_registry_contract_address,
        )

    try:
        secret_registry = blockchain_service.secret_registry(
            secret_registry_contract_address or to_canonical_address(
                contracts[CONTRACT_SECRET_REGISTRY]['address'], ), )
    except ContractVersionMismatch as e:
        handle_contract_version_mismatch(e)
    except AddressWithoutCode:
        handle_contract_no_code('secret registry',
                                secret_registry_contract_address)
    except AddressWrongContract:
        handle_contract_wrong_address('secret registry',
                                      secret_registry_contract_address)

    database_path = os.path.join(
        datadir,
        f'node_{pex(address)}',
        f'netid_{given_network_id}',
        f'network_{pex(token_network_registry.address)}',
        f'v{RAIDEN_DB_VERSION}_log.db',
    )
    config['database_path'] = database_path

    print(
        '\nYou are connected to the \'{}\' network and the DB path is: {}'.
        format(
            ID_TO_NETWORKNAME.get(given_network_id, given_network_id),
            database_path,
        ), )

    discovery = None
    if transport == 'udp':
        transport, discovery = _setup_udp(
            config,
            blockchain_service,
            address,
            contracts,
            endpoint_registry_contract_address,
        )
    elif transport == 'matrix':
        transport = _setup_matrix(config)
    else:
        raise RuntimeError(f'Unknown transport type "{transport}" given')

    raiden_event_handler = RaidenEventHandler()
    message_handler = MessageHandler()

    try:
        if 'contracts' in chain_config:
            start_block = chain_config['contracts']['TokenNetworkRegistry'][
                'block_number']
        else:
            start_block = 0

        raiden_app = App(
            config=config,
            chain=blockchain_service,
            query_start_block=start_block,
            default_registry=token_network_registry,
            default_secret_registry=secret_registry,
            transport=transport,
            raiden_event_handler=raiden_event_handler,
            message_handler=message_handler,
            discovery=discovery,
        )
    except RaidenError as e:
        click.secho(f'FATAL: {e}', fg='red')
        sys.exit(1)

    try:
        raiden_app.start()
    except RuntimeError as e:
        click.secho(f'FATAL: {e}', fg='red')
        sys.exit(1)
    except filelock.Timeout:
        name_or_id = ID_TO_NETWORKNAME.get(given_network_id, given_network_id)
        click.secho(
            f'FATAL: Another Raiden instance already running for account {address_hex} on '
            f'network id {name_or_id}',
            fg='red',
        )
        sys.exit(1)

    return raiden_app
Пример #11
0
def run_app(
        address,
        keystore_path,
        gas_price,
        eth_rpc_endpoint,
        tokennetwork_registry_contract_address,
        secret_registry_contract_address,
        endpoint_registry_contract_address,
        listen_address,
        mapped_socket,
        max_unresponsive_time,
        api_address,
        rpc,
        sync_check,
        console,
        password_file,
        web_ui,
        datadir,
        transport,
        matrix_server,
        network_id,
        environment_type,
        unrecoverable_error_should_crash,
        pathfinding_service_address,
        pathfinding_max_paths,
        config=None,
        extra_config=None,
        **kwargs,
):
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements,unused-argument

    from raiden.app import App

    _assert_sql_version()

    if transport == 'udp' and not mapped_socket:
        raise RuntimeError('Missing socket')

    if datadir is None:
        datadir = os.path.join(os.path.expanduser('~'), '.raiden')

    address_hex = to_normalized_address(address) if address else None
    address_hex, privatekey_bin = prompt_account(address_hex, keystore_path, password_file)
    address = to_canonical_address(address_hex)

    (listen_host, listen_port) = split_endpoint(listen_address)
    (api_host, api_port) = split_endpoint(api_address)

    config['transport']['udp']['host'] = listen_host
    config['transport']['udp']['port'] = listen_port
    config['console'] = console
    config['rpc'] = rpc
    config['web_ui'] = rpc and web_ui
    config['api_host'] = api_host
    config['api_port'] = api_port
    if mapped_socket:
        config['socket'] = mapped_socket.socket
        config['transport']['udp']['external_ip'] = mapped_socket.external_ip
        config['transport']['udp']['external_port'] = mapped_socket.external_port
    config['transport_type'] = transport
    config['transport']['matrix']['server'] = matrix_server
    config['transport']['udp']['nat_keepalive_retries'] = DEFAULT_NAT_KEEPALIVE_RETRIES
    timeout = max_unresponsive_time / DEFAULT_NAT_KEEPALIVE_RETRIES
    config['transport']['udp']['nat_keepalive_timeout'] = timeout
    config['privatekey_hex'] = encode_hex(privatekey_bin)
    config['unrecoverable_error_should_crash'] = unrecoverable_error_should_crash
    config['services']['pathfinding_service_address'] = pathfinding_service_address
    config['services']['pathfinding_max_paths'] = pathfinding_max_paths

    parsed_eth_rpc_endpoint = urlparse(eth_rpc_endpoint)
    if not parsed_eth_rpc_endpoint.scheme:
        eth_rpc_endpoint = f'http://{eth_rpc_endpoint}'

    web3 = _setup_web3(eth_rpc_endpoint)

    rpc_client = JSONRPCClient(
        web3,
        privatekey_bin,
        gas_price_strategy=gas_price,
        block_num_confirmations=DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS,
        uses_infura='infura.io' in eth_rpc_endpoint,
    )

    blockchain_service = BlockChainService(
        privatekey_bin=privatekey_bin,
        jsonrpc_client=rpc_client,
        # Not giving the contract manager here, but injecting it later
        # since we first need blockchain service to calculate the network id
    )

    given_network_id = network_id
    node_network_id = blockchain_service.network_id
    known_given_network_id = given_network_id in ID_TO_NETWORKNAME
    known_node_network_id = node_network_id in ID_TO_NETWORKNAME

    if node_network_id != given_network_id:
        if known_given_network_id and known_node_network_id:
            click.secho(
                f"The chosen ethereum network '{ID_TO_NETWORKNAME[given_network_id]}' "
                f"differs from the ethereum client '{ID_TO_NETWORKNAME[node_network_id]}'. "
                "Please update your settings.",
                fg='red',
            )
        else:
            click.secho(
                f"The chosen ethereum network id '{given_network_id}' differs "
                f"from the ethereum client '{node_network_id}'. "
                "Please update your settings.",
                fg='red',
            )
        sys.exit(1)

    config['chain_id'] = given_network_id

    # interpret the provided string argument
    if environment_type == Environment.PRODUCTION:
        # Safe configuration: restrictions for mainnet apply and matrix rooms have to be private
        config['environment_type'] = Environment.PRODUCTION
        config['transport']['matrix']['private_rooms'] = True
    else:
        config['environment_type'] = Environment.DEVELOPMENT

    environment_type = config['environment_type']
    print(f'Raiden is running in {environment_type.value.lower()} mode')

    chain_config = {}
    contract_addresses_known = False
    contracts = dict()
    contracts_version = 'pre_limits' if environment_type == Environment.DEVELOPMENT else None
    config['contracts_path'] = contracts_precompiled_path(contracts_version)
    if node_network_id in ID_TO_NETWORKNAME and ID_TO_NETWORKNAME[node_network_id] != 'smoketest':
        deployment_data = get_contracts_deployed(node_network_id, contracts_version)
        not_allowed = (  # for now we only disallow mainnet with test configuration
            network_id == 1 and
            environment_type == Environment.DEVELOPMENT
        )
        if not_allowed:
            click.secho(
                f'The chosen network ({ID_TO_NETWORKNAME[node_network_id]}) is not a testnet, '
                'but the "development" environment was selected.\n'
                'This is not allowed. Please start again with a safe environment setting '
                '(--environment production).',
                fg='red',
            )
            sys.exit(1)

        contracts = deployment_data['contracts']
        contract_addresses_known = True

    blockchain_service.inject_contract_manager(ContractManager(config['contracts_path']))

    if sync_check:
        check_synced(blockchain_service, known_node_network_id)

    contract_addresses_given = (
        tokennetwork_registry_contract_address is not None and
        secret_registry_contract_address is not None and
        endpoint_registry_contract_address is not None
    )

    if not contract_addresses_given and not contract_addresses_known:
        click.secho(
            f"There are no known contract addresses for network id '{given_network_id}'. "
            "Please provide them on the command line or in the configuration file.",
            fg='red',
        )
        sys.exit(1)

    try:
        token_network_registry = blockchain_service.token_network_registry(
            tokennetwork_registry_contract_address or to_canonical_address(
                contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['address'],
            ),
        )
    except ContractVersionMismatch as e:
        handle_contract_version_mismatch(e)
    except AddressWithoutCode:
        handle_contract_no_code('token network registry', tokennetwork_registry_contract_address)
    except AddressWrongContract:
        handle_contract_wrong_address(
            'token network registry',
            tokennetwork_registry_contract_address,
        )

    try:
        secret_registry = blockchain_service.secret_registry(
            secret_registry_contract_address or to_canonical_address(
                contracts[CONTRACT_SECRET_REGISTRY]['address'],
            ),
        )
    except ContractVersionMismatch as e:
        handle_contract_version_mismatch(e)
    except AddressWithoutCode:
        handle_contract_no_code('secret registry', secret_registry_contract_address)
    except AddressWrongContract:
        handle_contract_wrong_address('secret registry', secret_registry_contract_address)

    database_path = os.path.join(
        datadir,
        f'node_{pex(address)}',
        f'netid_{given_network_id}',
        f'network_{pex(token_network_registry.address)}',
        f'v{RAIDEN_DB_VERSION}_log.db',
    )
    config['database_path'] = database_path

    print(
        '\nYou are connected to the \'{}\' network and the DB path is: {}'.format(
            ID_TO_NETWORKNAME.get(given_network_id, given_network_id),
            database_path,
        ),
    )

    discovery = None
    if transport == 'udp':
        transport, discovery = _setup_udp(
            config,
            blockchain_service,
            address,
            contracts,
            endpoint_registry_contract_address,
        )
    elif transport == 'matrix':
        transport = _setup_matrix(config)
    else:
        raise RuntimeError(f'Unknown transport type "{transport}" given')

    raiden_event_handler = RaidenEventHandler()
    message_handler = MessageHandler()

    try:
        if 'contracts' in chain_config:
            start_block = chain_config['contracts']['TokenNetworkRegistry']['block_number']
        else:
            start_block = 0

        raiden_app = App(
            config=config,
            chain=blockchain_service,
            query_start_block=start_block,
            default_registry=token_network_registry,
            default_secret_registry=secret_registry,
            transport=transport,
            raiden_event_handler=raiden_event_handler,
            message_handler=message_handler,
            discovery=discovery,
        )
    except RaidenError as e:
        click.secho(f'FATAL: {e}', fg='red')
        sys.exit(1)

    try:
        raiden_app.start()
    except RuntimeError as e:
        click.secho(f'FATAL: {e}', fg='red')
        sys.exit(1)
    except filelock.Timeout:
        name_or_id = ID_TO_NETWORKNAME.get(given_network_id, given_network_id)
        click.secho(
            f'FATAL: Another Raiden instance already running for account {address_hex} on '
            f'network id {name_or_id}',
            fg='red',
        )
        sys.exit(1)

    return raiden_app
def verify_deployed_contracts(web3: Web3,
                              contract_manager: ContractManager,
                              deployment_data=None):
    chain_id = int(web3.version.network)
    deployment_file_path = None

    if deployment_data is None:
        deployment_data = get_contracts_deployed(
            chain_id, contract_manager.contracts_version)
        deployment_file_path = contracts_deployed_path(
            chain_id,
            contract_manager.contracts_version,
        )

    contracts = deployment_data['contracts']

    assert contract_manager.contracts_version == deployment_data[
        'contracts_version']
    assert chain_id == deployment_data['chain_id']

    endpoint_registry_address = contracts[CONTRACT_ENDPOINT_REGISTRY][
        'address']
    endpoint_registry_abi = contract_manager.get_contract_abi(
        CONTRACT_ENDPOINT_REGISTRY)
    endpoint_registry = web3.eth.contract(
        abi=endpoint_registry_abi,
        address=endpoint_registry_address,
    )
    endpoint_registry = PrivateContract(endpoint_registry)

    # Check that the deployed bytecode matches the precompiled data
    blockchain_bytecode = web3.eth.getCode(endpoint_registry_address).hex()
    compiled_bytecode = contract_manager.contracts[CONTRACT_ENDPOINT_REGISTRY][
        'bin']
    # Compiled code contains some additional initial data compared to the blockchain bytecode
    compiled_bytecode = compiled_bytecode[-len(blockchain_bytecode):]
    compiled_bytecode = hex(int(compiled_bytecode, 16))
    assert blockchain_bytecode == compiled_bytecode

    # Check blockchain transaction hash & block information
    receipt = web3.eth.getTransactionReceipt(
        contracts[CONTRACT_ENDPOINT_REGISTRY]['transaction_hash'], )
    assert receipt['blockNumber'] == contracts[CONTRACT_ENDPOINT_REGISTRY]['block_number'], \
        f"We have block_number {contracts[CONTRACT_ENDPOINT_REGISTRY]['block_number']} " \
        f"instead of {receipt['blockNumber']}"
    assert receipt['gasUsed'] == contracts[CONTRACT_ENDPOINT_REGISTRY]['gas_cost'], \
        f"We have gasUsed {contracts[CONTRACT_ENDPOINT_REGISTRY]['gas_cost']} " \
        f"instead of {receipt['gasUsed']}"
    assert receipt['contractAddress'] == contracts[CONTRACT_ENDPOINT_REGISTRY]['address'], \
        f"We have contractAddress {contracts[CONTRACT_ENDPOINT_REGISTRY]['address']} " \
        f"instead of {receipt['contractAddress']}"

    # Check the contract version
    version = endpoint_registry.functions.contract_version().call().decode()
    assert version == deployment_data['contracts_version']

    print(
        f'{CONTRACT_ENDPOINT_REGISTRY} at {endpoint_registry_address} '
        f'matches the compiled data from contracts.json', )

    secret_registry_address = contracts[CONTRACT_SECRET_REGISTRY]['address']
    secret_registry_abi = contract_manager.get_contract_abi(
        CONTRACT_SECRET_REGISTRY)
    secret_registry = web3.eth.contract(
        abi=secret_registry_abi,
        address=secret_registry_address,
    )
    secret_registry = PrivateContract(secret_registry)

    # Check that the deployed bytecode matches the precompiled data
    blockchain_bytecode = web3.eth.getCode(secret_registry_address).hex()
    compiled_bytecode = contract_manager.contracts[CONTRACT_SECRET_REGISTRY][
        'bin']
    compiled_bytecode = compiled_bytecode[-len(blockchain_bytecode):]
    compiled_bytecode = hex(int(compiled_bytecode, 16))
    assert blockchain_bytecode == compiled_bytecode

    # Check blockchain transaction hash & block information
    receipt = web3.eth.getTransactionReceipt(
        contracts[CONTRACT_SECRET_REGISTRY]['transaction_hash'], )
    assert receipt['blockNumber'] == contracts[CONTRACT_SECRET_REGISTRY]['block_number'], \
        f"We have block_number {contracts[CONTRACT_SECRET_REGISTRY]['block_number']} " \
        f"instead of {receipt['blockNumber']}"
    assert receipt['gasUsed'] == contracts[CONTRACT_SECRET_REGISTRY]['gas_cost'], \
        f"We have gasUsed {contracts[CONTRACT_SECRET_REGISTRY]['gas_cost']} " \
        f"instead of {receipt['gasUsed']}"
    assert receipt['contractAddress'] == contracts[CONTRACT_SECRET_REGISTRY]['address'], \
        f"We have contractAddress {contracts[CONTRACT_SECRET_REGISTRY]['address']} " \
        f"instead of {receipt['contractAddress']}"

    # Check the contract version
    version = secret_registry.functions.contract_version().call().decode()
    assert version == deployment_data['contracts_version']

    print(
        f'{CONTRACT_SECRET_REGISTRY} at {secret_registry_address} '
        f'matches the compiled data from contracts.json', )

    token_registry_address = contracts[CONTRACT_TOKEN_NETWORK_REGISTRY][
        'address']
    token_registry_abi = contract_manager.get_contract_abi(
        CONTRACT_TOKEN_NETWORK_REGISTRY, )
    token_network_registry = web3.eth.contract(
        abi=token_registry_abi,
        address=token_registry_address,
    )
    token_network_registry = PrivateContract(token_network_registry)

    # Check that the deployed bytecode matches the precompiled data
    blockchain_bytecode = web3.eth.getCode(token_registry_address).hex()
    compiled_bytecode = contract_manager.contracts[
        CONTRACT_TOKEN_NETWORK_REGISTRY]['bin']
    compiled_bytecode = compiled_bytecode[-len(blockchain_bytecode):]
    compiled_bytecode = hex(int(compiled_bytecode, 16))
    assert blockchain_bytecode == compiled_bytecode

    # Check blockchain transaction hash & block information
    receipt = web3.eth.getTransactionReceipt(
        contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['transaction_hash'], )
    assert receipt['blockNumber'] == contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['block_number'], \
        f"We have block_number {contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['block_number']} " \
        f"instead of {receipt['blockNumber']}"
    assert receipt['gasUsed'] == contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['gas_cost'], \
        f"We have gasUsed {contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['gas_cost']} " \
        f"instead of {receipt['gasUsed']}"
    assert receipt['contractAddress'] == contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['address'], \
        f"We have contractAddress {contracts[CONTRACT_TOKEN_NETWORK_REGISTRY]['address']} " \
        f"instead of {receipt['contractAddress']}"

    # Check the contract version
    version = token_network_registry.functions.contract_version().call(
    ).decode()
    assert version == deployment_data['contracts_version']

    # Check constructor parameters
    constructor_arguments = contracts[CONTRACT_TOKEN_NETWORK_REGISTRY][
        'constructor_arguments']
    assert to_checksum_address(
        token_network_registry.functions.secret_registry_address().call(),
    ) == secret_registry_address
    assert secret_registry_address == constructor_arguments[0]

    chain_id = token_network_registry.functions.chain_id().call()
    assert chain_id == constructor_arguments[1]

    settlement_timeout_min = token_network_registry.functions.settlement_timeout_min(
    ).call()
    settlement_timeout_max = token_network_registry.functions.settlement_timeout_max(
    ).call()
    assert settlement_timeout_min == constructor_arguments[2]
    assert settlement_timeout_max == constructor_arguments[3]

    print(
        f'{CONTRACT_TOKEN_NETWORK_REGISTRY} at {token_registry_address} '
        f'matches the compiled data from contracts.json', )

    if deployment_file_path is not None:
        print(
            f'Deployment info from {deployment_file_path} has been verified and it is CORRECT.'
        )
Пример #13
0
def verify_deployed_contracts(web3: Web3, contract_manager: ContractManager, deployment_data=None):
    chain_id = int(web3.version.network)
    deployment_file_path = None

    if deployment_data is None:
        deployment_data = get_contracts_deployed(chain_id, contract_manager.contracts_version)
        deployment_file_path = contracts_deployed_path(
            chain_id,
            contract_manager.contracts_version,
        )
    assert deployment_data is not None

    assert contract_manager.contracts_version == deployment_data['contracts_version']
    assert chain_id == deployment_data['chain_id']

    endpoint_registry = verify_deployed_contract(
        web3,
        contract_manager,
        deployment_data,
        CONTRACT_ENDPOINT_REGISTRY,
    )
    print(
        f'{CONTRACT_ENDPOINT_REGISTRY} at {endpoint_registry.address} '
        f'matches the compiled data from contracts.json',
    )

    secret_registry = verify_deployed_contract(
        web3,
        contract_manager,
        deployment_data,
        CONTRACT_SECRET_REGISTRY,
    )
    print(
        f'{CONTRACT_SECRET_REGISTRY} at {secret_registry.address} '
        f'matches the compiled data from contracts.json',
    )

    token_network_registry = verify_deployed_contract(
        web3,
        contract_manager,
        deployment_data,
        CONTRACT_TOKEN_NETWORK_REGISTRY,
    )

    # We need to also check the constructor parameters against the chain
    constructor_arguments = deployment_data['contracts'][
        CONTRACT_TOKEN_NETWORK_REGISTRY
    ]['constructor_arguments']
    assert to_checksum_address(
        token_network_registry.functions.secret_registry_address().call(),
    ) == secret_registry.address
    assert secret_registry.address == constructor_arguments[0]

    chain_id = token_network_registry.functions.chain_id().call()
    assert chain_id == constructor_arguments[1]

    settlement_timeout_min = token_network_registry.functions.settlement_timeout_min().call()
    settlement_timeout_max = token_network_registry.functions.settlement_timeout_max().call()
    assert settlement_timeout_min == constructor_arguments[2]
    assert settlement_timeout_max == constructor_arguments[3]

    print(
        f'{CONTRACT_TOKEN_NETWORK_REGISTRY} at {token_network_registry.address} '
        f'matches the compiled data from contracts.json',
    )

    if deployment_file_path is not None:
        print(f'Deployment info from {deployment_file_path} has been verified and it is CORRECT.')
Пример #14
0
def etherscan_verify_contract(
    chain_id: int,
    apikey: str,
    source_module: str,
    contract_name: str,
):
    """ Calls Etherscan API for verifying the Solidity source of a contract.

    Args:
        chain_id: EIP-155 chain id of the Ethereum chain
        apikey: key for calling Etherscan API
        source_module: a module name to look up contracts_source_path()
        contract_name: 'TokenNetworkRegistry', 'SecretRegistry' etc.
    """
    etherscan_api = api_of_chain_id[chain_id]
    deployment_info = get_contracts_deployed(
        chain_id=chain_id,
        services=(source_module == 'services'),
    )
    contract_manager = ContractManager(contracts_precompiled_path())

    data = post_data_for_etherscan_verification(
        apikey=apikey,
        deployment_info=deployment_info['contracts'][contract_name],
        source=join_sources(source_module, contract_name),
        contract_name=contract_name,
        metadata=json.loads(
            contract_manager.contracts[contract_name]['metadata']),
        constructor_args=get_constructor_args(deployment_info, contract_name,
                                              contract_manager),
    )
    response = requests.post(etherscan_api, data=data)
    content = json.loads(response.content.decode())
    print(content)
    print(
        f'Status: {content["status"]}; {content["message"]} ; GUID = {content["result"]}'
    )

    etherscan_url = etherscan_api.replace('api-', '').replace('api', '')
    etherscan_url += '/verifyContract2?a=' + data['contractaddress']
    manual_submission_guide = f"""Usually a manual submission to Etherscan works.
    Visit {etherscan_url}
    Use raiden_contracts/deploy/joined.sol."""

    if content['status'] == '1':  # submission succeeded, obtained GUID
        guid = content['result']
        status = '0'
        retries = 10
        while status == '0' and retries > 0:
            retries -= 1
            r = guid_status(etherscan_api=etherscan_api, guid=guid)
            status = r['status']
            if r['result'] == 'Fail - Unable to verify':
                raise ValueError(manual_submission_guide)
            if r['result'] == 'Pass - Verified':
                return
            print('Retrying...')
            sleep(5)
        raise TimeoutError(manual_submission_guide)
    else:
        if content['result'] == 'Contract source code already verified':
            return
        else:
            raise ValueError(
                'Etherscan submission failed for an unknown reason\n' +
                manual_submission_guide, )
def etherscan_verify(chain_id, apikey, guid, contract_name):
    contract_manager = ContractManager(contracts_precompiled_path())
    source_path = contracts_source_path()

    deployment_info = get_contracts_deployed(chain_id)

    if chain_id == 3:
        etherscan_api = 'https://api-ropsten.etherscan.io/api'
    elif chain_id == 4:
        etherscan_api = 'https://api-rinkeby.etherscan.io/api'
    elif chain_id == 42:
        etherscan_api = 'https://api-kovan.etherscan.io/api'
    elif chain_id == 1:
        etherscan_api = 'https://api.etherscan.io/api'

    if guid:
        guid_status(etherscan_api, guid)
        return

    if contract_name is None or contract_name == CONTRACT_ENDPOINT_REGISTRY:
        path = source_path['raiden'].joinpath(
            f'{CONTRACT_ENDPOINT_REGISTRY}.sol')
        source = path.read_text()
        constructor_args = ''
        etherscan_verify_contract(
            etherscan_api,
            apikey,
            contract_manager.contracts[CONTRACT_ENDPOINT_REGISTRY],
            CONTRACT_ENDPOINT_REGISTRY,
            deployment_info['contracts'][CONTRACT_ENDPOINT_REGISTRY],
            source,
            constructor_args,
        )

    if contract_name is None or contract_name == CONTRACT_SECRET_REGISTRY:
        path = source_path['raiden'].joinpath(
            f'{CONTRACT_SECRET_REGISTRY}.sol')
        source = path.read_text()
        constructor_args = ''
        etherscan_verify_contract(
            etherscan_api,
            apikey,
            contract_manager.contracts[CONTRACT_SECRET_REGISTRY],
            CONTRACT_SECRET_REGISTRY,
            deployment_info['contracts'][CONTRACT_SECRET_REGISTRY],
            source,
            constructor_args,
        )

    if contract_name is None or contract_name == CONTRACT_TOKEN_NETWORK_REGISTRY:
        source = (
            source_path['raiden'].joinpath('Utils.sol').read_text() +
            source_path['raiden'].joinpath('Token.sol').read_text() +
            source_path['raiden'].joinpath('lib', 'ECVerify.sol').read_text() +
            source_path['raiden'].joinpath('SecretRegistry.sol').read_text() +
            source_path['raiden'].joinpath('TokenNetwork.sol').read_text() +
            source_path['raiden'].joinpath(
                'TokenNetworkRegistry.sol').read_text())

        source = 'pragma solidity ^0.4.23;' + source.replace(
            'pragma solidity ^0.4.23;', '')
        source = source.replace('import "raiden/Token.sol";\n', '')
        source = source.replace('import "raiden/Utils.sol";\n', '')
        source = source.replace('import "raiden/lib/ECVerify.sol";\n', '')
        source = source.replace('import "raiden/SecretRegistry.sol";\n', '')
        source = source.replace('import "raiden/TokenNetwork.sol";\n', '')

        flatten_path = Path(__file__).parent.joinpath('flatten.sol')
        flatten_path.open('w').write(source)

        constructor_arguments = deployment_info['contracts'][
            CONTRACT_TOKEN_NETWORK_REGISTRY]['constructor_arguments']
        abi = contract_manager.contracts[CONTRACT_TOKEN_NETWORK_REGISTRY][
            'abi']
        constructor_types = [
            arg['type']
            for arg in list(filter(lambda x: x['type'] == 'constructor', abi),
                            )[0]['inputs']
        ]
        constructor_args = encode_abi(constructor_types,
                                      constructor_arguments).hex()
        print('constructor_args', constructor_arguments, constructor_types,
              constructor_args)

        etherscan_verify_contract(
            etherscan_api,
            apikey,
            contract_manager.contracts[CONTRACT_TOKEN_NETWORK_REGISTRY],
            CONTRACT_TOKEN_NETWORK_REGISTRY,
            deployment_info['contracts'][CONTRACT_TOKEN_NETWORK_REGISTRY],
            source,
            constructor_args,
        )
Пример #16
0
def main(
    eth_rpc,
    registry_address,
    start_block,
    port,
    confirmations,
):
    # setup logging
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        datefmt='%m-%d %H:%M:%S',
    )

    logging.getLogger('web3').setLevel(logging.INFO)
    logging.getLogger('urllib3.connectionpool').setLevel(logging.ERROR)

    log.info("Starting Raiden Metrics Server")
    try:
        log.info(f'Starting Web3 client for node at {eth_rpc}')
        web3 = Web3(HTTPProvider(eth_rpc))
        web3.middleware_stack.inject(geth_poa_middleware, layer=0)
    except ConnectionError:
        log.error(
            'Can not connect to the Ethereum client. Please check that it is running and that '
            'your settings are correct.')
        sys.exit()

    with no_ssl_verification():
        valid_params_given = is_checksum_address(
            registry_address) and start_block >= 0
        if not valid_params_given:
            try:
                chain_id = int(web3.net.version)
                # use limits for mainnet, pre limits for testnets
                is_mainnet = chain_id == 1
                version = None if is_mainnet else 'pre_limits'
                contract_data = get_contracts_deployed(int(web3.net.version),
                                                       version)
                token_network_registry_info = contract_data['contracts'][
                    CONTRACT_TOKEN_NETWORK_REGISTRY]  # noqa
                registry_address = token_network_registry_info['address']
                start_block = max(
                    0, token_network_registry_info['block_number'] - 100)
            except ValueError:
                log.error(
                    'Provided registry address or start block are not valid and '
                    'no deployed contracts were found')
                sys.exit(1)

        try:
            service = MetricsService(
                web3=web3,
                contract_manager=ContractManager(contracts_precompiled_path()),
                registry_address=registry_address,
                sync_start_block=start_block,
                required_confirmations=confirmations,
            )

            # re-enable once deployment works
            # gevent.spawn(write_topology_task, service)

            api = NetworkInfoAPI(service)
            api.run(port=port)
            print(f'Running metrics endpoint at http://localhost:{port}/json')

            print('Raiden Status Page backend running...')
            service.run()

        except (KeyboardInterrupt, SystemExit):
            print('Exiting...')
        finally:
            if service:
                log.info('Stopping Raiden Metrics Backend')
                service.stop()

    return 0
Пример #17
0
def verify_deployed_service_contracts(
    web3: Web3,
    contract_manager: ContractManager,
    token_address: str,
    deployment_data: dict=None,
):
    chain_id = int(web3.version.network)
    deployment_file_path = None

    if deployment_data is None:
        deployment_data = get_contracts_deployed(
            chain_id,
            contract_manager.contracts_version,
            services=True,
        )
        deployment_file_path = contracts_deployed_path(
            chain_id,
            contract_manager.contracts_version,
            services=True,
        )
    assert deployment_data is not None

    assert contract_manager.contracts_version == deployment_data['contracts_version']
    assert chain_id == deployment_data['chain_id']

    service_bundle = verify_deployed_contract(
        web3,
        contract_manager,
        deployment_data,
        CONTRACT_RAIDEN_SERVICE_BUNDLE,
    )

    # We need to also check the constructor parameters against the chain
    constructor_arguments = deployment_data['contracts'][
        CONTRACT_RAIDEN_SERVICE_BUNDLE
    ]['constructor_arguments']
    assert to_checksum_address(
        service_bundle.functions.token().call(),
    ) == token_address
    assert token_address == constructor_arguments[0]

    print(
        f'{CONTRACT_RAIDEN_SERVICE_BUNDLE} at {service_bundle.address} '
        f'matches the compiled data from contracts.json',
    )

    monitoring_service = verify_deployed_contract(
        web3,
        contract_manager,
        deployment_data,
        CONTRACT_MONITORING_SERVICE,
    )

    # We need to also check the constructor parameters against the chain
    constructor_arguments = deployment_data['contracts'][
        CONTRACT_MONITORING_SERVICE
    ]['constructor_arguments']

    assert to_checksum_address(
        monitoring_service.functions.token().call(),
    ) == token_address
    assert token_address == constructor_arguments[0]

    assert to_checksum_address(
        monitoring_service.functions.rsb().call(),
    ) == service_bundle.address
    assert service_bundle.address == constructor_arguments[1]

    print(
        f'{CONTRACT_MONITORING_SERVICE} at {monitoring_service.address} '
        f'matches the compiled data from contracts.json',
    )

    if deployment_file_path is not None:
        print(f'Deployment info from {deployment_file_path} has been verified and it is CORRECT.')
Пример #18
0
def main(
    eth_rpc,
    token_registry_address,
    endpoint_registry_address,
    start_block,
    confirmations,
    # latest,
):
    """Main command"""
    # setup logging
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s %(levelname)s %(message)s",
        datefmt="%Y%m%d %H:%M:%S",
    )
    log = logging.getLogger(__name__)
    logging.getLogger("web3").setLevel(logging.INFO)
    logging.getLogger("urllib3.connectionpool").setLevel(logging.ERROR)

    log.info("Starting Raiden Metrics Server")
    try:
        log.info(f"Starting Web3 client for node at {eth_rpc}")
        web3 = Web3(HTTPProvider(eth_rpc))
        web3.middleware_stack.inject(geth_poa_middleware, layer=0)
    except ConnectionError:
        log.error(
            "Can not connect to the Ethereum client. Please check that it is running and that "
            "your settings are correct."
        )
        sys.exit()

    # chain = Net(web3)
    # log.info(f"Net version = {chain.version}")
    # # use limits for mainnet, pre limits for testnets
    # is_mainnet = chain.version == 1
    # version = None if is_mainnet else "pre_limits"

    with no_ssl_verification():
        valid_params_given = (
            is_checksum_address(token_registry_address) and start_block >= 0
        )

        if not valid_params_given: # or latest is True
            try:
                contract_data = get_contracts_deployed(chain_id=4, version="pre_limits")
                token_network_registry_info = contract_data["contracts"][
                    CONTRACT_TOKEN_NETWORK_REGISTRY
                ]
                endpoint_registry_info = contract_data["contracts"][
                    CONTRACT_ENDPOINT_REGISTRY
                ]

                token_registry_address = token_network_registry_info["address"]
                endpoint_registry_address = endpoint_registry_info["address"]

                start_block = (
                    min(
                        token_network_registry_info["block_number"],
                        endpoint_registry_info["block_number"],
                    )
                    - 20
                )

            except ValueError as ex:
                log.error(ex)
                log.error(
                    "Provided registry address or start block are not valid and "
                    "no deployed contracts were found"
                )
                sys.exit(1)

        token_service = MetricsService(
            web3=web3,
            contract_manager=ContractManager(
                contracts_precompiled_path(version="pre_limits")
            ),
            token_registry_address=token_registry_address,
            endpoint_registry_address=endpoint_registry_address,
            sync_start_block=start_block,
            required_confirmations=confirmations,
        )

        token_service.run()

    sys.exit(0)