Esempio n. 1
0
def handle_message_crosssecretrequest(raiden, message):
    secret_request_message = SecretRequest(message.message_identifier,
                                           message.payment_identifier,
                                           message.secrethash, message.amount)

    secret_request_message.signature = message.secret_request_signature

    state_change = ReceiveSecretRequest(
        secret_request_message.payment_identifier,
        secret_request_message.amount,
        secret_request_message.secrethash,
        secret_request_message.sender,
    )

    row = raiden.wal.get_crosstransaction_by_identifier(message.cross_id)
    if row[7] == 6:
        raiden.handle_state_change(state_change)
        raiden.wal.change_crosstransaction_status(message.cross_id, 8)
        #sync
        acceptcross = AcceptCross(random.randint(0, UINT64_MAX), row[1],
                                  row[2], message.cross_id, 7)
        raiden.sign(acceptcross)
        raiden.transport.send_async(
            row[2],
            bytes("123", 'utf-8'),
            acceptcross,
        )
        log.info('##sync sended')
    else:
        raiden.wal.change_crosstransaction_status(message.cross_id, 5)
        state_change_id = raiden.wal.storage.write_state_change(state_change)
        raiden.wal.storage.change_crosstransaction_statechangeid(
            message.cross_id, state_change_id)
def test_secret_request_5():
    dict_data = {
        "type":
        "SecretRequest",
        "message_identifier":
        9443946215632930647,
        "payment_identifier":
        1322351847924173620,
        "amount":
        100000000000000000,
        "expiration":
        12000000,
        "secrethash":
        "0xaf1ca2932cb5c3e3045eedb17ce760419d2b3e5234eeefe6fd82475adeb4da10"
    }
    message = SecretRequest(message_identifier=dict_data["message_identifier"],
                            payment_identifier=dict_data["payment_identifier"],
                            secrethash=decode_hex(dict_data["secrethash"]),
                            amount=dict_data["amount"],
                            expiration=dict_data["expiration"])
    message.sign(signer)
    data_was_signed = message._data_to_sign()
    print("SR signature: " + message.signature.hex())
    assert recover(data_was_signed, message.signature) == to_canonical_address(
        "0x7ca28d3d760b4aa2b79e8d42cbdc187c7df9af40")
Esempio n. 3
0
def test_secret_request(iterations=ITERATIONS):
    identifier = 1
    hashlock = HASH
    msg = SecretRequest(
        identifier,
        hashlock
    )
    msg.sign(PRIVKEY, ADDRESS)
    run_timeit('SecretRequest', msg, iterations=iterations)
Esempio n. 4
0
def test_udp_decode_invalid_size_message(mock_udp):
    message = SecretRequest(
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=1,
        secrethash=UNIT_SECRETHASH,
        amount=1,
        expiration=10,
    )
    data = message.encode()
    wrong_command_id_data = data[:-1]
    assert not mock_udp.receive(wrong_command_id_data)
Esempio n. 5
0
def test_secret_request(iterations=ITERATIONS):
    identifier = 1
    hashlock = HASH
    amount = 1
    msg = SecretRequest(
        identifier,
        hashlock,
        amount,
    )
    msg.sign(PRIVKEY, ADDRESS)
    run_timeit('SecretRequest', msg, iterations=iterations)
Esempio n. 6
0
def test_udp_decode_invalid_size_message(mock_udp):
    message = SecretRequest(
        message_identifier=random.randint(0, UINT64_MAX),
        payment_identifier=1,
        secrethash=UNIT_SECRETHASH,
        amount=1,
        expiration=10,
    )
    data = message.encode()
    wrong_command_id_data = data[:-1]
    host_port = None
    assert not mock_udp.receive(wrong_command_id_data, host_port)
Esempio n. 7
0
    def on_mediatedtransfer(self, transfer):
        assert isinstance(transfer, MediatedTransfer)
        log.debug('ON MEDIATED TRANSFER', address=pex(self.raiden.address))

        channel = self.assetmanager.channels[transfer.sender]

        channel.register_transfer(
            transfer)  # this raises if the transfer is invalid

        # either we are the target of the transfer, so we need to send a
        # SecretRequest
        if transfer.target == self.raiden.address:
            secret_request = SecretRequest(transfer.lock.hashlock)
            self.raiden.sign(secret_request)
            self.raiden.send(transfer.initiator, secret_request)

            secret_request_task = ForwardSecretTask(
                self,
                transfer.lock.hashlock,
                recipient=transfer.sender,
            )
            secret_request_task.start()

        # or we are a participating node in the network and need to keep
        # forwarding the MediatedTransfer
        else:
            transfer_task = MediatedTransferTask(
                self,
                transfer.lock.amount,
                transfer.target,
                transfer.lock.hashlock,
                originating_transfer=transfer,
            )
            transfer_task.start()
Esempio n. 8
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. 9
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. 10
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. 11
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. 12
0
    def _run(self):  # pylint: disable=method-hidden
        transfer = self.originating_transfer
        assetmanager = self.transfermanager.assetmanager
        raiden = assetmanager.raiden

        transfer_details = '{} -> {} hash:{}'.format(
            pex(transfer.target),
            pex(transfer.initiator),
            pex(transfer.hash),
        )
        log.debug('END MEDIATED TRANSFER {}'.format(transfer_details))

        secret_request = SecretRequest(transfer.lock.hashlock)
        raiden.sign(secret_request)
        raiden.send(transfer.initiator, secret_request)

        self.event = AsyncResult()
        response = self.event.wait(raiden.config['msg_timeout'])

        if response is None:
            log.error('SECRETREQUEST TIMED OUT!')
            self.transfermanager.on_hashlock_result(transfer.hashlock, False)
            return

        if not isinstance(response, Secret):
            raise Exception('Invalid message received.')

        if sha3(response.secret) != transfer.lock.hashlock:
            raise Exception('Invalid secret received.')

        # update all channels and propagate the secret
        assetmanager.register_secret(response.secret)
        self.transfermanager.on_hashlock_result(transfer.lock.hashlock, True)
Esempio n. 13
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. 14
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. 15
0
def handle_send_secretrequest(
        raiden: 'RaidenService',
        secret_request_event: SendSecretRequest):
    secret_request_message = SecretRequest.from_event(secret_request_event)
    raiden.sign(secret_request_message)
    raiden.send_async(
        secret_request_event.receiver,
        secret_request_message,
    )
Esempio n. 16
0
def handle_send_secretrequest(
        raiden: 'RaidenService',
        secret_request_event: SendSecretRequest,
):
    secret_request_message = SecretRequest.from_event(secret_request_event)
    raiden.sign(secret_request_message)
    raiden.protocol.send_async(
        secret_request_event.queue_name,
        secret_request_event.recipient,
        secret_request_message,
    )
Esempio n. 17
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. 18
0
def make_message(convert_to_hex: bool = False, overwrite_data=None):
    room = Room(None, "!roomID:server")
    if not overwrite_data:
        message = SecretRequest(
            message_identifier=random.randint(0, UINT64_MAX),
            payment_identifier=1,
            secrethash=factories.UNIT_SECRETHASH,
            amount=1,
            expiration=10,
        )
        message.sign(LocalSigner(factories.HOP1_KEY))
        data = message.encode()
        if convert_to_hex:
            data = "0x" + data.hex()
        else:
            data = json.dumps(message.to_dict())
    else:
        data = overwrite_data

    event = dict(type="m.room.message",
                 sender=USERID1,
                 content={
                     "msgtype": "m.text",
                     "body": data
                 })
    return room, event
Esempio n. 19
0
def make_message(convert_to_hex: bool = False, overwrite_data=None):
    from matrix_client.room import Room
    room = Room(None, '!roomID:server')
    if not overwrite_data:
        message = SecretRequest(
            message_identifier=random.randint(0, UINT64_MAX),
            payment_identifier=1,
            secrethash=UNIT_SECRETHASH,
            amount=1,
            expiration=10,
        )
        message.sign(HOP1_KEY)
        data = message.encode()
        if convert_to_hex:
            data = '0x' + data.hex()
        else:
            data = json.dumps(message.to_dict())
    else:
        data = overwrite_data

    event = dict(
        type='m.room.message',
        sender=USERID1,
        content={
            'msgtype': 'm.text',
            'body': data,
        },
    )
    return room, event
Esempio n. 20
0
    def _run(self):  # pylint: disable=method-hidden
        mediated_transfer = self.originating_transfer
        assetmanager = self.transfermanager.assetmanager
        originating_channel = assetmanager.get_channel_by_partner_address(
            mediated_transfer.sender)
        raiden = assetmanager.raiden

        log.debug(
            'END MEDIATED TRANSFER %s -> %s msghash:%s hashlock:%s',
            pex(mediated_transfer.target),
            pex(mediated_transfer.initiator),
            pex(mediated_transfer.hash),
            pex(mediated_transfer.lock.hashlock),
        )

        secret_request = SecretRequest(mediated_transfer.lock.hashlock)
        raiden.sign(secret_request)

        response = self.send_and_wait_valid(raiden, mediated_transfer,
                                            secret_request)

        if response is None:
            timeout_message = originating_channel.create_timeouttransfer_for(
                mediated_transfer)
            raiden.send_async(mediated_transfer.sender, timeout_message)
            self.transfermanager.on_hashlock_result(
                mediated_transfer.lock.hashlock, False)
            return

        # register the secret so that a balance proof can be created but don't
        # claim until our partner has informed us that it's internal state is
        # updated
        originating_channel.register_secret(response.secret)

        secret_message = Secret(response.secret)
        raiden.sign(secret_message)
        raiden.send_async(mediated_transfer.sender, secret_message)

        # wait for the secret from `sender` to claim the lock
        while True:
            response = self.response_message.wait()
            # critical write section
            self.response_message = AsyncResult()
            # /critical write section

            if isinstance(
                    response,
                    Secret) and response.sender == mediated_transfer.sender:
                originating_channel.claim_lock(response.secret)
                self.transfermanager.on_hashlock_result(
                    mediated_transfer.lock.hashlock, True)
                return
Esempio n. 21
0
    def on_mediatedtransfer(self, transfer):
        assert isinstance(transfer, MediatedTransfer)
        log.debug('ON MEDIATED TRANSFER', address=pex(self.raiden.address))

        channel = self.assetmanager.channels[transfer.sender]
        channel.register_transfer(
            transfer)  # this raises if the transfer is invalid

        config = self.raiden.config

        # either we are the target of the transfer, so we need to send a
        # SecretRequest
        if transfer.target == self.raiden.address:
            secret_request = SecretRequest(transfer.lock.hashlock)
            self.raiden.sign(secret_request)
            self.raiden.send(transfer.initiator, secret_request)

            secret_request_task = ForwardSecretTask(
                self,
                transfer.lock.hashlock,
                recipient=transfer.sender,
                msg_timeout=config[
                    'msg_timeout']  # FIXME additional config['secret_request_timeout'] ?
            )
            secret_request_task.start()

        # or we are a participating node in the network and need to keep
        # forwarding the MediatedTransfer
        else:
            # subtract reveal_timeout from the lock expiration of the incoming transfer
            expiration = transfer.lock.expiration - config['reveal_timeout']

            transfer_task = MediatedTransferTask(
                self,
                transfer.lock.amount,
                transfer.target,
                transfer.lock.hashlock,
                expiration,
                originating_transfer=transfer,
            )
            transfer_task.start()
Esempio n. 22
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
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. 24
0
def test_secret_request(iterations=ITERATIONS):
    hashlock = HASH
    msg = SecretRequest(hashlock)
    msg.sign(PRIVKEY)
    run_timeit('SecretRequest', msg, iterations=iterations)
Esempio n. 25
0
    def _run(self):  # pylint: disable=method-hidden,too-many-locals
        fee = 0
        raiden = self.raiden

        from_mediated_transfer = self.from_mediated_transfer
        hashlock = from_mediated_transfer.lock.hashlock

        from_token = from_mediated_transfer.token
        to_token = self.to_token
        to_amount = self.to_amount

        to_graph = raiden.channelgraphs[to_token]
        from_graph = raiden.channelgraphs[from_token]

        from_channel = from_graph.partneraddress_channel[from_mediated_transfer.sender]

        raiden.register_task_for_hashlock(from_token, self, hashlock)
        raiden.register_channel_for_hashlock(from_token, from_channel, hashlock)

        lock_expiration = from_mediated_transfer.lock.expiration - raiden.config['reveal_timeout']
        lock_timeout = lock_expiration - raiden.get_block_number()

        to_routes = to_graph.get_best_routes(
            raiden.addres,
            from_mediated_transfer.initiator,  # route back to the initiator
            from_mediated_transfer.lock.amount,
            lock_timeout,
        )

        if log.isEnabledFor(logging.DEBUG):
            log.debug(
                'EXCHANGE TRANSFER %s -> %s msghash:%s hashlock:%s',
                pex(from_mediated_transfer.target),
                pex(from_mediated_transfer.initiator),
                pex(from_mediated_transfer.hash),
                pex(hashlock),
            )

        secret_request = SecretRequest(
            from_mediated_transfer.identifier,
            from_mediated_transfer.lock.hashlock,
            from_mediated_transfer.lock.amount,
        )
        raiden.sign(secret_request)
        raiden.send_async(from_mediated_transfer.initiator, secret_request)

        for path, to_channel in to_routes:
            to_next_hop = path[1]

            to_mediated_transfer = to_channel.create_mediatedtransfer(
                raiden.address,  # this node is the new initiator
                from_mediated_transfer.initiator,  # the initiator is the target for the to_token
                fee,
                to_amount,
                lock_expiration,
                hashlock,  # use the original hashlock
            )
            raiden.sign(to_mediated_transfer)

            if log.isEnabledFor(logging.DEBUG):
                log.debug(
                    'MEDIATED TRANSFER NEW PATH path:%s hashlock:%s',
                    lpex(path),
                    pex(from_mediated_transfer.lock.hashlock),
                )

            # The interest on the hashlock outlives this task, the secret
            # handling will happen only _once_
            raiden.register_channel_for_hashlock(to_token, to_channel, hashlock)
            to_channel.register_transfer(to_mediated_transfer)

            response = self.send_and_wait_valid(raiden, to_mediated_transfer)

            if log.isEnabledFor(logging.DEBUG):
                log.debug(
                    'EXCHANGE TRANSFER NEW PATH path:%s hashlock:%s',
                    lpex(path),
                    pex(hashlock),
                )

            # only refunds for `from_token` must be considered (check send_and_wait_valid)
            if isinstance(response, RefundTransfer):
                if response.lock.amount != to_mediated_transfer.amount:
                    log.info(
                        'Partner %s sent an invalid refund message with an invalid amount',
                        pex(to_next_hop),
                    )
                    raiden.on_hashlock_result(from_token, hashlock, False)
                    return
                else:
                    to_channel.register_transfer(response)

            elif isinstance(response, Secret):
                # claim the from_token
                raiden.handle_secret(
                    response.identifier,
                    from_token,
                    response.secret,
                    response,
                    hashlock,
                )

                # unlock the to_token
                raiden.handle_secret(
                    response.identifier,
                    to_token,
                    response.secret,
                    response,
                    hashlock,
                )

                self._wait_for_unlock_or_close(
                    raiden,
                    from_graph,
                    from_channel,
                    from_mediated_transfer,
                )
Esempio n. 26
0
 def from_dict(cls, data: Dict[str, Any]) -> "ActionSendSecretRequestLight":
     instance = cls(secret_request=SecretRequest.from_dict(
         data["secret_request"]),
                    sender=to_canonical_address(data["sender"]),
                    receiver=to_canonical_address(data["receiver"]))
     return instance
Esempio n. 27
0
    def on_event(self, event):
        if isinstance(event, SendMediatedTransfer):
            receiver = event.receiver
            fee = 0
            graph = self.raiden.token_to_channelgraph[event.token]
            channel = graph.partneraddress_to_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(
                self.raiden.get_block_number(),
                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):
            receiver = event.receiver
            fee = 0
            graph = self.raiden.token_to_channelgraph[event.token]
            channel = graph.partneraddress_to_channel[receiver]

            refund_transfer = channel.create_refundtransfer(
                event.initiator,
                event.target,
                fee,
                event.amount,
                event.identifier,
                event.expiration,
                event.hashlock,
            )

            self.raiden.sign(refund_transfer)
            channel.register_transfer(
                self.raiden.get_block_number(),
                refund_transfer,
            )
            self.raiden.send_async(receiver, refund_transfer)

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

        elif isinstance(event, EventTransferSentFailed):
            for result in self.raiden.identifier_to_results[event.identifier]:
                result.set(False)
        elif isinstance(event, UNEVENTEFUL_EVENTS):
            pass
        elif isinstance(event, EventUnlockFailed):
            log.error('UnlockFailed!',
                      initiator=event.initiator,
                      expiration=event.expiration)

        elif isinstance(event, ContractSendChannelClose):
            graph = self.raiden.token_to_channelgraph[event.token]
            channel = graph.address_to_channel[event.channel_address]

            balance_proof = channel.our_state.balance_proof.balance_proof
            channel.external_state.close(balance_proof)

        else:
            log.error('Unknown event {}'.format(type(event)))
Esempio n. 28
0
def test_secret_request(iterations=ITERATIONS):
    hashlock = HASH
    msg = SecretRequest(hashlock)
    msg.sign(PRIVKEY)
    run_timeit('SecretRequest', msg, iterations=iterations)
    def _run(self):  # pylint: disable=method-hidden,too-many-locals
        fee = 0
        raiden = self.raiden
        tokenswap = self.tokenswap

        # this is the MediatedTransfer that wil pay the maker's half of the
        # swap, not necessarily from him
        maker_paying_transfer = self.from_mediated_transfer

        # this is the address of the node that the taker actually has a channel
        # with (might or might not be the maker)
        maker_payer_hop = maker_paying_transfer.sender

        assert tokenswap.identifier == maker_paying_transfer.identifier
        assert tokenswap.from_token == maker_paying_transfer.token
        assert tokenswap.from_amount == maker_paying_transfer.lock.amount
        assert tokenswap.from_nodeaddress == maker_paying_transfer.initiator

        maker_receiving_token = tokenswap.to_token
        to_amount = tokenswap.to_amount

        identifier = maker_paying_transfer.identifier
        hashlock = maker_paying_transfer.lock.hashlock
        maker_address = maker_paying_transfer.initiator

        taker_receiving_token = maker_paying_transfer.token
        taker_paying_token = maker_receiving_token

        from_graph = raiden.token_to_channelgraph[taker_receiving_token]
        from_channel = from_graph.partneraddress_to_channel[maker_payer_hop]

        to_graph = raiden.token_to_channelgraph[maker_receiving_token]

        # update the channel's distributable and merkle tree
        from_channel.register_transfer(
            raiden.get_block_number(),
            maker_paying_transfer,
        )

        # register the task to receive Refund/Secrect/RevealSecret messages
        raiden.greenlet_task_dispatcher.register_task(self, hashlock)
        raiden.register_channel_for_hashlock(taker_receiving_token, from_channel, hashlock)

        # send to the maker a secret request informing how much the taker will
        # be _paid_, this is used to inform the maker that his part of the
        # mediated transfer is okay
        secret_request = SecretRequest(
            identifier,
            maker_paying_transfer.lock.hashlock,
            maker_paying_transfer.lock.amount,
        )
        raiden.sign(secret_request)
        raiden.send_async(maker_address, secret_request)

        lock_expiration = maker_paying_transfer.lock.expiration - raiden.config['reveal_timeout']

        # Note: taker may only try different routes if a RefundTransfer is
        # received, because the maker is the node controlling the secret
        available_routes = get_best_routes(
            to_graph,
            raiden.protocol.nodeaddresses_networkstatuses,
            raiden.address,
            maker_address,
            maker_paying_transfer.lock.amount,
            previous_address=None,
        )

        if not available_routes:
            if log.isEnabledFor(logging.DEBUG):
                node_address = raiden.address
                log.debug(
                    'TAKER TOKEN SWAP FAILED, NO ROUTES',
                    from_=pex(node_address),
                    to=pex(maker_address),
                )

            return

        first_transfer = None
        for route in available_routes:
            taker_paying_channel = to_graph.get_channel_by_contract_address(
                route.channel_address,
            )
            taker_paying_hop = route.node_address

            if log.isEnabledFor(logging.DEBUG):
                log.debug(
                    'TAKER TOKEN SWAP',
                    from_=pex(maker_paying_transfer.target),
                    to=pex(maker_address),
                    msghash=pex(maker_paying_transfer.hash),
                    hashlock=pex(hashlock),
                )

            # make a paying MediatedTransfer with same hashlock/identifier and the
            # taker's paying token/amount
            taker_paying_transfer = taker_paying_channel.create_mediatedtransfer(
                raiden.address,
                maker_address,
                fee,
                to_amount,
                identifier,
                lock_expiration,
                hashlock,
            )
            raiden.sign(taker_paying_transfer)
            taker_paying_channel.register_transfer(
                raiden.get_block_number(),
                taker_paying_transfer,
            )

            if not first_transfer:
                first_transfer = taker_paying_transfer

            if log.isEnabledFor(logging.DEBUG):
                log.debug(
                    'EXCHANGE TRANSFER NEW PATH',
                    path=lpex(taker_paying_hop),
                    hashlock=pex(hashlock),
                )

            # register the task to receive Refund/Secrect/RevealSecret messages
            raiden.register_channel_for_hashlock(
                maker_receiving_token,
                taker_paying_channel,
                hashlock,
            )

            response, secret = self.send_and_wait_valid(
                raiden,
                taker_paying_transfer,
                maker_payer_hop,
            )

            # only refunds for `maker_receiving_token` must be considered
            # (check send_and_wait_valid)
            if isinstance(response, RefundTransfer):
                if response.lock.amount != taker_paying_transfer.amount:
                    log.info(
                        'Partner %s sent an invalid refund message with an invalid amount',
                        pex(taker_paying_hop),
                    )
                    raiden.greenlet_task_dispatcher.unregister_task(self, hashlock, False)
                    return
                else:
                    taker_paying_channel.register_transfer(
                        raiden.get_block_number(),
                        response,
                    )

            elif isinstance(response, RevealSecret):
                # the secret was registered by the message handler

                # wait for the taker_paying_hop to reveal the secret prior to
                # unlocking locally
                if response.sender != taker_paying_hop:
                    response = self.wait_reveal_secret(
                        raiden,
                        taker_paying_hop,
                        taker_paying_transfer.lock.expiration,
                    )

                # unlock and send the Secret message
                raiden.handle_secret(
                    identifier,
                    taker_paying_token,
                    response.secret,
                    None,
                    hashlock,
                )

                # if the secret arrived early, withdraw it, otherwise send the
                # RevealSecret forward in the maker-path
                if secret:
                    raiden.handle_secret(
                        identifier,
                        taker_receiving_token,
                        response.secret,
                        secret,
                        hashlock,
                    )

                # wait for the withdraw in case it did not happen yet
                self._wait_for_unlock_or_close(
                    raiden,
                    from_graph,
                    from_channel,
                    maker_paying_transfer,
                )

                return

            # the lock expired
            else:
                if log.isEnabledFor(logging.DEBUG):
                    node_address = raiden.address
                    log.debug(
                        'TAKER TOKEN SWAP FAILED',
                        from_=pex(node_address),
                        to=pex(maker_address),
                    )

                self.async_result.set(False)
                return

        # no route is available, wait for the sent mediated transfer to expire
        self._wait_expiration(raiden, first_transfer)

        if log.isEnabledFor(logging.DEBUG):
            node_address = raiden.address
            log.debug(
                'TAKER TOKEN SWAP FAILED',
                from_=pex(node_address),
                to=pex(maker_address),
            )

        self.async_result.set(False)
Esempio n. 30
0
def handle_inittarget_light(
    state_change: ActionInitTargetLight,
    channel_state: NettingChannelState,
    pseudo_random_generator: random.Random,
    block_number: BlockNumber,
    storage
) -> TransitionResult[TargetTransferState]:
    """ Handles an ActionInitTarget state change. """
    transfer = state_change.transfer
    route = state_change.route

    assert channel_state.identifier == transfer.balance_proof.channel_identifier
    is_valid, channel_events, errormsg, handle_invoice_result = channel.handle_receive_lockedtransfer_light(
        channel_state, transfer, storage
    )

    if is_valid:
        # A valid balance proof does not mean the payment itself is still valid.
        # e.g. the lock may be near expiration or have expired. This is fine. The
        # message with an unusable lock must be handled to properly synchronize the
        # local view of the partner's channel state, allowing the next balance
        # proofs to be handled. This however, must only be done once, which is
        # enforced by the nonce increasing sequentially, which is verified by
        # the handler handle_receive_lockedtransfer.
        target_state = TargetTransferState(route, transfer)

        safe_to_wait, _ = is_safe_to_wait(
            transfer.lock.expiration, channel_state.reveal_timeout, block_number
        )

        # If there is not enough time to safely unlock the lock on-chain
        # silently let the transfer expire. The target task must be created to
        # handle the ReceiveLockExpired state change, which will clear the
        # expired lock.
        #
        # We add a new validation.
        # It is verified that if there was an invoice it was paid successfully,
        # if it was not, the payment is interrupted
        # by not generating an event send secret request
        if safe_to_wait and handle_invoice_result['is_valid']:
            payment = LightClientPayment(
                state_change.transfer.target, state_change.transfer.initiator,
                False,
                channel_state.token_network_identifier,
                transfer.lock.amount,
                str(date.today()),
                LightClientPaymentStatus.Pending,
                transfer.payment_identifier
            )

            payment_exists = LightClientService.get_light_client_payment(payment.payment_id, storage)
            if not payment_exists:
                LightClientMessageHandler.store_light_client_payment(payment, storage)

            message_identifier = message_identifier_from_prng(pseudo_random_generator)
            recipient = transfer.initiator
            secret_request = SendSecretRequest(
                recipient=Address(recipient),
                channel_identifier=CHANNEL_IDENTIFIER_GLOBAL_QUEUE,
                message_identifier=message_identifier,
                payment_identifier=transfer.payment_identifier,
                amount=transfer.lock.amount,
                expiration=transfer.lock.expiration,
                secrethash=transfer.lock.secrethash,
            )

            store_locked_transfer_event = StoreMessageEvent(transfer.message_identifier, transfer.payment_identifier, 1,
                                                            state_change.signed_lockedtransfer, True)

            secret_request_message = SecretRequest.from_event(secret_request)
            store_secret_request_event = StoreMessageEvent(message_identifier, transfer.payment_identifier, 5,
                                                           secret_request_message, False)
            channel_events.append(store_secret_request_event)
            channel_events.append(store_locked_transfer_event)

        iteration = TransitionResult(target_state, channel_events)
    else:
        # If the balance proof is not valid, do *not* create a task. Otherwise it's
        # possible for an attacker to send multiple invalid transfers, and increase
        # the memory usage of this Node.
        assert errormsg, "handle_receive_lockedtransfer should return error msg if not valid"
        unlock_failed = EventUnlockClaimFailed(
            identifier=transfer.payment_identifier,
            secrethash=transfer.lock.secrethash,
            reason=errormsg,
        )
        channel_events.append(unlock_failed)
        iteration = TransitionResult(None, channel_events)

    return iteration
Esempio n. 31
0
    def _run(self):  # pylint: disable=method-hidden
        raiden = self.raiden
        originating_transfer = self.originating_transfer
        hashlock = originating_transfer.lock.hashlock

        assetmanager = raiden.get_manager_by_asset_address(self.asset_address)
        transfermanager = assetmanager.transfermanager
        originating_channel = assetmanager.get_channel_by_partner_address(
            originating_transfer.sender, )

        transfermanager.register_task_for_hashlock(self, hashlock)
        assetmanager.register_channel_for_hashlock(originating_channel,
                                                   hashlock)

        if log.isEnabledFor(logging.DEBUG):
            log.debug(
                'END MEDIATED TRANSFER %s -> %s msghash:%s hashlock:%s',
                pex(originating_transfer.target),
                pex(originating_transfer.initiator),
                pex(originating_transfer.hash),
                pex(originating_transfer.lock.hashlock),
            )

        secret_request = SecretRequest(
            originating_transfer.identifier,
            originating_transfer.lock.hashlock,
            originating_transfer.lock.amount,
        )
        raiden.sign(secret_request)

        # If the transfer timed out in the initiator a new hashlock will be
        # created and this task will not receive a secret, this is fine because
        # the task will eventually exit once a blocktimeout happens and a new
        # task will be created for the new hashlock
        valid_messages_iterator = self.send_secretrequest_and_iter_valid(
            raiden,
            originating_transfer,
            secret_request,
        )

        for response in valid_messages_iterator:

            # at this point a Secret message is not valid
            if isinstance(response, RevealSecret):
                assetmanager.handle_secret(
                    originating_transfer.identifier,
                    response.secret,
                )

                self._wait_for_unlock_or_close(
                    raiden,
                    assetmanager,
                    originating_channel,
                    originating_transfer,
                )
                transfermanager.on_hashlock_result(hashlock, True)
                return

            elif response is TIMEOUT:
                # this task timeouts on a blocknumber, at this point all the other
                # nodes have timedout
                transfermanager.on_hashlock_result(
                    originating_transfer.lock.hashlock, False)
                break
Esempio n. 32
0
    def _run(self):  # pylint: disable=method-hidden,too-many-locals
        fee = 0
        raiden = self.raiden

        from_mediated_transfer = self.from_mediated_transfer
        hashlock = from_mediated_transfer.lock.hashlock

        from_asset = from_mediated_transfer.asset
        to_asset = self.to_asset
        to_amount = self.to_amount

        to_assetmanager = raiden.get_manager_by_asset_address(to_asset)
        from_assetmanager = raiden.get_manager_by_asset_address(from_asset)
        from_transfermanager = from_assetmanager.transfermanager

        from_channel = from_assetmanager.get_channel_by_partner_address(
            from_mediated_transfer.sender, )

        from_transfermanager.register_task_for_hashlock(self, hashlock)
        from_assetmanager.register_channel_for_hashlock(from_channel, hashlock)

        lock_expiration = from_mediated_transfer.lock.expiration - raiden.config[
            'reveal_timeout']
        lock_timeout = lock_expiration - raiden.chain.block_number()

        to_routes = to_assetmanager.get_best_routes(
            from_mediated_transfer.lock.amount,
            from_mediated_transfer.initiator,  # route back to the initiator
            lock_timeout,
        )

        if log.isEnabledFor(logging.DEBUG):
            log.debug(
                'EXCHANGE TRANSFER %s -> %s msghash:%s hashlock:%s',
                pex(from_mediated_transfer.target),
                pex(from_mediated_transfer.initiator),
                pex(from_mediated_transfer.hash),
                pex(hashlock),
            )

        secret_request = SecretRequest(
            from_mediated_transfer.identifier,
            from_mediated_transfer.lock.hashlock,
            from_mediated_transfer.lock.amount,
        )
        raiden.sign(secret_request)
        raiden.send_async(from_mediated_transfer.initiator, secret_request)

        for path, to_channel in to_routes:
            to_next_hop = path[1]

            to_mediated_transfer = to_channel.create_mediatedtransfer(
                raiden.address,  # this node is the new initiator
                from_mediated_transfer.
                initiator,  # the initiator is the target for the to_asset
                fee,
                to_amount,
                lock_expiration,
                hashlock,  # use the original hashlock
            )
            raiden.sign(to_mediated_transfer)

            if log.isEnabledFor(logging.DEBUG):
                log.debug(
                    'MEDIATED TRANSFER NEW PATH path:%s hashlock:%s',
                    lpex(path),
                    pex(from_mediated_transfer.lock.hashlock),
                )

            # Using assetmanager to register the interest because it outlives
            # this task, the secret handling will happen only _once_
            to_assetmanager.register_channel_for_hashlock(
                to_channel,
                hashlock,
            )
            to_channel.register_transfer(to_mediated_transfer)

            response = self.send_and_wait_valid(raiden, to_mediated_transfer)

            if log.isEnabledFor(logging.DEBUG):
                log.debug(
                    'EXCHANGE TRANSFER NEW PATH path:%s hashlock:%s',
                    lpex(path),
                    pex(hashlock),
                )

            # only refunds for `from_asset` must be considered (check send_and_wait_valid)
            if isinstance(response, RefundTransfer):
                if response.lock.amount != to_mediated_transfer.amount:
                    log.info(
                        'Partner %s sent an invalid refund message with an invalid amount',
                        pex(to_next_hop),
                    )
                    timeout_message = from_channel.create_timeouttransfer_for(
                        from_mediated_transfer)
                    raiden.send_async(from_mediated_transfer.sender,
                                      timeout_message)
                    self.transfermanager.on_hashlock_result(hashlock, False)
                    return
                else:
                    to_channel.register_transfer(response)

            elif isinstance(response, Secret):
                # this node is receiving the from_asset and sending the
                # to_asset, meaning that it can claim the to_asset but it needs
                # a Secret message to claim the from_asset
                to_assetmanager.handle_secretmessage(response)
                from_assetmanager.handle_secretmessage(response)

                self._wait_for_unlock_or_close(
                    raiden,
                    from_assetmanager,
                    from_channel,
                    from_mediated_transfer,
                )