Esempio n. 1
0
def test_regression_revealsecret_after_secret(raiden_network, token_addresses):
    """ A RevealSecret message received after a Secret message must be cleanly
    handled.
    """
    app0, app1, app2 = raiden_network
    token = token_addresses[0]

    identifier = 1
    transfer = app0.raiden.mediated_transfer_async(
        token_address=token,
        amount=1,
        target=app2.raiden.address,
        identifier=identifier,
    )
    assert transfer.wait()

    event = None
    for _, event in app1.raiden.wal.storage.get_events_by_block(0, 'latest'):
        if isinstance(event, SendRevealSecret):
            break
    assert event

    message_identifier = random.randint(0, UINT64_MAX)
    reveal_secret = RevealSecret(
        message_identifier,
        event.secret,
    )
    app2.raiden.sign(reveal_secret)

    reveal_data = reveal_secret.encode()
    app1.raiden.protocol.receive(reveal_data)
Esempio n. 2
0
def run_test_regression_revealsecret_after_secret(raiden_network,
                                                  token_addresses,
                                                  transport_protocol):
    app0, app1, app2 = raiden_network
    token = token_addresses[0]

    identifier = 1
    payment_network_identifier = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0), payment_network_identifier, token)
    payment_status = app0.raiden.mediated_transfer_async(
        token_network_identifier,
        amount=1,
        target=app2.raiden.address,
        identifier=identifier)
    assert payment_status.payment_done.wait()

    event = search_for_item(app1.raiden.wal.storage.get_events(),
                            SendSecretReveal, {})
    assert event

    message_identifier = random.randint(0, UINT64_MAX)
    reveal_secret = RevealSecret(message_identifier=message_identifier,
                                 secret=event.secret)
    app2.raiden.sign(reveal_secret)

    if transport_protocol is TransportProtocol.UDP:
        reveal_data = reveal_secret.encode()
        host_port = None
        app1.raiden.transport.receive(reveal_data, host_port)
    elif transport_protocol is TransportProtocol.MATRIX:
        app1.raiden.transport._receive_message(reveal_secret)  # pylint: disable=protected-access
    else:
        raise TypeError("Unknown TransportProtocol")
def test_regression_revealsecret_after_secret(raiden_network, token_addresses):
    """ A RevealSecret message received after a Secret message must be cleanly
    handled.
    """
    app0, app1, app2 = raiden_network
    token = token_addresses[0]

    identifier = 1
    transfer = app0.raiden.mediated_transfer_async(
        token_address=token,
        amount=1,
        target=app2.raiden.address,
        identifier=identifier,
    )
    assert transfer.wait()

    all_logs = app1.raiden.transaction_log.get_events_in_block_range(
        0,
        app1.raiden.get_block_number(),
    )

    secret = None
    for log in all_logs:
        event = log.event_object
        if isinstance(event, SendRevealSecret):
            secret = event.secret
            break
    assert secret

    reveal_secret = RevealSecret(secret)
    app2.raiden.sign(reveal_secret)

    reveal_data = reveal_secret.encode()
    app1.raiden.protocol.receive(reveal_data)
Esempio n. 4
0
def test_regression_revealsecret_after_secret(raiden_network, token_addresses):
    """ A RevealSecret message received after a Secret message must be cleanly
    handled.
    """
    app0, app1, app2 = raiden_network
    token = token_addresses[0]

    identifier = 1
    transfer = app0.raiden.mediated_transfer_async(
        token_address=token,
        amount=1,
        target=app2.raiden.address,
        identifier=identifier,
    )
    assert transfer.wait()

    all_logs = app1.raiden.transaction_log.get_events_in_block_range(
        0,
        app1.raiden.get_block_number(),
    )

    secret = None
    for log in all_logs:
        event = log.event_object
        if isinstance(event, SendRevealSecret):
            secret = event.secret
            break
    assert secret

    reveal_secret = RevealSecret(secret)
    app2.raiden.sign(reveal_secret)

    reveal_data = reveal_secret.encode()
    app1.raiden.protocol.receive(reveal_data)
def test_reveal_secret_7():
    print("Secret {} ".format(secret.hex()))
    print("SecretHash {} ".format(secrethash.hex()))
    message = RevealSecret(message_identifier=MessageID(2226977946511089099),
                           secret=secret)
    message.sign(signer)
    data_was_signed = message._data_to_sign()
    print("Reveal Secret signature: " + message.signature.hex())
    assert recover(data_was_signed, message.signature) == to_canonical_address(
        "0x7ca28d3d760b4aa2b79e8d42cbdc187c7df9af40")
def test_reveal_secret_9():
    message = RevealSecret(
        message_identifier=MessageID(10945162236180065780),
        secret=Secret(
            decode_hex(
                "0xb8ed582d16853c82a9a9a384118fcd10889ab0a5a3224ec6008bd88582319fc3"
            )))
    message.sign(signer)
    data_was_signed = message._data_to_sign()
    print("Reveal Secret signature 9: " + message.signature.hex())
    assert recover(data_was_signed, message.signature) == to_canonical_address(
        "0x7ca28d3d760b4aa2b79e8d42cbdc187c7df9af40")
Esempio n. 7
0
def run_test_automatic_secret_registration(raiden_chain, token_addresses):
    app0, app1 = raiden_chain
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    amount = 100
    identifier = 1

    hold_event_handler = HoldOffChainSecretRequest()
    message_handler = WaitForMessage()

    app1.raiden.raiden_event_handler = hold_event_handler
    app1.raiden.message_handler = message_handler

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

    hold_event_handler.hold_secretrequest_for(secrethash=secrethash)
    locked_transfer_received = message_handler.wait_for_message(
        LockedTransfer, {})

    app0.raiden.start_mediated_transfer_with_secret(
        token_network_identifier=token_network_identifier,
        amount=amount,
        fee=0,
        target=target,
        identifier=identifier,
        secret=secret,
    )

    # Wait for app1 to receive the locked transfer.
    locked_transfer_received.wait()

    # Stop app0 to avoid sending the unlock, this must be done after the locked
    # transfer is sent.
    app0.raiden.transport.stop()

    reveal_secret = RevealSecret(
        message_identifier=random.randint(0, UINT64_MAX),
        secret=secret,
    )
    app0.raiden.sign(reveal_secret)
    message_handler.on_message(app1.raiden, reveal_secret)

    chain_state = views.state_from_app(app1)

    secrethash = sha3(secret)
    target_task = chain_state.payment_mapping.secrethashes_to_task[secrethash]
    lock_expiration = target_task.target_state.transfer.lock.expiration
    app1.raiden.chain.wait_until_block(target_block_number=lock_expiration)

    assert app1.raiden.default_secret_registry.is_secret_registered(
        secrethash=secrethash,
        block_identifier='latest',
    )
Esempio n. 8
0
def test_close_channel_lack_of_balance_proof(raiden_chain, deposit, token_addresses):
    app0, app1 = raiden_chain
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    token_proxy = app0.raiden.chain.token(token_address)
    initial_balance0 = token_proxy.balance_of(app0.raiden.address)
    initial_balance1 = token_proxy.balance_of(app1.raiden.address)

    amount = 100
    identifier = 1
    secret = pending_mediated_transfer(
        raiden_chain,
        token_network_identifier,
        amount,
        identifier,
    )

    # Stop app0 to avoid sending the unlock
    app0.raiden.transport.stop_and_wait()

    reveal_secret = RevealSecret(
        random.randint(0, UINT64_MAX),
        secret,
    )
    app0.raiden.sign(reveal_secret)
    message_handler.on_message(app1.raiden, reveal_secret)

    RaidenAPI(app0.raiden).channel_close(
        app0.raiden.default_registry.address,
        token_address,
        app1.raiden.address,
    )

    channel_state = get_channelstate(app0, app1, token_network_identifier)
    waiting.wait_for_settle(
        app0.raiden,
        app0.raiden.default_registry.address,
        token_address,
        [channel_state.identifier],
        app0.raiden.alarm.sleep_time,
    )

    # wait for the node to call batch unlock
    with gevent.Timeout(10):
        wait_for_batch_unlock(
            app0,
            token_network_identifier,
            channel_state.partner_state.address,
            channel_state.our_state.address,
        )

    expected_balance0 = initial_balance0 + deposit - amount
    expected_balance1 = initial_balance1 + deposit + amount
    assert token_proxy.balance_of(app0.raiden.address) == expected_balance0
    assert token_proxy.balance_of(app1.raiden.address) == expected_balance1
Esempio n. 9
0
def test_receive_hashlocktransfer_unknown(raiden_network):
    app0 = raiden_network[0]  # pylint: disable=unbalanced-tuple-unpacking

    token_manager0 = app0.raiden.managers_by_token_address.values()[0]

    other_key = PrivateKey(HASH2, ctx=GLOBAL_CTX, raw=True)
    other_address = privatekey_to_address(other_key.private_key)
    amount = 10
    lock = Lock(amount, 1, HASH)
    refund_transfer = RefundTransfer(identifier=1,
                                     nonce=1,
                                     token=token_manager0.token_address,
                                     transferred_amount=amount,
                                     recipient=app0.raiden.address,
                                     locksroot=HASH,
                                     lock=lock)
    sign_and_send(refund_transfer, other_key, other_address, app0)

    transfer_timeout = TransferTimeout(HASH, HASH)
    sign_and_send(transfer_timeout, other_key, other_address, app0)

    secret = Secret(1, HASH, token_manager0.token_address)
    sign_and_send(secret, other_key, other_address, app0)

    secret_request = SecretRequest(1, HASH, 1)
    sign_and_send(secret_request, other_key, other_address, app0)

    reveal_secret = RevealSecret(HASH)
    sign_and_send(reveal_secret, other_key, other_address, app0)

    # Whenever processing of ConfirmTransfer is implemented test it here
    # too by removing the expectation of an exception
    with pytest.raises(KeyError):
        confirm_transfer = ConfirmTransfer(HASH)
        sign_and_send(confirm_transfer, other_key, other_address, app0)
Esempio n. 10
0
    def reveal_secret(self, raiden, secret, last_node, exchange_node):
        """ Reveal the `secret` to both participants.

        The secret must be revealed backwards to get the incentives right
        (first mediator would not forward the secret and get the transfer to
        itself).

        With exchanges there is an additional failure point, if a node is
        mediating both asset transfers it can intercept the transfer (as in not
        revealing the secret to others), for this reason it is not sufficient
        to just send the Secret backwards, the Secret must also be sent to the
        exchange_node.
        """
        # pylint: disable=no-self-use

        reveal_secret = RevealSecret(secret)
        raiden.sign(reveal_secret)

        # first reveal the secret to the last_node in the chain, proceed after
        # ack
        raiden.send_and_wait(last_node, reveal_secret,
                             timeout=None)  # XXX: wait for expiration

        # the last_node has acknowledged the Secret, so we know the exchange
        # has kicked-off, reveal the secret to the exchange_node to
        # avoid interceptions but dont wait
        raiden.send_async(exchange_node, reveal_secret)
Esempio n. 11
0
def test_receive_hashlocktransfer_unknown(raiden_network, token_addresses):
    app0 = raiden_network[0]
    token_address = token_addresses[0]

    other_key = HOP1_KEY
    other_address = HOP1
    amount = 10
    refund_transfer_message = make_refund_transfer(
        identifier=1,
        nonce=1,
        token=token_address,
        channel=other_address,
        transferred_amount=amount,
        recipient=app0.raiden.address,
        locksroot=UNIT_HASHLOCK,
        amount=amount,
        hashlock=UNIT_HASHLOCK,
    )
    sign_and_inject(refund_transfer_message, other_key, other_address, app0)

    secret = Secret(
        identifier=1,
        nonce=1,
        channel=make_address(),
        transferred_amount=amount,
        locksroot=UNIT_HASHLOCK,
        secret=UNIT_SECRET,
    )
    sign_and_inject(secret, other_key, other_address, app0)

    secret_request_message = SecretRequest(1, UNIT_HASHLOCK, 1)
    sign_and_inject(secret_request_message, other_key, other_address, app0)

    reveal_secret_message = RevealSecret(UNIT_SECRET)
    sign_and_inject(reveal_secret_message, other_key, other_address, app0)
Esempio n. 12
0
    def register_secret(self, secret):
        """ Register the secret with any channel that has a hashlock on it.

        This must search through all channels registered for a given hashlock
        and ignoring the tokens. Useful for refund transfer, split transfer,
        and token swaps.
        """
        hashlock = sha3(secret)
        revealsecret_message = RevealSecret(secret)
        self.sign(revealsecret_message)

        for hash_channel in self.token_to_hashlock_to_channels.itervalues():
            for channel in hash_channel[hashlock]:
                try:
                    channel.register_secret(secret)

                    # This will potentially be executed multiple times and could suffer
                    # from amplification, the protocol will ignore messages that were
                    # already registered and send it only until a first Ack is
                    # received.
                    self.send_async(
                        channel.partner_state.address,
                        revealsecret_message,
                    )
                except:  # pylint: disable=bare-except
                    # Only channels that care about the given secret can be
                    # registered and channels that have claimed the lock must
                    # be removed, so an exception should not happen at this
                    # point, nevertheless handle it because we dont want an
                    # error in a channel to mess the state from others.
                    log.error('programming error')
Esempio n. 13
0
def test_receive_hashlocktransfer_unknown(raiden_network):
    app0 = raiden_network[0]  # pylint: disable=unbalanced-tuple-unpacking

    graph0 = app0.raiden.channelgraphs.values()[0]

    other_key = PrivateKey(HASH2)
    other_address = privatekey_to_address(HASH2)
    amount = 10
    lock = Lock(amount, 1, HASH)
    refund_transfer = RefundTransfer(
        identifier=1,
        nonce=1,
        token=graph0.token_address,
        transferred_amount=amount,
        recipient=app0.raiden.address,
        locksroot=HASH,
        lock=lock
    )
    sign_and_send(refund_transfer, other_key, other_address, app0)

    secret = Secret(1, HASH, graph0.token_address)
    sign_and_send(secret, other_key, other_address, app0)

    secret_request = SecretRequest(1, HASH, 1)
    sign_and_send(secret_request, other_key, other_address, app0)

    reveal_secret = RevealSecret(HASH)
    sign_and_send(reveal_secret, other_key, other_address, app0)
Esempio n. 14
0
    def register_secret(self, secret: bytes):
        """ Register the secret with any channel that has a hashlock on it.

        This must search through all channels registered for a given hashlock
        and ignoring the tokens. Useful for refund transfer, split transfer,
        and token swaps.

        Raises:
            TypeError: If secret is unicode data.
        """
        if not isinstance(secret, bytes):
            raise TypeError('secret must be bytes')

        hashlock = sha3(secret)
        revealsecret_message = RevealSecret(secret)
        self.sign(revealsecret_message)

        for hash_channel in self.token_to_hashlock_to_channels.values():
            for channel in hash_channel[hashlock]:
                channel.register_secret(secret)

                # The protocol ignores duplicated messages.
                self.send_async(
                    channel.partner_state.address,
                    revealsecret_message,
                )
Esempio n. 15
0
def test_receive_hashlocktransfer_unknown(raiden_network):
    app0 = raiden_network[0]  # pylint: disable=unbalanced-tuple-unpacking

    token_manager0 = app0.raiden.managers_by_token_address.values()[0]

    other_key = PrivateKey(HASH2, ctx=GLOBAL_CTX, raw=True)
    other_address = privatekey_to_address(other_key.private_key)
    amount = 10
    lock = Lock(amount, 1, HASH)
    refund_transfer = RefundTransfer(identifier=1,
                                     nonce=1,
                                     token=token_manager0.token_address,
                                     transferred_amount=amount,
                                     recipient=app0.raiden.address,
                                     locksroot=HASH,
                                     lock=lock)
    sign_and_send(refund_transfer, other_key, other_address, app0)

    secret = Secret(1, HASH, token_manager0.token_address)
    sign_and_send(secret, other_key, other_address, app0)

    secret_request = SecretRequest(1, HASH, 1)
    sign_and_send(secret_request, other_key, other_address, app0)

    reveal_secret = RevealSecret(HASH)
    sign_and_send(reveal_secret, other_key, other_address, app0)
Esempio n. 16
0
def run_test_receive_secrethashtransfer_unknown(raiden_network,
                                                token_addresses):
    app0 = raiden_network[0]
    token_address = token_addresses[0]

    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    other_key = HOP1_KEY
    other_signer = LocalSigner(other_key)
    channel_identifier = make_channel_identifier()

    amount = 10
    refund_transfer_message = make_refund_transfer(
        payment_identifier=1,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel_identifier=channel_identifier,
        transferred_amount=amount,
        recipient=app0.raiden.address,
        locksroot=UNIT_SECRETHASH,
        amount=amount,
        secrethash=UNIT_SECRETHASH,
    )
    sign_and_inject(refund_transfer_message, other_signer, app0)

    unlock = Unlock(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=1,
        nonce=1,
        channel_identifier=channel_identifier,
        token_network_address=token_network_identifier,
        transferred_amount=amount,
        locked_amount=0,
        locksroot=UNIT_SECRETHASH,
        secret=UNIT_SECRET,
    )
    sign_and_inject(unlock, other_signer, app0)

    secret_request_message = SecretRequest(
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=1,
        secrethash=UNIT_SECRETHASH,
        amount=1,
        expiration=refund_transfer_message.lock.expiration,
    )
    sign_and_inject(secret_request_message, other_signer, app0)

    reveal_secret_message = RevealSecret(
        message_identifier=random.randint(0, UINT64_MAX),
        secret=UNIT_SECRET,
    )
    sign_and_inject(reveal_secret_message, other_signer, app0)
Esempio n. 17
0
def test_regression_revealsecret_after_secret(raiden_network, token_addresses,
                                              transport_config):
    """ A RevealSecret message received after a Secret message must be cleanly
    handled.
    """
    app0, app1, app2 = raiden_network
    token = token_addresses[0]

    identifier = 1
    payment_network_identifier = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        payment_network_identifier,
        token,
    )
    transfer = app0.raiden.mediated_transfer_async(
        token_network_identifier,
        amount=1,
        target=app2.raiden.address,
        identifier=identifier,
    )
    assert transfer.wait()

    event = must_contain_entry(
        app1.raiden.wal.storage.get_events(),
        SendSecretReveal,
        {},
    )
    assert event

    message_identifier = random.randint(0, UINT64_MAX)
    reveal_secret = RevealSecret(
        message_identifier,
        event.secret,
    )
    app2.raiden.sign(reveal_secret)

    if transport_config.protocol is TransportProtocol.UDP:
        reveal_data = reveal_secret.encode()
        host_port = None
        app1.raiden.transport.receive(reveal_data, host_port)
    elif transport_config.protocol is TransportProtocol.MATRIX:
        app1.raiden.transport._receive_message(reveal_secret)  # pylint: disable=protected-access
    else:
        raise TypeError('Unknown TransportProtocol')
Esempio n. 18
0
    def on_event(self, event):
        if isinstance(event, SendMediatedTransfer):
            receiver = event.receiver
            fee = 0
            graph = self.raiden.channelgraphs[event.token]
            channel = graph.partneraddress_channel[receiver]

            mediated_transfer = channel.create_mediatedtransfer(
                event.initiator,
                event.target,
                fee,
                event.amount,
                event.identifier,
                event.expiration,
                event.hashlock,
            )

            self.raiden.sign(mediated_transfer)
            channel.register_transfer(mediated_transfer)
            self.raiden.send_async(receiver, mediated_transfer)

        elif isinstance(event, SendRevealSecret):
            reveal_message = RevealSecret(event.secret)
            self.raiden.sign(reveal_message)
            self.raiden.send_async(event.receiver, reveal_message)

        elif isinstance(event, SendBalanceProof):
            # TODO: issue #189

            # unlock and update remotely (send the Secret message)
            self.raiden.handle_secret(
                event.identifier,
                event.token,
                event.secret,
                None,
                sha3(event.secret),
            )

        elif isinstance(event, SendSecretRequest):
            secret_request = SecretRequest(
                event.identifier,
                event.hashlock,
                event.amount,
            )
            self.raiden.sign(secret_request)
            self.raiden.send_async(event.receiver, secret_request)

        elif isinstance(event, SendRefundTransfer):
            pass

        elif isinstance(event, EventTransferCompleted):
            for result in self.raiden.identifier_result[event.identifier]:
                result.set(True)

        elif isinstance(event, EventTransferFailed):
            for result in self.raiden.identifier_result[event.identifier]:
                result.set(True)
Esempio n. 19
0
def handle_send_revealsecret(
        raiden: 'RaidenService',
        reveal_secret_event: SendRevealSecret):
    reveal_secret_message = RevealSecret.from_event(reveal_secret_event)
    raiden.sign(reveal_secret_message)
    raiden.send_async(
        reveal_secret_event.receiver,
        reveal_secret_message,
    )
Esempio n. 20
0
def test_regression_revealsecret_after_secret(raiden_network, token_addresses, transport_protocol):
    """ A RevealSecret message received after a Secret message must be cleanly
    handled.
    """
    app0, app1, app2 = raiden_network
    token = token_addresses[0]

    identifier = 1
    payment_network_identifier = app0.raiden.default_registry.address
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        payment_network_identifier,
        token,
    )
    transfer = app0.raiden.mediated_transfer_async(
        token_network_identifier,
        amount=1,
        target=app2.raiden.address,
        identifier=identifier,
    )
    assert transfer.wait()

    event = must_contain_entry(
        app1.raiden.wal.storage.get_events(),
        SendSecretReveal,
        {},
    )
    assert event

    message_identifier = random.randint(0, UINT64_MAX)
    reveal_secret = RevealSecret(
        message_identifier,
        event.secret,
    )
    app2.raiden.sign(reveal_secret)

    if transport_protocol is TransportProtocol.UDP:
        reveal_data = reveal_secret.encode()
        host_port = None
        app1.raiden.transport.receive(reveal_data, host_port)
    elif transport_protocol is TransportProtocol.MATRIX:
        app1.raiden.transport._receive_message(reveal_secret)  # pylint: disable=protected-access
    else:
        raise TypeError('Unknown TransportProtocol')
Esempio n. 21
0
def handle_send_revealsecret(
        raiden: 'RaidenService',
        reveal_secret_event: SendRevealSecret,
):
    reveal_secret_message = RevealSecret.from_event(reveal_secret_event)
    raiden.sign(reveal_secret_message)
    raiden.protocol.send_async(
        reveal_secret_event.queue_name,
        reveal_secret_event.recipient,
        reveal_secret_message,
    )
Esempio n. 22
0
    def from_dict(cls, data: Dict[str, Any]) -> "SendSecretRevealLight":
        restored = cls(
            sender=to_canonical_address(data["sender"]),
            recipient=to_canonical_address(data["recipient"]),
            channel_identifier=ChannelID(int(data["channel_identifier"])),
            message_identifier=MessageID(int(data["message_identifier"])),
            secret=deserialize_secret(data["secret"]),
            signed_secret_reveal=RevealSecret.from_dict(
                data["signed_secret_reveal"]))

        return restored
Esempio n. 23
0
def test_receive_secrethashtransfer_unknown(raiden_network, token_addresses):
    app0 = raiden_network[0]
    token_address = token_addresses[0]

    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    other_key = HOP1_KEY
    other_address = HOP1
    amount = 10
    refund_transfer_message = make_refund_transfer(
        payment_identifier=1,
        nonce=1,
        token_network_address=token_network_identifier,
        token=token_address,
        channel=other_address,
        transferred_amount=amount,
        recipient=app0.raiden.address,
        locksroot=UNIT_SECRETHASH,
        amount=amount,
        secrethash=UNIT_SECRETHASH,
    )
    sign_and_inject(refund_transfer_message, other_key, other_address, app0)

    secret = Secret(
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=1,
        nonce=1,
        channel=make_address(),
        token_network_address=token_network_identifier,
        transferred_amount=amount,
        locked_amount=0,
        locksroot=UNIT_SECRETHASH,
        secret=UNIT_SECRET,
    )
    sign_and_inject(secret, other_key, other_address, app0)

    secret_request_message = SecretRequest(
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=1,
        secrethash=UNIT_SECRETHASH,
        amount=1,
    )
    sign_and_inject(secret_request_message, other_key, other_address, app0)

    reveal_secret_message = RevealSecret(
        message_identifier=random.randint(0, UINT64_MAX),
        secret=UNIT_SECRET,
    )
    sign_and_inject(reveal_secret_message, other_key, other_address, app0)
Esempio n. 24
0
def test_automatic_secret_registration(raiden_chain, token_addresses):
    app0, app1 = raiden_chain
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    amount = 100
    identifier = 1

    hold_event_handler = HoldOffChainSecretRequest()
    app1.raiden.raiden_event_handler = hold_event_handler

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

    hold_event_handler.hold_secretrequest_for(secrethash=secrethash)

    app0.raiden.start_mediated_transfer_with_secret(
        token_network_identifier,
        amount,
        target,
        identifier,
        secret,
    )

    gevent.sleep(1)  # wait for the messages to be exchanged

    # Stop app0 to avoid sending the unlock
    app0.raiden.transport.stop()

    reveal_secret = RevealSecret(
        message_identifier=random.randint(0, UINT64_MAX),
        secret=secret,
    )
    app0.raiden.sign(reveal_secret)
    message_handler.MessageHandler().on_message(app1.raiden, reveal_secret)

    chain_state = views.state_from_app(app1)

    secrethash = sha3(secret)
    target_task = chain_state.payment_mapping.secrethashes_to_task[secrethash]
    lock_expiration = target_task.target_state.transfer.lock.expiration
    app1.raiden.chain.wait_until_block(target_block_number=lock_expiration)

    assert app1.raiden.default_secret_registry.check_registered(
        secrethash=secrethash,
        block_identifier='latest',
    )
Esempio n. 25
0
def test_close_channel_lack_of_balance_proof(
        raiden_chain,
        reveal_timeout,
        settle_timeout,
        token_addresses):

    app0, app1 = raiden_chain
    token_address = token_addresses[0]

    channel01 = channel(app0, app1, token_address)

    secret = sha3('test_close_channel_lack_of_balance_proof')
    hashlock = sha3(secret)

    fee = 0
    amount = 100
    identifier = 1
    expiration = app0.raiden.get_block_number() + reveal_timeout * 2
    transfer = channel01.create_mediatedtransfer(
        app0.raiden.address,
        app1.raiden.address,
        fee,
        amount,
        identifier,
        expiration,
        hashlock,
    )
    app0.raiden.sign(transfer)
    async_result = app0.raiden.send_async(app1.raiden.address, transfer)
    assert async_result.wait()

    reveal_secret = RevealSecret(secret)
    app0.raiden.sign(reveal_secret)
    async_result = app0.raiden.send_async(app1.raiden.address, reveal_secret)
    assert async_result.wait()

    wait_until = app0.raiden.get_block_number() + settle_timeout + 2
    wait_until_block(app0.raiden.chain, wait_until)

    # required for tester blockchain: let the alarm task run
    gevent.sleep(1)

    assert channel01.state != CHANNEL_STATE_OPENED
Esempio n. 26
0
def test_close_channel_lack_of_balance_proof(raiden_chain, deposit,
                                             token_addresses):
    app0, app1 = raiden_chain
    token_address = token_addresses[0]

    token_proxy = app0.raiden.chain.token(token_address)
    initial_balance0 = token_proxy.balance_of(app0.raiden.address)
    initial_balance1 = token_proxy.balance_of(app1.raiden.address)

    amount = 100
    identifier = 1
    secret = pending_mediated_transfer(
        raiden_chain,
        token_address,
        amount,
        identifier,
    )

    # Stop app0 to avoid sending the unlock
    app0.raiden.protocol.stop_and_wait()

    reveal_secret = RevealSecret(
        random.randint(0, UINT64_MAX),
        secret,
    )
    app0.raiden.sign(reveal_secret)
    udp_message_handler.on_udp_message(app1.raiden, reveal_secret)

    channel_state = get_channelstate(app0, app1, token_address)
    waiting.wait_for_settle(
        app0.raiden,
        app0.raiden.default_registry.address,
        token_address,
        [channel_state.identifier],
        app0.raiden.alarm.wait_time,
    )

    expected_balance0 = initial_balance0 + deposit - amount
    expected_balance1 = initial_balance1 + deposit + amount
    assert token_proxy.balance_of(app0.raiden.address) == expected_balance0
    assert token_proxy.balance_of(app1.raiden.address) == expected_balance1
Esempio n. 27
0
def message_from_sendevent(send_event: SendMessageEvent) -> Message:
    if type(send_event) == SendLockedTransfer:
        assert isinstance(send_event, SendLockedTransfer), MYPY_ANNOTATION
        message = LockedTransfer.from_event(send_event)
    elif type(send_event) == SendLockedTransferLight:
        assert isinstance(send_event, SendLockedTransferLight), MYPY_ANNOTATION
        message = send_event.signed_locked_transfer
    elif type(send_event) == SendSecretReveal:
        assert isinstance(send_event, SendSecretReveal), MYPY_ANNOTATION
        message = RevealSecret.from_event(send_event)
    elif type(send_event) == SendSecretRevealLight:
        assert isinstance(send_event, SendSecretRevealLight), MYPY_ANNOTATION
        message = send_event.signed_secret_reveal
    elif type(send_event) == SendBalanceProof:
        assert isinstance(send_event, SendBalanceProof), MYPY_ANNOTATION
        message = Unlock.from_event(send_event)
    elif type(send_event) == SendBalanceProofLight:
        assert isinstance(send_event, SendBalanceProofLight), MYPY_ANNOTATION
        message = send_event.signed_balance_proof
    elif type(send_event) == SendSecretRequest:
        assert isinstance(send_event, SendSecretRequest), MYPY_ANNOTATION
        message = SecretRequest.from_event(send_event)
    elif type(send_event) == SendSecretRequestLight:
        assert isinstance(send_event, SendSecretRequestLight), MYPY_ANNOTATION
        message = send_event.signed_secret_request
    elif type(send_event) == SendRefundTransfer:
        assert isinstance(send_event, SendRefundTransfer), MYPY_ANNOTATION
        message = RefundTransfer.from_event(send_event)
    elif type(send_event) == SendLockExpired:
        assert isinstance(send_event, SendLockExpired), MYPY_ANNOTATION
        message = LockExpired.from_event(send_event)
    elif type(send_event) == SendProcessed:
        assert isinstance(send_event, SendProcessed), MYPY_ANNOTATION
        message = Processed.from_event(send_event)
    else:
        raise ValueError(f"Unknown event type {send_event}")

    return message
Esempio n. 28
0
    def register_secret(self, secret):
        """ Register the secret with the interested channels.

        Note:
            The channel needs to be registered with
            `register_channel_for_hashlock`.
        """
        hashlock = sha3(secret)
        revealsecret_message = RevealSecret(secret)
        self.raiden.sign(revealsecret_message)

        channels_list = self.hashlock_channel[hashlock]
        for channel in channels_list:
            channel.register_secret(secret)

            # This will potentially be executed multiple times and could suffer
            # from amplification, the protocol will ignore messages that were
            # already registered and send it only until a first Ack is
            # received.
            self.raiden.send_async(
                channel.partner_state.address,
                revealsecret_message,
            )
Esempio n. 29
0
def test_automatic_secret_registration(raiden_chain, deposit, token_addresses,
                                       reveal_timeout):
    app0, app1 = raiden_chain
    token_address = token_addresses[0]
    token_network_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token_address,
    )

    amount = 100
    identifier = 1
    secret = pending_mediated_transfer(
        raiden_chain,
        token_network_identifier,
        amount,
        identifier,
    )

    # Stop app0 to avoid sending the unlock
    app0.raiden.transport.stop()

    reveal_secret = RevealSecret(
        random.randint(0, UINT64_MAX),
        secret,
    )
    app0.raiden.sign(reveal_secret)
    message_handler.on_message(app1.raiden, reveal_secret)

    chain_state = views.state_from_app(app1)

    secrethash = sha3(secret)
    target_task = chain_state.payment_mapping.secrethashes_to_task[secrethash]
    lock_expiration = target_task.target_state.transfer.lock.expiration
    wait_until_block(app1.raiden.chain, lock_expiration)

    assert app1.raiden.default_secret_registry.check_registered(secrethash)
def test_receive_hashlocktransfer_unknown(raiden_network):
    app0 = raiden_network[0]  # pylint: disable=unbalanced-tuple-unpacking

    graph0 = app0.raiden.token_to_channelgraph.values()[0]

    other_key = PrivateKey(HASH2)
    other_address = privatekey_to_address(HASH2)
    amount = 10
    refund_transfer = make_refund_transfer(
        identifier=1,
        nonce=1,
        token=graph0.token_address,
        channel=other_address,
        transferred_amount=amount,
        recipient=app0.raiden.address,
        locksroot=UNIT_HASHLOCK,
        amount=amount,
        hashlock=UNIT_HASHLOCK,
    )
    sign_and_send(refund_transfer, other_key, other_address, app0)

    secret = Secret(
        identifier=1,
        nonce=1,
        channel=make_address(),
        transferred_amount=amount,
        locksroot=UNIT_HASHLOCK,
        secret=UNIT_SECRET,
    )
    sign_and_send(secret, other_key, other_address, app0)

    secret_request = SecretRequest(1, UNIT_HASHLOCK, 1)
    sign_and_send(secret_request, other_key, other_address, app0)

    reveal_secret = RevealSecret(UNIT_SECRET)
    sign_and_send(reveal_secret, other_key, other_address, app0)
Esempio n. 31
0
    def handle_secret(  # pylint: disable=too-many-arguments
            self, identifier, token_address, secret, partner_secret_message,
            hashlock):
        """ Unlock/Witdraws locks, register the secret, and send Secret
        messages as necessary.

        This function will:
            - Unlock the locks created by this node and send a Secret message to
            the corresponding partner so that she can withdraw the token.
            - Withdraw the lock from sender.
            - Register the secret for the locks received and reveal the secret
            to the senders


        Note:
            The channel needs to be registered with
            `raiden.register_channel_for_hashlock`.
        """
        # handling the secret needs to:
        # - unlock the token for all `forward_channel` (the current one
        #   and the ones that failed with a refund)
        # - send a message to each of the forward nodes allowing them
        #   to withdraw the token
        # - register the secret for the `originating_channel` so that a
        #   proof can be made, if necessary
        # - reveal the secret to the `sender` node (otherwise we
        #   cannot withdraw the token)
        channels_list = self.token_to_hashlock_to_channels[token_address][
            hashlock]
        channels_to_remove = list()

        revealsecret_message = RevealSecret(secret)
        self.sign(revealsecret_message)

        messages_to_send = []
        for channel in channels_list:
            # unlock a pending lock
            if channel.our_state.is_known(hashlock):
                secret = channel.create_secret(identifier, secret)
                self.sign(secret)

                channel.register_transfer(
                    self.get_block_number(),
                    secret,
                )

                messages_to_send.append((
                    channel.partner_state.address,
                    secret,
                ))

                channels_to_remove.append(channel)

            # withdraw a pending lock
            elif channel.partner_state.is_known(hashlock):
                if partner_secret_message:
                    is_balance_proof = (partner_secret_message.sender
                                        == channel.partner_state.address
                                        and partner_secret_message.channel
                                        == channel.channel_address)

                    if is_balance_proof:
                        channel.register_transfer(
                            self.get_block_number(),
                            partner_secret_message,
                        )
                        channels_to_remove.append(channel)
                    else:
                        channel.register_secret(secret)
                        messages_to_send.append((
                            channel.partner_state.address,
                            revealsecret_message,
                        ))
                else:
                    channel.register_secret(secret)
                    messages_to_send.append((
                        channel.partner_state.address,
                        revealsecret_message,
                    ))

            else:
                log.error(
                    'Channel is registered for a given lock but the lock is not contained in it.'
                )

        for channel in channels_to_remove:
            channels_list.remove(channel)

        if not channels_list:
            del self.token_to_hashlock_to_channels[token_address][hashlock]

        # send the messages last to avoid races
        for recipient, message in messages_to_send:
            self.send_async(
                recipient,
                message,
            )
Esempio n. 32
0
    def _secret(self, identifier, secret, partner_secret_message, hashlock):
        channels_list = self.hashlock_channel[hashlock]
        channels_to_remove = list()

        # Dont use the partner_secret_message.token since it might not match with the
        # current token manager
        our_secret_message = Secret(identifier, secret, self.token_address)
        self.raiden.sign(our_secret_message)

        revealsecret_message = RevealSecret(secret)
        self.raiden.sign(revealsecret_message)

        for channel in channels_list:
            # critical read/write section
            # - the `release_lock` might raise if the `balance_proof` changes
            #   after the check
            # - a message created before the lock is release must be added in
            #   the message queue before `our_secret_message`
            # We are relying on the GIL and non-blocking apis instead of an
            # explicit lock.

            if channel.partner_state.balance_proof.is_unclaimed(hashlock):
                # we are the sender, so we can release the lock once the secret
                # is known and add the update message into the end of the
                # message queue, all the messages will remain consistent
                # (including the messages in-transit and the ones that are
                # already in the queue)
                channel.release_lock(secret)

                # notify our partner that our state is updated and it can
                # withdraw the token
                self.raiden.send_async(channel.partner_state.address,
                                       our_secret_message)

                channels_to_remove.append(channel)

            # we are the recipient, we can only withdraw the token if a secret
            # message is received from the correct sender and token address, so
            # withdraw if a valid message is received otherwise register the
            # secret and reveal the secret to channel patner.
            if channel.our_state.balance_proof.is_unclaimed(hashlock):
                # partner_secret_message might be None
                if partner_secret_message:
                    valid_sender = partner_secret_message.sender == channel.partner_state.address
                    valid_token = partner_secret_message.token == channel.token_address

                    if valid_sender and valid_token:
                        channel.withdraw_lock(secret)
                        channels_to_remove.append(channel)
                    else:
                        # assume our partner does not know the secret and reveal it
                        channel.register_secret(secret)
                        self.raiden.send_async(channel.partner_state.address,
                                               revealsecret_message)
                else:
                    channel.register_secret(secret)
                    self.raiden.send_async(channel.partner_state.address,
                                           revealsecret_message)
            # /critical read/write section

        for channel in channels_to_remove:
            channels_list.remove(channel)

        # delete the list from defaultdict, it wont be used again
        if len(channels_list) == 0:
            del self.hashlock_channel[hashlock]
Esempio n. 33
0
def test_regression_multiple_revealsecret(raiden_network, token_addresses, transport_protocol):
    """ Multiple RevealSecret messages arriving at the same time must be
    handled properly.

    Secret handling followed these steps:

        The Secret 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 Secret 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_identifier = views.get_token_network_identifier_by_token_address(
        views.state_from_app(app0),
        app0.raiden.default_registry.address,
        token,
    )
    channelstate_0_1 = get_channelstate(app0, app1, token_network_identifier)

    payment_identifier = 1
    secret = sha3(b'test_regression_multiple_revealsecret')
    secrethash = sha3(secret)
    expiration = app0.raiden.get_block_number() + 100
    lock_amount = 10
    lock = Lock(
        lock_amount,
        expiration,
        secrethash,
    )

    nonce = 1
    transferred_amount = 0
    mediated_transfer = LockedTransfer(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=payment_identifier,
        nonce=nonce,
        token_network_address=app0.raiden.default_registry.address,
        token=token,
        channel_identifier=channelstate_0_1.identifier,
        transferred_amount=transferred_amount,
        locked_amount=lock_amount,
        recipient=app1.raiden.address,
        locksroot=lock.secrethash,
        lock=lock,
        target=app1.raiden.address,
        initiator=app0.raiden.address,
    )
    app0.raiden.sign(mediated_transfer)

    if transport_protocol is TransportProtocol.UDP:
        message_data = mediated_transfer.encode()
        host_port = None
        app1.raiden.transport.receive(message_data, host_port)
    elif transport_protocol is TransportProtocol.MATRIX:
        app1.raiden.transport._receive_message(mediated_transfer)
    else:
        raise TypeError('Unknown TransportProtocol')

    reveal_secret = RevealSecret(
        random.randint(0, UINT64_MAX),
        secret,
    )
    app0.raiden.sign(reveal_secret)

    token_network_identifier = channelstate_0_1.token_network_identifier
    secret = Secret(
        chain_id=UNIT_CHAIN_ID,
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=payment_identifier,
        nonce=mediated_transfer.nonce + 1,
        token_network_address=token_network_identifier,
        channel_identifier=channelstate_0_1.identifier,
        transferred_amount=lock_amount,
        locked_amount=0,
        locksroot=EMPTY_MERKLE_ROOT,
        secret=secret,
    )
    app0.raiden.sign(secret)

    if transport_protocol is TransportProtocol.UDP:
        messages = [
            secret.encode(),
            reveal_secret.encode(),
        ]
        host_port = None
        receive_method = app1.raiden.transport.receive
        wait = [
            gevent.spawn_later(
                .1,
                receive_method,
                data,
                host_port,
            )
            for data in messages
        ]
    elif transport_protocol is TransportProtocol.MATRIX:
        messages = [
            secret,
            reveal_secret,
        ]
        receive_method = app1.raiden.transport._receive_message
        wait = [
            gevent.spawn_later(
                .1,
                receive_method,
                data,
            )
            for data in messages
        ]
    else:
        raise TypeError('Unknown TransportProtocol')

    gevent.joinall(wait)
def test_regression_multiple_revealsecret(raiden_network, token_addresses):
    """ Multiple RevealSecret messages arriving at the same time must be
    handled properly.

    Secret handling followed these steps:

        The Secret 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 hashlock

    The step marked with an asterisk above introduced a context-switch, this
    allowed a second Reveal Secret message to be handled before the channel was
    unregistered, because the channel was already updated an exception was raised
    for an unknown secret.
    """
    app0, app1 = raiden_network
    token = token_addresses[0]

    identifier = 1
    secret = sha3(b'test_regression_multiple_revealsecret')
    hashlock = sha3(secret)
    expiration = app0.raiden.get_block_number() + 100
    amount = 10

    mediated_transfer = channel(app0, app1, token).create_mediatedtransfer(
        transfer_initiator=app0.raiden.address,
        transfer_target=app1.raiden.address,
        fee=0,
        amount=amount,
        identifier=identifier,
        expiration=expiration,
        hashlock=hashlock,
    )
    app0.raiden.sign(mediated_transfer)

    message_data = mediated_transfer.encode()
    app1.raiden.protocol.receive(message_data)

    reveal_secret = RevealSecret(secret)
    app0.raiden.sign(reveal_secret)
    reveal_secret_data = reveal_secret.encode()

    secret = Secret(
        identifier=identifier,
        nonce=mediated_transfer.nonce + 1,
        channel=channel(app0, app1, token).channel_address,
        transferred_amount=amount,
        locksroot=EMPTY_MERKLE_ROOT,
        secret=secret,
    )
    app0.raiden.sign(secret)
    secret_data = secret.encode()

    messages = [
        secret_data,
        reveal_secret_data,
    ]

    wait = [
        gevent.spawn_later(
            .1,
            app1.raiden.protocol.receive,
            data,
        )
        for data in messages
    ]

    gevent.joinall(wait)