def test_mediated_transfer_events(raiden_network, number_of_nodes, token_addresses, network_wait):
    app0, app1, app2 = raiden_network
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )

    amount = 10
    mediated_transfer(
        app0,
        app2,
        token_network_identifier,
        amount,
        timeout=network_wait * number_of_nodes,
    )

    def test_initiator_events():
        initiator_blockevents = app0.raiden.wal.storage.get_events_by_identifier(
            from_identifier=0,
            to_identifier='latest',
        )
        initiator_events = [blocknumber_event[1] for blocknumber_event in initiator_blockevents]
        return (
            must_contain_entry(initiator_events, SendRevealSecret, {}) and
            must_contain_entry(initiator_events, EventUnlockSuccess, {})
        )

    assert wait_until(test_initiator_events, network_wait)

    def test_mediator_events():
        mediator_blockevents = app1.raiden.wal.storage.get_events_by_identifier(
            from_identifier=0,
            to_identifier='latest',
        )
        mediator_events = [blocknumber_event[1] for blocknumber_event in mediator_blockevents]
        return (
            must_contain_entry(mediator_events, EventUnlockSuccess, {}) and
            must_contain_entry(mediator_events, EventUnlockClaimSuccess, {})
        )

    assert wait_until(test_mediator_events, network_wait)

    def test_target_events():
        target_blockevents = app2.raiden.wal.storage.get_events_by_identifier(
            from_identifier=0,
            to_identifier='latest',
        )
        target_events = [blocknumber_event[1] for blocknumber_event in target_blockevents]
        return (
            must_contain_entry(target_events, SendSecretRequest, {}) and
            must_contain_entry(target_events, SendRevealSecret, {}) and
            must_contain_entry(target_events, EventUnlockClaimSuccess, {})
        )

    assert wait_until(test_target_events, network_wait)
예제 #2
0
def test_mediated_transfer_events(raiden_network, number_of_nodes, token_addresses, network_wait):
    app0, app1, app2 = raiden_network
    token_address = token_addresses[0]
    chain_state = views.state_from_app(app0)
    payment_network_id = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state,
        payment_network_id,
        token_address,
    )

    amount = 10
    mediated_transfer(
        app0,
        app2,
        token_network_identifier,
        amount,
        timeout=network_wait * number_of_nodes,
    )

    def test_initiator_events():
        initiator_events = app0.raiden.wal.storage.get_events()
        return (
            must_contain_entry(initiator_events, SendSecretReveal, {}) and
            must_contain_entry(initiator_events, EventUnlockSuccess, {})
        )

    assert wait_until(test_initiator_events, network_wait)

    def test_mediator_events():
        mediator_events = app1.raiden.wal.storage.get_events()
        return (
            must_contain_entry(mediator_events, EventUnlockSuccess, {}) and
            must_contain_entry(mediator_events, EventUnlockClaimSuccess, {})
        )

    assert wait_until(test_mediator_events, network_wait)

    def test_target_events():
        target_events = app2.raiden.wal.storage.get_events()
        return (
            must_contain_entry(target_events, SendSecretRequest, {}) and
            must_contain_entry(target_events, SendSecretReveal, {}) and
            must_contain_entry(target_events, EventUnlockClaimSuccess, {})
        )

    assert wait_until(test_target_events, network_wait)
def run_test_mediated_transfer_events(
        raiden_network,
        number_of_nodes,
        token_addresses,
        network_wait,
):
    app0, app1, app2 = raiden_network
    token_address = token_addresses[0]

    amount = 10
    transfer(
        initiator_app=app0,
        target_app=app2,
        token_address=token_address,
        amount=amount,
        identifier=1,
        timeout=network_wait * number_of_nodes,
    )

    def test_initiator_events():
        initiator_events = app0.raiden.wal.storage.get_events()
        return (
            search_for_item(initiator_events, SendSecretReveal, {}) and
            search_for_item(initiator_events, EventUnlockSuccess, {})
        )

    assert wait_until(test_initiator_events, network_wait)

    def test_mediator_events():
        mediator_events = app1.raiden.wal.storage.get_events()
        return (
            search_for_item(mediator_events, EventUnlockSuccess, {}) and
            search_for_item(mediator_events, EventUnlockClaimSuccess, {})
        )

    assert wait_until(test_mediator_events, network_wait)

    def test_target_events():
        target_events = app2.raiden.wal.storage.get_events()
        return (
            search_for_item(target_events, SendSecretRequest, {}) and
            search_for_item(target_events, SendSecretReveal, {}) and
            search_for_item(target_events, EventUnlockClaimSuccess, {})
        )

    assert wait_until(test_target_events, network_wait)
예제 #4
0
def run_test_echo_node_response(token_addresses, raiden_chain, network_wait):
    app0, app1, app2, echo_app = raiden_chain
    address_to_app = {app.raiden.address: app for app in raiden_chain}
    token_address = token_addresses[0]
    echo_api = RaidenAPI(echo_app.raiden)

    echo_node = EchoNode(echo_api, token_address)
    echo_node.ready.wait(timeout=30)
    assert echo_node.ready.is_set()
    expected = list()

    # Create some transfers
    for num, app in enumerate([app0, app1, app2]):
        amount = 1 + num
        payment_status = RaidenAPI(app.raiden).transfer_async(
            app.raiden.default_registry.address,
            token_address,
            amount,
            echo_app.raiden.address,
            10 ** (num + 1),
        )
        payment_status.payment_done.wait(timeout=20)
        expected.append(amount)

    while echo_node.num_handled_transfers < len(expected):
        gevent.sleep(.5)

    # Check that all transfers were handled correctly
    def test_events(handled_transfer):
        app = address_to_app[handled_transfer.initiator]
        events = RaidenAPI(app.raiden).get_raiden_events_payment_history(
            token_address=token_address,
        )

        received = {
            event.identifier: event
            for event in events
            if type(event) == EventPaymentReceivedSuccess
        }

        if len(received) != 1:
            return None
        transfer = received.popitem()[1]

        is_not_valid = (
            transfer.initiator != echo_app.raiden.address or
            transfer.identifier != handled_transfer.identifier + transfer.amount
        )

        if is_not_valid:
            return None
        return transfer

    for handled_transfer in echo_node.seen_transfers:
        assert wait_until(lambda: test_events(handled_transfer), network_wait)

    echo_node.stop()
예제 #5
0
def test_echo_node_response(token_addresses, raiden_chain, network_wait):
    app0, app1, app2, echo_app = raiden_chain
    address_to_app = {app.raiden.address: app for app in raiden_chain}
    token_address = token_addresses[0]
    echo_api = RaidenAPI(echo_app.raiden)

    echo_node = EchoNode(echo_api, token_address)
    echo_node.ready.wait(timeout=30)
    assert echo_node.ready.is_set()
    expected = list()

    # Create some transfers
    for num, app in enumerate([app0, app1, app2]):
        amount = 1 + num
        transfer_event = RaidenAPI(app.raiden).transfer_async(
            app.raiden.default_registry.address,
            token_address,
            amount,
            echo_app.raiden.address,
            10 ** (num + 1),
        )
        transfer_event.wait(timeout=20)
        expected.append(amount)

    while echo_node.num_handled_transfers < len(expected):
        gevent.sleep(.5)

    # Check that all transfers were handled correctly
    def test_events(handled_transfer):
        app = address_to_app[handled_transfer.initiator]
        events = RaidenAPI(app.raiden).get_raiden_events_payment_history(
            token_address=token_address,
        )

        received = {
            event.identifier: event
            for event in events
            if type(event) == EventPaymentReceivedSuccess
        }

        if len(received) != 1:
            return
        transfer = received.popitem()[1]

        is_not_valid = (
            transfer.initiator != echo_app.raiden.address or
            transfer.identifier != handled_transfer.identifier + transfer.amount
        )

        if is_not_valid:
            return
        return transfer

    for handled_transfer in echo_node.seen_transfers:
        assert wait_until(lambda: test_events(handled_transfer), network_wait)

    echo_node.stop()
예제 #6
0
def test_mediated_transfer_events(raiden_network, number_of_nodes,
                                  token_addresses, network_wait):
    app0, app1, app2 = raiden_network
    token_address = token_addresses[0]

    amount = 10
    transfer(
        initiator_app=app0,
        target_app=app2,
        token_address=token_address,
        amount=PaymentAmount(amount),
        identifier=PaymentID(1),
        timeout=network_wait * number_of_nodes,
    )

    def test_initiator_events():
        assert not has_unlock_failure(app0.raiden)
        initiator_events = app0.raiden.wal.storage.get_events()
        secret_reveal = search_for_item(initiator_events, SendSecretReveal, {})
        unlock_success = search_for_item(initiator_events, EventUnlockSuccess,
                                         {})
        return secret_reveal and unlock_success

    assert wait_until(test_initiator_events, network_wait)

    def test_mediator_events():
        assert not has_unlock_failure(app1.raiden)
        mediator_events = app1.raiden.wal.storage.get_events()
        unlock_success = search_for_item(mediator_events, EventUnlockSuccess,
                                         {})
        unlock_claim_success = search_for_item(mediator_events,
                                               EventUnlockClaimSuccess, {})
        return unlock_success and unlock_claim_success

    assert wait_until(test_mediator_events, network_wait)

    def test_target_events():
        assert not has_unlock_failure(app2.raiden)
        target_events = app2.raiden.wal.storage.get_events()
        return (search_for_item(target_events, SendSecretRequest, {})
                and search_for_item(target_events, SendSecretReveal, {}) and
                search_for_item(target_events, EventUnlockClaimSuccess, {}))

    assert wait_until(test_target_events, network_wait)
예제 #7
0
def test_echo_node_response(token_addresses, raiden_chain, network_wait):
    app0, app1, app2, echo_app = raiden_chain
    address_to_app = {app.raiden.address: app for app in raiden_chain}
    token_address = token_addresses[0]
    echo_api = RaidenAPI(echo_app.raiden)

    echo_node = EchoNode(echo_api, token_address)
    echo_node.ready.wait(timeout=30)
    assert echo_node.ready.is_set()
    expected = list()

    # Create some transfers
    for num, app in enumerate([app0, app1, app2]):
        amount = 1 + num
        transfer_event = RaidenAPI(app.raiden).transfer_async(
            app.raiden.default_registry.address,
            token_address,
            amount,
            echo_app.raiden.address,
            10**(num + 1),
        )
        transfer_event.wait(timeout=20)
        expected.append(amount)

    while echo_node.num_handled_transfers < len(expected):
        gevent.sleep(.5)

    # Check that all transfers were handled correctly
    def test_events(handled_transfer):
        app = address_to_app[handled_transfer['initiator']]
        events = get_channel_events_for_token(
            app,
            app.raiden.default_registry.address,
            token_address,
            0,
        )
        received = {
            event['identifier']: event
            for event in events
            if event['event'] == 'EventTransferReceivedSuccess'
        }
        if len(received) != 1:
            return
        transfer = received.popitem()[1]
        if (transfer['initiator'] != echo_app.raiden.address
                or transfer['identifier'] !=
                handled_transfer['identifier'] + transfer['amount']):
            return
        return transfer

    for handled_transfer in echo_node.seen_transfers:
        assert wait_until(lambda: test_events(handled_transfer), network_wait)

    echo_node.stop()
예제 #8
0
파일: python.py 프로젝트: schmidtbps/raiden
    def deposit(self, token_address, partner_address, amount):
        """ Deposit `amount` in the channel with the peer at `partner_address` and the
        given `token_address` in order to be able to do transfers.
        """
        if not isaddress(token_address):
            raise InvalidAddress(
                'Expected binary address format for token in channel deposit')

        if not isaddress(partner_address):
            raise InvalidAddress(
                'Expected binary address format for partner in channel deposit'
            )

        graph = self.raiden.token_to_channelgraph[token_address]
        channel = graph.partneraddress_to_channel[partner_address]
        netcontract_address = channel.external_state.netting_channel.address
        assert len(netcontract_address)

        # Obtain a reference to the token and approve the amount for funding
        token = self.raiden.chain.token(token_address)
        balance = token.balance_of(self.raiden.address.encode('hex'))

        if not balance >= amount:
            msg = "Not enough balance for token'{}' [{}]: have={}, need={}".format(
                token.proxy.name(), pex(token_address), balance, amount)
            raise InsufficientFunds(msg)

        token.approve(netcontract_address, amount)

        # Obtain the netting channel and fund it by depositing the amount
        old_balance = channel.contract_balance
        netting_channel = self.raiden.chain.netting_channel(
            netcontract_address)
        # actually make the deposit, and wait for it to be mined
        netting_channel.deposit(amount)

        # Wait until the balance has been updated via a state transition triggered
        # by processing the `ChannelNewBalance` event.
        # Usually, it'll take a single gevent.sleep, as we already have waited
        # for it to be mined, and only need to give the event handling greenlet
        # the chance to process the event, but let's wait 10s to be safe
        wait_timeout_secs = 10  # FIXME: hardcoded timeout
        if not wait_until(
                lambda: channel.contract_balance != old_balance,
                wait_timeout_secs,
                self.raiden.alarm.wait_time,
        ):
            raise EthNodeCommunicationError(
                'After {} seconds the deposit was not properly processed.'.
                format(wait_timeout_secs))

        return channel
예제 #9
0
def test_event_transfer_received_success(
    token_addresses,
    raiden_chain,
    network_wait,
    skip_if_not_udp,
):
    app0, app1, app2, receiver_app = raiden_chain
    token_address = token_addresses[0]

    expected = dict()

    for num, app in enumerate([app0, app1, app2]):
        amount = 1 + num
        transfer_event = RaidenAPI(app.raiden).transfer_async(
            app.raiden.default_registry.address,
            token_address,
            amount,
            receiver_app.raiden.address,
        )
        transfer_event.wait(timeout=20)
        expected[app.raiden.address] = amount

    # sleep is for the receiver's node to have time to process all events
    gevent.sleep(1)

    def test_events(amount, address):
        events = receiver_app.raiden.wal.storage.get_events_by_block(
            0, 'latest')
        events = [e[1] for e in events]
        return must_contain_entry(
            events,
            EventTransferReceivedSuccess,
            {
                'amount': amount,
                'initiator': address
            },
        )

    amounts = [1, 2, 3]
    addrs = [app0.raiden.address, app1.raiden.address, app2.raiden.address]
    for amount, address in zip(amounts, addrs):
        assert wait_until(
            lambda: test_events(amount, address),
            network_wait,
        )
예제 #10
0
def test_event_transfer_received_success(
    token_addresses,
    raiden_chain,
    network_wait,
):
    app0, app1, app2, receiver_app = raiden_chain
    token_address = token_addresses[0]

    expected = dict()

    for num, app in enumerate([app0, app1, app2]):
        amount = 1 + num
        transfer_event = RaidenAPI(app.raiden).transfer_async(
            app.raiden.default_registry.address,
            token_address,
            amount,
            receiver_app.raiden.address,
        )
        transfer_event.wait(timeout=20)
        expected[app.raiden.address] = amount

    # sleep is for the receiver's node to have time to process all events
    gevent.sleep(1)

    def test_events(amount, address):
        return search_for_item(
            receiver_app.raiden.wal.storage.get_events(),
            EventPaymentReceivedSuccess,
            {
                'amount': amount,
                'initiator': address
            },
        )

    amounts = [1, 2, 3]
    addrs = [app0.raiden.address, app1.raiden.address, app2.raiden.address]
    for amount, address in zip(amounts, addrs):
        assert wait_until(
            lambda: test_events(amount, address),
            network_wait,
        )
예제 #11
0
def test_event_transfer_received_success(
        token_addresses,
        raiden_chain,
        network_wait,
):
    app0, app1, app2, receiver_app = raiden_chain
    token_address = token_addresses[0]

    expected = dict()

    for num, app in enumerate([app0, app1, app2]):
        amount = 1 + num
        transfer_event = RaidenAPI(app.raiden).transfer_async(
            app.raiden.default_registry.address,
            token_address,
            amount,
            receiver_app.raiden.address,
        )
        transfer_event.wait(timeout=20)
        expected[app.raiden.address] = amount

    # sleep is for the receiver's node to have time to process all events
    gevent.sleep(1)

    def test_events(amount, address):
        return must_contain_entry(
            receiver_app.raiden.wal.storage.get_events(),
            EventPaymentReceivedSuccess,
            {'amount': amount, 'initiator': address},
        )

    amounts = [1, 2, 3]
    addrs = [app0.raiden.address, app1.raiden.address, app2.raiden.address]
    for amount, address in zip(amounts, addrs):
        assert wait_until(
            lambda: test_events(amount, address),
            network_wait,
        )
예제 #12
0
파일: python.py 프로젝트: zheewang/raiden
    def deposit(self,
                token_address,
                partner_address,
                amount,
                poll_timeout=DEFAULT_POLL_TIMEOUT):
        """ Deposit `amount` in the channel with the peer at `partner_address` and the
        given `token_address` in order to be able to do transfers.

        Raises:
            InvalidAddress: If either token_address or partner_address is not
            20 bytes long.
            TransactionThrew: May happen for multiple reasons:
                - If the token approval fails, e.g. the token may validate if
                  account has enough balance for the allowance.
                - The deposit failed, e.g. the allowance did not set the token
                  aside for use and the user spent it before deposit was called.
                - The channel was closed/settled between the allowance call and
                  the deposit call.
            AddressWithoutCode: The channel was settled during the deposit
            execution.
        """
        if not isaddress(token_address):
            raise InvalidAddress(
                'Expected binary address format for token in channel deposit')

        if not isaddress(partner_address):
            raise InvalidAddress(
                'Expected binary address format for partner in channel deposit'
            )

        graph = self.raiden.token_to_channelgraph.get(token_address)
        if graph is None:
            raise InvalidAddress('Unknown token address')

        channel = graph.partneraddress_to_channel.get(partner_address)
        if channel is None:
            raise InvalidAddress(
                'No channel with partner_address for the given token')

        if channel.token_address != token_address:
            raise InvalidAddress(
                'token_address does not match the netting channel attribute')

        token = self.raiden.chain.token(token_address)
        netcontract_address = channel.external_state.netting_channel.address
        old_balance = channel.contract_balance

        # Checking the balance is not helpful since this requires multiple
        # transactions that can race, e.g. the deposit check succeed but the
        # user spent his balance before deposit.
        balance = token.balance_of(hexlify(self.raiden.address))
        if not balance >= amount:
            msg = 'Not enough balance to deposit. {} Available={} Tried={}'.format(
                pex(token_address),
                balance,
                amount,
            )
            raise InsufficientFunds(msg)
        token.approve(netcontract_address, amount)

        channel_proxy = self.raiden.chain.netting_channel(netcontract_address)
        channel_proxy.deposit(amount)

        # Wait until the `ChannelNewBalance` event is processed.
        #
        # Usually a single sleep is sufficient, since the `deposit` waits for
        # the transaction to be polled.
        sucess = wait_until(
            lambda: channel.contract_balance != old_balance,
            poll_timeout,
            self.raiden.alarm.wait_time,
        )

        if not sucess:
            raise EthNodeCommunicationError(
                'After {} seconds the deposit was not properly processed.'.
                format(poll_timeout))

        return channel
예제 #13
0
    def deposit(self, token_address, partner_address, amount, poll_timeout=DEFAULT_POLL_TIMEOUT):
        """ Deposit `amount` in the channel with the peer at `partner_address` and the
        given `token_address` in order to be able to do transfers.

        Raises:
            InvalidAddress: If either token_address or partner_address is not
            20 bytes long.
            TransactionThrew: May happen for multiple reasons:
                - If the token approval fails, e.g. the token may validate if
                  account has enough balance for the allowance.
                - The deposit failed, e.g. the allowance did not set the token
                  aside for use and the user spent it before deposit was called.
                - The channel was closed/settled between the allowance call and
                  the deposit call.
            AddressWithoutCode: The channel was settled during the deposit
            execution.
        """
        if not isaddress(token_address):
            raise InvalidAddress('Expected binary address format for token in channel deposit')

        if not isaddress(partner_address):
            raise InvalidAddress('Expected binary address format for partner in channel deposit')

        graph = self.raiden.token_to_channelgraph.get(token_address)
        if graph is None:
            raise InvalidAddress('Unknown token address')

        channel = graph.partneraddress_to_channel.get(partner_address)
        if channel is None:
            raise InvalidAddress('No channel with partner_address for the given token')

        if channel.token_address != token_address:
            raise InvalidAddress('token_address does not match the netting channel attribute')

        token = self.raiden.chain.token(token_address)
        netcontract_address = channel.external_state.netting_channel.address
        old_balance = channel.contract_balance

        # Checking the balance is not helpful since this requires multiple
        # transactions that can race, e.g. the deposit check succeed but the
        # user spent his balance before deposit.
        balance = token.balance_of(hexlify(self.raiden.address))
        if not balance >= amount:
            msg = 'Not enough balance to deposit. {} Available={} Tried={}'.format(
                pex(token_address),
                balance,
                amount,
            )
            raise InsufficientFunds(msg)
        token.approve(netcontract_address, amount)

        channel_proxy = self.raiden.chain.netting_channel(netcontract_address)
        channel_proxy.deposit(amount)

        # Wait until the `ChannelNewBalance` event is processed.
        #
        # Usually a single sleep is sufficient, since the `deposit` waits for
        # the transaction to be polled.
        sucess = wait_until(
            lambda: channel.contract_balance != old_balance,
            poll_timeout,
            self.raiden.alarm.wait_time,
        )

        if not sucess:
            raise EthNodeCommunicationError(
                'After {} seconds the deposit was not properly processed.'.format(
                    poll_timeout
                )
            )

        return channel
예제 #14
0
def run_test_clear_closed_queue(raiden_network, token_addresses, network_wait):
    app0, app1 = raiden_network

    hold_event_handler = app1.raiden.raiden_event_handler

    registry_address = app0.raiden.default_registry.address
    token_address = token_addresses[0]
    chain_state0 = views.state_from_app(app0)
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state0, app0.raiden.default_registry.address, token_address)
    token_network = views.get_token_network_by_identifier(
        chain_state0, token_network_identifier)

    channel_identifier = get_channelstate(app0, app1,
                                          token_network_identifier).identifier

    assert (channel_identifier
            in token_network.partneraddresses_to_channelidentifiers[
                app1.raiden.address])

    target = app1.raiden.address
    secret = sha3(target)
    secrethash = sha3(secret)
    hold_event_handler.hold_secretrequest_for(secrethash=secrethash)

    # make an unconfirmed transfer to ensure the nodes have communicated
    amount = 10
    payment_identifier = 1337
    app0.raiden.start_mediated_transfer_with_secret(
        token_network_identifier=token_network_identifier,
        amount=amount,
        fee=0,
        target=target,
        identifier=payment_identifier,
        payment_hash_invoice=EMPTY_PAYMENT_HASH_INVOICE,
        secret=secret,
    )

    app1.raiden.transport.stop()
    app1.raiden.transport.get()

    # make sure to wait until the queue is created
    def has_initiator_events():
        initiator_events = app0.raiden.wal.storage.get_events()
        return search_for_item(initiator_events, SendLockedTransfer, {})

    assert wait_until(has_initiator_events, network_wait)

    # assert the specific queue is present
    chain_state0 = views.state_from_app(app0)
    queues0 = views.get_all_messagequeues(chain_state=chain_state0)
    assert [(queue_id, queue) for queue_id, queue in queues0.items()
            if queue_id.recipient == app1.raiden.address
            and queue_id.channel_identifier == channel_identifier and queue]

    # A ChannelClose event will be generated, this will be polled by both apps
    RaidenAPI(app0.raiden).channel_close(registry_address, token_address,
                                         app1.raiden.address)

    exception = ValueError("Could not get close event")
    with gevent.Timeout(seconds=30, exception=exception):
        waiting.wait_for_close(
            app0.raiden,
            registry_address,
            token_address,
            [channel_identifier],
            app0.raiden.alarm.sleep_time,
        )

    # assert all queues with this partner are gone or empty
    chain_state0 = views.state_from_app(app0)
    queues0 = views.get_all_messagequeues(chain_state=chain_state0)
    assert not [(queue_id, queue) for queue_id, queue in queues0.items()
                if queue_id.recipient == app1.raiden.address and queue]

    chain_state1 = views.state_from_app(app1)
    queues1 = views.get_all_messagequeues(chain_state=chain_state1)
    assert not [(queue_id, queue) for queue_id, queue in queues1.items()
                if queue_id.recipient == app0.raiden.address and queue]
예제 #15
0
def run_test_echo_node_lottery(token_addresses, raiden_chain, network_wait):
    app0, app1, app2, app3, echo_app, app4, app5, app6 = raiden_chain
    address_to_app = {app.raiden.address: app for app in raiden_chain}
    token_address = token_addresses[0]
    echo_api = RaidenAPI(echo_app.raiden)

    echo_node = EchoNode(echo_api, token_address)
    echo_node.ready.wait(timeout=30)
    assert echo_node.ready.is_set()

    expected = list()

    # Let 6 participants enter the pool
    amount = 7
    for num, app in enumerate([app0, app1, app2, app3, app4, app5]):
        payment_status = RaidenAPI(app.raiden).transfer_async(
            app.raiden.default_registry.address,
            token_address,
            amount,
            echo_app.raiden.address,
            10 ** (num + 1),
        )
        payment_status.payment_done.wait(timeout=20)
        expected.append(amount)

    # test duplicated identifier + amount is ignored
    payment_status = RaidenAPI(app5.raiden).transfer_async(
        app.raiden.default_registry.address,
        token_address,
        amount,  # same amount as before
        echo_app.raiden.address,
        10 ** 6,  # app5 used this identifier before
    ).payment_done.wait(timeout=20)

    # test pool size querying
    pool_query_identifier = 77  # unused identifier different from previous one
    payment_status = RaidenAPI(app5.raiden).transfer_async(
        app.raiden.default_registry.address,
        token_address,
        amount,
        echo_app.raiden.address,
        pool_query_identifier,
    ).payment_done.wait(timeout=20)
    expected.append(amount)

    # fill the pool
    payment_status = RaidenAPI(app6.raiden).transfer_async(
        app.raiden.default_registry.address,
        token_address,
        amount,
        echo_app.raiden.address,
        10 ** 7,
    ).payment_done.wait(timeout=20)
    expected.append(amount)

    while echo_node.num_handled_transfers < len(expected):
        gevent.sleep(.5)

    def get_echoed_transfer(sent_transfer):
        """For a given transfer sent to echo node, get the corresponding echoed transfer"""
        app = address_to_app[sent_transfer.initiator]
        events = RaidenAPI(app.raiden).get_raiden_events_payment_history(
            token_address=token_address,
        )

        def is_valid(event):
            return (
                type(event) == EventPaymentReceivedSuccess and
                event.initiator == echo_app.raiden.address and
                event.identifier == sent_transfer.identifier + event.amount
            )

        received = {
            event.identifier: event
            for event in events
            if is_valid(event)
        }

        if len(received) != 1:
            return None
        return received.popitem()[1]

    def received_is_of_size(size):
        """Return transfers received from echo_node when there's size transfers"""
        received = {}
        # Check that payout was generated and pool_size_query answered
        for handled_transfer in echo_node.seen_transfers:
            event = get_echoed_transfer(handled_transfer)
            if not event:
                continue
            received[event.identifier] = event
        if len(received) == size:
            return received

        return None

    # wait for the expected echoed transfers to be handled
    received = wait_until(lambda: received_is_of_size(2), 2 * network_wait)
    assert received

    received = sorted(received.values(), key=lambda transfer: transfer.amount)

    pool_query = received[0]
    assert pool_query.amount == 6
    assert pool_query.identifier == pool_query_identifier + 6

    winning_transfer = received[1]
    assert winning_transfer.initiator == echo_app.raiden.address
    assert winning_transfer.amount == 49
    assert (winning_transfer.identifier - 49) % 10 == 0

    echo_node.stop()
예제 #16
0
def test_echo_node_lottery(token_addresses, raiden_chain, network_wait):
    app0, app1, app2, app3, echo_app, app4, app5, app6 = raiden_chain
    address_to_app = {app.raiden.address: app for app in raiden_chain}
    token_address = token_addresses[0]
    echo_api = RaidenAPI(echo_app.raiden)

    echo_node = EchoNode(echo_api, token_address)
    echo_node.ready.wait(timeout=30)
    assert echo_node.ready.is_set()

    transfer_timeout = 10

    # Let 6 participants enter the pool
    amount = 7
    for num, app in enumerate([app0, app1, app2, app3, app4, app5]):
        identifier = 100 * num
        with watch_for_unlock_failures(*raiden_chain):
            transfer_and_await(
                app=app,
                token_address=token_address,
                target=echo_app.raiden.address,
                amount=amount,
                identifier=identifier,
                timeout=transfer_timeout,
            )

    # test duplicated identifier + amount is ignored
    with watch_for_unlock_failures(*raiden_chain):
        transfer_and_await(
            app=app5,
            token_address=token_address,
            target=echo_app.raiden.address,
            amount=amount,
            identifier=500,  # app5 used this identifier before
            timeout=transfer_timeout,
        )

    # test pool size querying
    pool_query_identifier = 77  # unused identifier different from previous one
    with watch_for_unlock_failures(*raiden_chain):
        transfer_and_await(
            app=app5,
            token_address=token_address,
            target=echo_app.raiden.address,
            amount=amount,
            identifier=pool_query_identifier,
            timeout=transfer_timeout,
        )

    # fill the pool
    with watch_for_unlock_failures(*raiden_chain):
        transfer_and_await(
            app=app6,
            token_address=token_address,
            target=echo_app.raiden.address,
            amount=amount,
            identifier=600,
            timeout=transfer_timeout,
        )

    def get_echoed_transfer(
            sent_transfer) -> Optional[EventPaymentReceivedSuccess]:
        """For a given transfer sent to echo node, get the corresponding echoed transfer"""
        app = address_to_app[sent_transfer.initiator]
        events = RaidenAPI(app.raiden).get_raiden_events_payment_history(
            token_address=token_address)
        for event in events:
            if not type(event) == EventPaymentReceivedSuccess:
                continue
            assert isinstance(event,
                              EventPaymentReceivedSuccess), MYPY_ANNOTATION
            if not (event.initiator == echo_app.raiden.address
                    and event.identifier
                    == sent_transfer.identifier + event.amount):
                continue

            return event

        return None

    def received_events_when_len(
            size: int) -> Optional[List[EventPaymentReceivedSuccess]]:
        """Return transfers received from echo_node when there's size transfers"""
        received_events = []
        # Check that payout was generated and pool_size_query answered
        for handled_transfer in echo_node.seen_transfers:
            event = get_echoed_transfer(handled_transfer)
            if not event:
                continue

            received_events.append(event)

        log.debug(
            "Checking number of received events",
            received_events=received_events,
            expected_size=size,
            actual_size=len(received_events),
            seen_transfers=echo_node.seen_transfers,
            received_transfers=received_events,
        )
        if len(received_events) == size:
            return received_events

        return None

    # wait for the expected echoed transfers to be handled
    received = wait_until(func=lambda: received_events_when_len(2),
                          wait_for=network_wait)
    assert received

    received.sort(key=lambda transfer: transfer.amount)

    pool_query = received[0]
    assert pool_query.amount == 6
    assert pool_query.identifier == pool_query_identifier + 6

    winning_transfer = received[1]
    assert winning_transfer.initiator == echo_app.raiden.address
    assert winning_transfer.amount == 49
    assert (winning_transfer.identifier - 49) % 10 == 0

    echo_node.stop()
def test_clear_closed_queue(raiden_network, token_addresses, deposit,
                            network_wait):
    """ Closing a channel clears the respective message queue. """
    app0, app1 = raiden_network
    registry_address = app0.raiden.default_registry.address
    token_address = token_addresses[0]
    chain_state0 = views.state_from_app(app0)
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state0,
        app0.raiden.default_registry.address,
        token_address,
    )
    token_network = views.get_token_network_by_identifier(
        chain_state0,
        token_network_identifier,
    )

    channel_identifier = get_channelstate(app0, app1,
                                          token_network_identifier).identifier

    assert channel_identifier in token_network.partneraddresses_to_channelidentifiers[
        app1.raiden.address]

    with dont_handle_secret_request_mock(app0):
        # make an unconfirmed transfer to ensure the nodes have communicated
        amount = 10
        payment_identifier = 1337
        app0.raiden.mediated_transfer_async(
            token_network_identifier=token_network_identifier,
            amount=amount,
            target=app1.raiden.address,
            identifier=payment_identifier,
        )

        app1.raiden.transport.stop()
        app1.raiden.transport.get()

        # make sure to wait until the queue is created
        def has_initiator_events():
            initiator_events = app0.raiden.wal.storage.get_events()
            return must_contain_entry(initiator_events, SendLockedTransfer, {})

        assert wait_until(has_initiator_events, network_wait)

    # assert the specific queue is present
    chain_state0 = views.state_from_app(app0)
    queues0 = views.get_all_messagequeues(chain_state=chain_state0)
    assert [(queue_id, queue) for queue_id, queue in queues0.items()
            if queue_id.recipient == app1.raiden.address
            and queue_id.channel_identifier == channel_identifier and queue]

    # A ChannelClose event will be generated, this will be polled by both apps
    RaidenAPI(app0.raiden).channel_close(
        registry_address,
        token_address,
        app1.raiden.address,
    )

    exception = ValueError('Could not get close event')
    with gevent.Timeout(seconds=30, exception=exception):
        waiting.wait_for_close(
            app0.raiden,
            registry_address,
            token_address,
            [channel_identifier],
            app0.raiden.alarm.sleep_time,
        )

    # assert all queues with this partner are gone or empty
    chain_state0 = views.state_from_app(app0)
    queues0 = views.get_all_messagequeues(chain_state=chain_state0)
    assert not [(queue_id, queue) for queue_id, queue in queues0.items()
                if queue_id.recipient == app1.raiden.address and queue]

    chain_state1 = views.state_from_app(app1)
    queues1 = views.get_all_messagequeues(chain_state=chain_state1)
    assert not [(queue_id, queue) for queue_id, queue in queues1.items()
                if queue_id.recipient == app0.raiden.address and queue]
예제 #18
0
def test_clear_closed_queue(raiden_network, token_addresses, deposit, network_wait):
    """ Closing a channel clears the respective message queue. """
    app0, app1 = raiden_network
    registry_address = app0.raiden.default_registry.address
    token_address = token_addresses[0]
    chain_state0 = views.state_from_app(app0)
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        chain_state0,
        app0.raiden.default_registry.address,
        token_address,
    )
    token_network = views.get_token_network_by_identifier(
        chain_state0,
        token_network_identifier,
    )

    channel_identifier = get_channelstate(app0, app1, token_network_identifier).identifier

    assert channel_identifier in token_network.partneraddresses_to_channelidentifiers[
        app1.raiden.address
    ]

    with dont_handle_secret_request_mock(app0):
        # make an unconfirmed transfer to ensure the nodes have communicated
        amount = 10
        payment_identifier = 1337
        app0.raiden.mediated_transfer_async(
            token_network_identifier=token_network_identifier,
            amount=amount,
            target=app1.raiden.address,
            identifier=payment_identifier,
        )

        app1.raiden.transport.stop()
        app1.raiden.transport.get()

        # make sure to wait until the queue is created
        def has_initiator_events():
            initiator_events = app0.raiden.wal.storage.get_events()
            return must_contain_entry(initiator_events, SendLockedTransfer, {})

        assert wait_until(has_initiator_events, network_wait)

    # assert the specific queue is present
    chain_state0 = views.state_from_app(app0)
    queues0 = views.get_all_messagequeues(chain_state=chain_state0)
    assert [
        (queue_id, queue)
        for queue_id, queue in queues0.items()
        if queue_id.recipient == app1.raiden.address and
        queue_id.channel_identifier == channel_identifier and queue
    ]

    # A ChannelClose event will be generated, this will be polled by both apps
    RaidenAPI(app0.raiden).channel_close(
        registry_address,
        token_address,
        app1.raiden.address,
    )

    exception = ValueError('Could not get close event')
    with gevent.Timeout(seconds=30, exception=exception):
        waiting.wait_for_close(
            app0.raiden,
            registry_address,
            token_address,
            [channel_identifier],
            app0.raiden.alarm.sleep_time,
        )

    # assert all queues with this partner are gone or empty
    chain_state0 = views.state_from_app(app0)
    queues0 = views.get_all_messagequeues(chain_state=chain_state0)
    assert not [
        (queue_id, queue)
        for queue_id, queue in queues0.items()
        if queue_id.recipient == app1.raiden.address and queue
    ]

    chain_state1 = views.state_from_app(app1)
    queues1 = views.get_all_messagequeues(chain_state=chain_state1)
    assert not [
        (queue_id, queue)
        for queue_id, queue in queues1.items()
        if queue_id.recipient == app0.raiden.address and queue
    ]
def test_clear_closed_queue(raiden_network: List[App], token_addresses,
                            network_wait):
    """ Closing a channel clears the respective message queue. """
    app0, app1 = raiden_network

    hold_event_handler = app1.raiden.raiden_event_handler
    assert isinstance(hold_event_handler, HoldRaidenEventHandler)

    registry_address = app0.raiden.default_registry.address
    token_address = token_addresses[0]
    chain_state0 = views.state_from_app(app0)
    token_network_address = views.get_token_network_address_by_token_address(
        chain_state0, app0.raiden.default_registry.address, token_address)
    assert token_network_address
    token_network = views.get_token_network_by_address(chain_state0,
                                                       token_network_address)
    assert token_network

    channel_identifier = get_channelstate(app0, app1,
                                          token_network_address).identifier

    assert (channel_identifier
            in token_network.partneraddresses_to_channelidentifiers[
                app1.raiden.address])

    target = app1.raiden.address
    secret = Secret(sha3(target))
    secrethash = sha256_secrethash(secret)
    hold_event_handler.hold_secretrequest_for(secrethash=secrethash)

    # make an unconfirmed transfer to ensure the nodes have communicated
    amount = PaymentAmount(10)
    payment_identifier = PaymentID(1337)
    app0.raiden.start_mediated_transfer_with_secret(
        token_network_address=token_network_address,
        amount=amount,
        target=TargetAddress(target),
        identifier=payment_identifier,
        secret=secret,
    )

    app1.raiden.transport.stop()
    app1.raiden.transport.greenlet.get()

    # make sure to wait until the queue is created
    def has_initiator_events():
        assert app0.raiden.wal, "raiden server must have been started"
        initiator_events = app0.raiden.wal.storage.get_events()
        return search_for_item(initiator_events, SendLockedTransfer, {})

    assert wait_until(has_initiator_events, network_wait)

    # assert the specific queue is present
    chain_state0 = views.state_from_app(app0)
    queues0 = views.get_all_messagequeues(chain_state=chain_state0)
    assert [
        (queue_id, queue) for queue_id, queue in queues0.items()
        if queue_id.recipient == app1.raiden.address and queue_id.
        canonical_identifier.channel_identifier == channel_identifier and queue
    ]

    # A ChannelClose event will be generated, this will be polled by both apps
    RaidenAPI(app0.raiden).channel_close(registry_address, token_address,
                                         app1.raiden.address)

    exception = ValueError("Could not get close event")
    with gevent.Timeout(seconds=30, exception=exception):
        waiting.wait_for_close(
            app0.raiden,
            registry_address,
            token_address,
            [channel_identifier],
            app0.raiden.alarm.sleep_time,
        )

    # assert all queues with this partner are gone or empty
    chain_state0 = views.state_from_app(app0)
    queues0 = views.get_all_messagequeues(chain_state=chain_state0)
    assert not [(queue_id, queue) for queue_id, queue in queues0.items()
                if queue_id.recipient == app1.raiden.address and queue]

    chain_state1 = views.state_from_app(app1)
    queues1 = views.get_all_messagequeues(chain_state=chain_state1)
    assert not [(queue_id, queue) for queue_id, queue in queues1.items()
                if queue_id.recipient == app0.raiden.address and queue]
예제 #20
0
def test_echo_node_lottery(token_addresses, raiden_chain, network_wait):
    app0, app1, app2, app3, echo_app, app4, app5, app6 = raiden_chain
    address_to_app = {app.raiden.address: app for app in raiden_chain}
    token_address = token_addresses[0]
    echo_api = RaidenAPI(echo_app.raiden)

    echo_node = EchoNode(echo_api, token_address)
    echo_node.ready.wait(timeout=30)
    assert echo_node.ready.is_set()

    expected = list()

    # Let 6 participants enter the pool
    amount = 7
    for num, app in enumerate([app0, app1, app2, app3, app4, app5]):
        transfer_event = RaidenAPI(app.raiden).transfer_async(
            app.raiden.default_registry.address,
            token_address,
            amount,
            echo_app.raiden.address,
            10 ** (num + 1),
        )
        transfer_event.wait(timeout=20)
        expected.append(amount)

    # test duplicated identifier + amount is ignored
    transfer_event = RaidenAPI(app5.raiden).transfer_async(
        app.raiden.default_registry.address,
        token_address,
        amount,  # same amount as before
        echo_app.raiden.address,
        10 ** 6,  # app5 used this identifier before
    ).wait(timeout=20)

    # test pool size querying
    pool_query_identifier = 77  # unused identifier different from previous one
    transfer_event = RaidenAPI(app5.raiden).transfer_async(
        app.raiden.default_registry.address,
        token_address,
        amount,
        echo_app.raiden.address,
        pool_query_identifier,
    ).wait(timeout=20)
    expected.append(amount)

    # fill the pool
    transfer_event = RaidenAPI(app6.raiden).transfer_async(
        app.raiden.default_registry.address,
        token_address,
        amount,
        echo_app.raiden.address,
        10 ** 7,
    ).wait(timeout=20)
    expected.append(amount)

    while echo_node.num_handled_transfers < len(expected):
        gevent.sleep(.5)

    def get_echoed_transfer(sent_transfer):
        """For a given transfer sent to echo node, get the corresponding echoed transfer"""
        app = address_to_app[sent_transfer.initiator]
        events = RaidenAPI(app.raiden).get_raiden_events_payment_history(
            token_address=token_address,
        )

        def is_valid(event):
            return (
                type(event) == EventPaymentReceivedSuccess and
                event.initiator == echo_app.raiden.address and
                event.identifier == sent_transfer.identifier + event.amount
            )

        received = {
            event.identifier: event
            for event in events
            if is_valid(event)
        }

        if len(received) != 1:
            return
        return received.popitem()[1]

    def received_is_of_size(size):
        """Return transfers received from echo_node when there's size transfers"""
        received = {}
        # Check that payout was generated and pool_size_query answered
        for handled_transfer in echo_node.seen_transfers:
            event = get_echoed_transfer(handled_transfer)
            if not event:
                continue
            received[event.identifier] = event
        if len(received) == size:
            return received

    # wait for the expected echoed transfers to be handled
    received = wait_until(lambda: received_is_of_size(2), 2 * network_wait)
    assert received

    received = sorted(received.values(), key=lambda transfer: transfer.amount)

    pool_query = received[0]
    assert pool_query.amount == 6
    assert pool_query.identifier == pool_query_identifier + 6

    winning_transfer = received[1]
    assert winning_transfer.initiator == echo_app.raiden.address
    assert winning_transfer.amount == 49
    assert (winning_transfer.identifier - 49) % 10 == 0

    echo_node.stop()