Пример #1
0
    def channel_batch_close(
        self,
        registry_address: typing.PaymentNetworkID,
        token_address: typing.TokenAddress,
        partner_addresses: typing.List[typing.Address],
        retry_timeout: typing.NetworkTimeout = DEFAULT_RETRY_TIMEOUT,
    ):
        """Close a channel opened with `partner_address` for the given
        `token_address`.

        Race condition, this can fail if channel was closed externally.
        """

        if not is_binary_address(token_address):
            raise InvalidAddress(
                'Expected binary address format for token in channel close')

        if not all(map(is_binary_address, partner_addresses)):
            raise InvalidAddress(
                'Expected binary address format for partner in channel close')

        valid_tokens = views.get_token_network_addresses_for(
            chain_state=views.state_from_raiden(self.raiden),
            payment_network_id=registry_address,
        )
        if token_address not in valid_tokens:
            raise UnknownTokenAddress('Token address is not known.')

        chain_state = views.state_from_raiden(self.raiden)
        channels_to_close = views.filter_channels_by_partneraddress(
            chain_state=chain_state,
            payment_network_id=registry_address,
            token_address=token_address,
            partner_addresses=partner_addresses,
        )
        token_network_identifier = views.get_token_network_identifier_by_token_address(
            chain_state=views.state_from_raiden(self.raiden),
            payment_network_id=registry_address,
            token_address=token_address,
        )

        for channel_state in channels_to_close:
            channel_close = ActionChannelClose(
                token_network_identifier=token_network_identifier,
                channel_identifier=channel_state.identifier,
            )

            self.raiden.handle_state_change(channel_close)

        channel_ids = [
            channel_state.identifier for channel_state in channels_to_close
        ]

        waiting.wait_for_close(
            raiden=self.raiden,
            payment_network_id=registry_address,
            token_address=token_address,
            channel_ids=channel_ids,
            retry_timeout=retry_timeout,
        )
Пример #2
0
    def channel_batch_close(self,
                            token_address,
                            partner_addresses,
                            poll_timeout=DEFAULT_POLL_TIMEOUT):
        """Close a channel opened with `partner_address` for the given
        `token_address`.

        Race condition, this can fail if channel was closed externally.
        """

        if not isaddress(token_address):
            raise InvalidAddress(
                'Expected binary address format for token in channel close')

        if not all(map(isaddress, partner_addresses)):
            raise InvalidAddress(
                'Expected binary address format for partner in channel close')

        valid_tokens = views.get_token_network_addresses_for(
            views.state_from_raiden(self.raiden),
            self.raiden.default_registry.address,
        )
        if token_address not in valid_tokens:
            raise UnknownTokenAddress('Token address is not known.')

        registry_address = self.raiden.default_registry.address
        node_state = views.state_from_raiden(self.raiden)
        channels_to_close = views.filter_channels_by_partneraddress(
            node_state,
            registry_address,
            token_address,
            partner_addresses,
        )

        for channel_state in channels_to_close:
            channel_close = ActionChannelClose(channel_state.identifier)
            state_change = ActionForTokenNetwork(
                registry_address,
                token_address,
                channel_close,
            )
            self.raiden.handle_state_change(state_change)

        msg = 'After {} seconds the deposit was not properly processed.'.format(
            poll_timeout)
        channel_ids = [
            channel_state.identifier for channel_state in channels_to_close
        ]

        with gevent.Timeout(poll_timeout, EthNodeCommunicationError(msg)):
            waiting.wait_for_close(
                self.raiden,
                registry_address,
                token_address,
                channel_ids,
                self.raiden.alarm.wait_time,
            )
Пример #3
0
    def channel_batch_close(
        self,
        registry_address: TokenNetworkRegistryAddress,
        token_address: TokenAddress,
        partner_addresses: List[Address],
        retry_timeout: NetworkTimeout = DEFAULT_RETRY_TIMEOUT,
    ) -> None:
        """Close a channel opened with `partner_address` for the given
        `token_address`.

        Race condition, this can fail if channel was closed externally.
        """

        if not is_binary_address(token_address):
            raise InvalidBinaryAddress(
                "Expected binary address format for token in channel close")

        if not all(map(is_binary_address, partner_addresses)):
            raise InvalidBinaryAddress(
                "Expected binary address format for partner in channel close")

        valid_tokens = views.get_token_identifiers(
            chain_state=views.state_from_raiden(self.raiden),
            token_network_registry_address=registry_address,
        )
        if token_address not in valid_tokens:
            raise UnknownTokenAddress("Token address is not known.")

        chain_state = views.state_from_raiden(self.raiden)
        channels_to_close = views.filter_channels_by_partneraddress(
            chain_state=chain_state,
            token_network_registry_address=registry_address,
            token_address=token_address,
            partner_addresses=partner_addresses,
        )

        close_state_changes: List[StateChange] = [
            ActionChannelClose(
                canonical_identifier=channel_state.canonical_identifier)
            for channel_state in channels_to_close
        ]

        greenlets = set(self.raiden.handle_state_changes(close_state_changes))
        gevent.joinall(greenlets, raise_error=True)

        channel_ids = [
            channel_state.identifier for channel_state in channels_to_close
        ]

        waiting.wait_for_close(
            raiden=self.raiden,
            token_network_registry_address=registry_address,
            token_address=token_address,
            channel_ids=channel_ids,
            retry_timeout=retry_timeout,
        )
Пример #4
0
    def channel_batch_close(
        self,
        registry_address: typing.PaymentNetworkID,
        token_address: typing.TokenAddress,
        partner_addresses: typing.List[typing.Address],
        retry_timeout: typing.NetworkTimeout = DEFAULT_RETRY_TIMEOUT,
    ):
        """Close a channel opened with `partner_address` for the given
        `token_address`.

        Race condition, this can fail if channel was closed externally.
        """

        if not is_binary_address(token_address):
            raise InvalidAddress(
                'Expected binary address format for token in channel close')

        if not all(map(is_binary_address, partner_addresses)):
            raise InvalidAddress(
                'Expected binary address format for partner in channel close')

        valid_tokens = views.get_token_network_addresses_for(
            views.state_from_raiden(self.raiden),
            registry_address,
        )
        if token_address not in valid_tokens:
            raise UnknownTokenAddress('Token address is not known.')

        chain_state = views.state_from_raiden(self.raiden)
        channels_to_close = views.filter_channels_by_partneraddress(
            chain_state,
            registry_address,
            token_address,
            partner_addresses,
        )
        token_network_identifier = views.get_token_network_identifier_by_token_address(
            views.state_from_raiden(self.raiden),
            registry_address,
            token_address,
        )

        # If concurrent operations are happening on one of the channels, fail entire
        # request.
        with ExitStack() as stack:
            # Put all the locks in this outer context so that the netting channel functions
            # don't release the locks when their context goes out of scope
            for channel_state in channels_to_close:
                channel = self.raiden.chain.payment_channel(
                    token_network_identifier,
                    channel_state.identifier,
                )
                stack.enter_context(channel.lock_or_raise())

            for channel_state in channels_to_close:
                channel_close = ActionChannelClose(
                    token_network_identifier,
                    channel_state.identifier,
                )

                self.raiden.handle_state_change(channel_close)

            channel_ids = [
                channel_state.identifier for channel_state in channels_to_close
            ]

            waiting.wait_for_close(
                self.raiden,
                registry_address,
                token_address,
                channel_ids,
                retry_timeout,
            )
 def make_tx(*args, **kwargs):  # pylint: disable=unused-argument
     close_channel = ActionChannelClose(canonical_identifier=channel_state.canonical_identifier)
     app0.raiden.handle_and_track_state_changes([close_channel])
Пример #6
0
    def channel_batch_close(self,
                            token_address,
                            partner_addresses,
                            poll_timeout=DEFAULT_POLL_TIMEOUT):
        """Close a channel opened with `partner_address` for the given
        `token_address`.

        Race condition, this can fail if channel was closed externally.
        """

        if not isaddress(token_address):
            raise InvalidAddress(
                'Expected binary address format for token in channel close')

        if not all(map(isaddress, partner_addresses)):
            raise InvalidAddress(
                'Expected binary address format for partner in channel close')

        valid_tokens = views.get_token_network_addresses_for(
            views.state_from_raiden(self.raiden),
            self.raiden.default_registry.address,
        )
        if token_address not in valid_tokens:
            raise UnknownTokenAddress('Token address is not known.')

        registry_address = self.raiden.default_registry.address
        node_state = views.state_from_raiden(self.raiden)
        channels_to_close = views.filter_channels_by_partneraddress(
            node_state,
            registry_address,
            token_address,
            partner_addresses,
        )

        # If concurrent operations are happening on one of the channels, fail entire
        # request.
        with ExitStack() as stack:
            # Put all the locks in this outer context so that the netting channel functions
            # don't release the locks when their context goes out of scope
            for channel_state in channels_to_close:
                channel = self.raiden.chain.netting_channel(
                    channel_state.identifier)

                # Check if we can acquire the lock. If we can't raise an exception, which
                # will cause the ExitStack to exit, releasing all locks acquired so far
                if not channel.channel_operations_lock.acquire(blocking=False):
                    raise ChannelBusyError(
                        f'Channel with id {channel_state.identifier} is '
                        f'busy with another ongoing operation.')

                stack.push(channel.channel_operations_lock)

            for channel_state in channels_to_close:
                channel_close = ActionChannelClose(
                    registry_address,
                    token_address,
                    channel_state.identifier,
                )

                self.raiden.handle_state_change(channel_close)

            msg = 'After {} seconds the deposit was not properly processed.'.format(
                poll_timeout)

            channel_ids = [
                channel_state.identifier for channel_state in channels_to_close
            ]

            with gevent.Timeout(poll_timeout, EthNodeCommunicationError(msg)):
                waiting.wait_for_close(
                    self.raiden,
                    registry_address,
                    token_address,
                    channel_ids,
                    self.raiden.alarm.wait_time,
                )
Пример #7
0
def test_subdispatch_by_canonical_id(chain_state):
    our_model, _ = create_model(balance=10, num_pending_locks=1)
    partner_model, _ = create_model(balance=0, num_pending_locks=0)
    channel_state = create_channel_from_models(
        our_model, partner_model, factories.make_privatekey_bin()
    )
    canonical_identifier = channel_state.canonical_identifier
    token_network = TokenNetworkState(
        address=canonical_identifier.token_network_address,
        token_address=factories.make_address(),
        network_graph=TokenNetworkGraphState(
            token_network_address=channel_state.token_network_address
        ),
    )
    token_network.partneraddresses_to_channelidentifiers[
        partner_model.participant_address
    ] = canonical_identifier.channel_identifier
    token_network.channelidentifiers_to_channels[
        canonical_identifier.channel_identifier
    ] = channel_state
    token_network_registry = TokenNetworkRegistryState(
        address=factories.make_address(), token_network_list=[token_network]
    )
    chain_state.identifiers_to_tokennetworkregistries[
        token_network_registry.address
    ] = token_network_registry
    chain_state.tokennetworkaddresses_to_tokennetworkregistryaddresses[
        canonical_identifier.token_network_address
    ] = token_network_registry.address
    # dispatching a Block will be ignored
    previous_state = deepcopy(chain_state)
    state_change = Block(
        block_number=chain_state.block_number,
        gas_limit=GAS_LIMIT,
        block_hash=chain_state.block_hash,
    )
    transition_result = subdispatch_by_canonical_id(
        chain_state=chain_state,
        canonical_identifier=canonical_identifier,
        state_change=state_change,
    )
    assert transition_result.new_state == previous_state
    assert transition_result.events == []

    state_change = ActionChannelClose(canonical_identifier=canonical_identifier)

    # dispatching for an unknown canonical_identifier will not emit events
    transition_result = subdispatch_by_canonical_id(
        chain_state=chain_state,
        canonical_identifier=CanonicalIdentifier(
            chain_identifier=chain_state.chain_id,
            token_network_address=factories.make_address(),
            channel_identifier=factories.make_channel_identifier(),
        ),
        state_change=state_change,
    )
    assert not transition_result.events, transition_result

    assert get_status(channel_state) == ChannelState.STATE_OPENED
    transition_result = subdispatch_by_canonical_id(
        chain_state=chain_state,
        canonical_identifier=canonical_identifier,
        state_change=state_change,
    )

    assert get_status(channel_state) == ChannelState.STATE_CLOSING
    assert transition_result.new_state == chain_state, transition_result
Пример #8
0
 def make_tx(*args, **kwargs):
     close_channel = ActionChannelClose(
         token_network_identifier=channel_state.token_network_identifier,
         channel_identifier=channel_state.identifier,
     )
     app0.raiden.handle_and_track_state_change(close_channel)