Settle the channel.

def settle(
            self,
            channel_identifier: ChannelID,
            transferred_amount: TokenAmount,
            locked_amount: TokenAmount,
            locksroot: Locksroot,
            partner: Address,
            partner_transferred_amount: TokenAmount,
            partner_locked_amount: TokenAmount,
            partner_locksroot: Locksroot,
            given_block_identifier: BlockSpecification,
    ):
        """ Settle the channel. """
        log_details = {
            'channel_identifier': channel_identifier,
            'token_network': pex(self.address),
            'node': pex(self.node_address),
            'partner': pex(partner),
            'transferred_amount': transferred_amount,
            'locked_amount': locked_amount,
            'locksroot': encode_hex(locksroot),
            'partner_transferred_amount': partner_transferred_amount,
            'partner_locked_amount': partner_locked_amount,
            'partner_locksroot': encode_hex(partner_locksroot),
        }
        log.debug('settle called', **log_details)

        checking_block = self.client.get_checking_block()
        # and now find out
        our_maximum = transferred_amount + locked_amount
        partner_maximum = partner_transferred_amount + partner_locked_amount

        # The second participant transferred + locked amount must be higher
        our_bp_is_larger = our_maximum > partner_maximum
        if our_bp_is_larger:
            kwargs = {
                'participant1': partner,
                'participant1_transferred_amount': partner_transferred_amount,
                'participant1_locked_amount': partner_locked_amount,
                'participant1_locksroot': partner_locksroot,
                'participant2': self.node_address,
                'participant2_transferred_amount': transferred_amount,
                'participant2_locked_amount': locked_amount,
                'participant2_locksroot': locksroot,
            }
        else:
            kwargs = {
                'participant1': self.node_address,
                'participant1_transferred_amount': transferred_amount,
                'participant1_locked_amount': locked_amount,
                'participant1_locksroot': locksroot,
                'participant2': partner,
                'participant2_transferred_amount': partner_transferred_amount,
                'participant2_locked_amount': partner_locked_amount,
                'participant2_locksroot': partner_locksroot,
            }
        try:
            self._settle_preconditions(
                channel_identifier=channel_identifier,
                partner=partner,
                block_identifier=given_block_identifier,
            )
        except NoStateForBlockIdentifier:
            # If preconditions end up being on pruned state skip them. Estimate
            # gas will stop us from sending a transaction that will fail
            pass

        with self.channel_operations_lock[partner]:
            error_prefix = 'Call to settle will fail'
            gas_limit = self.proxy.estimate_gas(
                checking_block,
                'settleChannel',
                channel_identifier=channel_identifier,
                **kwargs,
            )

            if gas_limit:
                error_prefix = 'settle call failed'
                gas_limit = safe_gas_limit(gas_limit, GAS_REQUIRED_FOR_SETTLE_CHANNEL)

                transaction_hash = self.proxy.transact(
                    'settleChannel',
                    gas_limit,
                    channel_identifier=channel_identifier,
                    **kwargs,
                )
                self.client.poll(transaction_hash)
                receipt_or_none = check_transaction_threw(self.client, transaction_hash)

        transaction_executed = gas_limit is not None
        if not transaction_executed or receipt_or_none:
            if transaction_executed:
                block = receipt_or_none['blockNumber']
            else:
                block = checking_block

            self.proxy.jsonrpc_client.check_for_insufficient_eth(
                transaction_name='settleChannel',
                transaction_executed=transaction_executed,
                required_gas=GAS_REQUIRED_FOR_SETTLE_CHANNEL,
                block_identifier=block,
            )
            msg = self._check_channel_state_after_settle(
                participant1=self.node_address,
                participant2=partner,
                block_identifier=block,
                channel_identifier=channel_identifier,
            )
            error_msg = f'{error_prefix}. {msg}'
            log.critical(error_msg, **log_details)
            raise RaidenUnrecoverableError(error_msg)

        log.info('settle successful', **log_details)