fakebank_api_check.c (8418B)
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/platform.h" 25 #include "taler/taler_fakebank_lib.h" 26 #include "taler/taler_bank_service.h" 27 #include "taler/taler_mhd_lib.h" 28 #include <gnunet/gnunet_mhd_compat.h> 29 #include "fakebank.h" 30 #include "fakebank_common_lookup.h" 31 32 33 /** 34 * Generate log messages for failed check operation. 35 * 36 * @param h handle to output transaction log for 37 */ 38 static void 39 check_log (struct TALER_FAKEBANK_Handle *h) 40 { 41 for (uint64_t i = 0; i<h->ram_limit; i++) 42 { 43 struct Transaction *t = h->transactions[i]; 44 45 if (NULL == t) 46 continue; 47 if (! t->unchecked) 48 continue; 49 switch (t->type) 50 { 51 case T_DEBIT: 52 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 53 "%s -> %s (%s) %s (%s)\n", 54 t->debit_account->account_name, 55 t->credit_account->account_name, 56 TALER_amount2s (&t->amount), 57 t->subject.debit.exchange_base_url, 58 "DEBIT"); 59 break; 60 case T_CREDIT: 61 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 62 "%s -> %s (%s) %s (%s)\n", 63 t->debit_account->account_name, 64 t->credit_account->account_name, 65 TALER_amount2s (&t->amount), 66 TALER_B2S (&t->subject.credit.reserve_pub), 67 "CREDIT"); 68 break; 69 case T_AUTH: 70 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 71 "%s -> %s (%s) %s (%s)\n", 72 t->debit_account->account_name, 73 t->credit_account->account_name, 74 TALER_amount2s (&t->amount), 75 TALER_B2S (&t->subject.auth.account_pub), 76 "AUTH"); 77 break; 78 case T_WAD: 79 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 80 "%s -> %s (%s) %s[%s] (%s)\n", 81 t->debit_account->account_name, 82 t->credit_account->account_name, 83 TALER_amount2s (&t->amount), 84 t->subject.wad.origin_base_url, 85 TALER_B2S (&t->subject.wad), 86 "WAD"); 87 break; 88 } 89 } 90 } 91 92 93 enum GNUNET_GenericReturnValue 94 TALER_FAKEBANK_check_debit (struct TALER_FAKEBANK_Handle *h, 95 const struct TALER_Amount *want_amount, 96 const char *want_debit, 97 const char *want_credit, 98 const char *exchange_base_url, 99 struct TALER_WireTransferIdentifierRawP *wtid) 100 { 101 struct Account *debit_account; 102 struct Account *credit_account; 103 104 GNUNET_assert (0 == 105 strcasecmp (want_amount->currency, 106 h->currency)); 107 debit_account = TALER_FAKEBANK_lookup_account_ (h, 108 want_debit, 109 NULL); 110 credit_account = TALER_FAKEBANK_lookup_account_ (h, 111 want_credit, 112 NULL); 113 if (NULL == debit_account) 114 { 115 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 116 "I wanted: %s->%s (%s) from exchange %s (DEBIT), but debit account does not even exist!\n", 117 want_debit, 118 want_credit, 119 TALER_amount2s (want_amount), 120 exchange_base_url); 121 return GNUNET_SYSERR; 122 } 123 if (NULL == credit_account) 124 { 125 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 126 "I wanted: %s->%s (%s) from exchange %s (DEBIT), but credit account does not even exist!\n", 127 want_debit, 128 want_credit, 129 TALER_amount2s (want_amount), 130 exchange_base_url); 131 return GNUNET_SYSERR; 132 } 133 for (struct Transaction *t = debit_account->out_tail; 134 NULL != t; 135 t = t->prev_out) 136 { 137 if ( (t->unchecked) && 138 (credit_account == t->credit_account) && 139 (T_DEBIT == t->type) && 140 (0 == TALER_amount_cmp (want_amount, 141 &t->amount)) && 142 (0 == strcasecmp (exchange_base_url, 143 t->subject.debit.exchange_base_url)) ) 144 { 145 *wtid = t->subject.debit.wtid; 146 t->unchecked = false; 147 return GNUNET_OK; 148 } 149 } 150 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 151 "Did not find matching transaction! I have:\n"); 152 check_log (h); 153 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 154 "I wanted: %s->%s (%s) from exchange %s (DEBIT)\n", 155 want_debit, 156 want_credit, 157 TALER_amount2s (want_amount), 158 exchange_base_url); 159 return GNUNET_SYSERR; 160 } 161 162 163 enum GNUNET_GenericReturnValue 164 TALER_FAKEBANK_check_credit (struct TALER_FAKEBANK_Handle *h, 165 const struct TALER_Amount *want_amount, 166 const char *want_debit, 167 const char *want_credit, 168 const struct TALER_ReservePublicKeyP *reserve_pub) 169 { 170 struct Account *debit_account; 171 struct Account *credit_account; 172 173 GNUNET_assert (0 == strcasecmp (want_amount->currency, 174 h->currency)); 175 debit_account = TALER_FAKEBANK_lookup_account_ (h, 176 want_debit, 177 NULL); 178 credit_account = TALER_FAKEBANK_lookup_account_ (h, 179 want_credit, 180 NULL); 181 if (NULL == debit_account) 182 { 183 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 184 "I wanted:\n%s -> %s (%s) with subject %s (CREDIT) but debit account is unknown.\n", 185 want_debit, 186 want_credit, 187 TALER_amount2s (want_amount), 188 TALER_B2S (reserve_pub)); 189 return GNUNET_SYSERR; 190 } 191 if (NULL == credit_account) 192 { 193 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 194 "I wanted:\n%s -> %s (%s) with subject %s (CREDIT) but credit account is unknown.\n", 195 want_debit, 196 want_credit, 197 TALER_amount2s (want_amount), 198 TALER_B2S (reserve_pub)); 199 return GNUNET_SYSERR; 200 } 201 for (struct Transaction *t = credit_account->in_tail; 202 NULL != t; 203 t = t->prev_in) 204 { 205 if ( (t->unchecked) && 206 (debit_account == t->debit_account) && 207 (T_CREDIT == t->type) && 208 (0 == TALER_amount_cmp (want_amount, 209 &t->amount)) && 210 (0 == GNUNET_memcmp (reserve_pub, 211 &t->subject.credit.reserve_pub)) ) 212 { 213 t->unchecked = false; 214 return GNUNET_OK; 215 } 216 } 217 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 218 "Did not find matching transaction!\nI have:\n"); 219 check_log (h); 220 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 221 "I wanted:\n%s -> %s (%s) with subject %s (CREDIT)\n", 222 want_debit, 223 want_credit, 224 TALER_amount2s (want_amount), 225 TALER_B2S (reserve_pub)); 226 return GNUNET_SYSERR; 227 } 228 229 230 enum GNUNET_GenericReturnValue 231 TALER_FAKEBANK_check_empty (struct TALER_FAKEBANK_Handle *h) 232 { 233 for (uint64_t i = 0; i<h->ram_limit; i++) 234 { 235 struct Transaction *t = h->transactions[i]; 236 237 if ( (NULL != t) && 238 (t->unchecked) ) 239 { 240 if (T_AUTH == t->type) 241 continue; /* ignore */ 242 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 243 "Expected empty transaction set, but I have:\n"); 244 check_log (h); 245 return GNUNET_SYSERR; 246 } 247 } 248 return GNUNET_OK; 249 }