exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

exchangedb_transactions.c (5627B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2017-2020 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file exchangedb/exchangedb_transactions.c
     18  * @brief Logic to compute transaction totals of a transaction list for a coin
     19  * @author Christian Grothoff
     20  */
     21 #include "exchange-database/free_coin_transaction_list.h"
     22 
     23 
     24 enum GNUNET_GenericReturnValue
     25 TALER_EXCHANGEDB_calculate_transaction_list_totals (
     26   struct TALER_EXCHANGEDB_TransactionList *tl,
     27   const struct TALER_Amount *off,
     28   struct TALER_Amount *ret)
     29 {
     30   struct TALER_Amount spent = *off;
     31   struct TALER_Amount refunded;
     32   struct TALER_Amount deposit_fee;
     33   bool have_refund;
     34 
     35   GNUNET_assert (GNUNET_OK ==
     36                  TALER_amount_set_zero (spent.currency,
     37                                         &refunded));
     38   have_refund = false;
     39   for (struct TALER_EXCHANGEDB_TransactionList *pos = tl;
     40        NULL != pos;
     41        pos = pos->next)
     42   {
     43     switch (pos->type)
     44     {
     45     case TALER_EXCHANGEDB_TT_DEPOSIT:
     46       /* spent += pos->amount_with_fee */
     47       if (0 >
     48           TALER_amount_add (&spent,
     49                             &spent,
     50                             &pos->details.deposit->amount_with_fee))
     51       {
     52         GNUNET_break (0);
     53         return GNUNET_SYSERR;
     54       }
     55       deposit_fee = pos->details.deposit->deposit_fee;
     56       break;
     57     case TALER_EXCHANGEDB_TT_MELT:
     58       /* spent += pos->amount_with_fee */
     59       if (0 >
     60           TALER_amount_add (&spent,
     61                             &spent,
     62                             &pos->details.melt->amount_with_fee))
     63       {
     64         GNUNET_break (0);
     65         return GNUNET_SYSERR;
     66       }
     67       break;
     68     case TALER_EXCHANGEDB_TT_REFUND:
     69       /* refunded += pos->refund_amount - pos->refund_fee */
     70       if (0 >
     71           TALER_amount_add (&refunded,
     72                             &refunded,
     73                             &pos->details.refund->refund_amount))
     74       {
     75         GNUNET_break (0);
     76         return GNUNET_SYSERR;
     77       }
     78       if (0 >
     79           TALER_amount_add (&spent,
     80                             &spent,
     81                             &pos->details.refund->refund_fee))
     82       {
     83         GNUNET_break (0);
     84         return GNUNET_SYSERR;
     85       }
     86       have_refund = true;
     87       break;
     88     case TALER_EXCHANGEDB_TT_RECOUP_REFRESH_RECEIVER:
     89       /* refunded += pos->value */
     90       if (0 >
     91           TALER_amount_add (&refunded,
     92                             &refunded,
     93                             &pos->details.old_coin_recoup->value))
     94       {
     95         GNUNET_break (0);
     96         return GNUNET_SYSERR;
     97       }
     98       break;
     99     case TALER_EXCHANGEDB_TT_RECOUP_WITHDRAW:
    100       /* spent += pos->value */
    101       if (0 >
    102           TALER_amount_add (&spent,
    103                             &spent,
    104                             &pos->details.recoup->value))
    105       {
    106         GNUNET_break (0);
    107         return GNUNET_SYSERR;
    108       }
    109       break;
    110     case TALER_EXCHANGEDB_TT_RECOUP_REFRESH:
    111       /* spent += pos->value */
    112       if (0 >
    113           TALER_amount_add (&spent,
    114                             &spent,
    115                             &pos->details.recoup_refresh->value))
    116       {
    117         GNUNET_break (0);
    118         return GNUNET_SYSERR;
    119       }
    120       break;
    121     case TALER_EXCHANGEDB_TT_PURSE_DEPOSIT:
    122       /* spent += pos->amount_with_fee */
    123       if (0 >
    124           TALER_amount_add (&spent,
    125                             &spent,
    126                             &pos->details.purse_deposit->amount))
    127       {
    128         GNUNET_break (0);
    129         return GNUNET_SYSERR;
    130       }
    131       deposit_fee = pos->details.purse_deposit->deposit_fee;
    132       break;
    133     case TALER_EXCHANGEDB_TT_PURSE_REFUND:
    134       /* refunded += pos->refund_amount - pos->refund_fee */
    135       if (0 >
    136           TALER_amount_add (&refunded,
    137                             &refunded,
    138                             &pos->details.purse_refund->refund_amount))
    139       {
    140         GNUNET_break (0);
    141         return GNUNET_SYSERR;
    142       }
    143       if (0 >
    144           TALER_amount_add (&spent,
    145                             &spent,
    146                             &pos->details.purse_refund->refund_fee))
    147       {
    148         GNUNET_break (0);
    149         return GNUNET_SYSERR;
    150       }
    151       have_refund = true;
    152       break;
    153     case TALER_EXCHANGEDB_TT_RESERVE_OPEN:
    154       /* spent += pos->amount_with_fee */
    155       if (0 >
    156           TALER_amount_add (&spent,
    157                             &spent,
    158                             &pos->details.reserve_open->coin_contribution))
    159       {
    160         GNUNET_break (0);
    161         return GNUNET_SYSERR;
    162       }
    163       break;
    164     }
    165   }
    166   if (have_refund)
    167   {
    168     /* If we gave any refund, also discount ONE deposit fee */
    169     if (0 >
    170         TALER_amount_add (&refunded,
    171                           &refunded,
    172                           &deposit_fee))
    173     {
    174       GNUNET_break (0);
    175       return GNUNET_SYSERR;
    176     }
    177   }
    178   /* spent = spent - refunded */
    179   if (0 >
    180       TALER_amount_subtract (&spent,
    181                              &spent,
    182                              &refunded))
    183   {
    184     GNUNET_break (0);
    185     return GNUNET_SYSERR;
    186   }
    187   *ret = spent;
    188   return GNUNET_OK;
    189 }