fakebank_api_check.c (8390B)
1 /* 2 This file is part of TALER 3 (C) 2016-2023 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or 6 modify it under the terms of the GNU General Public License 7 as published by the Free Software Foundation; either version 3, 8 or (at your option) any later version. 9 10 TALER is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public 16 License along with TALER; see the file COPYING. If not, 17 see <http://www.gnu.org/licenses/> 18 */ 19 /** 20 * @file bank-lib/fakebank_api_check.c 21 * @brief library that fakes being a Taler bank for testcases 22 * @author Christian Grothoff <christian@grothoff.org> 23 */ 24 #include "taler/taler_fakebank_lib.h" 25 #include "taler/taler_bank_service.h" 26 #include "taler/taler_mhd_lib.h" 27 #include <gnunet/gnunet_mhd_compat.h> 28 #include "fakebank.h" 29 #include "fakebank_common_lookup.h" 30 31 32 /** 33 * Generate log messages for failed check operation. 34 * 35 * @param h handle to output transaction log for 36 */ 37 static void 38 check_log (struct TALER_FAKEBANK_Handle *h) 39 { 40 for (uint64_t i = 0; i<h->ram_limit; i++) 41 { 42 struct Transaction *t = h->transactions[i]; 43 44 if (NULL == t) 45 continue; 46 if (! t->unchecked) 47 continue; 48 switch (t->type) 49 { 50 case T_DEBIT: 51 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 52 "%s -> %s (%s) %s (%s)\n", 53 t->debit_account->account_name, 54 t->credit_account->account_name, 55 TALER_amount2s (&t->amount), 56 t->subject.debit.exchange_base_url, 57 "DEBIT"); 58 break; 59 case T_CREDIT: 60 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 61 "%s -> %s (%s) %s (%s)\n", 62 t->debit_account->account_name, 63 t->credit_account->account_name, 64 TALER_amount2s (&t->amount), 65 TALER_B2S (&t->subject.credit.reserve_pub), 66 "CREDIT"); 67 break; 68 case T_AUTH: 69 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 70 "%s -> %s (%s) %s (%s)\n", 71 t->debit_account->account_name, 72 t->credit_account->account_name, 73 TALER_amount2s (&t->amount), 74 TALER_B2S (&t->subject.auth.account_pub), 75 "AUTH"); 76 break; 77 case T_WAD: 78 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 79 "%s -> %s (%s) %s[%s] (%s)\n", 80 t->debit_account->account_name, 81 t->credit_account->account_name, 82 TALER_amount2s (&t->amount), 83 t->subject.wad.origin_base_url, 84 TALER_B2S (&t->subject.wad), 85 "WAD"); 86 break; 87 } 88 } 89 } 90 91 92 enum GNUNET_GenericReturnValue 93 TALER_FAKEBANK_check_debit (struct TALER_FAKEBANK_Handle *h, 94 const struct TALER_Amount *want_amount, 95 const char *want_debit, 96 const char *want_credit, 97 const char *exchange_base_url, 98 struct TALER_WireTransferIdentifierRawP *wtid) 99 { 100 struct Account *debit_account; 101 struct Account *credit_account; 102 103 GNUNET_assert (0 == 104 strcasecmp (want_amount->currency, 105 h->currency)); 106 debit_account = TALER_FAKEBANK_lookup_account_ (h, 107 want_debit, 108 NULL); 109 credit_account = TALER_FAKEBANK_lookup_account_ (h, 110 want_credit, 111 NULL); 112 if (NULL == debit_account) 113 { 114 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 115 "I wanted: %s->%s (%s) from exchange %s (DEBIT), but debit account does not even exist!\n", 116 want_debit, 117 want_credit, 118 TALER_amount2s (want_amount), 119 exchange_base_url); 120 return GNUNET_SYSERR; 121 } 122 if (NULL == credit_account) 123 { 124 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 125 "I wanted: %s->%s (%s) from exchange %s (DEBIT), but credit account does not even exist!\n", 126 want_debit, 127 want_credit, 128 TALER_amount2s (want_amount), 129 exchange_base_url); 130 return GNUNET_SYSERR; 131 } 132 for (struct Transaction *t = debit_account->out_tail; 133 NULL != t; 134 t = t->prev_out) 135 { 136 if ( (t->unchecked) && 137 (credit_account == t->credit_account) && 138 (T_DEBIT == t->type) && 139 (0 == TALER_amount_cmp (want_amount, 140 &t->amount)) && 141 (0 == strcasecmp (exchange_base_url, 142 t->subject.debit.exchange_base_url)) ) 143 { 144 *wtid = t->subject.debit.wtid; 145 t->unchecked = false; 146 return GNUNET_OK; 147 } 148 } 149 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 150 "Did not find matching transaction! I have:\n"); 151 check_log (h); 152 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 153 "I wanted: %s->%s (%s) from exchange %s (DEBIT)\n", 154 want_debit, 155 want_credit, 156 TALER_amount2s (want_amount), 157 exchange_base_url); 158 return GNUNET_SYSERR; 159 } 160 161 162 enum GNUNET_GenericReturnValue 163 TALER_FAKEBANK_check_credit (struct TALER_FAKEBANK_Handle *h, 164 const struct TALER_Amount *want_amount, 165 const char *want_debit, 166 const char *want_credit, 167 const struct TALER_ReservePublicKeyP *reserve_pub) 168 { 169 struct Account *debit_account; 170 struct Account *credit_account; 171 172 GNUNET_assert (0 == strcasecmp (want_amount->currency, 173 h->currency)); 174 debit_account = TALER_FAKEBANK_lookup_account_ (h, 175 want_debit, 176 NULL); 177 credit_account = TALER_FAKEBANK_lookup_account_ (h, 178 want_credit, 179 NULL); 180 if (NULL == debit_account) 181 { 182 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 183 "I wanted:\n%s -> %s (%s) with subject %s (CREDIT) but debit account is unknown.\n", 184 want_debit, 185 want_credit, 186 TALER_amount2s (want_amount), 187 TALER_B2S (reserve_pub)); 188 return GNUNET_SYSERR; 189 } 190 if (NULL == credit_account) 191 { 192 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 193 "I wanted:\n%s -> %s (%s) with subject %s (CREDIT) but credit account is unknown.\n", 194 want_debit, 195 want_credit, 196 TALER_amount2s (want_amount), 197 TALER_B2S (reserve_pub)); 198 return GNUNET_SYSERR; 199 } 200 for (struct Transaction *t = credit_account->in_tail; 201 NULL != t; 202 t = t->prev_in) 203 { 204 if ( (t->unchecked) && 205 (debit_account == t->debit_account) && 206 (T_CREDIT == t->type) && 207 (0 == TALER_amount_cmp (want_amount, 208 &t->amount)) && 209 (0 == GNUNET_memcmp (reserve_pub, 210 &t->subject.credit.reserve_pub)) ) 211 { 212 t->unchecked = false; 213 return GNUNET_OK; 214 } 215 } 216 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 217 "Did not find matching transaction!\nI have:\n"); 218 check_log (h); 219 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 220 "I wanted:\n%s -> %s (%s) with subject %s (CREDIT)\n", 221 want_debit, 222 want_credit, 223 TALER_amount2s (want_amount), 224 TALER_B2S (reserve_pub)); 225 return GNUNET_SYSERR; 226 } 227 228 229 enum GNUNET_GenericReturnValue 230 TALER_FAKEBANK_check_empty (struct TALER_FAKEBANK_Handle *h) 231 { 232 for (uint64_t i = 0; i<h->ram_limit; i++) 233 { 234 struct Transaction *t = h->transactions[i]; 235 236 if ( (NULL != t) && 237 (t->unchecked) ) 238 { 239 if (T_AUTH == t->type) 240 continue; /* ignore */ 241 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 242 "Expected empty transaction set, but I have:\n"); 243 check_log (h); 244 return GNUNET_SYSERR; 245 } 246 } 247 return GNUNET_OK; 248 }