예제 #1
0
def message_from_sendevent(send_event: SendMessageEvent) -> Message:
    if type(send_event) == SendLockedTransfer:
        assert isinstance(send_event, SendLockedTransfer), MYPY_ANNOTATION
        return LockedTransfer.from_event(send_event)
    elif type(send_event) == SendSecretReveal:
        assert isinstance(send_event, SendSecretReveal), MYPY_ANNOTATION
        return RevealSecret.from_event(send_event)
    elif type(send_event) == SendBalanceProof:
        assert isinstance(send_event, SendBalanceProof), MYPY_ANNOTATION
        return Unlock.from_event(send_event)
    elif type(send_event) == SendSecretRequest:
        assert isinstance(send_event, SendSecretRequest), MYPY_ANNOTATION
        return SecretRequest.from_event(send_event)
    elif type(send_event) == SendRefundTransfer:
        assert isinstance(send_event, SendRefundTransfer), MYPY_ANNOTATION
        return RefundTransfer.from_event(send_event)
    elif type(send_event) == SendLockExpired:
        assert isinstance(send_event, SendLockExpired), MYPY_ANNOTATION
        return LockExpired.from_event(send_event)
    elif type(send_event) == SendWithdrawRequest:
        return WithdrawRequest.from_event(send_event)
    elif type(send_event) == SendWithdrawConfirmation:
        return WithdrawConfirmation.from_event(send_event)
    elif type(send_event) == SendWithdrawExpired:
        return WithdrawExpired.from_event(send_event)
    elif type(send_event) == SendProcessed:
        assert isinstance(send_event, SendProcessed), MYPY_ANNOTATION
        return Processed.from_event(send_event)
    else:
        raise ValueError(f"Unknown event type {send_event}")
예제 #2
0
def test_regression_multiple_revealsecret(
        raiden_network: List[App],
        token_addresses: List[TokenAddress]) -> None:
    """ Multiple RevealSecret messages arriving at the same time must be
    handled properly.

    Unlock handling followed these steps:

        The Unlock message arrives
        The secret is registered
        The channel is updated and the correspoding lock is removed
        * A balance proof for the new channel state is created and sent to the
          payer
        The channel is unregistered for the given secrethash

    The step marked with an asterisk above introduced a context-switch. This
    allowed a second Reveal Unlock message to be handled before the channel was
    unregistered. And because the channel was already updated an exception was raised
    for an unknown secret.
    """
    app0, app1 = raiden_network
    token = token_addresses[0]
    token_network_address = views.get_token_network_address_by_token_address(
        views.state_from_app(app0), app0.raiden.default_registry.address,
        token)
    assert token_network_address
    channelstate_0_1 = get_channelstate(app0, app1, token_network_address)

    payment_identifier = PaymentID(1)
    secret, secrethash = make_secret_with_hash()
    expiration = BlockExpiration(app0.raiden.get_block_number() + 100)
    lock_amount = PaymentWithFeeAmount(10)
    lock = Lock(amount=lock_amount,
                expiration=expiration,
                secrethash=secrethash)

    nonce = Nonce(1)
    transferred_amount = TokenAmount(0)
    mediated_transfer = LockedTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=make_message_identifier(),
        payment_identifier=payment_identifier,
        nonce=nonce,
        token_network_address=token_network_address,
        token=token,
        channel_identifier=channelstate_0_1.identifier,
        transferred_amount=transferred_amount,
        locked_amount=LockedAmount(lock_amount),
        recipient=app1.raiden.address,
        locksroot=Locksroot(lock.lockhash),
        lock=lock,
        target=TargetAddress(app1.raiden.address),
        initiator=InitiatorAddress(app0.raiden.address),
        signature=EMPTY_SIGNATURE,
        metadata=Metadata(routes=[
            RouteMetadata(route=[app0.raiden.address, app1.raiden.address])
        ]),
    )
    app0.raiden.sign(mediated_transfer)
    app1.raiden.on_messages([mediated_transfer])

    reveal_secret = RevealSecret(message_identifier=make_message_identifier(),
                                 secret=secret,
                                 signature=EMPTY_SIGNATURE)
    app0.raiden.sign(reveal_secret)

    token_network_address = channelstate_0_1.token_network_address
    unlock = Unlock(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=make_message_identifier(),
        payment_identifier=payment_identifier,
        nonce=Nonce(mediated_transfer.nonce + 1),
        token_network_address=token_network_address,
        channel_identifier=channelstate_0_1.identifier,
        transferred_amount=TokenAmount(lock_amount),
        locked_amount=LockedAmount(0),
        locksroot=LOCKSROOT_OF_NO_LOCKS,
        secret=secret,
        signature=EMPTY_SIGNATURE,
    )
    app0.raiden.sign(unlock)

    messages = [unlock, reveal_secret]
    receive_method = app1.raiden.on_messages
    wait = set(
        gevent.spawn_later(0.1, receive_method, [data]) for data in messages)

    gevent.joinall(wait, raise_error=True)
예제 #3
0
def test_receive_secrethashtransfer_unknown(
        raiden_network: List[RaidenService], token_addresses):
    app0 = raiden_network[0]
    token_address = token_addresses[0]

    token_network_address = views.get_token_network_address_by_token_address(
        views.state_from_raiden(app0), app0.default_registry.address,
        token_address)
    assert token_network_address

    other_key = HOP1_KEY
    other_signer = LocalSigner(other_key)
    canonical_identifier = factories.make_canonical_identifier(
        token_network_address=token_network_address)

    amount = TokenAmount(10)
    locksroot = Locksroot(make_32bytes())
    refund_transfer_message = factories.create(
        factories.RefundTransferProperties(
            payment_identifier=PaymentID(1),
            nonce=Nonce(1),
            token=token_address,
            canonical_identifier=canonical_identifier,
            transferred_amount=amount,
            recipient=TargetAddress(app0.address),
            locksroot=locksroot,
            amount=amount,
            secret=UNIT_SECRET,
        ))
    sign_and_inject(refund_transfer_message, other_signer, app0)

    unlock = Unlock(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=make_message_identifier(),
        payment_identifier=PaymentID(1),
        nonce=Nonce(1),
        channel_identifier=canonical_identifier.channel_identifier,
        token_network_address=token_network_address,
        transferred_amount=amount,
        locked_amount=LockedAmount(0),
        locksroot=locksroot,
        secret=UNIT_SECRET,
        signature=EMPTY_SIGNATURE,
    )
    sign_and_inject(unlock, other_signer, app0)

    secret_request_message = SecretRequest(
        message_identifier=make_message_identifier(),
        payment_identifier=PaymentID(1),
        secrethash=UNIT_SECRETHASH,
        amount=PaymentAmount(1),
        expiration=refund_transfer_message.lock.expiration,
        signature=EMPTY_SIGNATURE,
    )
    sign_and_inject(secret_request_message, other_signer, app0)

    reveal_secret_message = RevealSecret(
        message_identifier=make_message_identifier(),
        secret=UNIT_SECRET,
        signature=EMPTY_SIGNATURE)
    sign_and_inject(reveal_secret_message, other_signer, app0)
def test_pfs_send_unique_capacity_and_fee_updates_during_mediated_transfer(
        raiden_network):
    """
    Tests that PFSCapacityUpdates and PFSFeeUpdates are being
    sent only once with the most recent state change in a batch.
    """
    app0, app1 = raiden_network
    chain_state = views.state_from_app(app0)

    # There have been two PFSCapacityUpdates and two PFSFeeUpdates per channel per node
    assert len(get_messages(app0)) == 4
    # The mediator has two channels
    assert len(get_messages(app1)) == 4

    # Now we create two state_changes (Deposit) regarding the same channel
    # and trigger handle_state_changes() of node0. The expected outcome
    # is that only 1 PFSCapacityUpdate and 1 PFSFeeUpdate is being sent
    # not one per state change
    pfs_fee_update_1_of_app0 = get_messages(app0)[1]
    assert isinstance(pfs_fee_update_1_of_app0, PFSFeeUpdate)
    pfs_capacity_update_2_of_app0 = get_messages(app0)[2]
    assert isinstance(pfs_capacity_update_2_of_app0, PFSCapacityUpdate)
    canonical_identifier = pfs_fee_update_1_of_app0.canonical_identifier
    new_total_deposit_1 = pfs_capacity_update_2_of_app0.other_capacity * 2

    deposit_transaction_1 = TransactionChannelDeposit(
        app1.raiden.address, TokenAmount(new_total_deposit_1),
        chain_state.block_number)
    channel_deposit_1 = ContractReceiveChannelDeposit(
        transaction_hash=make_transaction_hash(),
        canonical_identifier=canonical_identifier,
        deposit_transaction=deposit_transaction_1,
        block_number=chain_state.block_number,
        block_hash=chain_state.block_hash,
        fee_config=MediationFeeConfig(),
    )

    new_total_deposit_2 = new_total_deposit_1 * 2
    deposit_transaction_2 = TransactionChannelDeposit(
        app1.raiden.address, TokenAmount(new_total_deposit_2),
        chain_state.block_number)

    channel_deposit_2 = ContractReceiveChannelDeposit(
        transaction_hash=make_transaction_hash(),
        canonical_identifier=canonical_identifier,
        deposit_transaction=deposit_transaction_2,
        block_number=chain_state.block_number,
        block_hash=chain_state.block_hash,
        fee_config=MediationFeeConfig(),
    )

    state_changes = [channel_deposit_1, channel_deposit_2]

    app0.raiden.handle_state_changes(state_changes=state_changes)

    # Now we should see that app0 send 2 new messages,
    # one PFSCapacityUpdate and one PFSFeeUpdate with
    # the updated amount of the initial amount * 4
    # so sending should only be triggered by the second state change

    pfs_capacity_update_3_of_app0 = get_messages(app0)[4]
    assert isinstance(pfs_capacity_update_3_of_app0, PFSCapacityUpdate)
    assert len(get_messages(app0)) == 6
    assert (pfs_capacity_update_3_of_app0.other_capacity ==
            pfs_capacity_update_2_of_app0.updating_capacity * 4)

    # Now we want to test if this also works with a state_change
    # that triggers only a PFSCapacityUpdate and no PFSFeeUpdate.
    # So at the end we expect 1 more PFSCapacityUpdate in the room.

    lock_secret_1 = keccak(b"test_end_state")
    unlock_message_1 = Unlock(
        chain_id=chain_state.chain_id,
        message_identifier=MessageID(123132),
        payment_identifier=PaymentID(1),
        nonce=Nonce(2),
        token_network_address=canonical_identifier.token_network_address,
        channel_identifier=canonical_identifier.channel_identifier,
        transferred_amount=TokenAmount(400),
        locked_amount=LockedAmount(0),
        locksroot=Locksroot(keccak(b"")),
        secret=Secret(lock_secret_1),
        signature=Signature(bytes(65)),
    )
    unlock_message_1.sign(app1.raiden.signer)
    balance_proof_1 = balanceproof_from_envelope(unlock_message_1)

    unlock_1 = ReceiveUnlock(
        message_identifier=MessageID(5135),
        secret=Secret(lock_secret_1),
        balance_proof=balance_proof_1,
        sender=balance_proof_1.sender,
    )

    lock_secret_2 = keccak(b"test_end_state_again")

    unlock_message_2 = Unlock(
        chain_id=chain_state.chain_id,
        message_identifier=MessageID(223132),
        payment_identifier=PaymentID(2),
        nonce=Nonce(2),
        token_network_address=canonical_identifier.token_network_address,
        channel_identifier=canonical_identifier.channel_identifier,
        transferred_amount=TokenAmount(500),
        locked_amount=LockedAmount(0),
        locksroot=Locksroot(keccak(b"")),
        secret=Secret(lock_secret_2),
        signature=Signature(bytes(65)),
    )

    unlock_message_2.sign(app1.raiden.signer)

    balance_proof_2 = balanceproof_from_envelope(unlock_message_2)

    unlock_2 = ReceiveUnlock(
        message_identifier=MessageID(5135),
        secret=Secret(lock_secret_2),
        balance_proof=balance_proof_2,
        sender=balance_proof_2.sender,
    )

    state_changes_2 = [unlock_1, unlock_2]

    app0.raiden.handle_state_changes(state_changes=state_changes_2)

    assert len(get_messages(app0)) == 7
    assert len([
        x for x in get_messages(app0) if isinstance(x, PFSCapacityUpdate)
    ]) == 4