Example #1
0
def test_handle_onchain_secretreveal():
    """ The target node must update the lock state when the secret is
    registered in the blockchain.
    """
    setup = make_target_state(
        block_number=1,
        expiration=1 + factories.UNIT_REVEAL_TIMEOUT,
    )
    assert factories.UNIT_SECRETHASH in setup.channel.partner_state.secrethashes_to_lockedlocks

    offchain_secret_reveal_iteration = target.state_transition(
        target_state=setup.new_state,
        state_change=ReceiveSecretReveal(UNIT_SECRET, setup.initiator),
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=setup.block_number,
    )
    assert UNIT_SECRETHASH in setup.channel.partner_state.secrethashes_to_unlockedlocks
    assert UNIT_SECRETHASH not in setup.channel.partner_state.secrethashes_to_lockedlocks

    # Make sure that an emptyhash on chain reveal is rejected.
    block_number_prior_the_expiration = setup.expiration - 2
    onchain_reveal = ContractReceiveSecretReveal(
        transaction_hash=factories.make_address(),
        secret_registry_address=factories.make_address(),
        secrethash=EMPTY_HASH_KECCAK,
        secret=EMPTY_HASH,
        block_number=block_number_prior_the_expiration,
    )
    onchain_secret_reveal_iteration = target.state_transition(
        target_state=offchain_secret_reveal_iteration.new_state,
        state_change=onchain_reveal,
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=block_number_prior_the_expiration,
    )
    unlocked_onchain = setup.channel.partner_state.secrethashes_to_onchain_unlockedlocks
    assert EMPTY_HASH_KECCAK not in unlocked_onchain

    # now let's go for the actual secret
    onchain_reveal.secret = UNIT_SECRET
    onchain_reveal.secrethash = UNIT_SECRETHASH
    onchain_secret_reveal_iteration = target.state_transition(
        target_state=offchain_secret_reveal_iteration.new_state,
        state_change=onchain_reveal,
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=block_number_prior_the_expiration,
    )
    unlocked_onchain = setup.channel.partner_state.secrethashes_to_onchain_unlockedlocks
    assert UNIT_SECRETHASH in unlocked_onchain

    # Check that after we register a lock on-chain handling the block again will
    # not cause us to attempt an onchain re-register
    extra_block_handle_transition = target.handle_block(
        target_state=onchain_secret_reveal_iteration.new_state,
        channel_state=setup.channel,
        block_number=block_number_prior_the_expiration + 1,
    )
    assert len(extra_block_handle_transition.events) == 0
Example #2
0
def test_handle_offchain_secretreveal_after_lock_expired():
    """Test that getting the secret revealed after lock expiration for the
    target does not end up continuously emitting EventUnlockClaimFailed

    Target part for https://github.com/raiden-network/raiden/issues/3086
    """
    setup = make_target_state()

    lock_expiration_block_number = channel.get_sender_expiration_threshold(
        setup.new_state.transfer.lock,
    )
    lock_expiration_block = Block(
        block_number=lock_expiration_block_number,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = target.state_transition(
        target_state=setup.new_state,
        state_change=lock_expiration_block,
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=lock_expiration_block_number,
    )
    state = iteration.new_state

    msg = 'At the expiration block we should get an EventUnlockClaimFailed'
    assert must_contain_entry(iteration.events, EventUnlockClaimFailed, {}), msg

    iteration = target.state_transition(
        target_state=state,
        state_change=ReceiveSecretReveal(UNIT_SECRET, setup.initiator),
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=lock_expiration_block_number + 1,
    )
    state = iteration.new_state

    next_block = Block(
        block_number=lock_expiration_block_number + 1,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = target.state_transition(
        target_state=state,
        state_change=next_block,
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=lock_expiration_block_number + 1,
    )
    msg = 'At the next block we should not get the same event'
    assert not must_contain_entry(iteration.events, EventUnlockClaimFailed, {}), msg
Example #3
0
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
Example #4
0
def test_handle_block_lower_block_number():
    """ Nothing changes. """
    initiator = factories.HOP6
    our_address = factories.ADDR
    amount = 3
    block_number = 10
    pseudo_random_generator = random.Random()

    from_channel, state = make_target_state(
        our_address,
        amount,
        block_number,
        initiator,
    )

    new_block = Block(block_number - 1)
    iteration = target.state_transition(
        state,
        new_block,
        from_channel,
        pseudo_random_generator,
        new_block.block_number,
    )
    assert iteration.new_state
    assert not iteration.events
Example #5
0
def subdispatch_targettask(
        chain_state: ChainState,
        state_change: StateChange,
        token_network_identifier: TokenNetworkID,
        channel_identifier: ChannelID,
        secrethash: SecretHash,
) -> TransitionResult:

    block_number = chain_state.block_number
    sub_task = chain_state.payment_mapping.secrethashes_to_task.get(secrethash)

    if not sub_task:
        is_valid_subtask = True
        target_state = None

    elif sub_task and isinstance(sub_task, TargetTask):
        is_valid_subtask = (
            token_network_identifier == sub_task.token_network_identifier
        )
        target_state = sub_task.target_state
    else:
        is_valid_subtask = False

    events = list()
    channel_state = None
    if is_valid_subtask:
        channel_state = views.get_channelstate_by_token_network_identifier(
            chain_state,
            token_network_identifier,
            channel_identifier,
        )

    if channel_state:
        pseudo_random_generator = chain_state.pseudo_random_generator

        iteration = target.state_transition(
            target_state,
            state_change,
            channel_state,
            pseudo_random_generator,
            block_number,
        )
        events = iteration.events

        if iteration.new_state:
            sub_task = TargetTask(
                token_network_identifier,
                channel_identifier,
                iteration.new_state,
            )
            chain_state.payment_mapping.secrethashes_to_task[secrethash] = sub_task
        elif secrethash in chain_state.payment_mapping.secrethashes_to_task:
            del chain_state.payment_mapping.secrethashes_to_task[secrethash]

    return TransitionResult(chain_state, events)
Example #6
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(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 = channel.get_receiver_expiration_threshold(from_transfer.lock)
    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, {})
Example #7
0
def test_handle_block_lower_block_number():
    """ Nothing changes. """
    setup = make_target_state(block_number=10)

    new_block = Block(
        block_number=setup.block_number - 1,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = target.state_transition(
        target_state=setup.new_state,
        state_change=new_block,
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=new_block.block_number,
    )
    assert iteration.new_state
    assert not iteration.events
def test_handle_block_lower_block_number():
    """ Nothing changes. """
    initiator = factories.HOP6
    our_address = factories.ADDR
    amount = 3
    block_number = 1
    expire = block_number + factories.UNIT_REVEAL_TIMEOUT

    state = make_target_state(
        our_address,
        amount,
        block_number,
        initiator,
        expire,
    )

    new_block = Block(block_number - 1)
    iteration = target.state_transition(state, new_block)
    assert iteration.new_state.block_number == block_number
Example #9
0
def test_handle_block():
    """ Increase the block number. """
    setup = make_target_state()

    new_block = Block(
        block_number=setup.block_number + 1,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )

    iteration = target.state_transition(
        target_state=setup.new_state,
        state_change=new_block,
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=new_block.block_number,
    )

    assert iteration.new_state
    assert not iteration.events
Example #10
0
def test_handle_block_lower_block_number():
    """ Nothing changes. """
    initiator = factories.HOP6
    our_address = factories.ADDR
    amount = 3
    block_number = 10

    from_channel, state = make_target_state(
        our_address,
        amount,
        block_number,
        initiator,
    )

    new_block = Block(block_number - 1)
    iteration = target.state_transition(
        state,
        new_block,
        from_channel,
        new_block.block_number,
    )
    assert iteration.new_state
    assert not iteration.events
Example #11
0
def test_handle_block():
    """ Increase the block number. """
    initiator = factories.HOP6
    our_address = factories.ADDR
    amount = 3
    block_number = 1

    from_channel, state = make_target_state(
        our_address,
        amount,
        block_number,
        initiator,
    )

    new_block = Block(block_number + 1)
    iteration = target.state_transition(
        state,
        new_block,
        from_channel,
        new_block.block_number,
    )
    assert iteration.new_state
    assert not iteration.events
def test_state_transition():
    """ Happy case testing. """
    lock_amount = 7
    block_number = 1
    initiator = factories.HOP6
    pseudo_random_generator = random.Random()

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

    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

    first_new_block = Block(
        block_number=block_number + 1,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    first_block_iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=first_new_block,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=first_new_block.block_number,
    )

    secret_reveal = ReceiveSecretReveal(factories.UNIT_SECRET, initiator)
    reveal_iteration = target.state_transition(
        target_state=first_block_iteration.new_state,
        state_change=secret_reveal,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=first_new_block.block_number,
    )
    assert reveal_iteration.events

    second_new_block = Block(
        block_number=block_number + 2,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=second_new_block,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=second_new_block.block_number,
    )
    assert not iteration.events

    balance_proof = create(
        BalanceProofSignedStateProperties(
            balance_proof=BalanceProofProperties(
                nonce=from_transfer.balance_proof.nonce + 1,
                transferred_amount=lock_amount,
                locked_amount=0,
                token_network_identifier=channels[0].token_network_identifier,
                channel_identifier=channels.get_route(0).channel_identifier,
                locksroot=EMPTY_MERKLE_ROOT,
            ),
            message_hash=b'\x00' * 32,  # invalid
        ))

    balance_proof_state_change = ReceiveUnlock(
        message_identifier=random.randint(0, UINT64_MAX),
        secret=UNIT_SECRET,
        balance_proof=balance_proof,
    )

    proof_iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=balance_proof_state_change,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number + 2,
    )
    assert proof_iteration.new_state is None
Example #13
0
def subdispatch_to_paymenttask(node_state, state_change, secrethash):
    block_number = node_state.block_number
    sub_task = node_state.payment_mapping.secrethashes_to_task.get(secrethash)
    events = list()

    if sub_task:
        if isinstance(sub_task, PaymentMappingState.InitiatorTask):
            payment_network_identifier = sub_task.payment_network_identifier
            token_address = sub_task.token_address

            token_network_state = get_token_network(
                node_state,
                payment_network_identifier,
                token_address,
            )

            if token_network_state:
                sub_iteration = initiator_manager.state_transition(
                    sub_task.manager_state,
                    state_change,
                    token_network_state.channelidentifiers_to_channels,
                    block_number,
                )
                events = sub_iteration.events

        elif isinstance(sub_task, PaymentMappingState.MediatorTask):
            payment_network_identifier = sub_task.payment_network_identifier
            token_address = sub_task.token_address

            token_network_state = get_token_network(
                node_state,
                payment_network_identifier,
                token_address,
            )

            if token_network_state:
                sub_iteration = mediator.state_transition(
                    sub_task.mediator_state,
                    state_change,
                    token_network_state.channelidentifiers_to_channels,
                    block_number,
                )
                events = sub_iteration.events

        elif isinstance(sub_task, PaymentMappingState.TargetTask):
            payment_network_identifier = sub_task.payment_network_identifier
            token_address = sub_task.token_address
            channel_identifier = sub_task.channel_identifier

            channel_state = views.get_channelstate_by_tokenaddress(
                node_state,
                payment_network_identifier,
                token_address,
                channel_identifier,
            )

            if channel_state:
                sub_iteration = target.state_transition(
                    sub_task.target_state,
                    state_change,
                    channel_state,
                    block_number,
                )
                events = sub_iteration.events

    return TransitionResult(node_state, events)
Example #14
0
def test_state_transition():
    """ Happy case testing. """
    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_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
    assert init_transition.new_state.route == from_route
    assert init_transition.new_state.transfer == from_transfer

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

    secret_reveal = ReceiveSecretReveal(factories.UNIT_SECRET, initiator)
    reveal_iteration = target.state_transition(
        first_block_iteration.new_state,
        secret_reveal,
        from_channel,
        pseudo_random_generator,
        first_new_block,
    )
    assert reveal_iteration.events

    second_new_block = Block(block_number + 2)
    iteration = target.state_transition(
        init_transition.new_state,
        second_new_block,
        from_channel,
        pseudo_random_generator,
        second_new_block.block_number,
    )
    assert not iteration.events

    nonce = from_transfer.balance_proof.nonce + 1
    transferred_amount = lock_amount
    locksroot = EMPTY_MERKLE_ROOT
    invalid_message_hash = b'\x00' * 32
    locked_amount = 0

    balance_proof = factories.make_signed_balance_proof(
        nonce,
        transferred_amount,
        locked_amount,
        from_channel.token_network_identifier,
        from_route.channel_identifier,
        locksroot,
        invalid_message_hash,
        UNIT_TRANSFER_PKEY,
        UNIT_TRANSFER_SENDER,
    )

    balance_proof_state_change = ReceiveUnlock(
        random.randint(0, UINT64_MAX),
        UNIT_SECRET,
        balance_proof,
    )

    proof_iteration = target.state_transition(
        init_transition.new_state,
        balance_proof_state_change,
        from_channel,
        pseudo_random_generator,
        block_number + 2,
    )
    assert proof_iteration.new_state is None
Example #15
0
def test_handle_offchain_secretreveal_after_lock_expired():
    """Test that getting the secret revealed after lock expiration for the
    target does not end up continuously emitting EventUnlockClaimFailed

    Target part for https://github.com/raiden-network/raiden/issues/3086
    """
    amount = 3
    block_number = 1
    expiration = block_number + factories.UNIT_REVEAL_TIMEOUT
    initiator = factories.HOP1
    our_address = factories.ADDR
    secret = factories.UNIT_SECRET
    pseudo_random_generator = random.Random()

    channel_state, state = make_target_state(
        our_address,
        amount,
        block_number,
        initiator,
        expiration,
    )

    lock_expiration = state.transfer.lock.expiration
    lock_expiration_block_number = lock_expiration + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS * 2
    lock_expiration_block = Block(
        block_number=lock_expiration_block_number,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = target.state_transition(
        target_state=state,
        state_change=lock_expiration_block,
        channel_state=channel_state,
        pseudo_random_generator=pseudo_random_generator,
        block_number=lock_expiration_block_number,
    )
    state = iteration.new_state

    msg = 'At the expiration block we should get an EventUnlockClaimFailed'
    assert must_contain_entry(iteration.events, EventUnlockClaimFailed, {}), msg

    iteration = target.state_transition(
        target_state=state,
        state_change=ReceiveSecretReveal(secret, initiator),
        channel_state=channel_state,
        pseudo_random_generator=pseudo_random_generator,
        block_number=lock_expiration_block_number + 1,
    )
    state = iteration.new_state

    next_block = Block(
        block_number=lock_expiration_block_number + 1,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = target.state_transition(
        target_state=state,
        state_change=next_block,
        channel_state=channel_state,
        pseudo_random_generator=pseudo_random_generator,
        block_number=lock_expiration_block_number + 1,
    )
    msg = 'At the next block we should not get the same event'
    assert not must_contain_entry(iteration.events, EventUnlockClaimFailed, {}), msg
Example #16
0
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(
        balance_proof=BalanceProofProperties(
            nonce=2,
            transferred_amount=from_transfer.balance_proof.transferred_amount,
            locked_amount=0,
            token_network_identifier=from_transfer.balance_proof.token_network_identifier,
            channel_identifier=channels[0].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 must_contain_entry(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 must_contain_entry(iteration.events, SendProcessed, {})
Example #17
0
def subdispatch_to_paymenttask(
        chain_state: ChainState, state_change: StateChange,
        secrethash: SecretHash) -> TransitionResult[ChainState]:
    block_number = chain_state.block_number
    block_hash = chain_state.block_hash
    sub_task = chain_state.payment_mapping.secrethashes_to_task.get(secrethash)
    events: List[Event] = list()

    if sub_task:
        pseudo_random_generator = chain_state.pseudo_random_generator
        sub_iteration: Union[TransitionResult[InitiatorPaymentState],
                             TransitionResult[MediatorTransferState],
                             TransitionResult[TargetTransferState], ]

        if isinstance(sub_task, InitiatorTask):
            token_network_identifier = sub_task.token_network_identifier
            token_network_state = get_token_network_by_address(
                chain_state, token_network_identifier)
            if token_network_state:
                sub_iteration = initiator_manager.state_transition(
                    sub_task.manager_state,
                    state_change,
                    token_network_state.channelidentifiers_to_channels,
                    pseudo_random_generator,
                    block_number,
                )
                events = sub_iteration.events

                if sub_iteration.new_state is None:
                    del chain_state.payment_mapping.secrethashes_to_task[
                        secrethash]

        elif isinstance(sub_task, MediatorTask):
            token_network_identifier = sub_task.token_network_identifier
            token_network_state = get_token_network_by_address(
                chain_state, token_network_identifier)

            if token_network_state:
                channelids_to_channels = token_network_state.channelidentifiers_to_channels
                sub_iteration = mediator.state_transition(
                    mediator_state=sub_task.mediator_state,
                    state_change=state_change,
                    channelidentifiers_to_channels=channelids_to_channels,
                    nodeaddresses_to_networkstates=chain_state.
                    nodeaddresses_to_networkstates,
                    pseudo_random_generator=pseudo_random_generator,
                    block_number=block_number,
                    block_hash=block_hash,
                )
                events = sub_iteration.events

                if sub_iteration.new_state is None:
                    del chain_state.payment_mapping.secrethashes_to_task[
                        secrethash]

        elif isinstance(sub_task, TargetTask):
            token_network_identifier = sub_task.token_network_identifier
            channel_identifier = sub_task.channel_identifier

            channel_state = views.get_channelstate_by_canonical_identifier(
                chain_state=chain_state,
                canonical_identifier=CanonicalIdentifier(
                    chain_identifier=chain_state.chain_id,
                    token_network_address=token_network_identifier,
                    channel_identifier=channel_identifier,
                ),
            )

            if channel_state:
                sub_iteration = target.state_transition(
                    target_state=sub_task.target_state,
                    state_change=state_change,
                    channel_state=channel_state,
                    pseudo_random_generator=pseudo_random_generator,
                    block_number=block_number,
                )
                events = sub_iteration.events

                if sub_iteration.new_state is None:
                    del chain_state.payment_mapping.secrethashes_to_task[
                        secrethash]

    return TransitionResult(chain_state, events)
Example #18
0
def test_state_transition():
    """ Happy case testing. """
    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_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
    assert init_transition.new_state.route == from_route
    assert init_transition.new_state.transfer == from_transfer

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

    secret_reveal = ReceiveSecretReveal(factories.UNIT_SECRET, initiator)
    reveal_iteration = target.state_transition(
        first_block_iteration.new_state,
        secret_reveal,
        from_channel,
        pseudo_random_generator,
        first_new_block,
    )
    assert reveal_iteration.events

    second_new_block = Block(block_number + 2)
    iteration = target.state_transition(
        init_transition.new_state,
        second_new_block,
        from_channel,
        pseudo_random_generator,
        second_new_block.block_number,
    )
    assert not iteration.events

    nonce = from_transfer.balance_proof.nonce + 1
    transferred_amount = lock_amount
    locksroot = EMPTY_MERKLE_ROOT
    invalid_message_hash = b'\x00' * 32
    locked_amount = 0

    balance_proof = factories.make_signed_balance_proof(
        nonce,
        transferred_amount,
        locked_amount,
        from_channel.token_network_identifier,
        from_route.channel_identifier,
        locksroot,
        invalid_message_hash,
        UNIT_TRANSFER_PKEY,
        UNIT_TRANSFER_SENDER,
    )

    balance_proof_state_change = ReceiveUnlock(
        message_identifier=random.randint(0, UINT64_MAX),
        secret=UNIT_SECRET,
        balance_proof=balance_proof,
    )

    proof_iteration = target.state_transition(
        init_transition.new_state,
        balance_proof_state_change,
        from_channel,
        pseudo_random_generator,
        block_number + 2,
    )
    assert proof_iteration.new_state is None
Example #19
0
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(
        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
    assert init_transition.new_state.from_hop == channels.get_hop(0)
    assert init_transition.new_state.transfer == from_transfer

    balance_proof = create(
        BalanceProofSignedStateProperties(
            nonce=2,
            # pylint: disable=no-member
            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,
        sender=balance_proof.sender,  # pylint: disable=no-member
    )

    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, {})
Example #20
0
def test_handle_onchain_secretreveal():
    """ The target node must update the lock state when the secret is
    registered in the blockchain.
    """
    amount = 3
    block_number = 1
    expiration = block_number + factories.UNIT_REVEAL_TIMEOUT
    initiator = factories.HOP1
    our_address = factories.ADDR
    secret = factories.UNIT_SECRET
    pseudo_random_generator = random.Random()

    channel_state, state = make_target_state(
        our_address,
        amount,
        block_number,
        initiator,
        expiration,
    )
    assert factories.UNIT_SECRETHASH in channel_state.partner_state.secrethashes_to_lockedlocks

    offchain_secret_reveal_iteration = target.state_transition(
        state,
        ReceiveSecretReveal(secret, initiator),
        channel_state,
        pseudo_random_generator,
        block_number,
    )
    assert factories.UNIT_SECRETHASH in channel_state.partner_state.secrethashes_to_unlockedlocks
    assert factories.UNIT_SECRETHASH not in channel_state.partner_state.secrethashes_to_lockedlocks

    # Make sure that an emptyhash on chain reveal is rejected.
    block_number_prior_the_expiration = expiration - 2
    onchain_reveal = ContractReceiveSecretReveal(
        transaction_hash=factories.make_address(),
        secret_registry_address=factories.make_address(),
        secrethash=EMPTY_HASH_KECCAK,
        secret=EMPTY_HASH,
        block_number=block_number_prior_the_expiration,
    )
    onchain_secret_reveal_iteration = target.state_transition(
        offchain_secret_reveal_iteration.new_state,
        onchain_reveal,
        channel_state,
        pseudo_random_generator,
        block_number_prior_the_expiration,
    )
    unlocked_onchain = channel_state.partner_state.secrethashes_to_onchain_unlockedlocks
    assert EMPTY_HASH_KECCAK not in unlocked_onchain

    # now let's go for the actual secret
    onchain_reveal.secret = secret
    onchain_reveal.secrethash = factories.UNIT_SECRETHASH
    onchain_secret_reveal_iteration = target.state_transition(
        offchain_secret_reveal_iteration.new_state,
        onchain_reveal,
        channel_state,
        pseudo_random_generator,
        block_number_prior_the_expiration,
    )
    unlocked_onchain = channel_state.partner_state.secrethashes_to_onchain_unlockedlocks
    assert factories.UNIT_SECRETHASH in unlocked_onchain

    # Check that after we register a lock on-chain handling the block again will
    # not cause us to attempt an onchain re-register
    extra_block_handle_transition = target.handle_block(
        onchain_secret_reveal_iteration.new_state,
        channel_state,
        block_number_prior_the_expiration + 1,
    )
    assert len(extra_block_handle_transition.events) == 0
Example #21
0
def subdispatch_to_paymenttask(
    chain_state: ChainState,
    state_change: StateChange,
    secrethash: SecretHash,
) -> TransitionResult[ChainState]:
    block_number = chain_state.block_number
    sub_task = chain_state.payment_mapping.secrethashes_to_task.get(secrethash)
    events: List[Event] = list()
    sub_iteration = None

    if sub_task:
        pseudo_random_generator = chain_state.pseudo_random_generator

        if isinstance(sub_task, InitiatorTask):
            token_network_identifier = sub_task.token_network_identifier
            token_network_state = views.get_token_network_by_identifier(
                chain_state,
                token_network_identifier,
            )
            if token_network_state:
                sub_iteration = initiator_manager.state_transition(
                    sub_task.manager_state,
                    state_change,
                    token_network_state.channelidentifiers_to_channels,
                    pseudo_random_generator,
                    block_number,
                )
                events = sub_iteration.events

        elif isinstance(sub_task, MediatorTask):
            token_network_identifier = sub_task.token_network_identifier
            token_network_state = views.get_token_network_by_identifier(
                chain_state,
                token_network_identifier,
            )

            if token_network_state:
                sub_iteration = mediator.state_transition(
                    sub_task.mediator_state,
                    state_change,
                    token_network_state.channelidentifiers_to_channels,
                    chain_state.nodeaddresses_to_networkstates,
                    pseudo_random_generator,
                    block_number,
                )
                events = sub_iteration.events

        elif isinstance(sub_task, TargetTask):
            token_network_identifier = sub_task.token_network_identifier
            channel_identifier = sub_task.channel_identifier

            channel_state = views.get_channelstate_by_token_network_identifier(
                chain_state,
                token_network_identifier,
                channel_identifier,
            )

            if channel_state:
                sub_iteration = target.state_transition(
                    sub_task.target_state,
                    state_change,
                    channel_state,
                    pseudo_random_generator,
                    block_number,
                )
                events = sub_iteration.events

        if sub_iteration and sub_iteration.new_state is None:
            del chain_state.payment_mapping.secrethashes_to_task[secrethash]

    return TransitionResult(chain_state, events)
Example #22
0
def subdispatch_to_paymenttask(
        chain_state: ChainState,
        state_change: StateChange,
        secrethash: SecretHash,
) -> TransitionResult:
    block_number = chain_state.block_number
    sub_task = chain_state.payment_mapping.secrethashes_to_task.get(secrethash)
    events = list()
    sub_iteration = None

    if sub_task:
        pseudo_random_generator = chain_state.pseudo_random_generator

        if isinstance(sub_task, InitiatorTask):
            token_network_identifier = sub_task.token_network_identifier
            token_network_state = views.get_token_network_by_identifier(
                chain_state,
                token_network_identifier,
            )
            if token_network_state:
                sub_iteration = initiator_manager.state_transition(
                    sub_task.manager_state,
                    state_change,
                    token_network_state.channelidentifiers_to_channels,
                    pseudo_random_generator,
                    block_number,
                )
                events = sub_iteration.events

        elif isinstance(sub_task, MediatorTask):
            token_network_identifier = sub_task.token_network_identifier
            token_network_state = views.get_token_network_by_identifier(
                chain_state,
                token_network_identifier,
            )

            if token_network_state:
                sub_iteration = mediator.state_transition(
                    sub_task.mediator_state,
                    state_change,
                    token_network_state.channelidentifiers_to_channels,
                    pseudo_random_generator,
                    block_number,
                )
                events = sub_iteration.events

        elif isinstance(sub_task, TargetTask):
            token_network_identifier = sub_task.token_network_identifier
            channel_identifier = sub_task.channel_identifier

            channel_state = views.get_channelstate_by_token_network_identifier(
                chain_state,
                token_network_identifier,
                channel_identifier,
            )

            if channel_state:
                sub_iteration = target.state_transition(
                    sub_task.target_state,
                    state_change,
                    channel_state,
                    pseudo_random_generator,
                    block_number,
                )
                events = sub_iteration.events

        if sub_iteration and sub_iteration.new_state is None:
            del chain_state.payment_mapping.secrethashes_to_task[secrethash]

    return TransitionResult(chain_state, events)
Example #23
0
def test_target_receive_lock_expired():
    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=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
    assert init_transition.new_state.route == from_route
    assert init_transition.new_state.transfer == from_transfer

    balance_proof = factories.make_signed_balance_proof(
        2,
        from_transfer.balance_proof.transferred_amount,
        0,
        from_transfer.balance_proof.token_network_identifier,
        from_channel.identifier,
        EMPTY_MERKLE_ROOT,
        from_transfer.lock.secrethash,
        sender_address=UNIT_TRANSFER_SENDER,
        private_key=UNIT_TRANSFER_PKEY,
    )

    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(
        init_transition.new_state,
        lock_expired_state_change,
        from_channel,
        pseudo_random_generator,
        block_before_confirmed_expiration,
    )
    assert not must_contain_entry(iteration.events, SendProcessed, {})

    block_lock_expired = block_before_confirmed_expiration + 1
    iteration = target.state_transition(
        init_transition.new_state,
        lock_expired_state_change,
        from_channel,
        pseudo_random_generator,
        block_lock_expired,
    )
    assert must_contain_entry(iteration.events, SendProcessed, {})
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 = ''
    signature = None

    balance_proof = BalanceProofState(
        nonce,
        transferred_amount,
        locksroot,
        from_route.channel_address,
        message_hash,
        signature,
    )

    balance_proof_state_change = ReceiveBalanceProof(
        from_transfer.identifier,
        from_route.node_address,
        balance_proof,
    )
    proof_iteration = target.state_transition(
        init_transition.new_state,
        balance_proof_state_change,
    )
    assert proof_iteration.new_state is None
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(
            balance_proof=BalanceProofProperties(
                nonce=2,
                transferred_amount=from_transfer.balance_proof.
                transferred_amount,
                locked_amount=0,
                token_network_identifier=from_transfer.balance_proof.
                token_network_identifier,
                channel_identifier=channels[0].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 must_contain_entry(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 must_contain_entry(iteration.events, SendProcessed, {})
Example #26
0
def test_state_transition():
    """ Happy case testing. """
    lock_amount = 7
    block_number = 1
    initiator = factories.HOP6
    pseudo_random_generator = random.Random()

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

    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

    first_new_block = Block(
        block_number=block_number + 1,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    first_block_iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=first_new_block,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=first_new_block.block_number,
    )

    secret_reveal = ReceiveSecretReveal(factories.UNIT_SECRET, initiator)
    reveal_iteration = target.state_transition(
        target_state=first_block_iteration.new_state,
        state_change=secret_reveal,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=first_new_block.block_number,
    )
    assert reveal_iteration.events

    second_new_block = Block(
        block_number=block_number + 2,
        gas_limit=1,
        block_hash=factories.make_transaction_hash(),
    )
    iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=second_new_block,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=second_new_block.block_number,
    )
    assert not iteration.events

    balance_proof = create(BalanceProofSignedStateProperties(
        balance_proof=BalanceProofProperties(
            nonce=from_transfer.balance_proof.nonce + 1,
            transferred_amount=lock_amount,
            locked_amount=0,
            token_network_identifier=channels[0].token_network_identifier,
            channel_identifier=channels.get_route(0).channel_identifier,
            locksroot=EMPTY_MERKLE_ROOT,
        ),
        message_hash=b'\x00' * 32,  # invalid
    ))

    balance_proof_state_change = ReceiveUnlock(
        message_identifier=random.randint(0, UINT64_MAX),
        secret=UNIT_SECRET,
        balance_proof=balance_proof,
    )

    proof_iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=balance_proof_state_change,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number + 2,
    )
    assert proof_iteration.new_state is None
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 = ''
    signature = None

    balance_proof = BalanceProofState(
        nonce,
        transferred_amount,
        locksroot,
        from_route.channel_address,
        message_hash,
        signature,
    )

    balance_proof_state_change = ReceiveBalanceProof(
        from_transfer.identifier,
        from_route.node_address,
        balance_proof,
    )
    proof_iteration = target.state_transition(
        init_transition.new_state,
        balance_proof_state_change,
    )
    assert proof_iteration.new_state is None
Example #28
0
def test_state_transition():
    """ Happy case testing. """
    lock_amount = 7
    block_number = 1
    initiator = factories.make_address()
    pseudo_random_generator = random.Random()

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

    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
    assert init_transition.new_state.from_hop == channels.get_hop(0)
    assert init_transition.new_state.transfer == from_transfer

    first_new_block = Block(block_number=block_number + 1,
                            gas_limit=1,
                            block_hash=factories.make_transaction_hash())
    first_block_iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=first_new_block,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=first_new_block.block_number,
    )

    secret_reveal = ReceiveSecretReveal(secret=UNIT_SECRET, sender=initiator)
    reveal_iteration = target.state_transition(
        target_state=first_block_iteration.new_state,
        state_change=secret_reveal,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=first_new_block.block_number,
    )
    assert reveal_iteration.events

    second_new_block = Block(block_number=block_number + 2,
                             gas_limit=1,
                             block_hash=factories.make_transaction_hash())
    iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=second_new_block,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=second_new_block.block_number,
    )
    assert not iteration.events

    balance_proof = create(
        BalanceProofSignedStateProperties(
            nonce=from_transfer.balance_proof.nonce + 1,  # pylint: disable=no-member
            transferred_amount=lock_amount,
            locked_amount=0,
            canonical_identifier=factories.make_canonical_identifier(
                token_network_address=channels[0].token_network_address,
                channel_identifier=channels.get_hop(0).channel_identifier,
            ),
            locksroot=LOCKSROOT_OF_NO_LOCKS,
            message_hash=b"\x00" * 32,  # invalid
        ))

    balance_proof_state_change = ReceiveUnlock(
        message_identifier=random.randint(0, UINT64_MAX),
        secret=UNIT_SECRET,
        balance_proof=balance_proof,
        sender=balance_proof.sender,  # pylint: disable=no-member
    )

    proof_iteration = target.state_transition(
        target_state=init_transition.new_state,
        state_change=balance_proof_state_change,
        channel_state=channels[0],
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number + 2,
    )
    assert proof_iteration.new_state is None
Example #29
0
def subdispatch_to_paymenttask(node_state, state_change, secrethash):
    block_number = node_state.block_number
    sub_task = node_state.payment_mapping.secrethashes_to_task.get(secrethash)
    events = list()
    sub_iteration = None

    if sub_task:
        pseudo_random_generator = node_state.pseudo_random_generator

        if isinstance(sub_task, PaymentMappingState.InitiatorTask):
            token_network_identifier = sub_task.token_network_identifier
            token_network_state = views.get_token_network_by_identifier(
                node_state,
                token_network_identifier,
            )

            if token_network_state:
                sub_iteration = initiator_manager.state_transition(
                    sub_task.manager_state,
                    state_change,
                    token_network_state.channelidentifiers_to_channels,
                    pseudo_random_generator,
                    block_number,
                )
                events = sub_iteration.events

        elif isinstance(sub_task, PaymentMappingState.MediatorTask):
            token_network_identifier = sub_task.token_network_identifier
            token_network_state = views.get_token_network_by_identifier(
                node_state,
                token_network_identifier,
            )

            if token_network_state:
                sub_iteration = mediator.state_transition(
                    sub_task.mediator_state,
                    state_change,
                    token_network_state.channelidentifiers_to_channels,
                    pseudo_random_generator,
                    block_number,
                )
                events = sub_iteration.events

        elif isinstance(sub_task, PaymentMappingState.TargetTask):
            token_network_identifier = sub_task.token_network_identifier
            channel_identifier = sub_task.channel_identifier
            token_network_state = views.get_token_network_by_identifier(
                node_state,
                token_network_identifier,
            )

            channel_state = views.get_channelstate_by_token_network_identifier(
                node_state,
                token_network_identifier,
                channel_identifier,
            )

            if channel_state:
                sub_iteration = target.state_transition(
                    sub_task.target_state,
                    state_change,
                    channel_state,
                    pseudo_random_generator,
                    block_number,
                )
                events = sub_iteration.events

        if sub_iteration and sub_iteration.new_state is None:
            del node_state.payment_mapping.secrethashes_to_task[secrethash]

    return TransitionResult(node_state, events)
Example #30
0
def test_handle_onchain_secretreveal():
    """ The target node must update the lock state when the secret is
    registered in the blockchain.
    """
    setup = make_target_state(
        block_number=1,
        expiration=1 + factories.UNIT_REVEAL_TIMEOUT,
    )
    assert factories.UNIT_SECRETHASH in setup.channel.partner_state.secrethashes_to_lockedlocks

    offchain_secret_reveal_iteration = target.state_transition(
        target_state=setup.new_state,
        state_change=ReceiveSecretReveal(UNIT_SECRET, setup.initiator),
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=setup.block_number,
    )
    assert UNIT_SECRETHASH in setup.channel.partner_state.secrethashes_to_unlockedlocks
    assert UNIT_SECRETHASH not in setup.channel.partner_state.secrethashes_to_lockedlocks

    # Make sure that an emptyhash on chain reveal is rejected.
    block_number_prior_the_expiration = setup.expiration - 2
    onchain_reveal = ContractReceiveSecretReveal(
        transaction_hash=factories.make_address(),
        secret_registry_address=factories.make_address(),
        secrethash=EMPTY_HASH_KECCAK,
        secret=EMPTY_HASH,
        block_number=block_number_prior_the_expiration,
        block_hash=factories.make_block_hash(),
    )
    onchain_secret_reveal_iteration = target.state_transition(
        target_state=offchain_secret_reveal_iteration.new_state,
        state_change=onchain_reveal,
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=block_number_prior_the_expiration,
    )
    unlocked_onchain = setup.channel.partner_state.secrethashes_to_onchain_unlockedlocks
    assert EMPTY_HASH_KECCAK not in unlocked_onchain

    # now let's go for the actual secret
    onchain_reveal.secret = UNIT_SECRET
    onchain_reveal.secrethash = UNIT_SECRETHASH
    onchain_secret_reveal_iteration = target.state_transition(
        target_state=offchain_secret_reveal_iteration.new_state,
        state_change=onchain_reveal,
        channel_state=setup.channel,
        pseudo_random_generator=setup.pseudo_random_generator,
        block_number=block_number_prior_the_expiration,
    )
    unlocked_onchain = setup.channel.partner_state.secrethashes_to_onchain_unlockedlocks
    assert UNIT_SECRETHASH in unlocked_onchain

    # Check that after we register a lock on-chain handling the block again will
    # not cause us to attempt an onchain re-register
    extra_block_handle_transition = target.handle_block(
        target_state=onchain_secret_reveal_iteration.new_state,
        channel_state=setup.channel,
        block_number=block_number_prior_the_expiration + 1,
        block_hash=factories.make_block_hash(),
    )
    assert len(extra_block_handle_transition.events) == 0