示例#1
0
def send_mediatedtransfer(
    initiator_state: InitiatorTransferState,
    channel_state: NettingChannelState,
    block_number: typing.BlockNumber,
) -> SendMediatedTransfer:
    """ Create a mediated transfer using channel.
    Raises:
        AssertionError: If the channel does not have enough capacity.
    """
    assert channel_state.token_address == initiator_state.transfer_description.token

    transfer_description = initiator_state.transfer_description
    lock_expiration = get_initial_lock_expiration(
        block_number,
        channel_state.settle_timeout,
    )

    mediatedtransfer_event = channel.send_mediatedtransfer(
        channel_state,
        transfer_description.initiator,
        transfer_description.target,
        transfer_description.amount,
        transfer_description.identifier,
        lock_expiration,
        transfer_description.hashlock,
    )
    assert mediatedtransfer_event

    initiator_state.transfer = mediatedtransfer_event.transfer

    return mediatedtransfer_event
示例#2
0
def test_channelstate_send_mediatedtransfer():
    """Sending a mediated transfer must update the participant state.

    This tests only the state of the sending node, without synchronisation.
    """
    our_model1, _ = create_model(70)
    partner_model1, _ = create_model(100)
    channel_state = create_channel_from_models(our_model1, partner_model1)

    lock_amount = 30
    lock_expiration = 10
    lock_secret = sha3(b'test_end_state')
    lock_hashlock = sha3(lock_secret)

    lock = HashTimeLockState(
        lock_amount,
        lock_expiration,
        lock_hashlock,
    )

    identifier = 1
    transfer_target = factories.make_address()
    transfer_initiator = factories.make_address()

    channel.send_mediatedtransfer(
        channel_state,
        transfer_initiator,
        transfer_target,
        lock_amount,
        identifier,
        lock_expiration,
        lock_hashlock,
    )

    our_model2 = our_model1._replace(
        distributable=our_model1.distributable - lock_amount,
        amount_locked=lock_amount,
        next_nonce=2,
        merkletree_leaves=[lock.lockhash],
    )
    partner_model2 = partner_model1

    assert_partner_state(channel_state.our_state, channel_state.partner_state,
                         our_model2)
    assert_partner_state(channel_state.partner_state, channel_state.our_state,
                         partner_model2)
示例#3
0
def make_mediated_transfer(
        from_channel,
        partner_channel,
        initiator,
        target,
        lock,
        pkey,
        secret=None
):
    """ Helper to create and register a mediated transfer from `from_channel` to
    `partner_channel`."""
    identifier = channel.get_next_nonce(from_channel.our_state)

    mediatedtransfer = channel.send_mediatedtransfer(
        from_channel,
        initiator,
        target,
        lock.amount,
        identifier,
        lock.expiration,
        lock.hashlock,
    )
    mediated_transfer_msg = MediatedTransfer.from_event(mediatedtransfer)

    address = privatekey_to_address(pkey)
    sign_key = PrivateKey(pkey)
    mediated_transfer_msg.sign(sign_key, address)

    # compute the signature
    balance_proof = balanceproof_from_envelope(mediated_transfer_msg)
    mediatedtransfer.balance_proof = balance_proof

    # if this fails it's not the right key for the current `from_channel`
    assert mediated_transfer_msg.sender == from_channel.our_state.address
    receive_mediatedtransfer = lockedtransfersigned_from_message(mediated_transfer_msg)

    channel.handle_receive_mediatedtransfer(
        partner_channel,
        receive_mediatedtransfer,
    )

    if secret is not None:
        random_sender = make_address()

        from_secretreveal = ReceiveSecretReveal(secret, random_sender)
        channel.handle_receive_secretreveal(from_channel, from_secretreveal)

        partner_secretreveal = ReceiveSecretReveal(secret, random_sender)
        channel.handle_receive_secretreveal(partner_channel, partner_secretreveal)

    return mediated_transfer_msg
示例#4
0
def next_transfer_pair(payer_transfer: LockedTransferSignedState,
                       available_routes: List['RouteState'],
                       channelidentifiers_to_channels: Dict,
                       timeout_blocks: int, block_number: int):
    """ Given a payer transfer tries a new route to proceed with the mediation.
    Args:
        payer_transfer: The transfer received from the payer_channel.
        routes: Current available routes that may be used, it's assumed that
            the routes list is ordered from best to worst.
        timeout_blocks: Base number of available blocks used to compute
            the lock timeout.
        block_number: The current block number.
    """
    assert timeout_blocks > 0
    assert timeout_blocks <= payer_transfer.lock.expiration - block_number

    transfer_pair = None
    mediated_events = list()

    payee_channel = next_channel_from_routes(
        available_routes,
        channelidentifiers_to_channels,
        payer_transfer.lock.amount,
        timeout_blocks,
    )

    if payee_channel:
        assert payee_channel.reveal_timeout < timeout_blocks
        assert payee_channel.token_address == payer_transfer.token

        lock_timeout = timeout_blocks - payee_channel.reveal_timeout
        lock_expiration = lock_timeout + block_number

        mediatedtransfer_event = channel.send_mediatedtransfer(
            payee_channel, payer_transfer.initiator, payer_transfer.target,
            payer_transfer.lock.amount, payer_transfer.identifier,
            lock_expiration, payer_transfer.lock.hashlock)
        assert mediatedtransfer_event

        transfer_pair = MediationPairState(
            payer_transfer,
            payee_channel.partner_state.address,
            mediatedtransfer_event.transfer,
        )

        mediated_events = [mediatedtransfer_event]

    return (
        transfer_pair,
        mediated_events,
    )