Exemple #1
0
def handle_offchain_secretreveal_light(
    initiator_state: InitiatorTransferState,
    state_change: ReceiveSecretRevealLight,
    channel_state: NettingChannelState,
    pseudo_random_generator: random.Random
) -> TransitionResult[InitiatorTransferState]:
    """ Once the next hop proves it knows the secret, the initiator can unlock
    the mediated transfer.

    This will validate the secret, and if valid a new balance proof is sent to
    the next hop with the current lock removed from the merkle tree and the
    transferred amount updated.
    """
    iteration: TransitionResult[InitiatorTransferState]
    valid_reveal = is_valid_secret_reveal(
        state_change=state_change,
        transfer_secrethash=initiator_state.transfer_description.secrethash,
        secret=state_change.secret,
    )
    sent_by_partner = state_change.sender == channel_state.partner_state.address
    is_channel_open = channel.get_status(channel_state) == CHANNEL_STATE_OPENED

    if valid_reveal and is_channel_open and sent_by_partner:
        unlock_events = events_for_unlock_base(
            initiator_state=initiator_state,
            channel_state=channel_state,
            secret=state_change.secret,
        )

        transfer_description = initiator_state.transfer_description

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

        store_received_secret_reveal_event = StoreMessageEvent(state_change.secret_reveal_message.message_identifier,
                                                               transfer_description.payment_identifier, 9,
                                                               state_change.secret_reveal_message,
                                                               True)
        store_created_unlock_event = StoreMessageEvent(message_identifier, transfer_description.payment_identifier, 11,
                                                       unlock_msg, False)

        events = list()
        events.append(store_received_secret_reveal_event)
        events.append(store_created_unlock_event)
        events.extend(unlock_events)
        iteration = TransitionResult(None, events)
    else:
        events = list()
        iteration = TransitionResult(initiator_state, events)

    return iteration
Exemple #2
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)
def test_balance_proof_11():
    dict_data = {
        "type":
        "Secret",
        "chain_id":
        33,
        "message_identifier":
        4334089825906208294,
        "payment_identifier":
        15193824610622741555,
        "secret":
        "0x8c45240e576c4befd51d063549ce18859c5a2b3c356035884588a65c3dfcef4b",
        "nonce":
        2,
        "token_network_address":
        "0x7351ed719de72db92a54c99ef2c4d287f69672a1",
        "channel_identifier":
        1,
        "transferred_amount":
        1000000000000000,
        "locked_amount":
        0,
        "locksroot":
        "0x0000000000000000000000000000000000000000000000000000000000000000"
    }

    message = Unlock(chain_id=dict_data["chain_id"],
                     message_identifier=dict_data["message_identifier"],
                     payment_identifier=dict_data["payment_identifier"],
                     secret=decode_hex(dict_data["secret"]),
                     nonce=dict_data["nonce"],
                     token_network_address=decode_hex(
                         dict_data["token_network_address"]),
                     channel_identifier=dict_data["channel_identifier"],
                     transferred_amount=dict_data["transferred_amount"],
                     locked_amount=dict_data["locked_amount"],
                     locksroot=decode_hex(dict_data["locksroot"]))

    message.sign(signer)
    data_was_signed = message._data_to_sign()
    print("Balance Proof signature: " + message.signature.hex())
    assert recover(data_was_signed, message.signature) == to_canonical_address(
        "0x7ca28d3d760b4aa2b79e8d42cbdc187c7df9af40")
def test_update_non_closing_balance_proof():
    dict_data = {
        "type":
        "Secret",
        "chain_id":
        33,
        "message_identifier":
        4174357123961474742,
        "payment_identifier":
        5100335212362582814,
        "secret":
        "0xd1b2cb5b175436f60b6e59be64f4c7b59b3569b8f877c55f66c8f8a6ba8055f4",
        "nonce":
        2,
        "token_network_address":
        "0x013b47e5eb40a476dc0e9a212d376899288561a2",
        "channel_identifier":
        14,
        "transferred_amount":
        20000000,
        "locked_amount":
        0,
        "locksroot":
        "0x0000000000000000000000000000000000000000000000000000000000000000",
        "signature":
        "0x94d6dba985096b6259151664367443bcd83c5e8cc1913c34bd3542b4ac1b4e7772696e145445625eef4167080fddb3ebe730c71319bee66235864661d9dddc2b1c"
    }
    # dict_data = {"type": "Secret", "chain_id": 33, "message_identifier": 18237677588114994956, "payment_identifier": 1322351847924173620, "secret": "0xa4678d1f1db376f20854619fc8aa8021f88f318e14ff600aa051e8e4ded5d023", "nonce": 2, "token_network_address": "0x7351ed719de72db92a54c99ef2c4d287f69672a1", "channel_identifier": 3, "transferred_amount": 100000000000000000, "locked_amount": 0, "locksroot": "0x0000000000000000000000000000000000000000000000000000000000000000", "signature": "0x5c805ba51ac4776d879c276d54c1ed97905399e227e7b9ef50aa4f36605ac25e5ab707641c4bd85a0d89549841beaf4f0e06c839ad5460aaf26d4c68b9af822c1b"}
    balance_proof_msg = Unlock.from_dict(dict_data)
    balance_proof = balanceproof_from_envelope(balance_proof_msg)
    non_closing_signature = create_balance_proof_update_signature(
        "0x013b47e5eb40a476dc0e9a212d376899288561a2", 14,
        balance_proof.balance_hash, 2, balance_proof.message_hash,
        decode_hex(
            "0x94d6dba985096b6259151664367443bcd83c5e8cc1913c34bd3542b4ac1b4e7772696e145445625eef4167080fddb3ebe730c71319bee66235864661d9dddc2b1c"
        ))

    our_signed_data = pack_balance_proof_update(
        nonce=balance_proof.nonce,
        balance_hash=balance_proof.balance_hash,
        additional_hash=balance_proof.message_hash,
        canonical_identifier=balance_proof.canonical_identifier,
        partner_signature=Signature(
            decode_hex(
                "0x94d6dba985096b6259151664367443bcd83c5e8cc1913c34bd3542b4ac1b4e7772696e145445625eef4167080fddb3ebe730c71319bee66235864661d9dddc2b1c"
            )))

    print("Update non consling blanace proof signature " +
          non_closing_signature.hex())
    our_recovered_address = recover(data=our_signed_data,
                                    signature=Signature(non_closing_signature))
    assert our_recovered_address == to_canonical_address(
        "0x7ca28d3d760b4aa2b79e8d42cbdc187c7df9af40")
 def get_latest_light_client_non_closing_balance_proof(
         cls, channel_id: int, storage: SerializedSQLiteStorage):
     latest_update_balance_proof_data = storage.get_latest_light_client_non_closing_balance_proof(
         channel_id)
     if latest_update_balance_proof_data:
         balance_proof = Unlock.from_dict(
             json.loads(latest_update_balance_proof_data[7]))
         return LightClientNonClosingBalanceProof(
             latest_update_balance_proof_data[1],
             latest_update_balance_proof_data[2],
             latest_update_balance_proof_data[3],
             latest_update_balance_proof_data[4],
             latest_update_balance_proof_data[5],
             latest_update_balance_proof_data[6], balance_proof,
             latest_update_balance_proof_data[8],
             latest_update_balance_proof_data[0])
     return None
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
Exemple #7
0
def test_regression_multiple_revealsecret(raiden_network, token_addresses,
                                          transport_protocol):
    """ Multiple RevealSecret messages arriving at the same time must be
    handled properly.

    Unlock handling followed these steps:

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

    The step marked with an asterisk above introduced a context-switch. This
    allowed a second Reveal Unlock message to be handled before the channel was
    unregistered. And because the channel was already updated an exception was raised
    for an unknown secret.
    """
    app0, app1 = raiden_network
    token = token_addresses[0]
    token_network_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
    unlock = Unlock(
        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(unlock)

    if transport_protocol is TransportProtocol.UDP:
        messages = [
            unlock.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 = [
            unlock,
            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 run_test_regression_multiple_revealsecret(raiden_network, token_addresses,
                                              transport_protocol):
    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(amount=lock_amount,
                expiration=expiration,
                secrethash=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(message_identifier=random.randint(
        0, UINT64_MAX),
                                 secret=secret)
    app0.raiden.sign(reveal_secret)

    token_network_identifier = channelstate_0_1.token_network_identifier
    unlock = Unlock(
        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(unlock)

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

    gevent.joinall(wait)