示例#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
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
def test_initiator_handle_contract_receive_secret_reveal_expired():
    """ Initiator must *not* unlock off-chain if the secret is revealed
    on-chain *after* the lock expiration.
    """
    setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2,
                                  block_number=10)

    transfer = setup.current_state.initiator.transfer
    assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks

    state_change = ContractReceiveSecretReveal(
        transaction_hash=factories.make_transaction_hash(),
        secret_registry_address=factories.make_address(),
        secrethash=transfer.lock.secrethash,
        secret=UNIT_SECRET,
        block_number=transfer.lock.expiration + 1,
    )

    iteration = initiator_manager.handle_onchain_secretreveal(
        payment_state=setup.current_state,
        state_change=state_change,
        channelidentifiers_to_channels=setup.channel_map,
        pseudo_random_generator=setup.prng,
    )

    assert events.must_contain_entry(iteration.events, SendBalanceProof,
                                     {}) is None
def test_initiator_handle_contract_receive_emptyhash_secret_reveal():
    """ Initiator must not accept contract receive secret reveal with emptyhash
    """
    setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2,
                                  block_number=10)

    transfer = setup.current_state.initiator.transfer
    assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks

    state_change = ContractReceiveSecretReveal(
        transaction_hash=factories.make_transaction_hash(),
        secret_registry_address=factories.make_address(),
        secrethash=transfer.lock.secrethash,
        secret=EMPTY_HASH,
        block_number=transfer.lock.expiration,
    )

    iteration = initiator_manager.handle_onchain_secretreveal(
        payment_state=setup.current_state,
        state_change=state_change,
        channelidentifiers_to_channels=setup.channel_map,
        pseudo_random_generator=setup.prng,
    )
    assert len(iteration.events) == 0
    # make sure the original lock wasn't moved
    assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks
def test_initiator_handle_contract_receive_secret_reveal():
    """ Initiator must unlock off-chain if the secret is revealed on-chain and
    the channel is open.
    """
    setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2,
                                  block_number=10)

    transfer = setup.current_state.initiator.transfer
    assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks

    state_change = ContractReceiveSecretReveal(
        transaction_hash=factories.make_transaction_hash(),
        secret_registry_address=factories.make_address(),
        secrethash=transfer.lock.secrethash,
        secret=UNIT_SECRET,
        block_number=transfer.lock.expiration,
    )

    message_identifier = message_identifier_from_prng(deepcopy(setup.prng))

    iteration = initiator_manager.handle_onchain_secretreveal(
        payment_state=setup.current_state,
        state_change=state_change,
        channelidentifiers_to_channels=setup.channel_map,
        pseudo_random_generator=setup.prng,
    )

    payment_identifier = setup.current_state.initiator.transfer_description.payment_identifier
    assert events.must_contain_entry(
        iteration.events, SendBalanceProof, {
            'message_identifier': message_identifier,
            'payment_identifier': payment_identifier,
        })
def test_initiator_handle_contract_receive_secret_reveal():
    """ Initiator must unlock off-chain if the secret is revealed on-chain and
    the channel is open.
    """
    amount = UNIT_TRANSFER_AMOUNT * 2

    channel1 = factories.make_channel(
        our_balance=amount,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    pseudo_random_generator = random.Random()

    channel_map = {
        channel1.identifier: channel1,
    }

    available_routes = [
        factories.route_from_channel(channel1),
    ]

    block_number = 10
    current_state = make_initiator_manager_state(
        routes=available_routes,
        transfer_description=factories.UNIT_TRANSFER_DESCRIPTION,
        channel_map=channel_map,
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )

    transfer = current_state.initiator.transfer

    assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks

    state_change = ContractReceiveSecretReveal(
        transaction_hash=factories.make_transaction_hash(),
        secret_registry_address=factories.make_address(),
        secrethash=transfer.lock.secrethash,
        secret=UNIT_SECRET,
        block_number=transfer.lock.expiration,
    )

    message_identifier = message_identifier_from_prng(
        deepcopy(pseudo_random_generator))

    iteration = initiator_manager.handle_onchain_secretreveal(
        payment_state=current_state,
        state_change=state_change,
        channelidentifiers_to_channels=channel_map,
        pseudo_random_generator=pseudo_random_generator,
    )

    assert events.must_contain_entry(
        iteration.events, SendBalanceProof, {
            'message_identifier':
            message_identifier,
            'payment_identifier':
            current_state.initiator.transfer_description.payment_identifier,
        })
示例#7
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

    block_number_prior_the_expiration = expiration - 2
    onchain_secret_reveal_iteration = target.state_transition(
        offchain_secret_reveal_iteration.new_state,
        ContractReceiveSecretReveal(
            transaction_hash=factories.make_address(),
            secret_registry_address=factories.make_address(),
            secrethash=UNIT_SECRETHASH,
            secret=UNIT_SECRET,
            block_number=block_number_prior_the_expiration,
        ),
        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
示例#8
0
def handle_secret_revealed(raiden, event, current_block_number):
    secret_registry_address = event.originating_contract
    data = event.event_data

    registeredsecret_state_change = ContractReceiveSecretReveal(
        secret_registry_address,
        data['secrethash'],
    )

    raiden.handle_state_change(registeredsecret_state_change,
                               current_block_number)
示例#9
0
def test_initiator_handle_contract_receive_secret_reveal():
    """ Make sure the initiator handles ContractReceiveSecretReveal
    and checks the existence of the transfer's secrethash in
    secrethashes_to_lockedlocks and secrethashes_to_onchain_unlockedlocks. """
    amount = UNIT_TRANSFER_AMOUNT * 2
    block_number = 1
    refund_pkey, refund_address = factories.make_privkey_address()
    pseudo_random_generator = random.Random()

    channel1 = factories.make_channel(
        our_balance=amount,
        token_address=UNIT_TOKEN_ADDRESS,
        token_network_identifier=UNIT_TOKEN_NETWORK_ADDRESS,
    )
    pseudo_random_generator = random.Random()

    channel_map = {
        channel1.identifier: channel1,
    }

    available_routes = [
        factories.route_from_channel(channel1),
    ]

    block_number = 10
    current_state = make_initiator_manager_state(
        routes=available_routes,
        transfer_description=factories.UNIT_TRANSFER_DESCRIPTION,
        channel_map=channel_map,
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )

    transfer = current_state.initiator.transfer

    assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks

    state_change = ContractReceiveSecretReveal(
        transaction_hash=factories.make_transaction_hash(),
        secret_registry_address=factories.make_address(),
        secrethash=transfer.lock.secrethash,
        secret=UNIT_SECRET,
    )

    initiator_manager.handle_onchain_secretreveal(
        payment_state=current_state,
        state_change=state_change,
        channelidentifiers_to_channels=channel_map,
        pseudo_random_generator=pseudo_random_generator,
    )

    assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_lockedlocks
    assert transfer.lock.secrethash in channel1.our_state.secrethashes_to_onchain_unlockedlocks
示例#10
0
def test_initiator_handle_contract_receive_after_channel_closed():
    """ Initiator must accept on-chain secret reveal if the channel is closed.
    However, the off-chain unlock must not be done!

    This will happen because secrets are registered after a channel is closed,
    during the settlement window.
    """
    block_number = 10
    setup = setup_initiator_tests(amount=UNIT_TRANSFER_AMOUNT * 2,
                                  block_number=block_number)

    transfer = setup.current_state.initiator.transfer
    assert transfer.lock.secrethash in setup.channel.our_state.secrethashes_to_lockedlocks

    channel_closed = ContractReceiveChannelClosed(
        transaction_hash=factories.make_transaction_hash(),
        transaction_from=factories.make_address(),
        token_network_identifier=setup.channel.token_network_identifier,
        channel_identifier=setup.channel.identifier,
        block_number=block_number,
    )

    channel_close_transition = channel.state_transition(
        channel_state=setup.channel,
        state_change=channel_closed,
        pseudo_random_generator=setup.prng,
        block_number=block_number,
    )
    channel_state = channel_close_transition.new_state

    state_change = ContractReceiveSecretReveal(
        transaction_hash=factories.make_transaction_hash(),
        secret_registry_address=factories.make_address(),
        secrethash=transfer.lock.secrethash,
        secret=UNIT_SECRET,
        block_number=transfer.lock.expiration,
    )

    channel_map = {
        channel_state.identifier: channel_state,
    }
    iteration = initiator_manager.handle_onchain_secretreveal(
        payment_state=setup.current_state,
        state_change=state_change,
        channelidentifiers_to_channels=channel_map,
        pseudo_random_generator=setup.prng,
    )
    secrethash = setup.current_state.initiator.transfer_description.secrethash
    assert secrethash in channel_state.our_state.secrethashes_to_onchain_unlockedlocks

    msg = 'The channel is closed already, the balance proof must not be sent off-chain'
    assert not events.must_contain_entry(iteration.events, SendBalanceProof,
                                         {}), msg
示例#11
0
def contractreceivesecretreveal_from_event(event: DecodedEvent) -> ContractReceiveSecretReveal:
    secret_registry_address = event.originating_contract
    data = event.event_data
    args = data["args"]

    return ContractReceiveSecretReveal(
        secret_registry_address=SecretRegistryAddress(secret_registry_address),
        secrethash=args["secrethash"],
        secret=args["secret"],
        transaction_hash=event.transaction_hash,
        block_number=event.block_number,
        block_hash=event.block_hash,
    )
def handle_secret_revealed(raiden, event):
    secret_registry_address = event.originating_contract
    data = event.event_data

    transaction_hash = data['transactionHash']
    assert transaction_hash, 'A mined transaction must have the hash field'

    registeredsecret_state_change = ContractReceiveSecretReveal(
        transaction_hash,
        secret_registry_address,
        data['secrethash'],
        data['secret'],
    )

    raiden.handle_state_change(registeredsecret_state_change)
示例#13
0
def handle_secret_revealed(raiden: RaidenService, event: Event):
    secret_registry_address = event.originating_contract
    data = event.event_data
    args = data['args']

    transaction_hash = data['transaction_hash']

    registeredsecret_state_change = ContractReceiveSecretReveal(
        transaction_hash=transaction_hash,
        secret_registry_address=secret_registry_address,
        secrethash=args['secrethash'],
        secret=args['secret'],
        block_number=data['block_number'],
    )

    raiden.handle_state_change(registeredsecret_state_change)
示例#14
0
def handle_secret_revealed(raiden, event, current_block_number):
    secret_registry_address = event.originating_contract
    data = event.event_data

    from_address = raiden.chain.client.get_transaction_from(
        event.event_data['transactionHash'])
    assert from_address, 'A mined transaction must have the from field'

    registeredsecret_state_change = ContractReceiveSecretReveal(
        from_address,
        secret_registry_address,
        data['secrethash'],
        data['secret'],
    )

    raiden.handle_state_change(registeredsecret_state_change,
                               current_block_number)
示例#15
0
def handle_secret_revealed(raiden: "RaidenService", event: Event):
    secret_registry_address = event.originating_contract
    data = event.event_data
    args = data["args"]
    block_number = data["block_number"]
    block_hash = data["block_hash"]
    transaction_hash = data["transaction_hash"]
    registeredsecret_state_change = ContractReceiveSecretReveal(
        transaction_hash=transaction_hash,
        secret_registry_address=secret_registry_address,
        secrethash=args["secrethash"],
        secret=args["secret"],
        block_number=block_number,
        block_hash=block_hash,
    )

    raiden.handle_and_track_state_change(registeredsecret_state_change)
def test_regression_onchain_secret_reveal_must_update_channel_state():
    """ If a secret is learned off-chain and then on-chain, the state of the
    lock must be updated in the channel.
    """
    pseudo_random_generator = random.Random()

    setup = factories.make_transfers_pair(2, block_number=10)

    mediator_state = MediatorTransferState(
        secrethash=UNIT_SECRETHASH,
        routes=setup.channels.get_routes(),
    )
    mediator_state.transfers_pair = setup.transfers_pair

    secret = UNIT_SECRET
    secrethash = UNIT_SECRETHASH
    payer_channel = mediator.get_payer_channel(setup.channel_map,
                                               setup.transfers_pair[0])
    payee_channel = mediator.get_payee_channel(setup.channel_map,
                                               setup.transfers_pair[0])
    lock = payer_channel.partner_state.secrethashes_to_lockedlocks[secrethash]

    mediator.state_transition(
        mediator_state=mediator_state,
        state_change=ReceiveSecretReveal(secret,
                                         payee_channel.partner_state.address),
        channelidentifiers_to_channels=setup.channel_map,
        nodeaddresses_to_networkstates=setup.channels.
        nodeaddresses_to_networkstates,
        pseudo_random_generator=pseudo_random_generator,
        block_number=setup.block_number,
        block_hash=setup.block_hash,
    )
    assert secrethash in payer_channel.partner_state.secrethashes_to_unlockedlocks

    secret_registry_address = factories.make_address()
    transaction_hash = factories.make_address()
    mediator.state_transition(
        mediator_state=mediator_state,
        state_change=ContractReceiveSecretReveal(
            transaction_hash=transaction_hash,
            secret_registry_address=secret_registry_address,
            secrethash=secrethash,
            secret=secret,
            block_number=setup.block_number,
            block_hash=setup.block_hash,
        ),
        channelidentifiers_to_channels=setup.channel_map,
        nodeaddresses_to_networkstates=setup.channels.
        nodeaddresses_to_networkstates,
        pseudo_random_generator=pseudo_random_generator,
        block_number=setup.block_number,
        block_hash=setup.block_hash,
    )
    assert secrethash in payer_channel.partner_state.secrethashes_to_onchain_unlockedlocks

    # Creates a transfer as it was from the *partner*
    send_lock_expired, _ = channel.create_sendexpiredlock(
        sender_end_state=payer_channel.partner_state,
        locked_lock=lock,
        pseudo_random_generator=pseudo_random_generator,
        chain_id=payer_channel.chain_id,
        token_network_identifier=payer_channel.token_network_identifier,
        channel_identifier=payer_channel.identifier,
        recipient=payer_channel.our_state.address,
    )
    assert send_lock_expired
    expired_message = message_from_sendevent(send_lock_expired,
                                             setup.channels.our_address(0))
    expired_message.sign(LocalSigner(setup.channels.partner_privatekeys[0]))
    balance_proof = balanceproof_from_envelope(expired_message)

    message_identifier = message_identifier_from_prng(pseudo_random_generator)
    expired_block_number = channel.get_sender_expiration_threshold(lock)
    mediator.state_transition(
        mediator_state=mediator_state,
        state_change=ReceiveLockExpired(
            balance_proof=balance_proof,
            secrethash=secrethash,
            message_identifier=message_identifier,
        ),
        channelidentifiers_to_channels=setup.channel_map,
        nodeaddresses_to_networkstates=setup.channels.
        nodeaddresses_to_networkstates,
        pseudo_random_generator=pseudo_random_generator,
        block_number=expired_block_number,
        block_hash=factories.make_block_hash(),
    )
    assert secrethash in payer_channel.partner_state.secrethashes_to_onchain_unlockedlocks
示例#17
0
def test_regression_onchain_secret_reveal_must_update_channel_state():
    """ If a secret is learned off-chain and then on-chain, the state of the
    lock must be updated in the channel.
    """
    amount = 10
    block_number = 10
    pseudo_random_generator = random.Random()

    channel_map, transfers_pair = factories.make_transfers_pair(
        [HOP2_KEY, HOP3_KEY],
        amount,
        block_number,
    )

    mediator_state = MediatorTransferState(UNIT_SECRETHASH)
    mediator_state.transfers_pair = transfers_pair

    secret = UNIT_SECRET
    secrethash = UNIT_SECRETHASH
    payer_channelid = transfers_pair[
        0].payer_transfer.balance_proof.channel_identifier
    payee_channelid = transfers_pair[
        0].payee_transfer.balance_proof.channel_identifier
    payer_channel = channel_map[payer_channelid]
    payee_channel = channel_map[payee_channelid]
    lock = payer_channel.partner_state.secrethashes_to_lockedlocks[secrethash]

    mediator.state_transition(
        mediator_state=mediator_state,
        state_change=ReceiveSecretReveal(secret,
                                         payee_channel.partner_state.address),
        channelidentifiers_to_channels=channel_map,
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )
    assert secrethash in payer_channel.partner_state.secrethashes_to_unlockedlocks

    secret_registry_address = factories.make_address()
    transaction_hash = factories.make_address()
    mediator.state_transition(
        mediator_state=mediator_state,
        state_change=ContractReceiveSecretReveal(
            transaction_hash,
            secret_registry_address,
            secrethash,
            secret,
            block_number,
        ),
        channelidentifiers_to_channels=channel_map,
        pseudo_random_generator=pseudo_random_generator,
        block_number=block_number,
    )
    assert secrethash in payer_channel.partner_state.secrethashes_to_onchain_unlockedlocks

    # Creates a transfer as it was from the *partner*
    send_lock_expired, _ = channel.create_sendexpiredlock(
        sender_end_state=payer_channel.partner_state,
        locked_lock=lock,
        pseudo_random_generator=pseudo_random_generator,
        chain_id=payer_channel.chain_id,
        token_network_identifier=payer_channel.token_network_identifier,
        channel_identifier=payer_channel.identifier,
        recipient=payer_channel.our_state.address,
    )
    assert send_lock_expired
    lock_expired_message = message_from_sendevent(send_lock_expired, HOP1)
    lock_expired_message.sign(HOP2_KEY)
    balance_proof = balanceproof_from_envelope(lock_expired_message)

    message_identifier = message_identifier_from_prng(pseudo_random_generator)
    expired_block_number = lock.expiration + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS * 2
    mediator.state_transition(
        mediator_state=mediator_state,
        state_change=ReceiveLockExpired(
            balance_proof=balance_proof,
            secrethash=secrethash,
            message_identifier=message_identifier,
        ),
        channelidentifiers_to_channels=channel_map,
        pseudo_random_generator=pseudo_random_generator,
        block_number=expired_block_number,
    )
    assert secrethash in payer_channel.partner_state.secrethashes_to_onchain_unlockedlocks