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, )
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, )
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, )
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])
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, )
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
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)