Пример #1
0
def test_event_operators():
    a = EventTransferSentSuccess(2)
    b = EventTransferSentSuccess(2)
    c = EventTransferSentSuccess(3)

    assert a == b
    assert not a != b
    assert a != c
    assert not a == c

    a = EventTransferSentFailed(2, 'BECAUSE')
    b = EventTransferSentFailed(2, 'BECAUSE')
    c = EventTransferSentFailed(3, 'UNKNOWN')

    assert a == b
    assert not a != b
    assert a != c
    assert not a == c

    a = EventTransferReceivedSuccess(2, 5, sha3('initiator'))
    b = EventTransferReceivedSuccess(2, 5, sha3('initiator'))
    c = EventTransferReceivedSuccess(3, 5, sha3('initiator'))
    d = EventTransferReceivedSuccess(3, 5, sha3('other initiator'))

    assert a == b
    assert not a != b
    assert a != c
    assert not a == c
    assert c != d
    assert not c == d
Пример #2
0
def test_event_operators():
    a = EventTransferSentSuccess(2)
    b = EventTransferSentSuccess(2)
    c = EventTransferSentSuccess(3)

    assert a == b
    assert not a != b
    assert a != c
    assert not a == c

    a = EventTransferSentFailed(2, 'BECAUSE')
    b = EventTransferSentFailed(2, 'BECAUSE')
    c = EventTransferSentFailed(3, 'UNKNOWN')

    assert a == b
    assert not a != b
    assert a != c
    assert not a == c

    a = EventTransferReceivedSuccess(2)
    b = EventTransferReceivedSuccess(2)
    c = EventTransferReceivedSuccess(3)

    assert a == b
    assert not a != b
    assert a != c
    assert not a == c
Пример #3
0
def test_event_operators():
    a = EventTransferSentSuccess(2, 5, sha3(b'target'))
    b = EventTransferSentSuccess(2, 5, sha3(b'target'))
    c = EventTransferSentSuccess(3, 4, sha3(b'target'))
    d = EventTransferSentSuccess(3, 4, sha3(b'differenttarget'))

    # pylint: disable=unneeded-not
    assert a == b
    assert not a != b
    assert a != c
    assert not a == c
    assert not c == d

    a = EventTransferSentFailed(2, 'BECAUSE')
    b = EventTransferSentFailed(2, 'BECAUSE')
    c = EventTransferSentFailed(3, 'UNKNOWN')

    assert a == b
    assert not a != b
    assert a != c
    assert not a == c

    a = EventTransferReceivedSuccess(2, 5, sha3(b'initiator'))
    b = EventTransferReceivedSuccess(2, 5, sha3(b'initiator'))
    c = EventTransferReceivedSuccess(3, 5, sha3(b'initiator'))
    d = EventTransferReceivedSuccess(3, 5, sha3(b'other initiator'))

    assert a == b
    assert not a != b
    assert a != c
    assert not a == c
    assert c != d
    assert not c == d
Пример #4
0
def handle_secretreveal(state, state_change):
    """ Send a balance proof to the next hop with the current mediated transfer
    lock removed and the balance updated.
    """
    if state_change.sender == state.route.node_address:
        # next hop learned the secret, unlock the token locally and send the
        # withdraw message to next hop
        transfer = state.transfer
        unlock_lock = SendBalanceProof(
            transfer.identifier,
            state.route.channel_address,
            transfer.token,
            state.route.node_address,
            transfer.secret,
        )

        transfer_success = EventTransferSentSuccess(
            transfer.identifier,
            transfer.amount,
            transfer.target,
        )

        unlock_success = EventUnlockSuccess(
            transfer.identifier,
            transfer.hashlock,
        )

        iteration = TransitionResult(None, [unlock_lock, transfer_success, unlock_success])
    else:
        iteration = TransitionResult(state, list())

    return iteration
def test_initiator_log_directransfer_success(
        raiden_chain,
        token_addresses,
        deposit):

    token_address = token_addresses[0]
    amount = int(deposit / 2.)
    identifier = 7

    app0, app1 = raiden_chain  # pylint: disable=unbalanced-tuple-unpacking
    direct_transfer(
        app0,
        app1,
        token_address,
        amount,
        identifier,
    )

    app0_events = get_all_state_events(app0.raiden.transaction_log)
    sucessful_transfers = [
        event.event_object for event in app0_events
        if isinstance(event.event_object, EventTransferSentSuccess)
    ]
    assert sucessful_transfers[0] == EventTransferSentSuccess(
        identifier,
    )
Пример #6
0
def handle_processed(
    chain_state: ChainState,
    state_change: ReceiveProcessed,
) -> TransitionResult:
    # TODO: improve the complexity of this algorithm
    events = list()
    for queue in chain_state.queueids_to_queues.values():
        remove = []

        # TODO: ensure Processed message came from the correct peer
        for pos, message in enumerate(queue):
            if message.message_identifier == state_change.message_identifier:
                if type(message) == SendDirectTransfer:
                    events.append(
                        EventTransferSentSuccess(
                            message.payment_identifier,
                            message.balance_proof.transferred_amount,
                            message.recipient,
                        ))
                remove.append(pos)

        for removepos in reversed(remove):
            queue.pop(removepos)

    return TransitionResult(chain_state, events)
Пример #7
0
def handle_secretreveal(
    initiator_state: InitiatorTransferState,
    state_change: ReceiveSecretReveal,
    channel_state: NettingChannelState,
    pseudo_random_generator: random.Random,
) -> TransitionResult:
    """ Send a balance proof to the next hop with the current mediated transfer
    lock removed and the balance updated.
    """
    is_valid_secret_reveal = (
        state_change.sender == channel_state.partner_state.address
        and state_change.secrethash
        == initiator_state.transfer_description.secrethash)

    # If the channel is closed the balance proof must not be sent
    is_channel_open = channel.get_status(channel_state) == CHANNEL_STATE_OPENED

    if is_valid_secret_reveal and is_channel_open:
        # next hop learned the secret, unlock the token locally and send the
        # withdraw message to next hop
        transfer_description = initiator_state.transfer_description

        message_identifier = message_identifier_from_prng(
            pseudo_random_generator)
        unlock_lock = channel.send_unlock(
            channel_state,
            transfer_description.payment_identifier,
            message_identifier,
            state_change.secret,
            state_change.secrethash,
        )

        # TODO: Emit these events after on-chain withdraw
        transfer_success = EventTransferSentSuccess(
            transfer_description.payment_identifier,
            transfer_description.amount,
            transfer_description.target,
        )

        unlock_success = EventUnlockSuccess(
            transfer_description.payment_identifier,
            transfer_description.secrethash,
        )

        iteration = TransitionResult(
            None, [transfer_success, unlock_success, unlock_lock])
    else:
        iteration = TransitionResult(initiator_state, list())

    return iteration
Пример #8
0
def handle_secretreveal2(initiator_state, state_change, channel_state):
    """ Send a balance proof to the next hop with the current mediated transfer
    lock removed and the balance updated.
    """
    is_valid_secret_reveal = (state_change.sender
                              == channel_state.partner_state.address
                              and state_change.hashlock
                              == initiator_state.transfer_description.hashlock)

    # If the channel is closed the balance proof must not be sent
    is_channel_open = channel.get_status(channel_state) == CHANNEL_STATE_OPENED

    if is_valid_secret_reveal and is_channel_open:
        # next hop learned the secret, unlock the token locally and send the
        # withdraw message to next hop
        transfer_description = initiator_state.transfer_description

        unlock_lock = channel.send_unlock(
            channel_state,
            transfer_description.identifier,
            state_change.secret,
            state_change.hashlock,
        )

        # TODO: Emit these events after on-chain withdraw
        transfer_success = EventTransferSentSuccess(
            transfer_description.identifier,
            transfer_description.amount,
            transfer_description.target,
        )

        unlock_success = EventUnlockSuccess(
            transfer_description.identifier,
            transfer_description.hashlock,
        )

        iteration = TransitionResult(
            None, [transfer_success, unlock_success, unlock_lock])
    else:
        iteration = TransitionResult(initiator_state, list())

    return iteration
Пример #9
0
    def direct_transfer_async(self, token_address, amount, target, identifier):
        """ Do a direct tranfer with target.

        Direct transfers are non cancellable and non expirable, since these
        transfers are a signed balance proof with the transferred amount
        incremented.

        Because the transfer is non cancellable, there is a level of trust with
        the target. After the message is sent the target is effectively paid
        and then it is not possible to revert.

        The async result will be set to False iff there is no direct channel
        with the target or the payer does not have balance to complete the
        transfer, otherwise because the transfer is non expirable the async
        result *will never be set to False* and if the message is sent it will
        hang until the target node acknowledge the message.

        This transfer should be used as an optimization, since only two packets
        are required to complete the transfer (from the payer's perspective),
        whereas the mediated transfer requires 6 messages.
        """
        graph = self.token_to_channelgraph[token_address]
        direct_channel = graph.partneraddress_to_channel.get(target)

        direct_channel_with_capacity = (direct_channel
                                        and direct_channel.can_transfer and
                                        amount <= direct_channel.distributable)

        if direct_channel_with_capacity:
            direct_transfer = direct_channel.create_directtransfer(
                amount, identifier)
            self.sign(direct_transfer)
            direct_channel.register_transfer(
                self.get_block_number(),
                direct_transfer,
            )

            direct_transfer_state_change = ActionTransferDirect(
                identifier,
                amount,
                token_address,
                direct_channel.partner_state.address,
            )
            # TODO: add the transfer sent event
            state_change_id = self.transaction_log.log(
                direct_transfer_state_change)

            # TODO: This should be set once the direct transfer is acknowledged
            transfer_success = EventTransferSentSuccess(
                identifier,
                amount,
                target,
            )
            self.transaction_log.log_events(state_change_id,
                                            [transfer_success],
                                            self.get_block_number())

            async_result = self.protocol.send_async(
                direct_channel.partner_state.address,
                direct_transfer,
            )

        else:
            async_result = AsyncResult()
            async_result.set(False)

        return async_result
Пример #10
0
    def _direct_or_mediated_transfer(self, token_address, amount, identifier, direct_channel):
        """ Check the direct channel and if possible use it, otherwise start a
        mediated transfer.
        """

        if not direct_channel.can_transfer:
            log.info(
                'DIRECT CHANNEL %s > %s is closed or has no funding',
                pex(direct_channel.our_state.address),
                pex(direct_channel.partner_state.address),
            )

            async_result = self._mediated_transfer(
                token_address,
                amount,
                identifier,
                direct_channel.partner_state.address,
            )

        elif amount > direct_channel.distributable:
            log.info(
                'DIRECT CHANNEL %s > %s doesnt have enough funds [%s]',
                pex(direct_channel.our_state.address),
                pex(direct_channel.partner_state.address),
                amount,
            )

            async_result = self._mediated_transfer(
                token_address,
                amount,
                identifier,
                direct_channel.partner_state.address,
            )

        else:
            direct_transfer = direct_channel.create_directtransfer(amount, identifier)
            self.sign(direct_transfer)
            direct_channel.register_transfer(
                self.get_block_number(),
                direct_transfer,
            )

            direct_transfer_state_change = ActionTransferDirect(
                identifier,
                amount,
                token_address,
                direct_channel.partner_state.address,
            )
            # TODO: add the transfer sent event
            state_change_id = self.transaction_log.log(direct_transfer_state_change)

            # TODO: This should be set once the direct transfer is acknowledged
            transfer_success = EventTransferSentSuccess(
                identifier,
            )
            self.transaction_log.log_events(
                state_change_id,
                [transfer_success],
                self.get_block_number()
            )

            async_result = self.protocol.send_async(
                direct_channel.partner_state.address,
                direct_transfer,
            )

        return async_result