def _validate_fees_can_pay(self, request, inputs, outputs, required_fees):
        """
        Calculate and verify that inputs and outputs for fees can both be paid and change is properly specified

        This function ASSUMES that validation of the fees for the request has already been done.

        :param request:
        :param required_fees:
        :return:
        """

        try:
            sum_inputs = self.utxo_cache.sum_inputs(inputs, is_committed=False)
        except UTXOError as ex:
            raise InvalidFundsError(request.identifier, request.reqId,
                                    "{}".format(ex))
        except Exception as ex:
            error = 'Exception {} while processing inputs/outputs'.format(ex)
            raise UnauthorizedClientRequest(request.identifier, request.reqId,
                                            error)
        else:
            change_amount = sum([a[AMOUNT] for a in outputs])
            expected_amount = change_amount + required_fees
            TokenStaticHelper.validate_given_inputs_outputs(
                sum_inputs, change_amount, expected_amount, request,
                'fees: {}'.format(required_fees))
    def _do_validate_inputs_ouputs(self, request):
        try:
            sum_in = TokenStaticHelper.sum_inputs(self.utxo_cache,
                                                  request,
                                                  is_committed=False)

            sum_out = TokenStaticHelper.sum_outputs(request)
        except Exception as ex:
            if isinstance(ex, InvalidClientMessageException):
                raise ex
            error = 'Exception {} while processing inputs/outputs'.format(ex)
            raise InvalidClientMessageException(
                request.identifier, getattr(request, 'reqId', None), error)
        else:
            return TokenStaticHelper.validate_given_inputs_outputs(
                sum_in, sum_out, sum_out, request)
def test_xfer_public_txn_inputs_not_greater():
    with pytest.raises(ExtraFundsError):
        TokenStaticHelper.validate_given_inputs_outputs(2, 1, 1, None)

    with pytest.raises(InvalidClientMessageException):
        TokenStaticHelper.validate_given_inputs_outputs(1, 2, 2, None)

    with pytest.raises(InvalidClientMessageException):
        TokenStaticHelper.validate_given_inputs_outputs(
            100000000000000000000000, 100000000000000000000001,
            100000000000000000000001, None)
def test_xfer_public_txn_equal():
    TokenStaticHelper.validate_given_inputs_outputs(1, 1, 1, None)
    TokenStaticHelper.validate_given_inputs_outputs(10, 10, 10, None)
    TokenStaticHelper.validate_given_inputs_outputs(100, 100, 100, None)
    TokenStaticHelper.validate_given_inputs_outputs(100000000000000,
                                                    100000000000000,
                                                    100000000000000, None)
    TokenStaticHelper.validate_given_inputs_outputs(9223372036854775807,
                                                    9223372036854775807,
                                                    9223372036854775807, None)
    TokenStaticHelper.validate_given_inputs_outputs(9223372036854775807000,
                                                    9223372036854775807000,
                                                    9223372036854775807000,
                                                    None)