<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def token_network_register( self, registry_address: PaymentNetworkID, token_address: TokenAddress, channel_participant_deposit_limit: TokenAmount, token_network_deposit_limit: TokenAmount, retry_timeout: NetworkTimeout = DEFAULT_RETRY_TIMEOUT, ) -> TokenNetworkAddress: """Register the `token_address` in the blockchain. If the address is already registered but the event has not been processed this function will block until the next block to make sure the event is processed. Raises: InvalidAddress: If the registry_address or token_address is not a valid address. AlreadyRegisteredTokenAddress: If the token is already registered. TransactionThrew: If the register transaction failed, this may happen because the account has not enough balance to pay for the gas or this register call raced with another transaction and lost. """


        if not is_binary_address(registry_address):
            raise InvalidAddress('registry_address must be a valid address in binary')

        if not is_binary_address(token_address):
            raise InvalidAddress('token_address must be a valid address in binary')

        if token_address in self.get_tokens_list(registry_address):
            raise AlreadyRegisteredTokenAddress('Token already registered')

        contracts_version = self.raiden.contract_manager.contracts_version

        registry = self.raiden.chain.token_network_registry(registry_address)

        try:
            if contracts_version == DEVELOPMENT_CONTRACT_VERSION:
                return registry.add_token_with_limits(
                    token_address=token_address,
                    channel_participant_deposit_limit=channel_participant_deposit_limit,
                    token_network_deposit_limit=token_network_deposit_limit,
                )
            else:
                return registry.add_token_without_limits(
                    token_address=token_address,
                )
        except RaidenRecoverableError as e:
            if 'Token already registered' in str(e):
                raise AlreadyRegisteredTokenAddress('Token already registered')
            # else
            raise

        finally:
            # Assume the transaction failed because the token is already
            # registered with the smart contract and this node has not yet
            # polled for the event (otherwise the check above would have
            # failed).
            #
            # To provide a consistent view to the user, wait one block, this
            # will guarantee that the events have been processed.
            next_block = self.raiden.get_block_number() + 1
            waiting.wait_for_block(self.raiden, next_block, retry_timeout)