Beispiel #1
0
    def _new_netting_channel(self, partner: typing.Address,
                             settle_timeout: int):
        if self.channel_exists(self.node_address, partner):
            raise DuplicatedChannelError(
                'Channel with given partner address already exists')

        transaction_hash = self.proxy.transact(
            'openChannel',
            self.node_address,
            partner,
            settle_timeout,
        )

        if not transaction_hash:
            raise RuntimeError('open channel transaction failed')

        self.client.poll(unhexlify(transaction_hash))

        if check_transaction_threw(self.client, transaction_hash):
            raise DuplicatedChannelError('Duplicated channel')

        return transaction_hash
Beispiel #2
0
    def _new_netting_channel(self, other_peer, settle_timeout):
        if self.channel_exists(other_peer):
            raise DuplicatedChannelError(
                'Channel with given partner address already exists')

        transaction_hash = estimate_and_transact(
            self.proxy,
            'newChannel',
            other_peer,
            settle_timeout,
        )

        if not transaction_hash:
            raise RuntimeError('open channel transaction failed')

        self.client.poll(unhexlify(transaction_hash),
                         timeout=self.poll_timeout)

        if check_transaction_threw(self.client, transaction_hash):
            raise DuplicatedChannelError('Duplicated channel')

        return transaction_hash
Beispiel #3
0
    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
Beispiel #4
0
    def new_netting_channel(self, peer1, peer2, settle_timeout):
        """ Creates a new netting contract between peer1 and peer2.

        Raises:
            ValueError: If peer1 or peer2 is not a valid address.
        """
        if not isaddress(peer1):
            raise ValueError('The peer1 must be a valid address')

        if not isaddress(peer2):
            raise ValueError('The peer2 must be a valid address')

        if peer1 == peer2:
            raise SamePeerAddress('peer1 and peer2 must not be equal')

        invalid_timeout = (
            settle_timeout < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN or
            settle_timeout > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX
        )
        if invalid_timeout:
            raise ValueError('settle_timeout must be in range [{}, {}]'.format(
                NETTINGCHANNEL_SETTLE_TIMEOUT_MIN, NETTINGCHANNEL_SETTLE_TIMEOUT_MAX
            ))

        if privatekey_to_address(self.private_key) == peer1:
            other = peer2
        else:
            other = peer1

        try:
            netting_channel_address_hex = self.proxy.newChannel(other, settle_timeout)

        except TransactionFailed:
            raise DuplicatedChannelError('Duplicated channel')

        self.tester_state.mine(number_of_blocks=1)

        channel = NettingChannelTesterMock(
            self.tester_state,
            self.private_key,
            netting_channel_address_hex,
        )

        return unhexlify(channel.address)
Beispiel #5
0
    def new_netting_channel(self, other_peer, settle_timeout):
        """ Creates a new netting contract between peer1 and peer2.

        Raises:
            ValueError: If other_peer is not a valid address.
        """
        if not isaddress(other_peer):
            raise ValueError('The other_peer must be a valid address')

        local_address = privatekey_to_address(self.private_key)
        if local_address == other_peer:
            raise SamePeerAddress(
                'The other peer must not have the same address as the client.')

        invalid_timeout = (settle_timeout < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN
                           or
                           settle_timeout > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX)
        if invalid_timeout:
            raise ValueError('settle_timeout must be in range [{}, {}]'.format(
                NETTINGCHANNEL_SETTLE_TIMEOUT_MIN,
                NETTINGCHANNEL_SETTLE_TIMEOUT_MAX))

        try:
            netting_channel_address_hex = self.proxy.newChannel(
                other_peer, settle_timeout, sender=self.private_key)
        except TransactionFailed:
            raise DuplicatedChannelError('Duplicated channel')

        self.tester_chain.mine(number_of_blocks=1)

        channel = NettingChannelTesterMock(
            self.tester_chain,
            self.private_key,
            netting_channel_address_hex,
        )

        return address_decoder(channel.address)
Beispiel #6
0
    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
Beispiel #7
0
    def new_netting_channel(self, other_peer: Address,
                            settle_timeout: int) -> Address:
        """ Creates and deploys a new netting channel contract.

        Args:
            other_peer: The peer to open the channel with.
            settle_timeout: The settle timout to use for this channel.

        Returns:
            The address of the new netting channel.
        """
        if not isaddress(other_peer):
            raise ValueError('The other_peer must be a valid address')

        invalid_timeout = (settle_timeout < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN
                           or
                           settle_timeout > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX)
        if invalid_timeout:
            raise InvalidSettleTimeout(
                'settle_timeout must be in range [{}, {}]'.format(
                    NETTINGCHANNEL_SETTLE_TIMEOUT_MIN,
                    NETTINGCHANNEL_SETTLE_TIMEOUT_MAX))

        local_address = privatekey_to_address(self.client.privkey)
        if local_address == other_peer:
            raise SamePeerAddress(
                'The other peer must not have the same address as the client.')

        transaction_hash = estimate_and_transact(
            self.proxy,
            'newChannel',
            other_peer,
            settle_timeout,
        )

        self.client.poll(unhexlify(transaction_hash),
                         timeout=self.poll_timeout)

        if check_transaction_threw(self.client, transaction_hash):
            raise DuplicatedChannelError('Duplicated channel')

        netting_channel_results_encoded = self.proxy.call(
            'getChannelWith',
            other_peer,
        )

        # address is at index 0
        netting_channel_address_encoded = netting_channel_results_encoded

        if not netting_channel_address_encoded:
            log.error('netting_channel_address failed',
                      peer1=pex(local_address),
                      peer2=pex(other_peer))
            raise RuntimeError('netting_channel_address failed')

        netting_channel_address_bin = address_decoder(
            netting_channel_address_encoded)

        if log.isEnabledFor(logging.INFO):
            log.info(
                'new_netting_channel called',
                peer1=pex(local_address),
                peer2=pex(other_peer),
                netting_channel=pex(netting_channel_address_bin),
            )

        return netting_channel_address_bin
Beispiel #8
0
    def new_netting_channel(self, peer1, peer2, settle_timeout):
        if not isaddress(peer1):
            raise ValueError('The peer1 must be a valid address')

        if not isaddress(peer2):
            raise ValueError('The peer2 must be a valid address')

        invalid_timeout = (settle_timeout < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN
                           or
                           settle_timeout > NETTINGCHANNEL_SETTLE_TIMEOUT_MAX)
        if invalid_timeout:
            raise ValueError('settle_timeout must be in range [{}, {}]'.format(
                NETTINGCHANNEL_SETTLE_TIMEOUT_MIN,
                NETTINGCHANNEL_SETTLE_TIMEOUT_MAX))

        if peer1 == peer2:
            raise SamePeerAddress('Peer1 and peer2 must not be equal')

        if privatekey_to_address(self.client.privkey) == peer1:
            other = peer2
        else:
            other = peer1

        transaction_hash = estimate_and_transact(
            self,
            self.proxy.newChannel,
            other,
            settle_timeout,
        )

        self.client.poll(transaction_hash.decode('hex'),
                         timeout=self.poll_timeout)

        if check_transaction_threw(self.client, transaction_hash):
            raise DuplicatedChannelError('Duplicated channel')

        netting_channel_results_encoded = self.proxy.getChannelWith.call(
            other,
            startgas=self.startgas,
        )

        # address is at index 0
        netting_channel_address_encoded = netting_channel_results_encoded

        if not netting_channel_address_encoded:
            log.error('netting_channel_address failed',
                      peer1=pex(peer1),
                      peer2=pex(peer2))
            raise RuntimeError('netting_channel_address failed')

        netting_channel_address_bin = address_decoder(
            netting_channel_address_encoded)

        if log.isEnabledFor(logging.INFO):
            log.info(
                'new_netting_channel called',
                peer1=pex(peer1),
                peer2=pex(peer2),
                netting_channel=pex(netting_channel_address_bin),
            )

        return netting_channel_address_bin
Beispiel #9
0
    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
Beispiel #10
0
    def channel_open(
            self,
            registry_address: typing.PaymentNetworkID,
            token_address: typing.TokenAddress,
            partner_address: typing.Address,
            settle_timeout: typing.BlockTimeout = None,
            reveal_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 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_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),
        )

        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
Beispiel #11
0
    def channel_open(
        self,
        registry_address: PaymentNetworkID,
        token_address: TokenAddress,
        partner_address: Address,
        settle_timeout: BlockTimeout = None,
        retry_timeout: NetworkTimeout = DEFAULT_RETRY_TIMEOUT,
    ) -> 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,
                    given_block_identifier=views.state_from_raiden(self.raiden).block_hash,
                )
            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,
        )

        assert channel_state, f"channel {channel_state} is gone"

        return channel_state.identifier
Beispiel #12
0
    def channel_open(
        self,
        registry_address: TokenNetworkRegistryAddress,
        token_address: TokenAddress,
        partner_address: Address,
        settle_timeout: BlockTimeout = None,
        reveal_timeout: BlockTimeout = None,
        retry_timeout: NetworkTimeout = DEFAULT_RETRY_TIMEOUT,
    ) -> 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 reveal_timeout is None:
            reveal_timeout = self.raiden.config.reveal_timeout

        if reveal_timeout <= 0:
            raise InvalidRevealTimeout(
                "reveal_timeout should be larger than zero")

        if settle_timeout < reveal_timeout * 2:
            raise InvalidSettleTimeout(
                "`settle_timeout` can not be smaller than double the "
                "`reveal_timeout`.\n "
                "\n "
                "The setting `reveal_timeout` determines the maximum number of "
                "blocks it should take a transaction to be mined when the "
                "blockchain is under congestion. This setting determines the "
                "when a node must go on-chain to register a secret, and it is "
                "therefore the lower bound of the lock expiration. The "
                "`settle_timeout` determines when a channel can be settled "
                "on-chain, for this operation to be safe all locks must have "
                "been resolved, for this reason the `settle_timeout` has to be "
                "larger than `reveal_timeout`.")

        if not is_binary_address(registry_address):
            raise InvalidBinaryAddress(
                "Expected binary address format for registry in channel open")

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

        if not is_binary_address(partner_address):
            raise InvalidBinaryAddress(
                "Expected binary address format for partner in channel open")

        confirmed_block_identifier = views.get_confirmed_blockhash(self.raiden)
        registry = self.raiden.proxy_manager.token_network_registry(
            registry_address, block_identifier=confirmed_block_identifier)

        settlement_timeout_min = registry.settlement_timeout_min(
            block_identifier=confirmed_block_identifier)
        settlement_timeout_max = registry.settlement_timeout_max(
            block_identifier=confirmed_block_identifier)

        if settle_timeout < settlement_timeout_min:
            raise InvalidSettleTimeout(
                f"Settlement timeout should be at least {settlement_timeout_min}"
            )

        if settle_timeout > settlement_timeout_max:
            raise InvalidSettleTimeout(
                f"Settlement timeout exceeds max of {settlement_timeout_max}")

        token_network_address = registry.get_token_network(
            token_address=token_address,
            block_identifier=confirmed_block_identifier)
        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.proxy_manager.token_network(
            address=token_network_address,
            block_identifier=confirmed_block_identifier)

        safety_deprecation_switch = token_network.safety_deprecation_switch(
            block_identifier=confirmed_block_identifier)

        if safety_deprecation_switch:
            msg = (
                "This token_network has been deprecated. New channels cannot be "
                "open for this network, usage of the newly deployed token "
                "network contract is highly encouraged.")
            raise TokenNetworkDeprecated(msg)

        duplicated_channel = self.is_already_existing_channel(
            token_network_address=token_network_address,
            partner_address=partner_address,
            block_identifier=confirmed_block_identifier,
        )
        if duplicated_channel:
            raise DuplicatedChannelError(
                f"A channel with {to_checksum_address(partner_address)} for token "
                f"{to_checksum_address(token_address)} already exists. "
                f"(At blockhash: {confirmed_block_identifier.hex()})")

        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,
                given_block_identifier=confirmed_block_identifier,
            )
        except DuplicatedChannelError:
            log.info("partner opened channel first")
        except RaidenRecoverableError:
            # The channel may have been created in the pending block.
            duplicated_channel = self.is_already_existing_channel(
                token_network_address=token_network_address,
                partner_address=partner_address)
            if duplicated_channel:
                log.info("Channel has already been opened")
            else:
                raise

        waiting.wait_for_newchannel(
            raiden=self.raiden,
            token_network_registry_address=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,
            token_network_registry_address=registry_address,
            token_address=token_address,
            partner_address=partner_address,
        )

        assert channel_state, f"channel {channel_state} is gone"

        self.raiden.set_channel_reveal_timeout(
            canonical_identifier=channel_state.canonical_identifier,
            reveal_timeout=reveal_timeout)

        return channel_state.identifier
Beispiel #13
0
    def new_netting_channel(self, peer1, peer2, settle_timeout):
        if not isaddress(peer1):
            raise ValueError('The peer1 must be a valid address')

        if not isaddress(peer2):
            raise ValueError('The peer2 must be a valid address')

        if settle_timeout < NETTINGCHANNEL_SETTLE_TIMEOUT_MIN:
            raise ValueError(
                'settle_timeout must be larger-or-equal to {}'.format(
                    NETTINGCHANNEL_SETTLE_TIMEOUT_MIN))

        if peer1 == peer2:
            raise SamePeerAddress('Peer1 and peer2 must not be equal')

        if privatekey_to_address(self.client.privkey) == peer1:
            other = peer2
        else:
            other = peer1

        transaction_hash = estimate_and_transact(
            self,
            self.proxy.newChannel,
            other,
            settle_timeout,
        )

        try:
            self.client.poll(transaction_hash.decode('hex'),
                             timeout=self.poll_timeout)
        except JSONRPCPollTimeoutException as e:
            raise e
        except InvalidTransaction as e:
            raise e

        if check_transaction_threw(self.client, transaction_hash):
            raise DuplicatedChannelError('Duplicated channel')

        netting_channel_results_encoded = self.proxy.getChannelWith.call(
            other,
            startgas=self.startgas,
        )

        # address is at index 0
        netting_channel_address_encoded = netting_channel_results_encoded

        if not netting_channel_address_encoded:
            log.error('netting_channel_address failed',
                      peer1=pex(peer1),
                      peer2=pex(peer2))
            raise RuntimeError('netting_channel_address failed')

        netting_channel_address_bin = address_decoder(
            netting_channel_address_encoded)

        log.info(
            'new_netting_channel called',
            peer1=pex(peer1),
            peer2=pex(peer2),
            netting_channel=pex(netting_channel_address_bin),
        )

        return netting_channel_address_bin