Пример #1
0
def clear_if_finalized(iteration):
    """ Clear the state if all transfer pairs have finalized. """
    state = iteration.new_state

    if state is None:
        return iteration

    # TODO: clear the expired transfer, this will need some sort of
    # synchronization among the nodes
    all_finalized = all(
        pair.payee_state in STATE_TRANSFER_PAID and pair.payer_state in STATE_TRANSFER_PAID
        for pair in state.transfers_pair
    )

    if all_finalized:
        return TransitionResult(None, iteration.events)
    return iteration
Пример #2
0
def handle_block(state, state_change):
    """ After Raiden learns about a new block this function must be called to
    handle expiration of the hash time lock.
    """
    state.block_number = max(
        state.block_number,
        state_change.block_number,
    )

    close_events = events_for_close(
        state.from_transfer,
        state.from_route,
        state.block_number,
    )
    iteration = TransitionResult(state, close_events)

    return iteration
Пример #3
0
def test_handle_node_change_network_state(chain_state, netting_channel_state,
                                          monkeypatch):
    state_change = ActionChangeNodeNetworkState(
        node_address=factories.make_address(),
        network_state=NetworkState.REACHABLE)
    transition_result = handle_action_change_node_network_state(
        chain_state, state_change)
    # no events if no mediator tasks are there to apply to
    assert not transition_result.events

    mediator_state = MediatorTransferState(
        secrethash=UNIT_SECRETHASH,
        routes=[
            RouteState(
                route=[netting_channel_state.partner_state.address],
                forward_channel_id=netting_channel_state.canonical_identifier.
                channel_identifier,
            )
        ],
    )
    subtask = MediatorTask(
        token_network_address=netting_channel_state.canonical_identifier.
        token_network_address,
        mediator_state=mediator_state,
    )
    chain_state.payment_mapping.secrethashes_to_task[UNIT_SECRETHASH] = subtask

    lock = factories.HashTimeLockState(amount=0,
                                       expiration=2,
                                       secrethash=UNIT_SECRETHASH)

    netting_channel_state.partner_state.secrethashes_to_lockedlocks[
        UNIT_SECRETHASH] = lock
    netting_channel_state.partner_state.pending_locks = PendingLocksState(
        [bytes(lock.encoded)])
    result = object()
    monkeypatch.setattr(
        raiden.transfer.node,
        "subdispatch_mediatortask",
        lambda *args, **kwargs: TransitionResult(chain_state, [result]),
    )
    transition_result = handle_action_change_node_network_state(
        chain_state, state_change)

    assert transition_result.events == [result]
Пример #4
0
def state_transition(
    initiator_state: InitiatorTransferState,
    state_change: StateChange,
    channel_state: NettingChannelState,
    pseudo_random_generator: random.Random,
) -> TransitionResult[InitiatorTransferState]:
    if type(state_change) == Block:
        assert isinstance(state_change, Block), MYPY_ANNOTATION
        iteration = handle_block(
            initiator_state, state_change, channel_state, pseudo_random_generator
        )
    elif type(state_change) == ReceiveSecretRequest:
        assert isinstance(state_change, ReceiveSecretRequest), MYPY_ANNOTATION
        iteration = handle_secretrequest(
            initiator_state, state_change, channel_state, pseudo_random_generator
        )
    elif type(state_change) == ReceiveSecretRequestLight:
        assert isinstance(state_change, ReceiveSecretRequestLight), MYPY_ANNOTATION
        iteration = handle_secretrequest_light(
            initiator_state, state_change, channel_state
        )
    elif type(state_change) == ReceiveSecretReveal:
        assert isinstance(state_change, ReceiveSecretReveal), MYPY_ANNOTATION
        iteration = handle_offchain_secretreveal(
            initiator_state, state_change, channel_state, pseudo_random_generator
        )
    elif type(state_change) == ReceiveSecretRevealLight:
        assert isinstance(state_change, ReceiveSecretRevealLight), MYPY_ANNOTATION
        iteration = handle_offchain_secretreveal_light(
            initiator_state, state_change, channel_state, pseudo_random_generator
        )
    elif type(state_change) == ContractReceiveSecretReveal:
        assert isinstance(state_change, ContractReceiveSecretReveal), MYPY_ANNOTATION
        iteration = handle_onchain_secretreveal(
            initiator_state, state_change, channel_state, pseudo_random_generator
        )
    elif type(state_change) == ActionSendSecretRevealLight:
        assert isinstance(state_change, ActionSendSecretRevealLight), MYPY_ANNOTATION
        iteration = handle_send_secret_reveal_light(
            initiator_state, state_change
        )
    else:
        iteration = TransitionResult(initiator_state, list())

    return iteration
Пример #5
0
def handle_batch_unlock(
        token_network_state,
        state_change,
        pseudo_random_generator,
        block_number,
):
    participant1 = state_change.participant
    participant2 = state_change.partner

    events = list()
    for channel_state in list(token_network_state.channelidentifiers_to_channels.values()):
        are_addresses_valid1 = (
            channel_state.our_state.address == participant1 and
            channel_state.partner_state.address == participant2
        )
        are_addresses_valid2 = (
            channel_state.our_state.address == participant2 and
            channel_state.partner_state.address == participant1
        )
        is_valid_locksroot = True
        is_valid_channel = (
            (are_addresses_valid1 or are_addresses_valid2) and
            is_valid_locksroot
        )

        if is_valid_channel:
            sub_iteration = channel.state_transition(
                channel_state,
                state_change,
                pseudo_random_generator,
                block_number,
            )
            events.extend(sub_iteration.events)

            if sub_iteration.new_state is None:

                del token_network_state.partneraddresses_to_channels[
                    channel_state.partner_state.address
                ][channel_state.identifier]

                del token_network_state.channelidentifiers_to_channels[
                    channel_state.identifier
                ]

    return TransitionResult(token_network_state, events)
Пример #6
0
def subdispatch_initiatortask(
    chain_state: ChainState,
    state_change: StateChange,
    token_network_address: TokenNetworkAddress,
    secrethash: SecretHash,
) -> TransitionResult[ChainState]:

    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
        manager_state = None

    elif sub_task and isinstance(sub_task, InitiatorTask):
        is_valid_subtask = token_network_address == sub_task.token_network_address
        manager_state = sub_task.manager_state
    else:
        is_valid_subtask = False

    events: List[Event] = list()
    if is_valid_subtask:
        pseudo_random_generator = chain_state.pseudo_random_generator

        token_network_state = get_token_network_by_address(chain_state, token_network_address)

        if token_network_state:
            iteration = initiator_manager.state_transition(
                payment_state=manager_state,
                state_change=state_change,
                channelidentifiers_to_channels=token_network_state.channelidentifiers_to_channels,
                nodeaddresses_to_networkstates=chain_state.nodeaddresses_to_networkstates,
                pseudo_random_generator=pseudo_random_generator,
                block_number=block_number,
            )
            events = iteration.events

            if iteration.new_state:
                sub_task = InitiatorTask(token_network_address, iteration.new_state)
                if sub_task is not None:
                    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)
Пример #7
0
def handle_batch_unlock(
        token_network_state: TokenNetworkState,
        state_change: ContractReceiveChannelBatchUnlock,
        block_number: BlockNumber,
        block_hash: BlockHash,
) -> TransitionResult:
    participant1 = state_change.participant
    participant2 = state_change.partner

    events = list()
    for channel_state in list(token_network_state.channelidentifiers_to_channels.values()):
        are_addresses_valid1 = (
            channel_state.our_state.address == participant1 and
            channel_state.partner_state.address == participant2
        )
        are_addresses_valid2 = (
            channel_state.our_state.address == participant2 and
            channel_state.partner_state.address == participant1
        )
        is_valid_locksroot = True
        is_valid_channel = (
            (are_addresses_valid1 or are_addresses_valid2) and
            is_valid_locksroot
        )

        if is_valid_channel:
            sub_iteration = channel.state_transition(
                channel_state=channel_state,
                state_change=state_change,
                block_number=block_number,
                block_hash=block_hash,
            )
            events.extend(sub_iteration.events)

            if sub_iteration.new_state is None:

                token_network_state.partneraddresses_to_channelidentifiers[
                    channel_state.partner_state.address
                ].remove(channel_state.identifier)

                del token_network_state.channelidentifiers_to_channels[
                    channel_state.identifier
                ]

    return TransitionResult(token_network_state, events)
Пример #8
0
def handle_closeroute(
        token_network_state: TokenNetworkState,
        state_change: ContractReceiveRouteClosed) -> TransitionResult:
    events: List[Event] = list()

    network_graph_state = token_network_state.network_graph

    # it might happen that both partners close at the same time, so the channel might
    # already be deleted
    if state_change.channel_identifier in network_graph_state.channel_identifier_to_participants:
        participant1, participant2 = network_graph_state.channel_identifier_to_participants[
            state_change.channel_identifier]
        token_network_state.network_graph.network.remove_edge(
            participant1, participant2)
        del token_network_state.network_graph.channel_identifier_to_participants[
            state_change.channel_identifier]

    return TransitionResult(token_network_state, events)
Пример #9
0
def handle_routechange(state, state_change):
    """ Handles an ActionRouteChange state change. """
    updated_route = state_change.route
    assert updated_route.node_address == state.from_route.node_address

    # the route might be closed by another task
    state.from_route = updated_route
    withdraw_events = events_for_withdraw(
        state.from_transfer,
        state.from_route,
    )

    iteration = TransitionResult(
        state,
        withdraw_events,
    )

    return iteration
Пример #10
0
def handle_action_transfer_direct(token_network_state, state_change,
                                  block_number):
    receiver_address = state_change.receiver_address
    channel_state = token_network_state.partneraddresses_to_channels.get(
        receiver_address)

    if channel_state:
        iteration = channel.state_transition(channel_state, state_change,
                                             block_number)
        events = iteration.events
    else:
        failure = EventTransferSentFailed(
            state_change.identifier,
            'Unknown partner channel',
        )
        events = [failure]

    return TransitionResult(token_network_state, events)
Пример #11
0
def user_cancel_transfer(state):
    """ Cancel the current in-transit message. """
    assert state.revealsecret is None, 'cannot cancel a transfer with a RevealSecret in flight'

    state.transfer.secret = None
    state.transfer.hashlock = None
    state.message = None
    state.route = None
    state.secretrequest = None
    state.revealsecret = None

    cancel = EventTransferFailed(
        identifier=state.transfer.identifier,
        reason='user canceled transfer',
    )
    iteration = TransitionResult(None, [cancel])

    return iteration
Пример #12
0
def handle_closeroute(token_network_state, state_change):
    events = list()

    network_graph_state = token_network_state.network_graph

    # it might happen that both partners close at the same time, so the channel might
    # already be deleted
    if state_change.channel_identifier in network_graph_state.channel_identifier_to_participants:
        participant1, participant2 = network_graph_state.channel_identifier_to_participants[
            state_change.channel_identifier]
        token_network_state.network_graph.network.remove_edge(
            participant1,
            participant2,
        )
        del token_network_state.network_graph.channel_identifier_to_participants[
            state_change.channel_identifier]

    return TransitionResult(token_network_state, events)
Пример #13
0
def handle_init(payment_state, state_change, channelidentifiers_to_channels,
                block_number):
    if payment_state is None:
        sub_iteration = initiator.try_new_route(
            channelidentifiers_to_channels,
            state_change.routes,
            state_change.transfer,
            block_number,
        )

        events = sub_iteration.events
        if sub_iteration.new_state:
            payment_state = InitiatorPaymentState(sub_iteration.new_state)
    else:
        events = list()

    iteration = TransitionResult(payment_state, events)
    return iteration
Пример #14
0
def handle_block(state, state_change):
    """ After Raiden learns about a new block this function must be called to
    handle expiration of the hash time lock.
    """
    state.block_number = max(
        state.block_number,
        state_change.block_number,
    )

    # only emit the close event once
    if state.state != 'waiting_close':
        close_events = events_for_close(state)
    else:
        close_events = list()

    iteration = TransitionResult(state, close_events)

    return iteration
Пример #15
0
def subdispatch_to_channel_by_id_and_address(
    token_network_state: TokenNetworkState,
    state_change: StateChangeWithChannelID,
    block_number: BlockNumber,
    block_hash: BlockHash,
    node_address: AddressHex = None
) -> TransitionResult:
    events = list()

    ids_to_channels = token_network_state.channelidentifiers_to_channels

    channel_state = None
    if node_address is not None:
        if node_address in ids_to_channels:
            channel_state = ids_to_channels[node_address].get(state_change.channel_identifier)
        else:
            lc_address = views.get_lc_address_by_channel_id_and_partner(token_network_state, node_address,
                                                                    state_change.canonical_identifier)
            node_address = lc_address
            if lc_address in token_network_state.channelidentifiers_to_channels:
                channel_state = token_network_state.channelidentifiers_to_channels[lc_address].get(
                    state_change.canonical_identifier.channel_identifier)
        if channel_state:
            result = channel.state_transition(
                channel_state=channel_state,
                state_change=state_change,
                block_number=block_number,
                block_hash=block_hash,
            )

            partner_to_channelids = token_network_state.partneraddresses_to_channelidentifiers[
                channel_state.partner_state.address
            ]

            channel_identifier = state_change.channel_identifier
            if result.new_state is None:
                del ids_to_channels[node_address][channel_identifier]
                partner_to_channelids.remove(channel_identifier)
            else:
                ids_to_channels[node_address][channel_identifier] = result.new_state

            events.extend(result.events)

    return TransitionResult(token_network_state, events)
Пример #16
0
def try_new_route(
    channelidentifiers_to_channels: ChannelMap,
    available_routes: typing.List[RouteState],
    transfer_description: TransferDescriptionWithSecretState,
    block_number: typing.BlockNumber,
) -> TransitionResult:

    channel_state = next_channel_from_routes(
        available_routes,
        channelidentifiers_to_channels,
        transfer_description.amount,
    )

    events = list()
    if channel_state is None:
        if not available_routes:
            reason = 'there is no route available'
        else:
            reason = 'none of the available routes could be used'

        transfer_failed = EventTransferSentFailed(
            identifier=transfer_description.identifier,
            reason=reason,
        )
        events.append(transfer_failed)

        initiator_state = None

    else:
        initiator_state = InitiatorTransferState(
            transfer_description,
            channel_state.identifier,
        )

        mediatedtransfer_event = send_mediatedtransfer(
            initiator_state,
            channel_state,
            block_number,
        )
        assert mediatedtransfer_event

        events.append(mediatedtransfer_event)

    return TransitionResult(initiator_state, events)
Пример #17
0
def state_transition(
    initiator_state: InitiatorTransferState,
    state_change: StateChange,
    channel_state: NettingChannelState,
    pseudo_random_generator: random.Random,
    block_number: BlockNumber,
) -> TransitionResult[Optional[InitiatorTransferState]]:
    if type(state_change) == Block:
        assert isinstance(state_change, Block), MYPY_ANNOTATION
        iteration = handle_block(
            initiator_state,
            state_change,
            channel_state,
            pseudo_random_generator,
        )
    elif type(state_change) == ReceiveSecretRequest:
        assert isinstance(state_change, ReceiveSecretRequest), MYPY_ANNOTATION
        iteration = handle_secretrequest(
            initiator_state,
            state_change,
            channel_state,
            pseudo_random_generator,
        )
    elif type(state_change) == ReceiveSecretReveal:
        assert isinstance(state_change, ReceiveSecretReveal), MYPY_ANNOTATION
        iteration = handle_offchain_secretreveal(
            initiator_state,
            state_change,
            channel_state,
            pseudo_random_generator,
        )
    elif type(state_change) == ContractReceiveSecretReveal:
        assert isinstance(state_change,
                          ContractReceiveSecretReveal), MYPY_ANNOTATION
        iteration = handle_onchain_secretreveal(
            initiator_state,
            state_change,
            channel_state,
            pseudo_random_generator,
        )
    else:
        iteration = TransitionResult(initiator_state, list())

    return iteration
Пример #18
0
def subdispatch_mediatortask(node_state, state_change,
                             payment_network_identifier, token_address,
                             secrethash):

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

    if not sub_task:
        is_valid_subtask = True
        mediator_state = None

    elif sub_task and isinstance(sub_task, PaymentMappingState.MediatorTask):
        is_valid_subtask = (payment_network_identifier
                            == sub_task.payment_network_identifier
                            and token_address == sub_task.token_address)
        mediator_state = sub_task.mediator_state
    else:
        is_valid_subtask = False

    events = list()
    if is_valid_subtask:
        token_network_state = get_token_network(
            node_state,
            payment_network_identifier,
            token_address,
        )
        iteration = mediator.state_transition(
            mediator_state,
            state_change,
            token_network_state.channelidentifiers_to_channels,
            block_number,
        )
        events = iteration.events

        if iteration.new_state:
            sub_task = PaymentMappingState.MediatorTask(
                payment_network_identifier,
                token_address,
                iteration.new_state,
            )
            node_state.payment_mapping.secrethashes_to_task[
                secrethash] = sub_task

    return TransitionResult(node_state, events)
Пример #19
0
def handle_send_directtransfer(channel_state, state_change):
    events = list()

    amount = state_change.amount
    identifier = state_change.identifier
    distributable_amount = get_distributable(channel_state.our_state,
                                             channel_state.partner_state)

    is_open = get_status(channel_state) == CHANNEL_STATE_OPENED
    is_valid = amount > 0
    can_pay = amount <= distributable_amount

    if is_open and is_valid and can_pay:
        direct_transfer = send_directtransfer(
            channel_state,
            amount,
            identifier,
        )
        events.append(direct_transfer)
    else:
        if not is_open:
            failure = EventTransferSentFailed(
                state_change.identifier,
                'Channel is not opened',
            )
            events.append(failure)

        elif not is_valid:
            msg = 'Transfer amount is invalid. Transfer: {}'.format(amount)

            failure = EventTransferSentFailed(state_change.identifier, msg)
            events.append(failure)

        elif not can_pay:
            msg = ('Transfer amount exceeds the available capacity. '
                   'Capacity: {}, Transfer: {}').format(
                       distributable_amount,
                       amount,
                   )

            failure = EventTransferSentFailed(state_change.identifier, msg)
            events.append(failure)

    return TransitionResult(channel_state, events)
Пример #20
0
def handle_block(
    payment_state: InitiatorPaymentState,
    state_change: Block,
    channelidentifiers_to_channels: typing.ChannelMap,
    pseudo_random_generator: random.Random,
) -> TransitionResult:
    channel_identifier = payment_state.initiator.channel_identifier
    channel_state = channelidentifiers_to_channels.get(channel_identifier)
    if not channel_state:
        return TransitionResult(payment_state, list())

    sub_iteration = initiator.handle_block(
        initiator_state=payment_state.initiator,
        state_change=state_change,
        channel_state=channel_state,
        pseudo_random_generator=pseudo_random_generator,
    )
    iteration = iteration_from_sub(payment_state, sub_iteration)
    return iteration
Пример #21
0
def handle_refundtransfer(state, state_change):
    """ Validate and handle a ReceiveTransferRefund state change.

    A node might participate in mediated transfer more than once because of
    refund transfers, eg. A-B-C-B-D-T, B tried to mediate the transfer through
    C, which didn't have an available route to proceed and refunds B, at this
    point B is part of the path again and will try a new partner to proceed
    with the mediation through D, D finally reaches the target T.

    In the above scenario B has two pairs of payer and payee transfers:

        payer:A payee:C from the first SendMediatedTransfer
        payer:C payee:D from the following SendRefundTransfer

    Args:
        state (MediatorState): Current state.
        state_change (ReceiveTransferRefund): The state change.

    Returns:
        TransitionResult: The resulting iteration.
    """
    assert state.secret is None, 'refunds are not allowed if the secret is revealed'

    # The last sent transfer is the only one thay may be refunded, all the
    # previous ones are refunded already.
    transfer_pair = state.transfers_pair[-1]
    payee_transfer = transfer_pair.payee_transfer

    if is_valid_refund(payee_transfer, state_change.sender,
                       state_change.transfer):
        payer_route = transfer_pair.payee_route
        payer_transfer = state_change.transfer
        iteration = mediate_transfer(
            state,
            payer_route,
            payer_transfer,
        )

    else:
        # TODO: Use an event to notify about byzantine behavior
        iteration = TransitionResult(state, list())

    return iteration
Пример #22
0
def handle_delivered(chain_state: ChainState,
                     state_change: ReceiveDelivered) -> TransitionResult:
    # TODO: improve the complexity of this algorithm
    queueids_to_remove = []
    queueid: QueueIdentifier
    for queueid, queue in chain_state.queueids_to_queues.items():
        if queueid.channel_identifier == CHANNEL_IDENTIFIER_GLOBAL_QUEUE:
            filtered_queue = [
                message for message in queue if
                message.message_identifier != state_change.message_identifier
            ]

            if not filtered_queue:
                queueids_to_remove.append(queueid)

    for queueid in queueids_to_remove:
        del chain_state.queueids_to_queues[queueid]

    return TransitionResult(chain_state, [])
Пример #23
0
def state_transition(payment_state, state_change,
                     channelidentifiers_to_channels, block_number):
    if type(state_change) == ActionInitInitiator:
        iteration = handle_init(
            payment_state,
            state_change,
            channelidentifiers_to_channels,
            block_number,
        )
    elif type(state_change) == ReceiveSecretRequest:
        sub_iteration = initiator.handle_secretrequest(
            payment_state.initiator,
            state_change,
        )
        iteration = iteration_from_sub(payment_state, sub_iteration)
    elif type(state_change) == ActionCancelRoute:
        iteration = handle_cancelroute(
            payment_state,
            state_change,
            channelidentifiers_to_channels,
            block_number,
        )
    elif type(state_change) == ReceiveTransferRefundCancelRoute:
        iteration = handle_transferrefund(
            payment_state,
            state_change,
            channelidentifiers_to_channels,
            block_number,
        )
    elif type(state_change) == ActionCancelPayment:
        iteration = handle_cancelpayment(payment_state, )
    elif type(state_change) == ReceiveSecretReveal:
        iteration = handle_secretreveal(
            payment_state,
            state_change,
            channelidentifiers_to_channels,
        )
    else:
        iteration = TransitionResult(payment_state, list())

    sanity_check(iteration.new_state)

    return iteration
Пример #24
0
def handle_channel_newbalance(channel_state, state_change):
    events = list()
    participant_address = state_change.participant_address

    if participant_address == channel_state.our_state.address:
        new_balance = max(
            channel_state.our_state.contract_balance,
            state_change.contract_balance,
        )
        channel_state.our_state.contract_balance = new_balance

    elif participant_address == channel_state.partner_state.address:
        new_balance = max(
            channel_state.partner_state.contract_balance,
            state_change.contract_balance,
        )
        channel_state.partner_state.contract_balance = new_balance

    return TransitionResult(channel_state, events)
Пример #25
0
def subdispatch_by_canonical_id(
        chain_state: ChainState, canonical_identifier: CanonicalIdentifier,
        state_change: StateChange) -> TransitionResult[ChainState]:
    token_network_state = get_token_network_by_address(
        chain_state, canonical_identifier.token_network_address)

    events: List[Event] = list()
    if token_network_state:
        iteration = token_network.state_transition(
            token_network_state=token_network_state,
            state_change=state_change,
            block_number=chain_state.block_number,
            block_hash=chain_state.block_hash,
        )
        assert iteration.new_state, "No token network state transition can lead to None"

        events = iteration.events

    return TransitionResult(chain_state, events)
Пример #26
0
def handle_token_network_action(
        chain_state: ChainState,
        state_change: TokenNetworkStateChange) -> TransitionResult[ChainState]:
    token_network_state = get_token_network_by_address(
        chain_state, state_change.token_network_identifier)

    events: List[Event] = list()
    if token_network_state:
        iteration = token_network.state_transition(
            token_network_state=token_network_state,
            state_change=state_change,
            block_number=chain_state.block_number,
            block_hash=chain_state.block_hash,
        )
        assert iteration.new_state, "No token network state transition leads to None"

        events = iteration.events

    return TransitionResult(chain_state, events)
Пример #27
0
def handle_channelnew(token_network_state, state_change):
    events = list()

    channel_state = state_change.channel_state
    channel_id = channel_state.identifier
    our_address = channel_state.our_state.address
    partner_address = channel_state.partner_state.address

    token_network_state.network_graph.network.add_edge(
        our_address,
        partner_address,
    )

    token_network_state.channelidentifiers_to_channels[
        channel_id] = channel_state
    token_network_state.partneraddresses_to_channels[
        partner_address] = channel_state

    return TransitionResult(token_network_state, events)
Пример #28
0
def handle_block(
        chain_state: ChainState,
        state_change: Block,
) -> TransitionResult:
    block_number = state_change.block_number
    chain_state.block_number = block_number

    # Subdispatch Block state change
    channels_result = subdispatch_to_all_channels(
        chain_state,
        state_change,
        block_number,
    )
    transfers_result = subdispatch_to_all_lockedtransfers(
        chain_state,
        state_change,
    )
    events = channels_result.events + transfers_result.events
    return TransitionResult(chain_state, events)
Пример #29
0
def subdispatch_to_all_channels(
        chain_state: ChainState,
        state_change: StateChange,
        block_number: typing.BlockNumber,
) -> TransitionResult:
    events = list()

    for payment_network in chain_state.identifiers_to_paymentnetworks.values():
        for token_network_state in payment_network.tokenidentifiers_to_tokennetworks.values():
            for channel_state in token_network_state.channelidentifiers_to_channels.values():
                result = channel.state_transition(
                    channel_state,
                    state_change,
                    chain_state.pseudo_random_generator,
                    block_number,
                )
                events.extend(result.events)

    return TransitionResult(chain_state, events)
Пример #30
0
def subdispatch_initiatortask(node_state, state_change,
                              payment_network_identifier,
                              token_network_identifier, hashlock):

    block_number = node_state.block_number
    sub_task = node_state.payment_mapping.hashlocks_to_task.get(hashlock)

    if not sub_task:
        is_valid_subtask = True
        manager_state = None

    elif sub_task and isinstance(sub_task, PaymentMappingState.InitiatorTask):
        is_valid_subtask = (
            payment_network_identifier == sub_task.payment_network_identifier
            and token_network_identifier == sub_task.token_network_identifier)
        manager_state = sub_task.manager_state
    else:
        is_valid_subtask = False

    events = list()
    if is_valid_subtask:
        token_network_state = get_token_network(
            node_state,
            payment_network_identifier,
            token_network_identifier,
        )
        iteration = initiator_manager.state_transition(
            manager_state,
            state_change,
            token_network_state.channelidentifiers_to_channels,
            block_number,
        )
        events = iteration.events

        if iteration.new_state:
            sub_task = PaymentMappingState.InitiatorTask(
                payment_network_identifier,
                token_network_identifier,
                iteration.new_state,
            )
            node_state.payment_mapping.hashlocks_to_task[hashlock] = sub_task

    return TransitionResult(node_state, events)