Beispiel #1
0
def test_target_lock_is_expired_if_secret_is_not_registered_onchain():
    lock_amount = 7
    block_number = 1
    initiator = factories.HOP6
    pseudo_random_generator = random.Random()

    our_balance = 100
    our_address = factories.make_address()
    partner_balance = 130

    from_channel = factories.make_channel(
        our_address=our_address,
        our_balance=our_balance,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=partner_balance,
    )
    from_route = factories.route_from_channel(from_channel)
    expiration = block_number + from_channel.settle_timeout - from_channel.reveal_timeout

    from_transfer = factories.make_signed_transfer_for(
        from_channel,
        lock_amount,
        initiator,
        our_address,
        expiration,
        UNIT_SECRET,
    )

    init = ActionInitTarget(
        from_route,
        from_transfer,
    )

    init_transition = target.state_transition(
        None,
        init,
        from_channel,
        pseudo_random_generator,
        block_number,
    )
    assert init_transition.new_state is not None

    secret_reveal_iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=ReceiveSecretReveal(UNIT_SECRET,
                                         from_channel.partner_state.address),
        channel_state=from_channel,
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )

    expired_block_number = from_transfer.lock.expiration + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS
    iteration = target.state_transition(
        target_state=secret_reveal_iteration.new_state,
        state_change=Block(expired_block_number, None, None),
        channel_state=from_channel,
        pseudo_random_generator=pseudo_random_generator,
        block_number=expired_block_number,
    )
    assert must_contain_entry(iteration.events, EventUnlockClaimFailed, {})
def test_handle_inittarget():
    """ Init transfer must send a secret request if the expiration is valid. """
    block_number = 1
    pseudo_random_generator = random.Random()

    channels = make_channel_set([channel_properties])

    transfer_properties = LockedTransferSignedStateProperties(
        amount=channels[0].partner_state.contract_balance,
        expiration=channels[0].reveal_timeout + block_number + 1,
        canonical_identifier=channels[0].canonical_identifier,
        transferred_amount=0,
        locked_amount=channels[0].partner_state.contract_balance,
    )
    from_transfer = create(transfer_properties)

    state_change = ActionInitTarget(channels.get_route(0), from_transfer)

    iteration = target.handle_inittarget(state_change, channels[0],
                                         pseudo_random_generator, block_number)

    assert search_for_item(
        iteration.events,
        SendSecretRequest,
        {
            "payment_identifier": from_transfer.payment_identifier,
            "amount": from_transfer.lock.amount,
            "secrethash": from_transfer.lock.secrethash,
            "recipient": UNIT_TRANSFER_INITIATOR,
        },
    )
    assert search_for_item(iteration.events, SendProcessed, {})
Beispiel #3
0
def test_target_accept_keccak_empty_hash():
    lock_amount = 7
    block_number = 1
    pseudo_random_generator = random.Random()

    channels = make_channel_set([channel_properties2])
    expiration = block_number + channels[0].settle_timeout - channels[
        0].reveal_timeout

    from_transfer = factories.make_signed_transfer_for(
        channels[0],
        factories.LockedTransferSignedStateProperties(
            amount=lock_amount,
            target=channels.our_address(0),
            expiration=expiration,
            secret=EMPTY_SECRET,
        ),
        allow_invalid=True,
    )

    init = ActionInitTarget(
        from_hop=channels.get_hop(0),
        transfer=from_transfer,
        balance_proof=from_transfer.balance_proof,
        sender=from_transfer.balance_proof.sender,  # pylint: disable=no-member
    )

    init_transition = target.state_transition(
        target_state=None,
        state_change=init,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )
    assert init_transition.new_state
Beispiel #4
0
def test_handle_inittarget_bad_expiration():
    """ Init transfer must do nothing if the expiration is bad. """
    block_number = 1
    amount = 3
    initiator = factories.HOP1
    target_address = UNIT_TRANSFER_TARGET
    payment_network_identifier = factories.make_address()

    from_channel = factories.make_channel(
        our_address=target_address,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=amount,
    )
    from_route = factories.route_from_channel(from_channel)

    expiration = from_channel.reveal_timeout + block_number + 1
    from_transfer = factories.make_signed_transfer_for(
        from_channel,
        amount,
        initiator,
        target_address,
        expiration,
        UNIT_SECRET,
    )

    channel.handle_receive_lockedtransfer(
        from_channel,
        from_transfer,
    )

    state_change = ActionInitTarget(payment_network_identifier, from_route, from_transfer)
    iteration = target.handle_inittarget(state_change, from_channel, block_number)
    assert must_contain_entry(iteration.events, EventWithdrawFailed, {})
def test_target_reject_keccak_empty_hash():
    lock_amount = 7
    block_number = 1
    pseudo_random_generator = random.Random()

    channels = make_channel_set([channel_properties2])
    expiration = block_number + channels[0].settle_timeout - channels[
        0].reveal_timeout

    from_transfer = factories.make_signed_transfer_for(
        channels[0],
        factories.LockedTransferSignedStateProperties(
            transfer=factories.LockedTransferProperties(
                amount=lock_amount,
                target=channels.our_address(0),
                expiration=expiration,
                secret=EMPTY_HASH,
            ), ),
        allow_invalid=True,
    )

    init = ActionInitTarget(route=channels.get_route(0),
                            transfer=from_transfer)

    init_transition = target.state_transition(
        target_state=None,
        state_change=init,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )
    assert init_transition.new_state is None
Beispiel #6
0
def test_handle_inittarget_bad_expiration():
    """ Init transfer must do nothing if the expiration is bad. """
    block_number = 1
    amount = 3
    expire = factories.UNIT_REVEAL_TIMEOUT + block_number

    from_transfer = factories.make_transfer(
        amount,
        factories.ADDR,
        expire,
    )
    from_route = factories.make_route(
        factories.HOP1,
        amount,
    )
    state_change = ActionInitTarget(
        factories.ADDR,
        from_route,
        from_transfer,
        factories.UNIT_HASHLOCK,
        block_number,
    )

    iteration = target.handle_inittarget(state_change)
    assert len(iteration.events) == 0
Beispiel #7
0
def test_handle_inittarget():
    """ Init transfer must send a secret request if the expiration is valid. """
    block_number = 1
    amount = 3
    expire = factories.UNIT_REVEAL_TIMEOUT + block_number + 1
    initiator = factories.HOP1

    from_route, from_transfer = factories.make_from(
        amount,
        factories.ADDR,
        expire,
        initiator,
    )
    state_change = ActionInitTarget(
        factories.ADDR,
        from_route,
        from_transfer,
        block_number,
    )

    iteration = target.handle_inittarget(state_change)

    events = iteration.events
    assert isinstance(events[0], SendSecretRequest)

    assert events[0].identifier == from_transfer.identifier
    assert events[0].amount == from_transfer.amount
    assert events[0].hashlock == from_transfer.hashlock
    assert events[0].receiver == initiator
def test_target_receive_lock_expired():
    lock_amount = 7
    block_number = 1
    pseudo_random_generator = random.Random()

    channels = make_channel_set([channel_properties2])
    expiration = block_number + channels[0].settle_timeout - channels[
        0].reveal_timeout

    from_transfer = make_target_transfer(channels[0],
                                         amount=lock_amount,
                                         block_number=block_number)

    init = ActionInitTarget(channels.get_route(0), from_transfer)

    init_transition = target.state_transition(
        target_state=None,
        state_change=init,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )
    assert init_transition.new_state is not None
    assert init_transition.new_state.route == channels.get_route(0)
    assert init_transition.new_state.transfer == from_transfer

    balance_proof = create(
        BalanceProofSignedStateProperties(
            nonce=2,
            transferred_amount=from_transfer.balance_proof.transferred_amount,
            locked_amount=0,
            canonical_identifier=channels[0].canonical_identifier,
            message_hash=from_transfer.lock.secrethash,
        ))

    lock_expired_state_change = ReceiveLockExpired(
        balance_proof=balance_proof,
        secrethash=from_transfer.lock.secrethash,
        message_identifier=1)

    block_before_confirmed_expiration = expiration + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS - 1
    iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=lock_expired_state_change,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_before_confirmed_expiration,
    )
    assert not search_for_item(iteration.events, SendProcessed, {})

    block_lock_expired = block_before_confirmed_expiration + 1
    iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=lock_expired_state_change,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_lock_expired,
    )
    assert search_for_item(iteration.events, SendProcessed, {})
Beispiel #9
0
def test_state_transition():
    """ Happy case testing. """
    amount = 7
    block_number = 1
    initiator = factories.HOP6
    expire = block_number + factories.UNIT_REVEAL_TIMEOUT

    from_route, from_transfer = factories.make_from(
        amount,
        factories.ADDR,
        expire,
        initiator,
    )
    init = ActionInitTarget(
        factories.ADDR,
        from_route,
        from_transfer,
        block_number,
    )

    init_transition = target.state_transition(None, init)
    assert init_transition.new_state is not None
    assert init_transition.new_state.from_route == from_route
    assert init_transition.new_state.from_transfer == from_transfer

    first_new_block = Block(block_number + 1)
    first_block_iteration = target.state_transition(init_transition.new_state,
                                                    first_new_block)
    assert first_block_iteration.new_state.block_number == block_number + 1

    secret_reveal = ReceiveSecretReveal(factories.UNIT_SECRET, initiator)
    reveal_iteration = target.state_transition(first_block_iteration.new_state,
                                               secret_reveal)
    assert reveal_iteration.new_state.from_transfer.secret == factories.UNIT_SECRET

    second_new_block = Block(block_number + 2)
    second_block_iteration = target.state_transition(init_transition.new_state,
                                                     second_new_block)
    assert second_block_iteration.new_state.block_number == block_number + 2

    nonce = 11
    transferred_amount = 13
    locksroot = ''
    message_hash = ''
    balance_proof = ReceiveBalanceProof(
        from_transfer.identifier,
        from_route.node_address,
        nonce,
        transferred_amount,
        locksroot,
        from_route.channel_address,
        message_hash,
    )
    proof_iteration = target.state_transition(init_transition.new_state,
                                              balance_proof)
    assert proof_iteration.new_state is None
Beispiel #10
0
    def handle_message_lockedtransfer(
        raiden: "RaidenService", message: LockedTransfer  # pylint: disable=unused-argument
    ) -> List[StateChange]:
        secrethash = message.lock.secrethash
        # We must check if the secret was registered against the latest block,
        # even if the block is forked away and the transaction that registers
        # the secret is removed from the blockchain. The rationale here is that
        # someone else does know the secret, regardless of the chain state, so
        # the node must not use it to start a payment.
        #
        # For this particular case, it's preferable to use `latest` instead of
        # having a specific block_hash, because it's preferable to know if the secret
        # was ever known, rather than having a consistent view of the blockchain.
        registered = raiden.default_secret_registry.is_secret_registered(
            secrethash=secrethash, block_identifier=BLOCK_ID_LATEST
        )
        if registered:
            log.warning(
                f"Ignoring received locked transfer with secrethash {to_hex(secrethash)} "
                f"since it is already registered in the secret registry"
            )
            return []

        assert message.sender, "Invalid message dispatched, it should be signed"

        from_transfer = lockedtransfersigned_from_message(message)
        from_hop = HopState(
            node_address=message.sender,
            # pylint: disable=E1101
            channel_identifier=from_transfer.balance_proof.channel_identifier,
        )
        if message.target == TargetAddress(raiden.address):
            raiden.immediate_health_check_for(Address(message.initiator))
            return [
                ActionInitTarget(
                    from_hop=from_hop,
                    transfer=from_transfer,
                    balance_proof=from_transfer.balance_proof,
                    sender=from_transfer.balance_proof.sender,
                )
            ]
        else:
            route_states = routing.resolve_routes(
                routes=message.metadata.routes,
                token_network_address=from_transfer.balance_proof.token_network_address,
                chain_state=views.state_from_raiden(raiden),
            )
            return [
                ActionInitMediator(
                    from_hop=from_hop,
                    route_states=route_states,
                    from_transfer=from_transfer,
                    balance_proof=from_transfer.balance_proof,
                    sender=from_transfer.balance_proof.sender,
                )
            ]
Beispiel #11
0
def test_target_transfer_invalid_if_lock_registered_onchain():
    lock_amount = 7
    block_number = 1
    initiator = factories.HOP6
    pseudo_random_generator = random.Random()

    our_balance = 100
    our_address = factories.make_address()
    partner_balance = 130

    from_channel = factories.make_channel(
        our_address=our_address,
        our_balance=our_balance,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=partner_balance,
    )
    from_route = factories.route_from_channel(from_channel)
    expiration = block_number + from_channel.settle_timeout - from_channel.reveal_timeout

    from_transfer = factories.make_signed_transfer_for(
        from_channel,
        lock_amount,
        initiator,
        our_address,
        expiration,
        UNIT_SECRET,
        identifier=1,
        nonce=1,
    )

    init = ActionInitTarget(
        from_route,
        from_transfer,
    )

    secrethash = from_transfer.lock.secrethash
    # mock register secret on-chain
    from_channel.our_state.secrethashes_to_lockedlocks[
        secrethash] = from_transfer.lock
    channel.register_onchain_secret(
        channel_state=from_channel,
        secret=UNIT_SECRET,
        secrethash=secrethash,
        secret_reveal_block_number=0,
        delete_lock=True,
    )

    init_transition = target.state_transition(
        None,
        init,
        from_channel,
        pseudo_random_generator,
        block_number,
    )
    assert init_transition.new_state is None
Beispiel #12
0
def target_init(transfer: LockedTransfer):
    from_transfer = lockedtransfersigned_from_message(transfer)
    from_route = RouteState(
        transfer.sender,
        from_transfer.balance_proof.channel_address,
    )
    init_target_statechange = ActionInitTarget(
        from_route,
        from_transfer,
    )
    return init_target_statechange
def test_invalid_instantiation_action_init_mediator_and_target(
        additional_args):
    hop_state = HopState(
        node_address=factories.make_address(),
        channel_identifier=factories.make_channel_identifier(),
    )

    route_state = RouteState(route=[factories.make_address()])

    not_a_route_state = object()
    valid_transfer = factories.create(
        factories.LockedTransferSignedStateProperties())
    wrong_type_transfer = factories.create(
        factories.TransferDescriptionProperties())

    with pytest.raises(ValueError):
        ActionInitMediator(
            from_transfer=wrong_type_transfer,
            from_hop=hop_state,
            route_states=[route_state],
            **additional_args,
        )

    with pytest.raises(ValueError):
        ActionInitMediator(
            from_transfer=valid_transfer,
            from_hop=not_a_route_state,
            route_states=[route_state],
            **additional_args,
        )

    with pytest.raises(ValueError):
        ActionInitTarget(transfer=wrong_type_transfer,
                         from_hop=hop_state,
                         **additional_args)

    with pytest.raises(ValueError):
        ActionInitTarget(transfer=valid_transfer,
                         from_hop=not_a_route_state,
                         **additional_args)
Beispiel #14
0
def test_get_state_change_with_transfer_by_secrethash():
    serializer = JSONSerializer()
    storage = SerializedSQLiteStorage(":memory:", serializer)

    mediator_secret, mediator_secrethash = factories.make_secret_with_hash()
    channels = factories.mediator_make_channel_pair()
    mediator_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            secret=mediator_secret,
            target=channels.partner_address(1),
            initiator=channels.partner_address(0),
        )
    )
    mediator_state_change = factories.mediator_make_init_action(channels, mediator_transfer)

    target_secret, target_secrethash = factories.make_secret_with_hash()
    from_channel = factories.create(
        factories.NettingChannelStateProperties(
            partner_state=factories.NettingChannelEndStateProperties(
                balance=100, address=factories.make_address()
            )
        )
    )
    target_transfer = factories.create(
        factories.LockedTransferSignedStateProperties(
            secret=target_secret,
            target=channels.our_address(0),
            initiator=channels.partner_address(1),
        )
    )

    target_state_change = ActionInitTarget(
        from_hop=HopState(
            node_address=from_channel.partner_state.address,
            channel_identifier=from_channel.canonical_identifier.channel_identifier,
        ),
        transfer=target_transfer,
        balance_proof=target_transfer.balance_proof,
        sender=target_transfer.balance_proof.sender,  # pylint: disable=no-member
    )

    assert storage.count_state_changes() == 0
    storage.write_state_changes([mediator_state_change, target_state_change])
    assert storage.count_state_changes() == 2

    restored = get_state_change_with_transfer_by_secrethash(storage, mediator_secrethash)
    assert isinstance(restored.data, ActionInitMediator)
    assert restored.data.from_transfer == mediator_transfer

    restored = get_state_change_with_transfer_by_secrethash(storage, target_secrethash)
    assert isinstance(restored.data, ActionInitTarget)
    assert restored.data.transfer == target_transfer
Beispiel #15
0
def target_init(raiden, transfer):
    from_transfer = lockedtransfersigned_from_message(transfer)
    from_route = RouteState(
        transfer.sender,
        from_transfer.balance_proof.channel_address,
    )
    registry_address = raiden.default_registry.address
    init_target_statechange = ActionInitTarget(
        registry_address,
        from_route,
        from_transfer,
    )
    return init_target_statechange
Beispiel #16
0
def locked_transfer_to_action_init_target(
        locked_transfer: LockedTransfer) -> ActionInitTarget:
    from_transfer = lockedtransfersigned_from_message(locked_transfer)
    channel_id = from_transfer.balance_proof.channel_identifier  # pylint: disable=no-member
    from_hop = HopState(node_address=Address(locked_transfer.initiator),
                        channel_identifier=channel_id)
    init_target_statechange = ActionInitTarget(
        from_hop=from_hop,
        transfer=from_transfer,
        balance_proof=from_transfer.balance_proof,
        sender=from_transfer.balance_proof.sender,  # pylint: disable=no-member
    )

    return init_target_statechange
Beispiel #17
0
def test_handle_inittarget_bad_expiration():
    """ Init transfer must do nothing if the expiration is bad. """
    block_number = 1
    pseudo_random_generator = random.Random()

    channels = make_channel_set([channel_properties])
    expiration = channels[0].reveal_timeout + block_number + 1
    from_transfer = make_target_transfer(channels[0], expiration=expiration)

    channel.handle_receive_lockedtransfer(channels[0], from_transfer)

    state_change = ActionInitTarget(channels.get_route(0), from_transfer)
    iteration = target.handle_inittarget(state_change, channels[0],
                                         pseudo_random_generator, block_number)
    assert search_for_item(iteration.events, EventUnlockClaimFailed, {})
def test_handle_inittarget():
    """ Init transfer must send a secret request if the expiration is valid. """
    amount = 3
    block_number = 1
    initiator = factories.HOP1
    target_address = UNIT_TRANSFER_TARGET
    payment_network_identifier = factories.make_address()
    pseudo_random_generator = random.Random()

    from_channel = factories.make_channel(
        our_address=target_address,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=amount,
    )
    from_route = factories.route_from_channel(from_channel)

    expiration = from_channel.reveal_timeout + block_number + 1
    from_transfer = factories.make_signed_transfer(
        amount,
        initiator,
        target_address,
        expiration,
        UNIT_SECRET,
        channel_identifier=from_channel.identifier,
    )

    state_change = ActionInitTarget(
        payment_network_identifier,
        from_route,
        from_transfer,
    )

    iteration = target.handle_inittarget(
        state_change,
        from_channel,
        pseudo_random_generator,
        block_number,
    )

    events = iteration.events
    assert events
    assert isinstance(events[0], SendSecretRequest)

    assert events[0].payment_identifier == from_transfer.payment_identifier
    assert events[0].amount == from_transfer.lock.amount
    assert events[0].secrethash == from_transfer.lock.secrethash
    assert events[0].recipient == initiator
Beispiel #19
0
def test_handle_inittarget():
    """ Init transfer must send a secret request if the expiration is valid. """
    amount = 3
    block_number = 1
    initiator = factories.HOP1
    target_address = UNIT_TRANSFER_TARGET
    pseudo_random_generator = random.Random()

    from_channel = factories.make_channel(
        our_address=target_address,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=amount,
    )
    from_route = factories.route_from_channel(from_channel)

    expiration = from_channel.reveal_timeout + block_number + 1
    from_transfer = factories.make_signed_transfer(
        amount,
        initiator,
        target_address,
        expiration,
        UNIT_SECRET,
        channel_identifier=from_channel.identifier,
        token_network_address=from_channel.token_network_identifier,
    )

    state_change = ActionInitTarget(
        from_route,
        from_transfer,
    )

    iteration = target.handle_inittarget(
        state_change,
        from_channel,
        pseudo_random_generator,
        block_number,
    )

    assert must_contain_entry(
        iteration.events, SendSecretRequest, {
            'payment_identifier': from_transfer.payment_identifier,
            'amount': from_transfer.lock.amount,
            'secrethash': from_transfer.lock.secrethash,
            'recipient': initiator,
        })
    assert must_contain_entry(iteration.events, SendProcessed, {})
Beispiel #20
0
def make_target_state(
    our_address=factories.ADDR,
    amount=3,
    block_number=1,
    initiator=UNIT_TRANSFER_INITIATOR,
    expiration=None,
    pseudo_random_generator=None,
):
    pseudo_random_generator = pseudo_random_generator or random.Random()
    channels = make_channel_set(
        [
            NettingChannelStateProperties(
                our_state=NettingChannelEndStateProperties(address=our_address),
                partner_state=NettingChannelEndStateProperties(
                    address=UNIT_TRANSFER_SENDER, balance=amount
                ),
            )
        ]
    )

    expiration = expiration or channels[0].reveal_timeout + block_number + 1
    from_transfer = make_target_transfer(channels[0], amount, expiration, initiator)

    state_change = ActionInitTarget(
        from_hop=channels.get_hop(0),
        transfer=from_transfer,
        balance_proof=from_transfer.balance_proof,
        sender=from_transfer.balance_proof.sender,  # pylint: disable=no-member
    )
    iteration = target.handle_inittarget(
        state_change=state_change,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )

    return TargetStateSetup(
        channel=channels[0],
        new_state=iteration.new_state,
        our_address=our_address,
        initiator=initiator,
        expiration=expiration,
        amount=amount,
        block_number=block_number,
        pseudo_random_generator=pseudo_random_generator,
    )
Beispiel #21
0
def test_target_lock_is_expired_if_secret_is_not_registered_onchain():
    lock_amount = 7
    block_number = 1
    pseudo_random_generator = random.Random()

    channels = make_channel_set([channel_properties2])
    from_transfer = make_target_transfer(channels[0],
                                         amount=lock_amount,
                                         block_number=1)

    init = ActionInitTarget(
        from_hop=channels.get_hop(0),
        transfer=from_transfer,
        balance_proof=from_transfer.balance_proof,
        sender=from_transfer.balance_proof.sender,  # pylint: disable=no-member
    )

    init_transition = target.state_transition(
        target_state=None,
        state_change=init,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )
    assert init_transition.new_state is not None

    secret_reveal_iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=ReceiveSecretReveal(UNIT_SECRET,
                                         channels[0].partner_state.address),
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )

    expired_block_number = channel.get_receiver_expiration_threshold(
        from_transfer.lock.expiration)
    iteration = target.state_transition(
        target_state=secret_reveal_iteration.new_state,
        state_change=Block(expired_block_number, None, None),
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=expired_block_number,
    )
    assert search_for_item(iteration.events, EventUnlockClaimFailed, {})
Beispiel #22
0
def make_init_state_change(our_address, amount, block_number, initiator, expire=None):
    if expire is None:
        expire = block_number + factories.UNIT_REVEAL_TIMEOUT

    from_route, from_transfer = factories.make_from(
        amount,
        our_address,
        expire,
        initiator,
    )
    init = ActionInitTarget(
        our_address,
        from_route,
        from_transfer,
        block_number,
    )

    return init
Beispiel #23
0
def test_target_reject_keccak_empty_hash():
    lock_amount = 7
    block_number = 1
    initiator = factories.HOP6
    pseudo_random_generator = random.Random()

    our_balance = 100
    our_address = factories.make_address()
    partner_balance = 130

    from_channel = factories.make_channel(
        our_address=our_address,
        our_balance=our_balance,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=partner_balance,
    )
    from_route = factories.route_from_channel(from_channel)
    expiration = block_number + from_channel.settle_timeout - from_channel.reveal_timeout

    from_transfer = factories.make_signed_transfer_for(
        channel_state=from_channel,
        amount=lock_amount,
        initiator=initiator,
        target=our_address,
        expiration=expiration,
        secret=EMPTY_HASH,
        allow_invalid=True,
    )

    init = ActionInitTarget(
        route=from_route,
        transfer=from_transfer,
    )

    init_transition = target.state_transition(
        None,
        init,
        from_channel,
        pseudo_random_generator,
        block_number,
    )
    assert init_transition.new_state is None
Beispiel #24
0
    def target_mediated_transfer(self, message):
        graph = self.token_to_channelgraph[message.token]
        from_channel = graph.partneraddress_to_channel[message.sender]
        from_route = channel_to_routestate(from_channel, message.sender)

        from_transfer = lockedtransfer_from_message(message)
        our_address = self.address
        block_number = self.get_block_number()

        init_target = ActionInitTarget(
            our_address,
            from_route,
            from_transfer,
            block_number,
        )

        state_manager = StateManager(target_task.state_transition, None)
        self.state_machine_event_handler.log_and_dispatch(state_manager, init_target)

        identifier = message.identifier
        self.identifier_to_statemanagers[identifier].append(state_manager)
def test_target_lock_is_expired_if_secret_is_not_registered_onchain():
    lock_amount = 7
    block_number = 1
    pseudo_random_generator = random.Random()

    channels = make_channel_set([channel_properties2])
    from_transfer = make_target_transfer(channels[0],
                                         amount=lock_amount,
                                         block_number=1)

    init = ActionInitTarget(channels.get_route(0), from_transfer)

    init_transition = target.state_transition(
        target_state=None,
        state_change=init,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )
    assert init_transition.new_state is not None

    secret_reveal_iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=ReceiveSecretReveal(UNIT_SECRET,
                                         channels[0].partner_state.address),
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )

    expired_block_number = from_transfer.lock.expiration + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS
    iteration = target.state_transition(
        target_state=secret_reveal_iteration.new_state,
        state_change=Block(expired_block_number, None, None),
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=expired_block_number,
    )
    assert must_contain_entry(iteration.events, EventUnlockClaimFailed, {})
Beispiel #26
0
def action_init_initiator_to_action_init_target(
    action: ActionInitInitiator,
    channel: NettingChannelState,
    block_number: BlockNumber,
    route_state: RouteState,
    address: Address,
    private_key: PrivateKey,
) -> ActionInitTarget:
    transfer = signed_transfer_from_description(
        private_key=private_key,
        description=action.transfer,
        channel=channel,
        message_id=factories.make_message_identifier(),
        block_number=block_number,
        route_state=route_state,
        route_states=action.routes,
    )
    from_hop = HopState(node_address=address,
                        channel_identifier=channel.identifier)
    return ActionInitTarget(from_hop=from_hop,
                            transfer=transfer,
                            sender=address,
                            balance_proof=transfer.balance_proof)
def test_handle_inittarget():
    """ Init transfer must send a secret request if the expiration is valid. """
    block_number = 1
    pseudo_random_generator = random.Random()

    channels = make_channel_set([channel_properties])

    transfer_properties = LockedTransferSignedStateProperties(
        transfer=LockedTransferProperties(
            amount=channels[0].partner_state.contract_balance,
            expiration=channels[0].reveal_timeout + block_number + 1,
            balance_proof=BalanceProofProperties(
                channel_identifier=channels[0].identifier,
                token_network_identifier=channels[0].token_network_identifier,
                transferred_amount=0,
                locked_amount=channels[0].partner_state.contract_balance,
            ),
        ), )
    from_transfer = create(transfer_properties)

    state_change = ActionInitTarget(channels.get_route(0), from_transfer)

    iteration = target.handle_inittarget(
        state_change,
        channels[0],
        pseudo_random_generator,
        block_number,
    )

    assert must_contain_entry(
        iteration.events, SendSecretRequest, {
            'payment_identifier': from_transfer.payment_identifier,
            'amount': from_transfer.lock.amount,
            'secrethash': from_transfer.lock.secrethash,
            'recipient': UNIT_TRANSFER_INITIATOR,
        })
    assert must_contain_entry(iteration.events, SendProcessed, {})
Beispiel #28
0
def make_target_state(
        our_address,
        amount,
        block_number,
        initiator,
        expiration=None,
        pseudo_random_generator=None,
):
    pseudo_random_generator = pseudo_random_generator or random.Random()

    from_channel = factories.make_channel(
        our_address=our_address,
        partner_address=UNIT_TRANSFER_SENDER,
        partner_balance=amount,
    )
    from_route = factories.route_from_channel(from_channel)

    if expiration is None:
        expiration = from_channel.reveal_timeout + block_number + 1

    from_transfer = factories.make_signed_transfer_for(
        from_channel,
        amount,
        initiator,
        our_address,
        expiration,
        UNIT_SECRET,
    )

    state_change = ActionInitTarget(from_route, from_transfer)
    iteration = target.handle_inittarget(
        state_change,
        from_channel,
        pseudo_random_generator,
        block_number,
    )
    return from_channel, iteration.new_state
Beispiel #29
0
def test_get_state_change_with_balance_proof():
    """ All state changes which contain a balance proof must be found by when
    querying the database.
    """
    serializer = JSONSerializer
    storage = SQLiteStorage(':memory:', serializer)
    counter = itertools.count()

    lock_expired = ReceiveLockExpired(
        balance_proof=make_signed_balance_proof_from_counter(counter),
        secrethash=sha3(factories.make_secret(next(counter))),
        message_identifier=next(counter),
    )
    unlock = ReceiveUnlock(
        message_identifier=next(counter),
        secret=sha3(factories.make_secret(next(counter))),
        balance_proof=make_signed_balance_proof_from_counter(counter),
    )
    transfer_refund = ReceiveTransferRefund(
        transfer=make_signed_transfer_from_counter(counter),
        routes=list(),
    )
    transfer_refund_cancel_route = ReceiveTransferRefundCancelRoute(
        routes=list(),
        transfer=make_signed_transfer_from_counter(counter),
        secret=sha3(factories.make_secret(next(counter))),
    )
    mediator_from_route, mediator_signed_transfer = make_from_route_from_counter(
        counter)
    action_init_mediator = ActionInitMediator(
        routes=list(),
        from_route=mediator_from_route,
        from_transfer=mediator_signed_transfer,
    )
    target_from_route, target_signed_transfer = make_from_route_from_counter(
        counter)
    action_init_target = ActionInitTarget(
        route=target_from_route,
        transfer=target_signed_transfer,
    )

    statechanges_balanceproofs = [
        (lock_expired, lock_expired.balance_proof),
        (unlock, unlock.balance_proof),
        (transfer_refund, transfer_refund.transfer.balance_proof),
        (transfer_refund_cancel_route,
         transfer_refund_cancel_route.transfer.balance_proof),
        (action_init_mediator,
         action_init_mediator.from_transfer.balance_proof),
        (action_init_target, action_init_target.transfer.balance_proof),
    ]

    timestamp = datetime.utcnow().isoformat(timespec='milliseconds')

    for state_change, _ in statechanges_balanceproofs:
        storage.write_state_change(state_change, timestamp)

    for state_change, balance_proof in statechanges_balanceproofs:
        state_change_record = get_state_change_with_balance_proof(
            storage=storage,
            chain_id=balance_proof.chain_id,
            token_network_identifier=balance_proof.token_network_identifier,
            channel_identifier=balance_proof.channel_identifier,
            sender=balance_proof.sender,
            balance_hash=balance_proof.balance_hash,
        )
        assert state_change_record.data == state_change
Beispiel #30
0
def test_multiple_channel_states(
    chain_state,
    token_network_state,
    our_address,
):
    open_block_number = 10
    pseudo_random_generator = random.Random()
    pkey, address = factories.make_privkey_address()

    amount = 30
    our_balance = amount + 50
    channel_state = factories.make_channel(
        our_balance=our_balance,
        our_address=our_address,
        partner_balance=our_balance,
        partner_address=address,
    )
    payment_network_identifier = factories.make_payment_network_identifier()

    channel_new_state_change = ContractReceiveChannelNew(
        factories.make_transaction_hash(),
        token_network_state.address,
        channel_state,
    )

    channel_new_iteration = token_network.state_transition(
        payment_network_identifier,
        token_network_state,
        channel_new_state_change,
        pseudo_random_generator,
        open_block_number,
    )

    lock_amount = 30
    lock_expiration = 20
    lock_secret = sha3(b'test_end_state')
    lock_secrethash = sha3(lock_secret)
    lock = HashTimeLockState(
        lock_amount,
        lock_expiration,
        lock_secrethash,
    )

    mediated_transfer = make_receive_transfer_mediated(
        channel_state=channel_state,
        privkey=pkey,
        nonce=1,
        transferred_amount=0,
        lock=lock,
        token_network_address=token_network_state.address,
    )

    from_route = factories.route_from_channel(channel_state)
    init_target = ActionInitTarget(
        from_route,
        mediated_transfer,
    )

    node.state_transition(chain_state, init_target)

    closed_block_number = open_block_number + 10
    channel_close_state_change = ContractReceiveChannelClosed(
        factories.make_transaction_hash(),
        channel_state.partner_state.address,
        token_network_state.address,
        channel_state.identifier,
        closed_block_number,
    )

    channel_closed_iteration = token_network.state_transition(
        payment_network_identifier,
        channel_new_iteration.new_state,
        channel_close_state_change,
        pseudo_random_generator,
        closed_block_number,
    )

    settle_block_number = closed_block_number + channel_state.settle_timeout + 1
    channel_settled_state_change = ContractReceiveChannelSettled(
        factories.make_transaction_hash(),
        token_network_state.address,
        channel_state.identifier,
        settle_block_number,
    )

    channel_settled_iteration = token_network.state_transition(
        payment_network_identifier,
        channel_closed_iteration.new_state,
        channel_settled_state_change,
        pseudo_random_generator,
        closed_block_number,
    )

    token_network_state_after_settle = channel_settled_iteration.new_state
    ids_to_channels = token_network_state_after_settle.channelidentifiers_to_channels
    assert len(ids_to_channels) == 1
    assert channel_state.identifier in ids_to_channels

    # Create new channel while the previous one is pending unlock
    new_channel_state = factories.make_channel(
        our_balance=our_balance,
        partner_balance=our_balance,
        partner_address=address,
    )
    channel_new_state_change = ContractReceiveChannelNew(
        factories.make_transaction_hash(),
        token_network_state.address,
        new_channel_state,
    )

    channel_new_iteration = token_network.state_transition(
        payment_network_identifier,
        token_network_state,
        channel_new_state_change,
        pseudo_random_generator,
        open_block_number,
    )

    token_network_state_after_new_open = channel_new_iteration.new_state
    ids_to_channels = token_network_state_after_new_open.channelidentifiers_to_channels

    assert len(ids_to_channels) == 2
    assert channel_state.identifier in ids_to_channels