def wait_for_participant_newbalance( raiden: "RaidenService", payment_network_id: PaymentNetworkID, token_address: TokenAddress, partner_address: Address, target_address: Address, target_balance: TokenAmount, retry_timeout: float, ) -> None: """Wait until a given channels balance exceeds the target balance. Note: This does not time out, use gevent.Timeout. """ if target_address == raiden.address: balance = lambda channel_state: channel_state.our_state.contract_balance elif target_address == partner_address: balance = lambda channel_state: channel_state.partner_state.contract_balance else: raise ValueError( "target_address must be one of the channel participants") channel_state = views.get_channelstate_for(views.state_from_raiden(raiden), payment_network_id, token_address, partner_address) while balance(channel_state) < target_balance: assert raiden, ALARM_TASK_ERROR_MSG assert raiden.alarm, ALARM_TASK_ERROR_MSG gevent.sleep(retry_timeout) channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_address, partner_address)
def wait_for_newchannel( raiden: RaidenService, payment_network_id: typing.PaymentNetworkID, token_address: typing.TokenAddress, partner_address: typing.Address, retry_timeout: float, ) -> None: """Wait until the channel with partner_address is registered. Note: This does not time out, use gevent.Timeout. """ channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_address, partner_address, ) while channel_state is None: gevent.sleep(retry_timeout) channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_address, partner_address, )
def wait_for_participant_newbalance(raiden, payment_network_id, token_address, partner_address, target_address, target_balance, poll_timeout): """Wait until a given channels balance exceeds the target balance. Note: This does not time out, use gevent.Timeout. """ if target_address == raiden.address: balance = lambda channel_state: channel_state.our_state.contract_balance elif target_address == partner_address: balance = lambda channel_state: channel_state.partner_state.contract_balance else: raise ValueError( 'target_address must be one of the channel participants') channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_address, partner_address, ) while balance(channel_state) < target_balance: gevent.sleep(poll_timeout) channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_address, partner_address, )
def wait_for_newchannel( raiden: "RaidenService", payment_network_id: PaymentNetworkID, token_address: TokenAddress, creator_address: Address, partner_address: Address, retry_timeout: float, ) -> None: """Wait until the channel with partner_address is registered. Note: This does not time out, use gevent.Timeout. """ channel_state = views.get_channelstate_for(views.state_from_raiden(raiden), payment_network_id, token_address, creator_address, partner_address) while channel_state is None: assert raiden, ALARM_TASK_ERROR_MSG assert raiden.alarm, ALARM_TASK_ERROR_MSG gevent.sleep(retry_timeout) channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_address, creator_address, partner_address)
def wait_for_participant_newbalance( raiden: "RaidenService", payment_network_id: PaymentNetworkID, token_address: TokenAddress, partner_address: Address, target_address: Address, target_balance: TokenAmount, retry_timeout: float, ) -> None: """Wait until a given channels balance exceeds the target balance. Note: This does not time out, use gevent.Timeout. """ channel_state = views.get_channelstate_for(views.state_from_raiden(raiden), payment_network_id, token_address, target_address, partner_address) balance = _check_balance(channel_state, target_address) while balance < target_balance: assert raiden, ALARM_TASK_ERROR_MSG assert raiden.alarm, ALARM_TASK_ERROR_MSG gevent.sleep(retry_timeout) channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_address, target_address, partner_address) balance = _check_balance(channel_state, target_address)
def run_smoketests( raiden_service: RaidenService, transport: str, token_addresses, discovery_address, debug: bool = False, ): """ Test that the assembled raiden_service correctly reflects the configuration from the smoketest_genesis. """ try: chain = raiden_service.chain token_network_added_events = raiden_service.default_registry.filter_token_added_events( ) events_token_addresses = [ event['args']['token_address'] for event in token_network_added_events ] assert events_token_addresses == token_addresses if transport == 'udp': discovery_addresses = list(chain.address_to_discovery.keys()) assert len(discovery_addresses) == 1, repr( chain.address_to_discovery) assert discovery_addresses[0] == discovery_address discovery = chain.address_to_discovery[discovery_addresses[0]] assert discovery.endpoint_by_address( raiden_service.address) != TEST_ENDPOINT token_networks = views.get_token_network_addresses_for( views.state_from_raiden(raiden_service), raiden_service.default_registry.address, ) assert len(token_networks) == 1 channel_state = views.get_channelstate_for( views.state_from_raiden(raiden_service), raiden_service.default_registry.address, token_networks[0], decode_hex(TEST_PARTNER_ADDRESS), ) distributable = channel.get_distributable( channel_state.our_state, channel_state.partner_state, ) assert distributable == TEST_DEPOSIT_AMOUNT assert distributable == channel_state.our_state.contract_balance assert channel.get_status(channel_state) == CHANNEL_STATE_OPENED # Run API test run_restapi_smoketests() except: # NOQA pylint: disable=bare-except error = traceback.format_exc() if debug: import pdb pdb.post_mortem() # pylint: disable=no-member return error return None
def open( self, registry_address, partner_address, token_address, settle_timeout=None, reveal_timeout=None, balance=None, ): try: self.raiden_api.channel_open( registry_address, token_address, partner_address, settle_timeout, reveal_timeout, ) except (InvalidAddress, InvalidSettleTimeout, SamePeerAddress, AddressWithoutCode, NoTokenManager, DuplicatedChannelError) as e: return api_error( errors=str(e), status_code=HTTPStatus.CONFLICT, ) if balance: # make initial deposit try: self.raiden_api.channel_deposit( registry_address, token_address, partner_address, balance, ) except EthNodeCommunicationError as e: return api_error( errors=str(e), status_code=HTTPStatus.REQUEST_TIMEOUT, ) except InsufficientFunds as e: return api_error( errors=str(e), status_code=HTTPStatus.PAYMENT_REQUIRED, ) channel_state = views.get_channelstate_for( views.state_from_raiden(self.raiden_api.raiden), registry_address, token_address, partner_address, ) result = self.channel_schema.dump( channelstate_to_api_dict(channel_state)) return api_response( result=checksummed_response_dict(result.data), status_code=HTTPStatus.CREATED, )
def test_matrix_tx_error_handling( # pylint: disable=unused-argument raiden_chain: List[App], token_addresses, request ): """Proxies exceptions must be forwarded by the transport.""" if request.config.option.usepdb: pytest.skip("test fails with pdb") app0, app1 = raiden_chain token_address = token_addresses[0] channel_state = views.get_channelstate_for( chain_state=views.state_from_app(app0), token_network_registry_address=app0.raiden.default_registry.address, token_address=token_address, partner_address=app1.raiden.address, ) burn_eth(app0.raiden.rpc_client) 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]) app0.raiden.transport._client.add_presence_listener(make_tx) exception = ValueError("Exception was not raised from the transport") with pytest.raises(InsufficientEth), gevent.Timeout(10, exception=exception): # Change presence in peer app to trigger callback in app0 app1.raiden.transport._client.set_presence_state(UserPresence.UNAVAILABLE.value) app0.raiden.greenlet.get()
def get_pending_transfers( self, token_address: TokenAddress = None, partner_address: Address = None) -> List[Dict[str, Any]]: chain_state = views.state_from_raiden(self.raiden) transfer_tasks = views.get_all_transfer_tasks(chain_state) channel_id = None confirmed_block_identifier = chain_state.block_hash if token_address is not None: token_network = self.raiden.default_registry.get_token_network( token_address=token_address, block_identifier=confirmed_block_identifier) if token_network is None: raise UnknownTokenAddress( f"Token {to_checksum_address(token_address)} not found.") if partner_address is not None: partner_channel = views.get_channelstate_for( chain_state=chain_state, token_network_registry_address=self.raiden. default_registry.address, token_address=token_address, partner_address=partner_address, ) if not partner_channel: raise ChannelNotFound( "Channel with partner `partner_address not found.`") channel_id = partner_channel.identifier return transfer_tasks_view(transfer_tasks, token_address, channel_id)
def get_channel_list( self, registry_address: typing.PaymentNetworkID, token_address: typing.TokenAddress = None, partner_address: typing.Address = None, ) -> typing.List[NettingChannelState]: """Returns a list of channels associated with the optionally given `token_address` and/or `partner_address`. Args: token_address: an optionally provided token address partner_address: an optionally provided partner address Return: A list containing all channels the node participates. Optionally filtered by a token address and/or partner address. Raises: KeyError: An error occurred when the token address is unknown to the node. """ if registry_address and not is_binary_address(registry_address): raise InvalidAddress('Expected binary address format for registry in get_channel_list') if token_address and not is_binary_address(token_address): raise InvalidAddress('Expected binary address format for token in get_channel_list') if partner_address: if not is_binary_address(partner_address): raise InvalidAddress( 'Expected binary address format for partner in get_channel_list', ) if not token_address: raise UnknownTokenAddress('Provided a partner address but no token address') if token_address and partner_address: channel_state = views.get_channelstate_for( chain_state=views.state_from_raiden(self.raiden), payment_network_id=registry_address, token_address=token_address, partner_address=partner_address, ) if channel_state: result = [channel_state] else: result = [] elif token_address: result = views.list_channelstate_for_tokennetwork( chain_state=views.state_from_raiden(self.raiden), payment_network_id=registry_address, token_address=token_address, ) else: result = views.list_all_channelstate( chain_state=views.state_from_raiden(self.raiden), ) return result
def get_channel_list(self, token_address=None, partner_address=None): """Returns a list of channels associated with the optionally given `token_address` and/or `partner_address`. Args: token_address (bin): an optionally provided token address partner_address (bin): an optionally provided partner address Return: A list containing all channels the node participates. Optionally filtered by a token address and/or partner address. Raises: KeyError: An error occurred when the token address is unknown to the node. """ if token_address and not isaddress(token_address): raise InvalidAddress( 'Expected binary address format for token in get_channel_list') if partner_address and not isaddress(partner_address): raise InvalidAddress( 'Expected binary address format for partner in get_channel_list' ) registry_address = self.raiden.default_registry.address result = list() if token_address and partner_address: channel_state = views.get_channelstate_for( views.state_from_raiden(self.raiden), registry_address, token_address, partner_address, ) if channel_state: result = [channel_state] else: result = [] elif token_address: result = views.list_channelstate_for_tokennetwork( views.state_from_raiden(self.raiden), registry_address, token_address, ) elif partner_address: result = views.list_channelstate_for_tokennetwork( views.state_from_raiden(self.raiden), registry_address, partner_address, ) else: result = views.list_all_channelstate( views.state_from_raiden(self.raiden), ) return result
def test_matrix_tx_error_handling( # pylint: disable=unused-argument skip_if_not_matrix, raiden_chain, token_addresses): """Proxies exceptions must be forwarded by the transport.""" app0, app1 = raiden_chain token_address = token_addresses[0] channel_state = views.get_channelstate_for( chain_state=views.state_from_app(app0), payment_network_id=app0.raiden.default_registry.address, token_address=token_address, partner_address=app1.raiden.address, ) burn_eth(app0.raiden) def make_tx(*args, **kwargs): # pylint: disable=unused-argument close_channel = ActionChannelClose( canonical_identifier=channel_state.canonical_identifier) app0.raiden.handle_and_track_state_change(close_channel) app0.raiden.transport._client.add_presence_listener(make_tx) exception = ValueError("exception was not raised from the transport") with pytest.raises(InsufficientFunds), gevent.Timeout(200, exception=exception): app0.raiden.get()
def wait_for_payment_balance( raiden: RaidenService, payment_network_id: typing.PaymentNetworkID, token_address: typing.TokenAddress, partner_address: typing.Address, target_address: typing.Address, target_balance: typing.TokenAmount, retry_timeout: float, ) -> None: """Wait until a given channels balance exceeds the target balance. Note: This does not time out, use gevent.Timeout. """ def get_balance(end_state): if end_state.balance_proof: return end_state.balance_proof.transferred_amount else: return 0 if target_address == raiden.address: balance = lambda channel_state: get_balance(channel_state.partner_state ) elif target_address == partner_address: balance = lambda channel_state: get_balance(channel_state.our_state) else: raise ValueError( 'target_address must be one of the channel participants') channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_address, partner_address, ) while balance(channel_state) < target_balance: log.critical('wait', b=balance(channel_state), t=target_balance) gevent.sleep(retry_timeout) channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_address, partner_address, )
def run_smoketests(raiden_service: RaidenService, test_config: Dict, debug: bool = False): """ Test that the assembled raiden_service correctly reflects the configuration from the smoketest_genesis. """ try: chain = raiden_service.chain assert ( raiden_service.default_registry.address == to_canonical_address(test_config['contracts']['registry_address']) ) assert ( raiden_service.default_secret_registry.address == to_canonical_address(test_config['contracts']['secret_registry_address']) ) token_network_added_events = raiden_service.default_registry.filter_token_added_events() token_addresses = [event['args']['token_address'] for event in token_network_added_events] assert token_addresses == [test_config['contracts']['token_address']] if test_config.get('transport') == 'udp': assert len(chain.address_to_discovery.keys()) == 1, repr(chain.address_to_discovery) assert ( list(chain.address_to_discovery.keys())[0] == to_canonical_address(test_config['contracts']['discovery_address']) ) discovery = list(chain.address_to_discovery.values())[0] assert discovery.endpoint_by_address(raiden_service.address) != TEST_ENDPOINT token_networks = views.get_token_network_addresses_for( views.state_from_raiden(raiden_service), raiden_service.default_registry.address, ) assert len(token_networks) == 1 channel_state = views.get_channelstate_for( views.state_from_raiden(raiden_service), raiden_service.default_registry.address, token_networks[0], unhexlify(TEST_PARTNER_ADDRESS), ) distributable = channel.get_distributable( channel_state.our_state, channel_state.partner_state, ) assert distributable == TEST_DEPOSIT_AMOUNT assert distributable == channel_state.our_state.contract_balance assert channel.get_status(channel_state) == CHANNEL_STATE_OPENED # Run API test run_restapi_smoketests() except Exception: error = traceback.format_exc() if debug: import pdb pdb.post_mortem() return error
def get_channelstate(app0, app1, token_address) -> 'NettingChannelState': registry_address = app0.raiden.default_registry.address channel_state = views.get_channelstate_for( views.state_from_app(app0), registry_address, token_address, app1.raiden.address, ) return channel_state
def get_channel_list(self, registry_address, token_address=None, partner_address=None): """Returns a list of channels associated with the optionally given `token_address` and/or `partner_address`. Args: token_address (bin): an optionally provided token address partner_address (bin): an optionally provided partner address Return: A list containing all channels the node participates. Optionally filtered by a token address and/or partner address. Raises: KeyError: An error occurred when the token address is unknown to the node. """ if token_address and not is_binary_address(token_address): raise InvalidAddress('Expected binary address format for token in get_channel_list') if partner_address and not is_binary_address(partner_address): raise InvalidAddress('Expected binary address format for partner in get_channel_list') result = list() if token_address and partner_address: channel_state = views.get_channelstate_for( views.state_from_raiden(self.raiden), registry_address, token_address, partner_address, ) if channel_state: result = [channel_state] else: result = [] elif token_address: result = views.list_channelstate_for_tokennetwork( views.state_from_raiden(self.raiden), registry_address, token_address, ) elif partner_address: result = views.list_channelstate_for_tokennetwork( views.state_from_raiden(self.raiden), registry_address, partner_address, ) else: result = views.list_all_channelstate( views.state_from_raiden(self.raiden), ) return result
def test_get_channelstate_for(): test_state = factories.make_chain_state(number_of_channels=3) partner_address = test_state.channels[1].partner_state.address assert (views.get_channelstate_for( chain_state=test_state.chain_state, token_network_registry_address=test_state. token_network_registry_address, token_address=test_state.token_address, partner_address=partner_address, ) == test_state.channels[1])
def wait_for_payment_balance( raiden: RaidenService, payment_network_id: typing.PaymentNetworkID, token_address: typing.TokenAddress, partner_address: typing.Address, target_address: typing.Address, target_balance: typing.TokenAmount, retry_timeout: float, ) -> None: """Wait until a given channels balance exceeds the target balance. Note: This does not time out, use gevent.Timeout. """ def get_balance(end_state): if end_state.balance_proof: return end_state.balance_proof.transferred_amount else: return 0 if target_address == raiden.address: balance = lambda channel_state: get_balance(channel_state.partner_state) elif target_address == partner_address: balance = lambda channel_state: get_balance(channel_state.our_state) else: raise ValueError('target_address must be one of the channel participants') channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_address, partner_address, ) while balance(channel_state) < target_balance: log.critical('wait', b=balance(channel_state), t=target_balance) gevent.sleep(retry_timeout) channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_address, partner_address, )
def smoketest_perform_tests( raiden_service: RaidenService, transport: str, token_addresses, discovery_address, ): """ Perform high level tests designed to quickly discover broken functionality. """ try: chain = raiden_service.chain token_network_added_events = raiden_service.default_registry.filter_token_added_events( ) events_token_addresses = [ event['args']['token_address'] for event in token_network_added_events ] assert events_token_addresses == token_addresses if transport == 'udp': discovery_addresses = list(chain.address_to_discovery.keys()) assert len(discovery_addresses) == 1, repr( chain.address_to_discovery) assert discovery_addresses[0] == discovery_address discovery = chain.address_to_discovery[discovery_addresses[0]] assert discovery.endpoint_by_address( raiden_service.address) != TEST_ENDPOINT token_networks = views.get_token_identifiers( views.state_from_raiden(raiden_service), raiden_service.default_registry.address, ) assert len(token_networks) == 1 channel_state = views.get_channelstate_for( views.state_from_raiden(raiden_service), raiden_service.default_registry.address, token_networks[0], decode_hex(TEST_PARTNER_ADDRESS), ) distributable = channel.get_distributable( channel_state.our_state, channel_state.partner_state, ) assert distributable == TEST_DEPOSIT_AMOUNT assert distributable == channel_state.our_state.contract_balance assert channel.get_status(channel_state) == CHANNEL_STATE_OPENED # Run API test run_restapi_smoketests() except: # NOQA pylint: disable=bare-except error = traceback.format_exc() return error return None
def set_reveal_timeout( self, registry_address: TokenNetworkRegistryAddress, token_address: TokenAddress, partner_address: Address, reveal_timeout: BlockTimeout, ) -> None: """ Set the `reveal_timeout` in the channel with the peer at `partner_address` and the given `token_address`. Raises: InvalidBinaryAddress: If either token_address or partner_address is not 20 bytes long. InvalidRevealTimeout: If reveal_timeout has an invalid value. """ chain_state = views.state_from_raiden(self.raiden) token_addresses = views.get_token_identifiers(chain_state, registry_address) channel_state = views.get_channelstate_for( chain_state=chain_state, token_network_registry_address=registry_address, token_address=token_address, partner_address=partner_address, ) if not is_binary_address(token_address): raise InvalidBinaryAddress( "Expected binary address format for token in channel deposit") if not is_binary_address(partner_address): raise InvalidBinaryAddress( "Expected binary address format for partner in channel deposit" ) if token_address not in token_addresses: raise UnknownTokenAddress("Unknown token address") if channel_state is None: raise NonexistingChannel( "No channel with partner_address for the given token") if reveal_timeout <= 0: raise InvalidRevealTimeout( "reveal_timeout should be larger than zero.") if channel_state.settle_timeout < reveal_timeout * 2: raise InvalidRevealTimeout( "`settle_timeout` should be at least double the " "provided `reveal_timeout`.") self.raiden.set_channel_reveal_timeout( canonical_identifier=channel_state.canonical_identifier, reveal_timeout=reveal_timeout)
def wait_for_newchannel( raiden: "RaidenService", token_network_registry_address: TokenNetworkRegistryAddress, token_address: TokenAddress, partner_address: Address, retry_timeout: float, ) -> None: # pragma: no unittest """Wait until the channel with partner_address is registered. Note: This does not time out, use gevent.Timeout. """ channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), token_network_registry_address, token_address, partner_address, ) log_details = { "node": to_checksum_address(raiden.address), "token_network_registry_address": to_checksum_address(token_network_registry_address), "token_address": to_checksum_address(token_address), "partner_address": to_checksum_address(partner_address), } while channel_state is None: assert raiden, ALARM_TASK_ERROR_MSG assert raiden.alarm, ALARM_TASK_ERROR_MSG log.debug("wait_for_newchannel", **log_details) gevent.sleep(retry_timeout) channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), token_network_registry_address, token_address, partner_address, )
def test_handle_insufficient_eth(raiden_network, token_addresses, caplog): app0, app1 = raiden_network token = token_addresses[0] registry_address = app0.raiden.default_registry.address channel_state = views.get_channelstate_for( chain_state=views.state_from_raiden(app0.raiden), token_network_registry_address=registry_address, token_address=token, partner_address=app1.raiden.address, ) assert isinstance(channel_state, NettingChannelState) channel_identifier = channel_state.identifier transfer( initiator_app=app0, target_app=app1, amount=PaymentAmount(1), token_address=token, identifier=PaymentID(1), timeout=60, ) app1.raiden.stop() burn_eth(app1.raiden.rpc_client) app1.raiden.start() settle_block_timeout = BlockTimeout( exception_to_throw=RuntimeError("Settle did not happen."), raiden=app0.raiden, block_number=app0.raiden.get_block_number() + channel_state.settle_timeout * 2, retry_timeout=DEFAULT_RETRY_TIMEOUT, ) with settle_block_timeout: RaidenAPI(app0.raiden).channel_close( registry_address=registry_address, token_address=token, partner_address=app1.raiden.address, ) waiting.wait_for_settle( raiden=app0.raiden, token_network_registry_address=registry_address, token_address=token, channel_ids=[channel_identifier], retry_timeout=DEFAULT_RETRY_TIMEOUT, ) assert any( "subtask died" in message and "insufficient ETH" in message for message in caplog.messages )
def wait_for_newchannel(raiden, payment_network_id, token_network_id, partner_address, poll_timeout): """Wait until the channel with partner_address is registered. Note: This does not time out, use gevent.Timeout. """ channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_network_id, partner_address, ) while channel_state is None: gevent.sleep(poll_timeout) channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_network_id, partner_address, )
def wait_for_newbalance(raiden, payment_network_id, token_network_id, partner_address, target_balance, poll_timeout): """Wait until a given channels balance exceeds the target balance. Note: This does not time out, use gevent.Timeout. """ channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_network_id, partner_address, ) while channel_state.our_state.contract_balance < target_balance: gevent.sleep(poll_timeout) channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_network_id, partner_address, )
def can_open_channel(registry_address: PaymentNetworkID, token_address: TokenAddress, creator_address: Address, partner_address: Address, settle_timeout: BlockTimeout, raiden) -> TokenNetwork: if settle_timeout < raiden.config["reveal_timeout"] * 2: raise InvalidSettleTimeout( "settle_timeout can not be smaller than double the reveal_timeout" ) if not is_binary_address(registry_address): raise InvalidAddress( "Expected binary address format for registry in channel open") if not is_binary_address(token_address): raise InvalidAddress( "Expected binary address format for token in channel open") if not is_binary_address(partner_address): raise InvalidAddress( "Expected binary address format for partner in channel open") if not is_binary_address(creator_address): raise InvalidAddress( "Expected binary address format for creator in channel open") chain_state = views.state_from_raiden(raiden) channel_state = views.get_channelstate_for( chain_state=chain_state, payment_network_id=registry_address, creator_address=creator_address, token_address=token_address, partner_address=partner_address, ) if channel_state: raise DuplicatedChannelError( "Channel with given partner address already exists") registry: TokenNetworkRegistry = raiden.chain.token_network_registry( registry_address) token_network = raiden.chain.token_network( registry.get_token_network(token_address)) if token_network is None: raise TokenNotRegistered( "Token network for token %s does not exist" % to_checksum_address(token_address)) return token_network
def wait_for_participant_newbalance( raiden: RaidenService, payment_network_id: typing.PaymentNetworkID, token_address: typing.TokenAddress, partner_address: typing.Address, target_address: typing.Address, target_balance: typing.TokenAmount, retry_timeout: float, ) -> None: """Wait until a given channels balance exceeds the target balance. Note: This does not time out, use gevent.Timeout. """ if target_address == raiden.address: balance = lambda channel_state: channel_state.our_state.contract_balance elif target_address == partner_address: balance = lambda channel_state: channel_state.partner_state.contract_balance else: raise ValueError('target_address must be one of the channel participants') channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_address, partner_address, ) while balance(channel_state) < target_balance: gevent.sleep(retry_timeout) channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), payment_network_id, token_address, partner_address, )
def test_handle_insufficient_eth( raiden_network: List[RaidenService], restart_node, token_addresses, caplog ): app0, app1 = raiden_network token = token_addresses[0] registry_address = app0.default_registry.address channel_state = views.get_channelstate_for( chain_state=views.state_from_raiden(app0), token_network_registry_address=registry_address, token_address=token, partner_address=app1.address, ) assert isinstance(channel_state, NettingChannelState) channel_identifier = channel_state.identifier with block_offset_timeout(app0): transfer( initiator_app=app0, target_app=app1, token_address=token, amount=PaymentAmount(1), identifier=PaymentID(1), ) app1.stop() burn_eth(app1.rpc_client) restart_node(app1) block_offset = BlockOffset(channel_state.settle_timeout * 2) with block_offset_timeout(app0, "Settle did not happen", block_offset): RaidenAPI(app0).channel_close( registry_address=registry_address, token_address=token, partner_address=app1.address, ) waiting.wait_for_settle( raiden=app0, token_network_registry_address=registry_address, token_address=token, channel_ids=[channel_identifier], retry_timeout=DEFAULT_RETRY_TIMEOUT, ) assert any( "subtask died" in message and "insufficient ETH" in message for message in caplog.messages )
def run_smoketests(raiden_service, test_config, debug=False): """ Test that the assembled raiden_service correctly reflects the configuration from the smoketest_genesis. """ try: chain = raiden_service.chain assert ( raiden_service.default_registry.address == to_canonical_address( test_config['contracts']['registry_address'])) assert (raiden_service.default_registry.token_addresses() == [ to_canonical_address(test_config['contracts']['token_address']) ]) assert len(chain.address_to_discovery.keys()) == 1 assert (list( chain.address_to_discovery.keys())[0] == to_canonical_address( test_config['contracts']['discovery_address'])) discovery = list(chain.address_to_discovery.values())[0] assert discovery.endpoint_by_address( raiden_service.address) != TEST_ENDPOINT token_networks = views.get_token_network_addresses_for( views.state_from_raiden(raiden_service), raiden_service.default_registry.address, ) assert len(token_networks) == 1 channel_state = views.get_channelstate_for( views.state_from_raiden(raiden_service), raiden_service.default_registry.address, token_networks[0], unhexlify(TEST_PARTNER_ADDRESS), ) distributable = channel.get_distributable( channel_state.our_state, channel_state.partner_state, ) assert distributable == TEST_DEPOSIT_AMOUNT assert distributable == channel_state.our_state.contract_balance assert channel.get_status(channel_state) == CHANNEL_STATE_OPENED run_restapi_smoketests(raiden_service, test_config) except Exception: error = traceback.format_exc() if debug: pdb.post_mortem() return error
def set_total_channel_deposit( self, registry_address: typing.PaymentNetworkID, token_address: typing.TokenAddress, partner_address: typing.Address, total_deposit: typing.TokenAmount, retry_timeout: typing.NetworkTimeout = DEFAULT_RETRY_TIMEOUT, ): """ Set the `total_deposit` in the channel with the peer at `partner_address` and the given `token_address` in order to be able to do transfers. Raises: InvalidAddress: If either token_address or partner_address is not 20 bytes long. TransactionThrew: May happen for multiple reasons: - If the token approval fails, e.g. the token may validate if account has enough balance for the allowance. - The deposit failed, e.g. the allowance did not set the token aside for use and the user spent it before deposit was called. - The channel was closed/settled between the allowance call and the deposit call. AddressWithoutCode: The channel was settled during the deposit execution. DepositOverLimit: The total deposit amount is higher than the limit. """ chain_state = views.state_from_raiden(self.raiden) token_networks = views.get_token_network_addresses_for( chain_state, registry_address, ) channel_state = views.get_channelstate_for( chain_state, registry_address, token_address, partner_address, ) if not is_binary_address(token_address): raise InvalidAddress( 'Expected binary address format for token in channel deposit') if not is_binary_address(partner_address): raise InvalidAddress( 'Expected binary address format for partner in channel deposit' ) if token_address not in token_networks: raise UnknownTokenAddress('Unknown token address') if channel_state is None: raise InvalidAddress( 'No channel with partner_address for the given token') token = self.raiden.chain.token(token_address) netcontract_address = channel_state.identifier token_network_registry = self.raiden.chain.token_network_registry( registry_address) token_network_address = token_network_registry.get_token_network( token_address) token_network_proxy = self.raiden.chain.token_network( token_network_address) channel_proxy = self.raiden.chain.payment_channel( token_network_proxy.address, netcontract_address, ) balance = token.balance_of(self.raiden.address) if self.raiden.config['network_type'] == NetworkType.MAIN: deposit_limit = (token_network_proxy.proxy.contract.functions. channel_participant_deposit_limit().call()) if total_deposit > deposit_limit: raise DepositOverLimit( 'The deposit of {} is bigger than the current limit of {}'. format( total_deposit, deposit_limit, ), ) if total_deposit <= channel_state.our_state.contract_balance: # no action required return addendum = total_deposit - channel_state.our_state.contract_balance # If this check succeeds it does not imply the the `deposit` will # succeed, since the `deposit` transaction may race with another # transaction. if not balance >= addendum: msg = 'Not enough balance to deposit. {} Available={} Needed={}'.format( pex(token_address), balance, addendum, ) raise InsufficientFunds(msg) # If concurrent operations are happening on the channel, fail the request with channel_proxy.lock_or_raise(): # set_total_deposit calls approve # token.approve(netcontract_address, addendum) channel_proxy.set_total_deposit(total_deposit) target_address = self.raiden.address waiting.wait_for_participant_newbalance( self.raiden, registry_address, token_address, partner_address, target_address, total_deposit, retry_timeout, )
def channel_open( self, registry_address: typing.PaymentNetworkID, token_address: typing.TokenAddress, partner_address: typing.Address, settle_timeout: typing.BlockTimeout = None, retry_timeout: typing.NetworkTimeout = DEFAULT_RETRY_TIMEOUT, ) -> typing.ChannelID: """ Open a channel with the peer at `partner_address` with the given `token_address`. """ if settle_timeout is None: settle_timeout = self.raiden.config['settle_timeout'] if settle_timeout < self.raiden.config['reveal_timeout'] * 2: raise InvalidSettleTimeout( 'settle_timeout can not be smaller than double the reveal_timeout', ) if not is_binary_address(registry_address): raise InvalidAddress( 'Expected binary address format for registry in channel open') if not is_binary_address(token_address): raise InvalidAddress( 'Expected binary address format for token in channel open') if not is_binary_address(partner_address): raise InvalidAddress( 'Expected binary address format for partner in channel open') chain_state = views.state_from_raiden(self.raiden) channel_state = views.get_channelstate_for( chain_state, registry_address, token_address, partner_address, ) if channel_state: raise DuplicatedChannelError( 'Channel with given partner address already exists') registry = self.raiden.chain.token_network_registry(registry_address) token_network_address = registry.get_token_network(token_address) if token_network_address is None: raise TokenNotRegistered( 'Token network for token %s does not exist' % to_checksum_address(token_address), ) token_network = self.raiden.chain.token_network( registry.get_token_network(token_address), ) has_enough_reserve, estimated_required_reserve = has_enough_gas_reserve( self.raiden, channels_to_open=1, ) if not has_enough_reserve: raise InsufficientGasReserve(( 'The account balance is below the estimated amount necessary to ' 'finish the lifecycles of all active channels. A balance of at ' f'least {estimated_required_reserve} wei is required.')) try: token_network.new_netting_channel( partner_address, settle_timeout, ) except DuplicatedChannelError: log.info('partner opened channel first') waiting.wait_for_newchannel( self.raiden, registry_address, token_address, partner_address, retry_timeout, ) chain_state = views.state_from_raiden(self.raiden) channel_state = views.get_channelstate_for( chain_state, registry_address, token_address, partner_address, ) return channel_state.identifier
def wait_for_payment_balance( raiden: "RaidenService", token_network_registry_address: TokenNetworkRegistryAddress, token_address: TokenAddress, partner_address: Address, target_address: Address, target_balance: TokenAmount, retry_timeout: float, ) -> None: # pragma: no unittest """Wait until a given channel's balance exceeds the target balance. Note: This does not time out, use gevent.Timeout. """ def get_balance(end_state: NettingChannelEndState) -> TokenAmount: if end_state.balance_proof: return end_state.balance_proof.transferred_amount else: return TokenAmount(0) if target_address == raiden.address: balance = lambda channel_state: get_balance(channel_state.partner_state ) elif target_address == partner_address: balance = lambda channel_state: get_balance(channel_state.our_state) else: raise ValueError( "target_address must be one of the channel participants") channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), token_network_registry_address, token_address, partner_address, ) current_balance = balance(channel_state) log_details = { "token_network_registry_address": to_checksum_address(token_network_registry_address), "token_address": to_checksum_address(token_address), "partner_address": to_checksum_address(partner_address), "target_address": to_checksum_address(target_address), "target_balance": target_balance, } while current_balance < target_balance: assert raiden, ALARM_TASK_ERROR_MSG assert raiden.alarm, ALARM_TASK_ERROR_MSG log.critical("wait_for_payment_balance", current_balance=current_balance, **log_details) gevent.sleep(retry_timeout) channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), token_network_registry_address, token_address, partner_address, ) current_balance = balance(channel_state)
def wait_for_participant_deposit( raiden: "RaidenService", token_network_registry_address: TokenNetworkRegistryAddress, token_address: TokenAddress, partner_address: Address, target_address: Address, target_balance: TokenAmount, retry_timeout: float, ) -> None: # pragma: no unittest """Wait until a given channels balance exceeds the target balance. Note: This does not time out, use gevent.Timeout. """ if target_address == raiden.address: balance = lambda channel_state: channel_state.our_state.contract_balance else: balance = lambda channel_state: channel_state.partner_state.contract_balance channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), token_network_registry_address, token_address, partner_address, ) if not channel_state: raise ValueError( "no channel could be found between provided partner and target addresses" ) current_balance = balance(channel_state) log_details = { "node": to_checksum_address(raiden.address), "token_network_registry_address": to_checksum_address(token_network_registry_address), "token_address": to_checksum_address(token_address), "partner_address": to_checksum_address(partner_address), "target_address": to_checksum_address(target_address), "target_balance": target_balance, } while current_balance < target_balance: assert raiden, ALARM_TASK_ERROR_MSG assert raiden.alarm, ALARM_TASK_ERROR_MSG log.debug("wait_for_participant_deposit", current_balance=current_balance, **log_details) gevent.sleep(retry_timeout) channel_state = views.get_channelstate_for( views.state_from_raiden(raiden), token_network_registry_address, token_address, partner_address, ) current_balance = balance(channel_state)
def channel_open( self, registry_address, token_address, partner_address, settle_timeout=None, reveal_timeout=None, poll_timeout=DEFAULT_POLL_TIMEOUT, retry_timeout=DEFAULT_RETRY_TIMEOUT, ): """ Open a channel with the peer at `partner_address` with the given `token_address`. """ if reveal_timeout is None: reveal_timeout = self.raiden.config['reveal_timeout'] if settle_timeout is None: settle_timeout = self.raiden.config['settle_timeout'] if settle_timeout <= reveal_timeout: raise InvalidSettleTimeout( 'reveal_timeout can not be larger-or-equal to settle_timeout', ) if not is_binary_address(registry_address): raise InvalidAddress('Expected binary address format for registry in channel open') if not is_binary_address(token_address): raise InvalidAddress('Expected binary address format for token in channel open') if not is_binary_address(partner_address): raise InvalidAddress('Expected binary address format for partner in channel open') chain_state = views.state_from_raiden(self.raiden) channel_state = views.get_channelstate_for( chain_state, registry_address, token_address, partner_address, ) if channel_state: raise DuplicatedChannelError('Channel with given partner address already exists') registry = self.raiden.chain.token_network_registry(registry_address) token_network = self.raiden.chain.token_network( registry.get_token_network(token_address), ) try: token_network.new_netting_channel( partner_address, settle_timeout, ) except DuplicatedChannelError: log.info('partner opened channel first') msg = 'After {} seconds the channel was not properly created.'.format( poll_timeout, ) with gevent.Timeout(poll_timeout, EthNodeCommunicationError(msg)): waiting.wait_for_newchannel( self.raiden, registry_address, token_address, partner_address, retry_timeout, ) chain_state = views.state_from_raiden(self.raiden) channel_state = views.get_channelstate_for( chain_state, registry_address, token_address, partner_address, ) return channel_state.identifier
def set_total_channel_deposit( self, registry_address, token_address, partner_address, total_deposit, poll_timeout=DEFAULT_POLL_TIMEOUT, retry_timeout=DEFAULT_RETRY_TIMEOUT, ): """ Set the `total_deposit` in the channel with the peer at `partner_address` and the given `token_address` in order to be able to do transfers. Raises: InvalidAddress: If either token_address or partner_address is not 20 bytes long. TransactionThrew: May happen for multiple reasons: - If the token approval fails, e.g. the token may validate if account has enough balance for the allowance. - The deposit failed, e.g. the allowance did not set the token aside for use and the user spent it before deposit was called. - The channel was closed/settled between the allowance call and the deposit call. AddressWithoutCode: The channel was settled during the deposit execution. DepositOverLimit: The total deposit amount is higher than the limit. """ chain_state = views.state_from_raiden(self.raiden) token_networks = views.get_token_network_addresses_for( chain_state, registry_address, ) channel_state = views.get_channelstate_for( chain_state, registry_address, token_address, partner_address, ) if not is_binary_address(token_address): raise InvalidAddress('Expected binary address format for token in channel deposit') if not is_binary_address(partner_address): raise InvalidAddress('Expected binary address format for partner in channel deposit') if token_address not in token_networks: raise UnknownTokenAddress('Unknown token address') if channel_state is None: raise InvalidAddress('No channel with partner_address for the given token') token = self.raiden.chain.token(token_address) netcontract_address = channel_state.identifier token_network_registry = self.raiden.chain.token_network_registry(registry_address) token_network_address = token_network_registry.get_token_network(token_address) token_network_proxy = self.raiden.chain.token_network(token_network_address) channel_proxy = self.raiden.chain.payment_channel( token_network_proxy.address, netcontract_address, ) balance = token.balance_of(self.raiden.address) deposit_limit = token_network_proxy.proxy.contract.functions.deposit_limit().call() if total_deposit > deposit_limit: raise DepositOverLimit( 'The deposit of {} is bigger than the current limit of {}'.format( total_deposit, deposit_limit, ), ) if total_deposit <= channel_state.our_state.contract_balance: # no action required return addendum = total_deposit - channel_state.our_state.contract_balance # If this check succeeds it does not imply the the `deposit` will # succeed, since the `deposit` transaction may race with another # transaction. if not balance >= addendum: msg = 'Not enough balance to deposit. {} Available={} Needed={}'.format( pex(token_address), balance, addendum, ) raise InsufficientFunds(msg) # If concurrent operations are happening on the channel, fail the request with channel_proxy.lock_or_raise(): # set_total_deposit calls approve # token.approve(netcontract_address, addendum) channel_proxy.set_total_deposit(total_deposit) msg = 'After {} seconds the deposit was not properly processed.'.format( poll_timeout, ) # Wait until the `ChannelNewBalance` event is processed. with gevent.Timeout(poll_timeout, EthNodeCommunicationError(msg)): target_address = self.raiden.address waiting.wait_for_participant_newbalance( self.raiden, registry_address, token_address, partner_address, target_address, total_deposit, retry_timeout, )
def open( self, registry_address, partner_address, token_address, settle_timeout=None, reveal_timeout=None, balance=None, ): try: self.raiden_api.channel_open( registry_address, token_address, partner_address, settle_timeout, reveal_timeout, ) except EthNodeCommunicationError: return api_response( result='', status_code=HTTPStatus.ACCEPTED, ) except (InvalidAddress, InvalidSettleTimeout, SamePeerAddress, AddressWithoutCode, DuplicatedChannelError) as e: return api_error( errors=str(e), status_code=HTTPStatus.CONFLICT, ) except InsufficientFunds as e: return api_error( errors=str(e), status_code=HTTPStatus.PAYMENT_REQUIRED, ) if balance: # make initial deposit try: self.raiden_api.set_total_channel_deposit( registry_address, token_address, partner_address, balance, ) except EthNodeCommunicationError: return api_response( result='', status_code=HTTPStatus.ACCEPTED, ) except InsufficientFunds as e: return api_error( errors=str(e), status_code=HTTPStatus.PAYMENT_REQUIRED, ) except DepositOverLimit as e: return api_error( errors=str(e), status_code=HTTPStatus.EXPECTATION_FAILED, ) channel_state = views.get_channelstate_for( views.state_from_raiden(self.raiden_api.raiden), registry_address, token_address, partner_address, ) result = self.channel_schema.dump(channel_state) return api_response( result=result.data, status_code=HTTPStatus.CREATED, )
def test_recovery_unhappy_case( raiden_network, number_of_nodes, deposit, token_addresses, network_wait, skip_if_not_udp, retry_timeout, ): app0, app1, app2 = raiden_network token_address = token_addresses[0] chain_state = views.state_from_app(app0) payment_network_id = app0.raiden.default_registry.address token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state, payment_network_id, token_address, ) # make a few transfers from app0 to app2 amount = 1 spent_amount = deposit - 2 for _ in range(spent_amount): mediated_transfer( app0, app2, token_network_identifier, amount, timeout=network_wait * number_of_nodes, ) app0.raiden.stop() host_port = (app0.raiden.config['host'], app0.raiden.config['port']) socket = server._udp_socket(host_port) new_transport = UDPTransport( app0.discovery, socket, app0.raiden.transport.throttle_policy, app0.raiden.config['transport'], ) app0.stop() RaidenAPI(app1.raiden).channel_close( app1.raiden.default_registry.address, token_address, app0.raiden.address, ) channel01 = views.get_channelstate_for( views.state_from_app(app1), app1.raiden.default_registry.address, token_address, app0.raiden.address, ) waiting.wait_for_settle( app1.raiden, app1.raiden.default_registry.address, token_address, [channel01.identifier], retry_timeout, ) app0_restart = App( config=app0.config, chain=app0.raiden.chain, query_start_block=0, default_registry=app0.raiden.default_registry, default_secret_registry=app0.raiden.default_secret_registry, transport=new_transport, discovery=app0.raiden.discovery, ) del app0 # from here on the app0_restart should be used assert_synched_channel_state( token_network_identifier, app0_restart, deposit - spent_amount, [], app1, deposit + spent_amount, [], ) assert_synched_channel_state( token_network_identifier, app1, deposit - spent_amount, [], app2, deposit + spent_amount, [], )
def test_recovery_unhappy_case( raiden_network, number_of_nodes, deposit, token_addresses, network_wait, skip_if_not_udp, retry_timeout, ): app0, app1, app2 = raiden_network token_address = token_addresses[0] chain_state = views.state_from_app(app0) payment_network_id = app0.raiden.default_registry.address token_network_identifier = views.get_token_network_identifier_by_token_address( chain_state, payment_network_id, token_address, ) # make a few transfers from app0 to app2 amount = 1 spent_amount = deposit - 2 for _ in range(spent_amount): mediated_transfer( app0, app2, token_network_identifier, amount, timeout=network_wait * number_of_nodes, ) app0.raiden.stop() host_port = ( app0.raiden.config['transport']['udp']['host'], app0.raiden.config['transport']['udp']['port'], ) socket = server._udp_socket(host_port) new_transport = UDPTransport( app0.raiden.address, app0.discovery, socket, app0.raiden.transport.throttle_policy, app0.raiden.config['transport']['udp'], ) app0.stop() RaidenAPI(app1.raiden).channel_close( app1.raiden.default_registry.address, token_address, app0.raiden.address, ) channel01 = views.get_channelstate_for( views.state_from_app(app1), app1.raiden.default_registry.address, token_address, app0.raiden.address, ) waiting.wait_for_settle( app1.raiden, app1.raiden.default_registry.address, token_address, [channel01.identifier], retry_timeout, ) raiden_event_handler = RaidenEventHandler() message_handler = MessageHandler() app0_restart = App( config=app0.config, chain=app0.raiden.chain, query_start_block=0, default_registry=app0.raiden.default_registry, default_secret_registry=app0.raiden.default_secret_registry, transport=new_transport, raiden_event_handler=raiden_event_handler, message_handler=message_handler, discovery=app0.raiden.discovery, ) del app0 # from here on the app0_restart should be used app0_restart.start() state_changes = app0_restart.raiden.wal.storage.get_statechanges_by_identifier( from_identifier=0, to_identifier='latest', ) assert must_contain_entry(state_changes, ContractReceiveChannelSettled, { 'token_network_identifier': token_network_identifier, 'channel_identifier': channel01.identifier, })
def channel_open( self, registry_address: typing.PaymentNetworkID, token_address: typing.TokenAddress, partner_address: typing.Address, settle_timeout: typing.BlockTimeout = None, retry_timeout: typing.NetworkTimeout = DEFAULT_RETRY_TIMEOUT, ) -> typing.ChannelID: """ Open a channel with the peer at `partner_address` with the given `token_address`. """ if settle_timeout is None: settle_timeout = self.raiden.config['settle_timeout'] if settle_timeout < self.raiden.config['reveal_timeout'] * 2: raise InvalidSettleTimeout( 'settle_timeout can not be smaller than double the reveal_timeout', ) if not is_binary_address(registry_address): raise InvalidAddress('Expected binary address format for registry in channel open') if not is_binary_address(token_address): raise InvalidAddress('Expected binary address format for token in channel open') if not is_binary_address(partner_address): raise InvalidAddress('Expected binary address format for partner in channel open') chain_state = views.state_from_raiden(self.raiden) channel_state = views.get_channelstate_for( chain_state=chain_state, payment_network_id=registry_address, token_address=token_address, partner_address=partner_address, ) if channel_state: raise DuplicatedChannelError('Channel with given partner address already exists') registry = self.raiden.chain.token_network_registry(registry_address) token_network_address = registry.get_token_network(token_address) if token_network_address is None: raise TokenNotRegistered( 'Token network for token %s does not exist' % to_checksum_address(token_address), ) token_network = self.raiden.chain.token_network( registry.get_token_network(token_address), ) with self.raiden.gas_reserve_lock: has_enough_reserve, estimated_required_reserve = has_enough_gas_reserve( self.raiden, channels_to_open=1, ) if not has_enough_reserve: raise InsufficientGasReserve(( 'The account balance is below the estimated amount necessary to ' 'finish the lifecycles of all active channels. A balance of at ' f'least {estimated_required_reserve} wei is required.' )) try: token_network.new_netting_channel( partner=partner_address, settle_timeout=settle_timeout, ) except DuplicatedChannelError: log.info('partner opened channel first') waiting.wait_for_newchannel( raiden=self.raiden, payment_network_id=registry_address, token_address=token_address, partner_address=partner_address, retry_timeout=retry_timeout, ) chain_state = views.state_from_raiden(self.raiden) channel_state = views.get_channelstate_for( chain_state=chain_state, payment_network_id=registry_address, token_address=token_address, partner_address=partner_address, ) return channel_state.identifier
def set_total_channel_deposit( self, registry_address: typing.PaymentNetworkID, token_address: typing.TokenAddress, partner_address: typing.Address, total_deposit: typing.TokenAmount, retry_timeout: typing.NetworkTimeout = DEFAULT_RETRY_TIMEOUT, ): """ Set the `total_deposit` in the channel with the peer at `partner_address` and the given `token_address` in order to be able to do transfers. Raises: InvalidAddress: If either token_address or partner_address is not 20 bytes long. TransactionThrew: May happen for multiple reasons: - If the token approval fails, e.g. the token may validate if account has enough balance for the allowance. - The deposit failed, e.g. the allowance did not set the token aside for use and the user spent it before deposit was called. - The channel was closed/settled between the allowance call and the deposit call. AddressWithoutCode: The channel was settled during the deposit execution. DepositOverLimit: The total deposit amount is higher than the limit. """ chain_state = views.state_from_raiden(self.raiden) token_networks = views.get_token_network_addresses_for( chain_state, registry_address, ) channel_state = views.get_channelstate_for( chain_state=chain_state, payment_network_id=registry_address, token_address=token_address, partner_address=partner_address, ) if not is_binary_address(token_address): raise InvalidAddress('Expected binary address format for token in channel deposit') if not is_binary_address(partner_address): raise InvalidAddress('Expected binary address format for partner in channel deposit') if token_address not in token_networks: raise UnknownTokenAddress('Unknown token address') if channel_state is None: raise InvalidAddress('No channel with partner_address for the given token') token = self.raiden.chain.token(token_address) token_network_registry = self.raiden.chain.token_network_registry(registry_address) token_network_address = token_network_registry.get_token_network(token_address) token_network_proxy = self.raiden.chain.token_network(token_network_address) channel_proxy = self.raiden.chain.payment_channel( token_network_address=token_network_proxy.address, channel_id=channel_state.identifier, ) balance = token.balance_of(self.raiden.address) if self.raiden.config['environment_type'] == Environment.PRODUCTION: deposit_limit = ( token_network_proxy.proxy.contract.functions. channel_participant_deposit_limit().call() ) elif self.raiden.config['environment_type'] == Environment.DEVELOPMENT: deposit_limit = ( token_network_proxy.proxy.contract.functions. deposit_limit().call() ) if total_deposit > deposit_limit: raise DepositOverLimit( 'The deposit of {} is bigger than the current limit of {}'.format( total_deposit, deposit_limit, ), ) addendum = total_deposit - channel_state.our_state.contract_balance # If this check succeeds it does not imply the the `deposit` will # succeed, since the `deposit` transaction may race with another # transaction. if not balance >= addendum: msg = 'Not enough balance to deposit. {} Available={} Needed={}'.format( pex(token_address), balance, addendum, ) raise InsufficientFunds(msg) # set_total_deposit calls approve # token.approve(netcontract_address, addendum) channel_proxy.set_total_deposit(total_deposit) target_address = self.raiden.address waiting.wait_for_participant_newbalance( raiden=self.raiden, payment_network_id=registry_address, token_address=token_address, partner_address=partner_address, target_address=target_address, target_balance=total_deposit, retry_timeout=retry_timeout, )
def test_settle_is_automatically_called(raiden_network, token_addresses): """Settle is automatically called by one of the nodes.""" app0, app1 = raiden_network registry_address = app0.raiden.default_registry.address token_address = token_addresses[0] token_network_identifier = views.get_token_network_identifier_by_token_address( views.state_from_app(app0), app0.raiden.default_registry.address, token_address, ) token_network = views.get_token_network_by_identifier( views.state_from_app(app0), token_network_identifier, ) channel_identifier = get_channelstate(app0, app1, token_network_identifier).identifier assert channel_identifier in token_network.partneraddresses_to_channelidentifiers[ app1.raiden.address ] # A ChannelClose event will be generated, this will be polled by both apps # and each must start a task for calling settle RaidenAPI(app1.raiden).channel_close( registry_address, token_address, app0.raiden.address, ) waiting.wait_for_close( app0.raiden, registry_address, token_address, [channel_identifier], app0.raiden.alarm.sleep_time, ) channel_state = views.get_channelstate_for( views.state_from_raiden(app0.raiden), registry_address, token_address, app1.raiden.address, ) assert channel_state.close_transaction.finished_block_number waiting.wait_for_settle( app0.raiden, registry_address, token_address, [channel_identifier], app0.raiden.alarm.sleep_time, ) token_network = views.get_token_network_by_identifier( views.state_from_app(app0), token_network_identifier, ) assert channel_identifier not in token_network.partneraddresses_to_channelidentifiers[ app1.raiden.address ] state_changes = app0.raiden.wal.storage.get_statechanges_by_identifier( from_identifier=0, to_identifier='latest', ) assert must_contain_entry(state_changes, ContractReceiveChannelClosed, { 'token_network_identifier': token_network_identifier, 'channel_identifier': channel_identifier, 'transaction_from': app1.raiden.address, 'block_number': channel_state.close_transaction.finished_block_number, }) assert must_contain_entry(state_changes, ContractReceiveChannelSettled, { 'token_network_identifier': token_network_identifier, 'channel_identifier': channel_identifier, })