예제 #1
0
def test_invalid_chain_id():
    with pytest.raises(SystemExit):
        get_contract_addresses_and_start_block(
            chain_id=ChainID(123456789),
            contracts_version=DEFAULT_VERSION,
            contracts=[],
            address_overwrites={},
        )
예제 #2
0
def connect_to_blockchain(
    eth_rpc: str, used_contracts: List[str], address_overwrites: Dict[str,
                                                                      Address]
) -> Tuple[Web3, Dict[str, Contract], BlockNumber]:
    try:
        provider = HTTPProvider(eth_rpc)
        web3 = Web3(provider)
        # Will throw ConnectionError on bad Ethereum client
        chain_id = ChainID(int(web3.net.version))
    except requests.exceptions.ConnectionError:
        log.error(
            "Can not connect to the Ethereum client. Please check that it is running and that "
            "your settings are correct.",
            eth_rpc=eth_rpc,
        )
        sys.exit(1)

    # Add POA middleware for geth POA chains, no/op for other chains
    web3.middleware_stack.inject(geth_poa_middleware, layer=0)

    # give web3 some time between retries before failing
    provider.middlewares.replace("http_retry_request",
                                 http_retry_with_backoff_middleware)

    addresses, start_block = get_contract_addresses_and_start_block(
        chain_id=chain_id,
        contracts=used_contracts,
        address_overwrites=address_overwrites)
    contracts = {
        c: web3.eth.contract(abi=CONTRACT_MANAGER.get_contract_abi(c),
                             address=address)
        for c, address in addresses.items()
    }

    return web3, contracts, start_block
예제 #3
0
def test_contract_info_returns_nothing_with_partial_invalid_config():
    address1 = Address('0x' + '1' * 40)
    infos = get_contract_addresses_and_start_block(
        chain_id=ChainID(123456789),
        contracts_version=DEFAULT_VERSION,
        token_network_registry_address=address1,
    )
    assert infos is None
예제 #4
0
def connect_to_blockchain(
    eth_rpc: URI,
    gas_price_strategy: Optional[Callable[[Web3, Any], Wei]],
    used_contracts: List[str],
    address_overwrites: Dict[str, Address],
    development_environment: ContractDevEnvironment,
) -> Tuple[Web3, Dict[str, Contract], BlockNumber]:
    try:
        provider = HTTPProvider(eth_rpc)
        web3 = Web3(provider)
        # Will throw ConnectionError on bad Ethereum client
        chain_id = ChainID(web3.eth.chain_id)
    except requests.exceptions.ConnectionError:
        log.error(
            "Can not connect to the Ethereum client. Please check that it is running and that "
            "your settings are correct.",
            eth_rpc=eth_rpc,
        )
        sys.exit(1)

    # Add POA middleware for geth POA chains, no/op for other chains
    web3.middleware_onion.inject(geth_poa_middleware, layer=0)

    # Set gas price strategy
    # for that we also need a cache middleware, otherwise sampling is expensive
    web3.middleware_onion.add(simple_cache_middleware)

    if not gas_price_strategy:
        chain_id = ChainID(web3.eth.chain_id)
        gas_price_strategy = (rpc_gas_price_strategy
                              if "arbitrum" in ID_TO_CHAINNAME.get(
                                  chain_id, "") else fast_gas_price_strategy)

    web3.eth.setGasPriceStrategy(gas_price_strategy)

    # give web3 some time between retries before failing
    # TODO: find a way to to this type safe
    provider.middlewares.replace(  # type: ignore
        "http_retry_request", http_retry_with_backoff_middleware)

    addresses, start_block = get_contract_addresses_and_start_block(
        chain_id=chain_id,
        contracts=used_contracts,
        address_overwrites=address_overwrites,
        development_environment=development_environment,
    )
    contracts = {
        c: web3.eth.contract(abi=CONTRACT_MANAGER.get_contract_abi(c),
                             address=address)
        for c, address in addresses.items()
    }

    return web3, contracts, start_block
예제 #5
0
def test_contract_info_defaults():
    infos = get_contract_addresses_and_start_block(
        chain_id=DEFAULT_CHAIN_ID,
        contracts_version=DEFAULT_VERSION,
    )
    assert infos is not None
    assert infos[
        CONTRACT_TOKEN_NETWORK_REGISTRY] == '0xde1fAa1385403f05C20a8ca5a0D5106163A35B6e'
    assert infos[
        CONTRACT_MONITORING_SERVICE] == '0x58c73CabCFB3c55B420E3F60a4b06098e9D1960E'
    assert infos[
        CONTRACT_USER_DEPOSIT] == '0x85F2c5eA50861DF5eA2EBd3651fAB091e14B849C'
    assert infos[START_BLOCK_ID] == 5235446
예제 #6
0
def test_contract_info_returns_user_defaults_with_full_config():
    address1 = Address('0x' + '1' * 40)
    address2 = Address('0x' + '2' * 40)
    address3 = Address('0x' + '3' * 40)
    infos = get_contract_addresses_and_start_block(
        chain_id=ChainID(123456789),
        contracts_version=DEFAULT_VERSION,
        token_network_registry_address=address1,
        monitor_contract_address=address2,
        user_deposit_contract_address=address3,
        start_block=123,
    )
    assert infos is not None
    assert infos[CONTRACT_TOKEN_NETWORK_REGISTRY] == address1
    assert infos[CONTRACT_MONITORING_SERVICE] == address2
    assert infos[CONTRACT_USER_DEPOSIT] == address3
    assert infos[START_BLOCK_ID] == 123
예제 #7
0
def test_contract_info_defaults():
    infos, start_block = get_contract_addresses_and_start_block(
        chain_id=DEFAULT_CHAIN_ID,
        contracts=[
            CONTRACT_TOKEN_NETWORK_REGISTRY,
            CONTRACT_MONITORING_SERVICE,
            CONTRACT_USER_DEPOSIT,
        ],
        address_overwrites={},
        contracts_version=DEFAULT_VERSION,
    )
    assert infos is not None
    assert infos[CONTRACT_TOKEN_NETWORK_REGISTRY] == decode_hex(
        "0x5a5cf4a63022f61f1506d1a2398490c2e8dfbb98")
    assert infos[CONTRACT_MONITORING_SERVICE] == decode_hex(
        "0x20e8e5181000e60799a523a2023d630868f378fd")
    assert infos[CONTRACT_USER_DEPOSIT] == decode_hex(
        "0x0794f09913aa8c77c8c5bdd1ec4bb51759ee0cc5")
    assert start_block == 2723614
예제 #8
0
def test_contract_info_defaults():
    infos, start_block = get_contract_addresses_and_start_block(
        chain_id=DEFAULT_CHAIN_ID,
        contracts=[
            CONTRACT_TOKEN_NETWORK_REGISTRY,
            CONTRACT_MONITORING_SERVICE,
            CONTRACT_USER_DEPOSIT,
        ],
        address_overwrites={},
        contracts_version=DEFAULT_VERSION,
    )
    assert infos is not None
    assert infos[CONTRACT_TOKEN_NETWORK_REGISTRY] == decode_hex(
        "0xde1fAa1385403f05C20a8ca5a0D5106163A35B6e")
    assert infos[CONTRACT_MONITORING_SERVICE] == decode_hex(
        "0x58c73CabCFB3c55B420E3F60a4b06098e9D1960E")
    assert infos[CONTRACT_USER_DEPOSIT] == decode_hex(
        "0x85F2c5eA50861DF5eA2EBd3651fAB091e14B849C")
    assert start_block == 5235446
예제 #9
0
def test_contract_info_overwrite_defaults():
    address1 = Address(bytes([1] * 20))
    address2 = Address(bytes([2] * 20))
    address3 = Address(bytes([3] * 20))
    infos, start_block = get_contract_addresses_and_start_block(
        chain_id=DEFAULT_CHAIN_ID,
        contracts_version=DEFAULT_VERSION,
        contracts=[
            CONTRACT_TOKEN_NETWORK_REGISTRY,
            CONTRACT_MONITORING_SERVICE,
            CONTRACT_USER_DEPOSIT,
        ],
        address_overwrites={
            CONTRACT_TOKEN_NETWORK_REGISTRY: address1,
            CONTRACT_MONITORING_SERVICE: address2,
            CONTRACT_USER_DEPOSIT: address3,
        },
    )
    assert infos is not None
    assert infos[CONTRACT_TOKEN_NETWORK_REGISTRY] == address1
    assert infos[CONTRACT_MONITORING_SERVICE] == address2
    assert infos[CONTRACT_USER_DEPOSIT] == address3
    assert start_block == 0
예제 #10
0
def main(
    keystore_file: str,
    password: str,
    eth_rpc: str,
    registry_address: Address,
    monitor_contract_address: Address,
    user_deposit_contract_address: Address,
    start_block: int,
    confirmations: int,
    log_level: str,
    state_db: str,
    min_reward: int,
) -> None:
    setup_logging(log_level)

    with open(keystore_file, 'r') as keystore:
        try:
            private_key = Account.decrypt(
                keyfile_json=json.load(keystore),
                password=password,
            )
        except ValueError as error:
            log.critical(
                'Could not decode keyfile with given password. Please try again.',
                reason=str(error),
            )
            sys.exit(1)

    provider = HTTPProvider(eth_rpc)
    web3 = Web3(provider)
    contract_manager = ContractManager(contracts_precompiled_path())
    contract_infos = get_contract_addresses_and_start_block(
        chain_id=int(web3.net.version),
        contracts_version=None,
        token_network_registry_address=registry_address,
        monitor_contract_address=monitor_contract_address,
        user_deposit_contract_address=user_deposit_contract_address,
        start_block=start_block,
    )

    if contract_infos is None:
        log.critical(
            'Could not find correct contracts to use. Please check your configuration'
        )
        sys.exit(1)
    else:
        log.info(
            'Contract information',
            registry_address=contract_infos[CONTRACT_TOKEN_NETWORK_REGISTRY],
            monitor_contract_address=contract_infos[
                CONTRACT_MONITORING_SERVICE],
            user_deposit_contract_address=contract_infos[
                CONTRACT_USER_DEPOSIT],
            sync_start_block=contract_infos[START_BLOCK_ID],
        )

    ms = MonitoringService(
        web3=web3,
        contract_manager=contract_manager,
        private_key=private_key,
        registry_address=contract_infos[CONTRACT_TOKEN_NETWORK_REGISTRY],
        monitor_contract_address=contract_infos[CONTRACT_MONITORING_SERVICE],
        user_deposit_contract_address=contract_infos[CONTRACT_USER_DEPOSIT],
        sync_start_block=contract_infos[START_BLOCK_ID],
        required_confirmations=confirmations,
        db_filename=state_db,
        min_reward=min_reward,
    )
    ms.start()
예제 #11
0
def main(
    keystore_file: str,
    password: str,
    eth_rpc: str,
    registry_address: Address,
    user_deposit_contract_address: Address,
    start_block: int,
    confirmations: int,
    host: str,
    log_level: str,
    state_db: str,
    service_fee: int,
):
    """Console script for pathfinding_service.

    Logging can be quickly set by specifying a global log level or in a
    detailed way by using a log configuration file. See
    https://docs.python.org/3.7/library/logging.config.html#logging-config-dictschema
    for a detailed description of the format.
    """
    setup_logging(log_level)

    log.info("Starting Raiden Pathfinding Service")

    contracts_version = '0.10.1'
    log.info(f'Using contracts version: {contracts_version}')

    with open(keystore_file, 'r') as keystore:
        try:
            private_key = Account.decrypt(
                keyfile_json=json.load(keystore),
                password=password,
            ).hex()
        except ValueError as error:
            log.critical(
                'Could not decode keyfile with given password. Please try again.',
                reason=str(error),
            )
            sys.exit(1)
    try:
        log.info(f'Starting Web3 client for node at {eth_rpc}')
        provider = HTTPProvider(eth_rpc)
        web3 = Web3(provider)
        net_version = int(
            web3.net.version
        )  # Will throw ConnectionError on bad Ethereum client
    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(1)

    # Add POA middleware for geth POA chains, no/op for other chains
    web3.middleware_stack.inject(geth_poa_middleware, layer=0)

    # give web3 some time between retries before failing
    provider.middlewares.replace(
        'http_retry_request',
        http_retry_with_backoff_middleware,
    )

    contract_infos = get_contract_addresses_and_start_block(
        chain_id=net_version,
        contracts_version=contracts_version,
        token_network_registry_address=registry_address,
        # necessary so that the overwrite logic works properly
        monitor_contract_address='0x' + '1' * 40,
        user_deposit_contract_address=user_deposit_contract_address,
        start_block=start_block,
    )

    if contract_infos is None:
        log.critical(
            'Could not find correct contracts to use. Please check your configuration'
        )
        sys.exit(1)
    else:
        log.info(
            'Contract information',
            registry_address=contract_infos[CONTRACT_TOKEN_NETWORK_REGISTRY],
            user_deposit_contract_address=contract_infos[
                CONTRACT_USER_DEPOSIT],
            sync_start_block=contract_infos[START_BLOCK_ID],
        )

    service = None
    api = None
    try:
        log.info('Starting Pathfinding Service...')
        service = PathfindingService(
            web3=web3,
            contract_manager=contract_manager,
            registry_address=contract_infos[CONTRACT_TOKEN_NETWORK_REGISTRY],
            user_deposit_contract_address=contract_infos[
                CONTRACT_USER_DEPOSIT],
            sync_start_block=contract_infos[START_BLOCK_ID],
            required_confirmations=confirmations,
            private_key=private_key,
            poll_interval=DEFAULT_POLL_INTERVALL,
            db_filename=state_db,
            service_fee=service_fee,
        )

        api = ServiceApi(service)
        api.run(host=host)

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

    return 0
예제 #12
0
def test_contract_info_returns_nothing_with_invalid_config():
    infos = get_contract_addresses_and_start_block(
        chain_id=ChainID(123456789),
        contracts_version=DEFAULT_VERSION,
    )
    assert infos is None