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 (5769B)


      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   GNUNET_assert (GNUNET_OK ==
     39                  TALER_amount_set_zero (spent.currency,
     40                                         &deposit_fee));
     41   have_refund = false;
     42   for (struct TALER_EXCHANGEDB_TransactionList *pos = tl;
     43        NULL != pos;
     44        pos = pos->next)
     45   {
     46     switch (pos->type)
     47     {
     48     case TALER_EXCHANGEDB_TT_DEPOSIT:
     49       /* spent += pos->amount_with_fee */
     50       if (0 >
     51           TALER_amount_add (&spent,
     52                             &spent,
     53                             &pos->details.deposit->amount_with_fee))
     54       {
     55         GNUNET_break (0);
     56         return GNUNET_SYSERR;
     57       }
     58       deposit_fee = pos->details.deposit->deposit_fee;
     59       break;
     60     case TALER_EXCHANGEDB_TT_MELT:
     61       /* spent += pos->amount_with_fee */
     62       if (0 >
     63           TALER_amount_add (&spent,
     64                             &spent,
     65                             &pos->details.melt->amount_with_fee))
     66       {
     67         GNUNET_break (0);
     68         return GNUNET_SYSERR;
     69       }
     70       break;
     71     case TALER_EXCHANGEDB_TT_REFUND:
     72       /* refunded += pos->refund_amount - pos->refund_fee */
     73       if (0 >
     74           TALER_amount_add (&refunded,
     75                             &refunded,
     76                             &pos->details.refund->refund_amount))
     77       {
     78         GNUNET_break (0);
     79         return GNUNET_SYSERR;
     80       }
     81       if (0 >
     82           TALER_amount_add (&spent,
     83                             &spent,
     84                             &pos->details.refund->refund_fee))
     85       {
     86         GNUNET_break (0);
     87         return GNUNET_SYSERR;
     88       }
     89       have_refund = true;
     90       break;
     91     case TALER_EXCHANGEDB_TT_RECOUP_REFRESH_RECEIVER:
     92       /* refunded += pos->value */
     93       if (0 >
     94           TALER_amount_add (&refunded,
     95                             &refunded,
     96                             &pos->details.old_coin_recoup->value))
     97       {
     98         GNUNET_break (0);
     99         return GNUNET_SYSERR;
    100       }
    101       break;
    102     case TALER_EXCHANGEDB_TT_RECOUP_WITHDRAW:
    103       /* spent += pos->value */
    104       if (0 >
    105           TALER_amount_add (&spent,
    106                             &spent,
    107                             &pos->details.recoup->value))
    108       {
    109         GNUNET_break (0);
    110         return GNUNET_SYSERR;
    111       }
    112       break;
    113     case TALER_EXCHANGEDB_TT_RECOUP_REFRESH:
    114       /* spent += pos->value */
    115       if (0 >
    116           TALER_amount_add (&spent,
    117                             &spent,
    118                             &pos->details.recoup_refresh->value))
    119       {
    120         GNUNET_break (0);
    121         return GNUNET_SYSERR;
    122       }
    123       break;
    124     case TALER_EXCHANGEDB_TT_PURSE_DEPOSIT:
    125       /* spent += pos->amount_with_fee */
    126       if (0 >
    127           TALER_amount_add (&spent,
    128                             &spent,
    129                             &pos->details.purse_deposit->amount))
    130       {
    131         GNUNET_break (0);
    132         return GNUNET_SYSERR;
    133       }
    134       deposit_fee = pos->details.purse_deposit->deposit_fee;
    135       break;
    136     case TALER_EXCHANGEDB_TT_PURSE_REFUND:
    137       /* refunded += pos->refund_amount - pos->refund_fee */
    138       if (0 >
    139           TALER_amount_add (&refunded,
    140                             &refunded,
    141                             &pos->details.purse_refund->refund_amount))
    142       {
    143         GNUNET_break (0);
    144         return GNUNET_SYSERR;
    145       }
    146       if (0 >
    147           TALER_amount_add (&spent,
    148                             &spent,
    149                             &pos->details.purse_refund->refund_fee))
    150       {
    151         GNUNET_break (0);
    152         return GNUNET_SYSERR;
    153       }
    154       have_refund = true;
    155       break;
    156     case TALER_EXCHANGEDB_TT_RESERVE_OPEN:
    157       /* spent += pos->amount_with_fee */
    158       if (0 >
    159           TALER_amount_add (&spent,
    160                             &spent,
    161                             &pos->details.reserve_open->coin_contribution))
    162       {
    163         GNUNET_break (0);
    164         return GNUNET_SYSERR;
    165       }
    166       break;
    167     }
    168   }
    169   if (have_refund)
    170   {
    171     /* If we gave any refund, also discount ONE deposit fee */
    172     if (0 >
    173         TALER_amount_add (&refunded,
    174                           &refunded,
    175                           &deposit_fee))
    176     {
    177       GNUNET_break (0);
    178       return GNUNET_SYSERR;
    179     }
    180   }
    181   /* spent = spent - refunded */
    182   if (0 >
    183       TALER_amount_subtract (&spent,
    184                              &spent,
    185                              &refunded))
    186   {
    187     GNUNET_break (0);
    188     return GNUNET_SYSERR;
    189   }
    190   *ret = spent;
    191   return GNUNET_OK;
    192 }