Beispiel #1
0
def test_api_compliance(discovery_blockchain, local):
    contract_discovery_instance, address = discovery_blockchain
    if local:
        contract_discovery_instance = Discovery()
        assert isinstance(contract_discovery_instance, Discovery)
    else:
        assert isinstance(contract_discovery_instance, ContractDiscovery)

    # test that `get` for unknown address raises KeyError
    with pytest.raises(KeyError):
        assert contract_discovery_instance.get(
            ('01' * 20).decode('hex')) is None

    assert contract_discovery_instance.nodeid_by_host_port(
        ('127.0.0.1', 44444)) is None

    # test, that `update_endpoint` and 'classic' `register` do the same
    contract_discovery_instance.register(address, '127.0.0.1', 44444)
    not local and gevent.sleep(30)
    assert contract_discovery_instance.nodeid_by_host_port(
        ('127.0.0.1', 44444)) == address

    # test, that `register`ing twice does update do the same
    contract_discovery_instance.register(address, '127.0.0.1', 88888)
    not local and gevent.sleep(30)
    assert contract_discovery_instance.nodeid_by_host_port(
        ('127.0.0.1', 88888)) == address
Beispiel #2
0
def create_apps(
        blockchain_services,
        raiden_udp_ports,
        transport_class,
        verbosity,
        send_ping_time,
        max_unresponsive_time,
        reveal_timeout):
    """ Create the apps.

    Note:
        The generated network will use two subnets, 127.0.0.10 and 127.0.0.11,
        for this test to work in a mac both virtual interfaces must be created
        prior to the test execution::

            MacOSX (tested on 10.11.5):
                         interface       ip address netmask
                ifconfig lo0       alias 127.0.0.10 255.255.255.0
                ifconfig lo0       alias 127.0.0.11 255.255.255.0

            Alternative syntax:
                ifconfig lo:0 127.0.0.10
                ifconfig lo:1 127.0.0.11
    """
    # pylint: disable=too-many-locals
    half_of_nodes = len(blockchain_services) // 2
    discovery = Discovery()

    apps = []
    for idx, blockchain in enumerate(blockchain_services):
        port = raiden_udp_ports[idx]
        private_key = blockchain.private_key
        nodeid = privatekey_to_address(private_key)

        if verbosity > 7:
            blockchain.set_verbosity(1)

        # split the nodes into two different networks
        if idx > half_of_nodes:
            # TODO: check if the loopback interfaces exists
            host = '127.0.0.11'
        else:
            host = '127.0.0.10'

        discovery.register(nodeid, host, port)

        app = create_app(
            private_key,
            blockchain,
            discovery,
            transport_class,
            send_ping_time,
            max_unresponsive_time,
            port=port,
            host=host,
            reveal_timeout=reveal_timeout
        )
        apps.append(app)

    return apps
Beispiel #3
0
def tps_run(host, port, config, privatekey, rpc_server, registry_address,
            token_address, transfer_amount, parallel):
    # pylint: disable=too-many-locals,too-many-arguments
    ourprivkey, _ = hostport_to_privkeyaddr(host, port)

    rpc_connection = rpc_server.split(':')
    rpc_connection = (rpc_connection[0], int(rpc_connection[1]))

    with codecs.open(config, encoding='utf8') as handler:
        config = yaml.load(handler)

    config['host'] = host
    config['port'] = port
    config['privkey'] = ourprivkey

    rpc_connection = rpc_server.split(':')
    host, port = (rpc_connection[0], int(rpc_connection[1]))

    rpc_client = JSONRPCClient(
        privkey=privatekey,
        host=host,
        port=port,
        print_communication=False,
    )

    blockchain_service = BlockChainService(
        privatekey,
        registry_address,
        rpc_client,
    )

    discovery = Discovery()
    found_ouraddress = False
    for node in config['nodes']:
        _, address = hostport_to_privkeyaddr(node['host'], node['port'])

        discovery.register(address, node['host'], node['port'])

        if host == node['host'] and str(port) == node['port']:
            found_ouraddress = True

    if not found_ouraddress:
        print('We are not registered in the configuration file')
        sys.exit(1)

    app = App(config, blockchain_service, discovery)

    for _ in range(parallel):
        gevent.spawn(random_transfer, app, token_address, transfer_amount)

    # wait for interrupt
    event = gevent.event.Event()
    gevent.signal(signal.SIGQUIT, event.set)
    gevent.signal(signal.SIGTERM, event.set)
    gevent.signal(signal.SIGINT, event.set)
    event.wait()

    app.stop()
Beispiel #4
0
def tps_run(host, port, config, rpc_server, channelmanager_address,
            asset_address, transfer_amount, parallel):
    # pylint: disable=too-many-locals,too-many-arguments
    ourprivkey, _ = hostport_to_privkeyaddr(host, port)

    rpc_connection = rpc_server.split(':')
    rpc_connection = (rpc_connection[0], int(rpc_connection[1]))

    with codecs.open(config, encoding='utf8') as handler:
        config = yaml.load(handler)

    config['host'] = host
    config['port'] = port
    config['privkey'] = ourprivkey

    blockchain_service = BlockChainService(rpc_server, channelmanager_address)

    discovery = Discovery()
    found_ouraddress = False
    for node in config['nodes']:
        _, address = hostport_to_privkeyaddr(node['host'], node['port'])

        discovery.register(address, node['host'], node['port'])

        if host == node['host'] and str(port) == node['port']:
            found_ouraddress = True

    if not found_ouraddress:
        print('We are not registered in the configuration file')
        sys.exit(1)

    app = App(config, blockchain_service, discovery)

    for asset_address in blockchain_service.asset_addresses:
        all_netting_contracts = blockchain_service.nettingaddresses_by_asset_participant(
            asset,
            app.raiden.address,
        )

        for netting_contract_address in all_netting_contracts:
            app.raiden.setup_channel(
                asset,
                netting_contract_address,
                app.config['reveal_timeout'],
            )

    for _ in range(parallel):
        gevent.spawn(random_transfer, app, asset_address, transfer_amount)

    # wait for interrupt
    event = gevent.event.Event()
    gevent.signal(signal.SIGQUIT, event.set)
    gevent.signal(signal.SIGTERM, event.set)
    gevent.signal(signal.SIGINT, event.set)
    event.wait()

    app.stop()
Beispiel #5
0
def create_apps(
        blockchain_services,
        transport_class,
        verbosity,
        send_ping_time,
        max_unresponsive_time):
    """ Create the apps.

    Note:
        The generated network will use two subnets, 127.0.0.10 and 127.0.0.11,
        for this test to work in a mac both virtual interfaces must be created
        prior to the test execution::

            ifconfig lo:0 127.0.0.10
            ifconfig lo:1 127.0.0.11
    """
    # pylint: disable=too-many-locals
    half_of_nodes = len(blockchain_services) // 2
    discovery = Discovery()

    apps = []
    for idx, blockchain in enumerate(blockchain_services):
        port = INITIAL_PORT + idx
        private_key = blockchain.private_key
        nodeid = privatekey_to_address(private_key)

        if verbosity > 7:
            blockchain.set_verbosity(1)

        # split the nodes into two different networks
        if idx > half_of_nodes:
            # TODO: check if the loopback interfaces exists
            host = '127.0.0.11'
        else:
            host = '127.0.0.10'

        discovery.register(nodeid, host, port)

        app = create_app(
            private_key,
            blockchain,
            discovery,
            transport_class,
            send_ping_time,
            max_unresponsive_time,
            port=port,
            host=host
        )
        apps.append(app)

    return apps
Beispiel #6
0
def test_mock_registry_api_compliance():
    address = make_address()
    contract_discovery_instance = Discovery()

    # `get` for unknown address raises
    with pytest.raises(InvalidAddress):
        contract_discovery_instance.get(address)

    # `update_endpoint` and 'classic' `register` do the same
    contract_discovery_instance.register(address, "127.0.0.1", 44444)
    assert contract_discovery_instance.get(address) == ("127.0.0.1", 44444)

    # `register`ing twice does update do the same
    contract_discovery_instance.register(address, "127.0.0.1", 88888)
    assert contract_discovery_instance.get(address) == ("127.0.0.1", 88888)
Beispiel #7
0
def api_raiden_service(monkeypatch, api_test_server, api_test_context,
                       blockchain_services, transport_class,
                       max_unresponsive_time, send_ping_time, reveal_timeout,
                       raiden_udp_ports):
    blockchain = blockchain_services[0]
    config = copy.deepcopy(App.default_config)

    config['port'] = raiden_udp_ports[0]
    config['host'] = '127.0.0.1'
    config['privatekey_hex'] = blockchain.private_key.encode('hex')
    config['send_ping_time'] = send_ping_time
    config['max_unresponsive_time'] = max_unresponsive_time
    config['reveal_timeout'] = reveal_timeout
    raiden_service = RaidenService(blockchain, blockchain.private_key,
                                   transport_class, Discovery(), config)
    monkeypatch.setattr(raiden_service.api, 'get_channel_list',
                        api_test_context.query_channels)
    monkeypatch.setattr(raiden_service.api, 'get_tokens_list',
                        api_test_context.query_tokens)
    monkeypatch.setattr(raiden_service.api, 'open',
                        api_test_context.open_channel)
    monkeypatch.setattr(raiden_service.api, 'deposit',
                        api_test_context.deposit)
    monkeypatch.setattr(raiden_service.api, 'close', api_test_context.close)
    monkeypatch.setattr(raiden_service.api, 'settle', api_test_context.settle)
    monkeypatch.setattr(raiden_service.api, 'get_channel',
                        api_test_context.get_channel)

    # also make sure that the test server's raiden_api uses this mock
    # raiden service
    monkeypatch.setattr(api_test_server, 'raiden_api', raiden_service.api)
    return raiden_service
Beispiel #8
0
def test_mock_registry_api_compliance():
    address = make_address()
    contract_discovery_instance = Discovery()

    # `get` for unknown address raises
    with pytest.raises(InvalidAddress):
        contract_discovery_instance.get(address)

    # `update_endpoint` and 'classic' `register` do the same
    contract_discovery_instance.register(address, '127.0.0.1', 44444)
    assert contract_discovery_instance.get(address) == ('127.0.0.1', 44444)

    # `register`ing twice does update do the same
    contract_discovery_instance.register(address, '127.0.0.1', 88888)
    assert contract_discovery_instance.get(address) == ('127.0.0.1', 88888)
Beispiel #9
0
def api_raiden_service(monkeypatch, api_backend, api_test_context,
                       blockchain_services, transport_class, reveal_timeout,
                       raiden_udp_ports, tmpdir):

    blockchain = blockchain_services[0]
    config = copy.deepcopy(App.DEFAULT_CONFIG)

    config['port'] = raiden_udp_ports[0]
    config['host'] = '127.0.0.1'
    config['external_ip'] = '127.0.0.1'
    config['external_port'] = raiden_udp_ports[0]
    config['privatekey_hex'] = blockchain.private_key.encode('hex')
    config['reveal_timeout'] = reveal_timeout
    config['database_path'] = os.path.join(tmpdir.strpath, 'database.db')
    raiden_service = RaidenService(
        blockchain, blockchain.private_key,
        transport_class(config['host'], config['port']), Discovery(), config)
    api = RaidenAPI(raiden_service)
    monkeypatch.setattr(api, 'get_channel_list',
                        api_test_context.query_channels)
    monkeypatch.setattr(api, 'get_tokens_list', api_test_context.query_tokens)
    monkeypatch.setattr(api, 'open', api_test_context.open_channel)
    monkeypatch.setattr(api, 'deposit', api_test_context.deposit)
    monkeypatch.setattr(api, 'close', api_test_context.close)
    monkeypatch.setattr(api, 'settle', api_test_context.settle)
    monkeypatch.setattr(api, 'get_channel', api_test_context.get_channel)
    monkeypatch.setattr(api, 'get_network_events',
                        api_test_context.get_network_events)
    monkeypatch.setattr(api, 'get_token_network_events',
                        api_test_context.get_token_network_events)
    monkeypatch.setattr(api, 'get_channel_events',
                        api_test_context.get_channel_events)
    monkeypatch.setattr(api, 'transfer', api_test_context.transfer)
    monkeypatch.setattr(api, 'token_swap', api_test_context.token_swap)
    monkeypatch.setattr(api, 'expect_token_swap',
                        api_test_context.expect_token_swap)
    monkeypatch.setattr(api, 'connect_token_network', api_test_context.connect)
    monkeypatch.setattr(api, 'leave_token_network', api_test_context.leave)
    monkeypatch.setattr(api, 'get_connection_manager_funds',
                        api_test_context.get_connection_manager_funds)
    monkeypatch.setattr(api, 'get_connection_managers_list',
                        api_test_context.get_connection_managers_list)
    monkeypatch.setattr(api, 'register_token', api_test_context.register_token)
    monkeypatch.setattr(api, 'manager_address_if_token_registered',
                        api_test_context.manager_address_if_token_registered)

    # also make sure that the test server's raiden_api uses this mock
    # raiden service
    _, raiden_api = api_backend
    monkeypatch.setattr(raiden_api, 'raiden_api', api)
    return raiden_service
Beispiel #10
0
def api_raiden_service(
        monkeypatch,
        api_backend,
        api_test_context,
        blockchain_services,
        transport_class,
        max_unresponsive_time,
        send_ping_time,
        reveal_timeout,
        raiden_udp_ports,
        tmpdir):

    blockchain = blockchain_services[0]
    config = copy.deepcopy(App.default_config)

    config['port'] = raiden_udp_ports[0]
    config['host'] = '127.0.0.1'
    config['privatekey_hex'] = blockchain.private_key.encode('hex')
    config['send_ping_time'] = send_ping_time
    config['max_unresponsive_time'] = max_unresponsive_time
    config['reveal_timeout'] = reveal_timeout
    config['database_path'] = os.path.join(tmpdir.strpath, 'database.db')
    raiden_service = RaidenService(
        blockchain,
        blockchain.private_key,
        transport_class,
        Discovery(),
        config
    )
    api = RaidenAPI(raiden_service)
    monkeypatch.setattr(api, 'get_channel_list', api_test_context.query_channels)
    monkeypatch.setattr(api, 'get_tokens_list', api_test_context.query_tokens)
    monkeypatch.setattr(api, 'open', api_test_context.open_channel)
    monkeypatch.setattr(api, 'deposit', api_test_context.deposit)
    monkeypatch.setattr(api, 'close', api_test_context.close)
    monkeypatch.setattr(api, 'settle', api_test_context.settle)
    monkeypatch.setattr(api, 'get_channel', api_test_context.get_channel)
    monkeypatch.setattr(api, 'get_network_events', api_test_context.get_network_events)
    monkeypatch.setattr(api, 'get_token_network_events', api_test_context.get_token_network_events)
    monkeypatch.setattr(api, 'get_channel_events', api_test_context.get_channel_events)
    monkeypatch.setattr(api, 'transfer', api_test_context.transfer)
    monkeypatch.setattr(api, 'token_swap', api_test_context.token_swap)
    monkeypatch.setattr(api, 'expect_token_swap', api_test_context.expect_token_swap)

    # also make sure that the test server's raiden_api uses this mock
    # raiden service
    _, raiden_api = api_backend
    monkeypatch.setattr(raiden_api, 'raiden_api', api)
    return raiden_service
Beispiel #11
0
def profile_transfer(num_nodes=10, channels_per_node=2):
    num_tokens = 1
    deposit = 10000

    tokens = [
        sha3('token:{}'.format(number))[:20] for number in range(num_tokens)
    ]

    private_keys = [
        sha3('speed:{}'.format(position)) for position in range(num_nodes)
    ]

    blockchain_services = list()
    tester = tester_state(
        private_keys[0],
        private_keys,
        tester_blockgas_limit(),
    )
    nettingchannel_library_address = tester_nettingchannel_library_address(
        tester_state, )
    channelmanager_library_address = tester_channelmanager_library_address(
        tester_state,
        nettingchannel_library_address,
    )
    registry_address = tester_registry_address(
        tester_state,
        channelmanager_library_address,
    )
    for privkey in private_keys:
        blockchain = BlockChainServiceTesterMock(
            privkey,
            tester,
            registry_address,
        )
        blockchain_services.append(blockchain)

    registry = blockchain_services[0].registry(registry_address)
    for token in tokens:
        registry.add_token(token)

    discovery_mock = Discovery()
    endpoint_discovery_services = [discovery_mock for _ in private_keys]

    verbosity = 3
    apps = create_apps(
        blockchain_services,
        endpoint_discovery_services,
        tokens,
        channels_per_node,
        deposit,
        DEFAULT_SETTLE_TIMEOUT,
        UDPTransport,
        verbosity,
    )

    main_app = apps[0]

    # channels
    main_graph = main_app.raiden.token_to_channelgraph[tokens[0]]

    # search for a path of length=2 A > B > C
    num_hops = 2
    source = main_app.raiden.address
    paths = main_graph.get_paths_of_length(source, num_hops)

    # sanity check
    assert paths

    path = paths[0]
    target = path[-1]

    # addresses
    token_address = main_graph.token_address

    amount = 10

    # measure the hot path
    with profiling.profile():
        result = main_app.raiden.mediated_transfer_async(
            token_address,
            amount,
            target,
            1,
        )
        result.wait()

    profiling.print_all_threads()
Beispiel #12
0
def create_sequential_network(private_keys, asset_address, registry_address,  # pylint: disable=too-many-arguments
                              channels_per_node, deposit, settle_timeout,
                              poll_timeout, transport_class,
                              blockchain_service_class):
    """ Create a fully connected network with `num_nodes`, the nodes are
    connect sequentially.

    Returns:
        A list of apps of size `num_nodes`, with the property that every
        sequential pair in the list has an open channel with `deposit` for each
        participant.
    """
    # pylint: disable=too-many-locals

    random.seed(42)

    host = '127.0.0.1'
    num_nodes = len(private_keys)

    if num_nodes < 2:
        raise ValueError('cannot create a network with less than two nodes')

    if channels_per_node not in (0, 1, 2, CHAIN):
        raise ValueError('can only create networks with 0, 1, 2 or CHAIN channels')

    discovery = Discovery()
    blockchain_service_class = blockchain_service_class or BlockChainServiceMock

    apps = []
    for idx, privatekey_bin in enumerate(private_keys):
        port = INITIAL_PORT + idx
        nodeid = privtoaddr(privatekey_bin)

        discovery.register(nodeid, host, port)

        jsonrpc_client = JSONRPCClient(
            privkey=privatekey_bin,
            print_communication=False,
        )
        blockchain_service = blockchain_service_class(
            jsonrpc_client,
            registry_address,
            poll_timeout=poll_timeout,
        )

        app = create_app(
            privatekey_bin,
            blockchain_service,
            discovery,
            transport_class,
            port=port,
            host=host,
        )
        apps.append(app)

    if channels_per_node == 0:
        app_channels = list()

    if channels_per_node == 1:
        every_two = iter(apps)
        app_channels = list(zip(every_two, every_two))

    if channels_per_node == 2:
        app_channels = list(zip(apps, apps[1:] + [apps[0]]))

    if channels_per_node == CHAIN:
        app_channels = list(zip(apps[:-1], apps[1:]))

    setup_channels(
        asset_address,
        app_channels,
        deposit,
        settle_timeout,
    )

    for app in apps:
        app.raiden.register_registry(app.raiden.chain.default_registry)

    return apps
Beispiel #13
0
def create_network(private_keys, assets_addresses, registry_address,  # pylint: disable=too-many-arguments
                   channels_per_node, deposit, settle_timeout, poll_timeout,
                   transport_class, blockchain_service_class):
    """ Initialize a local test network using the UDP protocol.

    Note:
        The generated network will use two subnets, 127.0.0.10 and 127.0.0.11,
        for this test to work both virtual interfaces must be created prior to
        the test execution::

            ifconfig lo:0 127.0.0.10
            ifconfig lo:1 127.0.0.11
    """
    # pylint: disable=too-many-locals

    random.seed(1337)
    num_nodes = len(private_keys)

    if channels_per_node is not CHAIN and channels_per_node > num_nodes:
        raise ValueError("Can't create more channels than nodes")

    # if num_nodes it is not even
    half_of_nodes = int(floor(len(private_keys) / 2))

    # globals
    discovery = Discovery()

    # The mock needs to be atomic since all app's will use the same instance,
    # for the real application the syncronization is done by the JSON-RPC
    # server
    blockchain_service_class = blockchain_service_class or BlockChainServiceMock

    # Each app instance is a Node in the network
    apps = []
    for idx, privatekey_bin in enumerate(private_keys):

        # TODO: check if the loopback interfaces exists
        # split the nodes into two different networks
        if idx > half_of_nodes:
            host = '127.0.0.11'
        else:
            host = '127.0.0.10'

        nodeid = privtoaddr(privatekey_bin)
        port = INITIAL_PORT + idx

        discovery.register(nodeid, host, port)

        jsonrpc_client = JSONRPCClient(
            privkey=privatekey_bin,
            print_communication=False,
        )
        blockchain_service = blockchain_service_class(
            jsonrpc_client,
            registry_address,
            poll_timeout=poll_timeout,
        )

        app = create_app(
            privatekey_bin,
            blockchain_service,
            discovery,
            transport_class,
            port=port,
            host=host,
        )

        apps.append(app)

    for asset in assets_addresses:
        if channels_per_node == CHAIN:
            app_channels = list(zip(apps[:-1], apps[1:]))
        else:
            app_channels = list(network_with_minimum_channels(apps, channels_per_node))

        setup_channels(
            asset,
            app_channels,
            deposit,
            settle_timeout,
        )

    for app in apps:
        app.raiden.register_registry(app.raiden.chain.default_registry)

    return apps
Beispiel #14
0
def tps_run(
        host,
        port,
        config,
        privatekey,
        rpc_server,
        registry_address,
        secret_registry_address,
        token_address,
        transfer_amount,
        parallel):
    # pylint: disable=too-many-locals,too-many-arguments
    ourprivkey, _ = hostport_to_privkeyaddr(host, port)

    rpc_connection = rpc_server.split(':')
    rpc_connection = (rpc_connection[0], int(rpc_connection[1]))

    with codecs.open(config, encoding='utf8') as handler:
        config = yaml.load(handler)

    config['host'] = host
    config['port'] = port
    config['privkey'] = ourprivkey

    rpc_connection = rpc_server.split(':')
    host, port = (rpc_connection[0], int(rpc_connection[1]))

    rpc_client = JSONRPCClient(
        host,
        port,
        privatekey,
    )

    blockchain_service = BlockChainService(privatekey, rpc_client)

    discovery = Discovery()
    found_ouraddress = False
    for node in config['nodes']:
        _, address = hostport_to_privkeyaddr(node['host'], node['port'])

        discovery.register(address, node['host'], node['port'])

        if host == node['host'] and str(port) == node['port']:
            found_ouraddress = True

    if not found_ouraddress:
        print('We are not registered in the configuration file')
        sys.exit(1)

    throttle_policy = TokenBucket(
        config['protocol']['throttle_capacity'],
        config['protocol']['throttle_fill_rate'],
    )

    transport = UDPTransport(
        discovery,
        server._udp_socket((host, port)),
        throttle_policy,
        config['protocol'],
    )

    app = App(
        config=config,
        chain=blockchain_service,
        query_start_block=0,
        default_registry=registry_address,
        default_secret_registry=secret_registry_address,
        transport=transport,
        discovery=discovery,
    )

    for _ in range(parallel):
        gevent.spawn(random_transfer, app, token_address, transfer_amount)

    # wait for interrupt
    event = gevent.event.Event()
    gevent.signal(signal.SIGQUIT, event.set)
    gevent.signal(signal.SIGTERM, event.set)
    gevent.signal(signal.SIGINT, event.set)
    event.wait()

    app.stop()
Beispiel #15
0
def create_apps(
        blockchain_services,
        raiden_udp_ports,
        transport_class,
        verbosity,
        reveal_timeout,
        settle_timeout,
        database_paths,
        retry_interval,
        retries_before_backoff,
        throttle_capacity,
        throttle_fill_rate,
        nat_invitation_timeout,
        nat_keepalive_retries,
        nat_keepalive_timeout):

    """ Create the apps.

    Note:
        The generated network will use two subnets, 127.0.0.10 and 127.0.0.11,
        for this test to work in a mac both virtual interfaces must be created
        prior to the test execution::

            MacOSX (tested on 10.11.5):
                         interface       ip address netmask
                ifconfig lo0       alias 127.0.0.10 255.255.255.0
                ifconfig lo0       alias 127.0.0.11 255.255.255.0

            Alternative syntax:
                ifconfig lo:0 127.0.0.10
                ifconfig lo:1 127.0.0.11
    """
    # pylint: disable=too-many-locals
    half_of_nodes = len(blockchain_services) // 2
    discovery = Discovery()

    apps = []
    for idx, blockchain in enumerate(blockchain_services):
        port = raiden_udp_ports[idx]
        private_key = blockchain.private_key
        nodeid = privatekey_to_address(private_key)

        if verbosity > 7:
            blockchain.set_verbosity(1)

        # split the nodes into two different networks
        if idx > half_of_nodes:
            # TODO: check if the loopback interfaces exists
            host = '127.0.0.11'
        else:
            host = '127.0.0.10'

        discovery.register(nodeid, host, port)

        config = {
            'host': host,
            'port': port,
            'privatekey_hex': private_key.encode('hex'),
            'reveal_timeout': reveal_timeout,
            'settle_timeout': settle_timeout,
            'database_path': database_paths[idx],
            'protocol': {
                'retry_interval': retry_interval,
                'retries_before_backoff': retries_before_backoff,
                'throttle_capacity': throttle_capacity,
                'throttle_fill_rate': throttle_fill_rate,
                'nat_invitation_timeout': nat_invitation_timeout,
                'nat_keepalive_retries': nat_keepalive_retries,
                'nat_keepalive_timeout': nat_keepalive_timeout,
            },
            'rpc': True,
            'console': False,
        }
        copy = App.DEFAULT_CONFIG.copy()
        copy.update(config)

        app = App(
            copy,
            blockchain,
            discovery,
            transport_class,
        )
        app.raiden.protocol.transport.throttle_policy = DummyPolicy()
        apps.append(app)

    return apps
def test_api_compliance(discovery_blockchain, local):
    contract_discovery_instance, address = discovery_blockchain
    if local:
        contract_discovery_instance = Discovery()
        assert isinstance(contract_discovery_instance, Discovery)
    else:
        assert isinstance(contract_discovery_instance, ContractDiscovery)

    # test that `get` for unknown address raises KeyError
    with pytest.raises(KeyError):
        assert contract_discovery_instance.get(('01' * 20).decode('hex')) is None

    assert contract_discovery_instance.nodeid_by_host_port(('127.0.0.1', 44444)) is None

    # test, that `update_endpoint` and 'classic' `register` do the same
    contract_discovery_instance.register(address, '127.0.0.1', 44444)
    not local and gevent.sleep(30)
    assert contract_discovery_instance.nodeid_by_host_port(('127.0.0.1', 44444)) == address
    assert contract_discovery_instance.get(address) == ('127.0.0.1', 44444)
    # test, that `register`ing twice does update do the same
    contract_discovery_instance.register(address, '127.0.0.1', 88888)
    not local and gevent.sleep(30)
    assert contract_discovery_instance.nodeid_by_host_port(('127.0.0.1', 88888)) == address
    assert contract_discovery_instance.get(address) == ('127.0.0.1', 88888)
def tps_run(
        host,
        port,
        config,
        privatekey,
        rpc_server,
        registry_address,
        token_address,
        transfer_amount,
        parallel):
    # pylint: disable=too-many-locals,too-many-arguments
    ourprivkey, _ = hostport_to_privkeyaddr(host, port)

    rpc_connection = rpc_server.split(':')
    rpc_connection = (rpc_connection[0], int(rpc_connection[1]))

    with codecs.open(config, encoding='utf8') as handler:
        config = yaml.load(handler)

    config['host'] = host
    config['port'] = port
    config['privkey'] = ourprivkey

    rpc_connection = rpc_server.split(':')
    host, port = (rpc_connection[0], int(rpc_connection[1]))

    rpc_client = JSONRPCClient(
        host,
        port,
        privatekey,
    )

    blockchain_service = BlockChainService(
        privatekey,
        rpc_client,
        GAS_LIMIT,
        GAS_PRICE,
    )

    discovery = Discovery()
    found_ouraddress = False
    for node in config['nodes']:
        _, address = hostport_to_privkeyaddr(node['host'], node['port'])

        discovery.register(address, node['host'], node['port'])

        if host == node['host'] and str(port) == node['port']:
            found_ouraddress = True

    if not found_ouraddress:
        print('We are not registered in the configuration file')
        sys.exit(1)

    app = App(
        config,
        blockchain_service,
        discovery,
    )

    for _ in range(parallel):
        gevent.spawn(random_transfer, app, token_address, transfer_amount)

    # wait for interrupt
    event = gevent.event.Event()
    gevent.signal(signal.SIGQUIT, event.set)
    gevent.signal(signal.SIGTERM, event.set)
    gevent.signal(signal.SIGINT, event.set)
    event.wait()

    app.stop()
Beispiel #18
0
def main():
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('rpc_server',
                        help='The host:port of the json-rpc server')
    parser.add_argument('registry_address',
                        help='The asset registry contract address')
    parser.add_argument('config_file',
                        help='Configuration file for the raiden note')

    parser.add_argument(
        '-h',
        '--host',
        default='0.0.0.0',
        help='Local address that the raiden app will bind to',
    )
    parser.add_argument(
        '-p',
        '--port',
        default=INITIAL_PORT,
        help='Local port that the raiden app will bind to',
    )

    args = parser.parse_args()

    rpc_connection = args.rpc_server.split(':')
    rpc_connection = (rpc_connection[0], int(rpc_connection[1]))
    config_file = args.config_file
    host = args.host
    port = args.port

    with codecs.open(config_file, encoding='utf8') as handler:
        config = yaml.load(handler)

    config['host'] = host
    config['port'] = port

    if 'privkey' not in config:
        print('Missing "privkey" in the configuration file, cannot proceed')
        sys.exit(1)

    blockchain_server = BlockChainService(
        rpc_connection,
        config['privkey'],
        privtoaddr(config['privkey']),
        args.registry_address,
    )
    discovery = Discovery()

    for node in config['nodes']:
        discovery.register(node['nodeid'], node['host'], node['port'])

    app = App(config, blockchain_server, discovery)

    for asset_address in blockchain_server.asset_addresses:
        app.raiden.setup_asset(asset_address, app.config['reveal_timeout'])

    # TODO:
    # - Ask for confirmation to quit if there are any locked transfers that did
    # not timeout.

    # wait for interrupt
    event = gevent.event.Event()
    gevent.signal(signal.SIGQUIT, event.set)
    gevent.signal(signal.SIGTERM, event.set)
    gevent.signal(signal.SIGINT, event.set)
    event.wait()

    app.stop()
Beispiel #19
0
def create_sequential_network(blockchain_services, asset_address,
                              channels_per_node, deposit, settle_timeout,
                              transport_class, verbosity):
    """ Create a fully connected network with `num_nodes`, the nodes are
    connect sequentially.

    Returns:
        A list of apps of size `num_nodes`, with the property that every
        sequential pair in the list has an open channel with `deposit` for each
        participant.
    """
    # pylint: disable=too-many-locals

    host = '127.0.0.1'
    num_nodes = len(blockchain_services)

    if num_nodes < 2:
        raise ValueError('cannot create a network with less than two nodes')

    if channels_per_node not in (0, 1, 2, CHAIN):
        raise ValueError(
            'can only create networks with 0, 1, 2 or CHAIN channels')

    discovery = Discovery()

    apps = []
    for idx, blockchain in enumerate(blockchain_services):
        port = INITIAL_PORT + idx
        private_key = blockchain.private_key
        nodeid = privatekey_to_address(private_key)

        discovery.register(nodeid, host, port)

        if verbosity > 7:
            blockchain.set_verbose()

        app = create_app(
            private_key,
            blockchain,
            discovery,
            transport_class,
            port=port,
            host=host,
        )
        apps.append(app)

    if channels_per_node == 0:
        app_channels = list()

    if channels_per_node == 1:
        every_two = iter(apps)
        app_channels = list(zip(every_two, every_two))

    if channels_per_node == 2:
        app_channels = list(zip(apps, apps[1:] + [apps[0]]))

    if channels_per_node == CHAIN:
        app_channels = list(zip(apps[:-1], apps[1:]))

    setup_channels(
        asset_address,
        app_channels,
        deposit,
        settle_timeout,
    )

    for app in apps:
        app.raiden.register_registry(app.raiden.chain.default_registry)

    return apps
Beispiel #20
0
def test_mock_registry_api_compliance():
    address = make_address()
    contract_discovery_instance = Discovery()

    # `get` for unknown address raises
    with pytest.raises(KeyError):
        contract_discovery_instance.get(address)

    assert contract_discovery_instance.nodeid_by_host_port(
        ('127.0.0.1', 44444)) is None

    # `update_endpoint` and 'classic' `register` do the same
    contract_discovery_instance.register(address, '127.0.0.1', 44444)
    assert contract_discovery_instance.nodeid_by_host_port(
        ('127.0.0.1', 44444)) == address
    assert contract_discovery_instance.get(address) == ('127.0.0.1', 44444)

    # `register`ing twice does update do the same
    contract_discovery_instance.register(address, '127.0.0.1', 88888)
    assert contract_discovery_instance.nodeid_by_host_port(
        ('127.0.0.1', 88888)) == address
    assert contract_discovery_instance.get(address) == ('127.0.0.1', 88888)
Beispiel #21
0
def create_network(
        private_keys,
        assets_addresses,
        registry_address,  # pylint: disable=too-many-arguments
        channels_per_node,
        deposit,
        settle_timeout,
        poll_timeout,
        transport_class,
        blockchain_service_class):
    """ Initialize a local test network using the UDP protocol.

    Note:
        The generated network will use two subnets, 127.0.0.10 and 127.0.0.11,
        for this test to work both virtual interfaces must be created prior to
        the test execution::

            ifconfig lo:0 127.0.0.10
            ifconfig lo:1 127.0.0.11
    """
    # pylint: disable=too-many-locals

    random.seed(1337)
    num_nodes = len(private_keys)

    if channels_per_node is not CHAIN and channels_per_node > num_nodes:
        raise ValueError("Can't create more channels than nodes")

    # if num_nodes it is not even
    half_of_nodes = int(floor(len(private_keys) / 2))

    # globals
    discovery = Discovery()

    # The mock needs to be atomic since all app's will use the same instance,
    # for the real application the syncronization is done by the JSON-RPC
    # server
    blockchain_service_class = blockchain_service_class or BlockChainServiceMock

    # Each app instance is a Node in the network
    apps = []
    for idx, privatekey_bin in enumerate(private_keys):

        # TODO: check if the loopback interfaces exists
        # split the nodes into two different networks
        if idx > half_of_nodes:
            host = '127.0.0.11'
        else:
            host = '127.0.0.10'

        nodeid = privtoaddr(privatekey_bin)
        port = INITIAL_PORT + idx

        discovery.register(nodeid, host, port)

        jsonrpc_client = JSONRPCClient(
            privkey=privatekey_bin,
            print_communication=False,
        )
        blockchain_service = blockchain_service_class(
            jsonrpc_client,
            registry_address,
            poll_timeout=poll_timeout,
        )

        app = create_app(
            privatekey_bin,
            blockchain_service,
            discovery,
            transport_class,
            port=port,
            host=host,
        )

        apps.append(app)

    for asset in assets_addresses:
        if channels_per_node == CHAIN:
            app_channels = list(zip(apps[:-1], apps[1:]))
        else:
            app_channels = list(
                network_with_minimum_channels(apps, channels_per_node))

        setup_channels(
            asset,
            app_channels,
            deposit,
            settle_timeout,
        )

    for app in apps:
        app.raiden.register_registry(app.raiden.chain.default_registry)

    return apps
Beispiel #22
0
def main():
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('rpc_server', help='The host:port of the json-rpc server')
    parser.add_argument('registry_address', help='The asset registry contract address')
    parser.add_argument('config_file', help='Configuration file for the raiden note')

    parser.add_argument(
        '-h',
        '--host',
        default='0.0.0.0',
        help='Local address that the raiden app will bind to',
    )
    parser.add_argument(
        '-p',
        '--port',
        default=INITIAL_PORT,
        help='Local port that the raiden app will bind to',
    )

    args = parser.parse_args()

    rpc_connection = args.rpc_server.split(':')
    rpc_connection = (rpc_connection[0], int(rpc_connection[1]))
    config_file = args.config_file
    host = args.host
    port = args.port

    with codecs.open(config_file, encoding='utf8') as handler:
        config = yaml.load(handler)

    config['host'] = host
    config['port'] = port

    if 'privkey' not in config:
        print('Missing "privkey" in the configuration file, cannot proceed')
        sys.exit(1)

    blockchain_server = BlockChainService(rpc_connection, args.registry_address)
    discovery = Discovery()

    for node in config['nodes']:
        discovery.register(node['nodeid'], node['host'], node['port'])

    app = App(config, blockchain_server, discovery)

    for asset_address in blockchain_server.asset_addresses:
        app.raiden.setup_asset(asset_address, app.config['min_locktime'])

    # TODO:
    # - Ask for confirmation to quit if there are any locked transfers that did
    # not timeout.

    # wait for interrupt
    event = gevent.event.Event()
    gevent.signal(signal.SIGQUIT, event.set)
    gevent.signal(signal.SIGTERM, event.set)
    gevent.signal(signal.SIGINT, event.set)
    event.wait()

    app.stop()
Beispiel #23
0
def create_sequential_network(
        private_keys,
        asset_address,
        registry_address,  # pylint: disable=too-many-arguments
        channels_per_node,
        deposit,
        settle_timeout,
        poll_timeout,
        transport_class,
        blockchain_service_class):
    """ Create a fully connected network with `num_nodes`, the nodes are
    connect sequentially.

    Returns:
        A list of apps of size `num_nodes`, with the property that every
        sequential pair in the list has an open channel with `deposit` for each
        participant.
    """
    # pylint: disable=too-many-locals

    random.seed(42)

    host = '127.0.0.1'
    num_nodes = len(private_keys)

    if num_nodes < 2:
        raise ValueError('cannot create a network with less than two nodes')

    if channels_per_node not in (0, 1, 2, CHAIN):
        raise ValueError(
            'can only create networks with 0, 1, 2 or CHAIN channels')

    discovery = Discovery()
    blockchain_service_class = blockchain_service_class or BlockChainServiceMock

    apps = []
    for idx, privatekey_bin in enumerate(private_keys):
        port = INITIAL_PORT + idx
        nodeid = privtoaddr(privatekey_bin)

        discovery.register(nodeid, host, port)

        jsonrpc_client = JSONRPCClient(
            privkey=privatekey_bin,
            print_communication=False,
        )
        blockchain_service = blockchain_service_class(
            jsonrpc_client,
            registry_address,
            poll_timeout=poll_timeout,
        )

        app = create_app(
            privatekey_bin,
            blockchain_service,
            discovery,
            transport_class,
            port=port,
            host=host,
        )
        apps.append(app)

    if channels_per_node == 0:
        app_channels = list()

    if channels_per_node == 1:
        every_two = iter(apps)
        app_channels = list(zip(every_two, every_two))

    if channels_per_node == 2:
        app_channels = list(zip(apps, apps[1:] + [apps[0]]))

    if channels_per_node == CHAIN:
        app_channels = list(zip(apps[:-1], apps[1:]))

    setup_channels(
        asset_address,
        app_channels,
        deposit,
        settle_timeout,
    )

    for app in apps:
        app.raiden.register_registry(app.raiden.chain.default_registry)

    return apps
Beispiel #24
0
def test_mock_registry_api_compliance():
    address = make_address()
    contract_discovery_instance = Discovery()

    # `get` for unknown address raises
    with pytest.raises(KeyError):
        contract_discovery_instance.get(address)

    assert contract_discovery_instance.nodeid_by_host_port(('127.0.0.1', 44444)) is None

    # `update_endpoint` and 'classic' `register` do the same
    contract_discovery_instance.register(address, '127.0.0.1', 44444)
    assert contract_discovery_instance.nodeid_by_host_port(('127.0.0.1', 44444)) == address
    assert contract_discovery_instance.get(address) == ('127.0.0.1', 44444)

    # `register`ing twice does update do the same
    contract_discovery_instance.register(address, '127.0.0.1', 88888)
    assert contract_discovery_instance.nodeid_by_host_port(('127.0.0.1', 88888)) == address
    assert contract_discovery_instance.get(address) == ('127.0.0.1', 88888)
Beispiel #25
0
def create_network(blockchain_services, assets_addresses, channels_per_node,
                   deposit, settle_timeout, transport_class, verbosity):
    """ Initialize a raiden test network.

    Note:
        The generated network will use two subnets, 127.0.0.10 and 127.0.0.11,
        for this test to work in a mac both virtual interfaces must be created
        prior to the test execution::

            ifconfig lo:0 127.0.0.10
            ifconfig lo:1 127.0.0.11
    """
    # pylint: disable=too-many-locals

    num_nodes = len(blockchain_services)

    if channels_per_node is not CHAIN and channels_per_node > num_nodes:
        raise ValueError("Can't create more channels than nodes")

    half_of_nodes = len(blockchain_services) // 2
    discovery = Discovery()

    apps = []
    for idx, blockchain in enumerate(blockchain_services):
        private_key = blockchain.private_key

        # TODO: check if the loopback interfaces exists
        # split the nodes into two different networks
        if idx > half_of_nodes:
            host = '127.0.0.11'
        else:
            host = '127.0.0.10'

        nodeid = privatekey_to_address(private_key)
        port = INITIAL_PORT + idx

        discovery.register(nodeid, host, port)

        if verbosity > 7:
            blockchain.set_verbose()

        app = create_app(
            private_key,
            blockchain,
            discovery,
            transport_class,
            port=port,
            host=host,
        )
        apps.append(app)

    for asset in assets_addresses:
        if channels_per_node == CHAIN:
            app_channels = list(zip(apps[:-1], apps[1:]))
        else:
            app_channels = list(
                network_with_minimum_channels(apps, channels_per_node))

        setup_channels(
            asset,
            app_channels,
            deposit,
            settle_timeout,
        )

    for app in apps:
        app.raiden.register_registry(app.raiden.chain.default_registry)

    return apps