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 }