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 }