Line data Source code
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 0 : check_log (struct TALER_FAKEBANK_Handle *h)
39 : {
40 0 : for (uint64_t i = 0; i<h->ram_limit; i++)
41 : {
42 0 : struct Transaction *t = h->transactions[i];
43 :
44 0 : if (NULL == t)
45 0 : continue;
46 0 : if (! t->unchecked)
47 0 : continue;
48 0 : switch (t->type)
49 : {
50 0 : case T_DEBIT:
51 0 : 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 0 : break;
59 0 : case T_CREDIT:
60 0 : 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 0 : break;
68 0 : case T_AUTH:
69 0 : 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 0 : break;
77 0 : case T_WAD:
78 0 : 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 0 : break;
87 : }
88 : }
89 0 : }
90 :
91 :
92 : enum GNUNET_GenericReturnValue
93 48 : 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 48 : GNUNET_assert (0 ==
104 : strcasecmp (want_amount->currency,
105 : h->currency));
106 48 : debit_account = TALER_FAKEBANK_lookup_account_ (h,
107 : want_debit,
108 : NULL);
109 48 : credit_account = TALER_FAKEBANK_lookup_account_ (h,
110 : want_credit,
111 : NULL);
112 48 : if (NULL == debit_account)
113 : {
114 0 : 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 0 : return GNUNET_SYSERR;
121 : }
122 48 : if (NULL == credit_account)
123 : {
124 0 : 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 0 : return GNUNET_SYSERR;
131 : }
132 48 : for (struct Transaction *t = debit_account->out_tail;
133 209 : NULL != t;
134 161 : t = t->prev_out)
135 : {
136 209 : if ( (t->unchecked) &&
137 74 : (credit_account == t->credit_account) &&
138 104 : (T_DEBIT == t->type) &&
139 52 : (0 == TALER_amount_cmp (want_amount,
140 52 : &t->amount)) &&
141 48 : (0 == strcasecmp (exchange_base_url,
142 48 : t->subject.debit.exchange_base_url)) )
143 : {
144 48 : *wtid = t->subject.debit.wtid;
145 48 : t->unchecked = false;
146 48 : return GNUNET_OK;
147 : }
148 : }
149 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
150 : "Did not find matching transaction! I have:\n");
151 0 : check_log (h);
152 0 : 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 0 : return GNUNET_SYSERR;
159 : }
160 :
161 :
162 : enum GNUNET_GenericReturnValue
163 45 : 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 45 : GNUNET_assert (0 == strcasecmp (want_amount->currency,
173 : h->currency));
174 45 : debit_account = TALER_FAKEBANK_lookup_account_ (h,
175 : want_debit,
176 : NULL);
177 45 : credit_account = TALER_FAKEBANK_lookup_account_ (h,
178 : want_credit,
179 : NULL);
180 45 : if (NULL == debit_account)
181 : {
182 0 : 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 0 : return GNUNET_SYSERR;
189 : }
190 45 : if (NULL == credit_account)
191 : {
192 0 : 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 0 : return GNUNET_SYSERR;
199 : }
200 45 : for (struct Transaction *t = credit_account->in_tail;
201 50 : NULL != t;
202 5 : t = t->prev_in)
203 : {
204 50 : if ( (t->unchecked) &&
205 50 : (debit_account == t->debit_account) &&
206 100 : (T_CREDIT == t->type) &&
207 50 : (0 == TALER_amount_cmp (want_amount,
208 50 : &t->amount)) &&
209 45 : (0 == GNUNET_memcmp (reserve_pub,
210 : &t->subject.credit.reserve_pub)) )
211 : {
212 45 : t->unchecked = false;
213 45 : return GNUNET_OK;
214 : }
215 : }
216 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
217 : "Did not find matching transaction!\nI have:\n");
218 0 : check_log (h);
219 0 : 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 0 : return GNUNET_SYSERR;
226 : }
227 :
228 :
229 : enum GNUNET_GenericReturnValue
230 40 : TALER_FAKEBANK_check_empty (struct TALER_FAKEBANK_Handle *h)
231 : {
232 2621480 : for (uint64_t i = 0; i<h->ram_limit; i++)
233 : {
234 2621440 : struct Transaction *t = h->transactions[i];
235 :
236 2621440 : if ( (NULL != t) &&
237 349 : (t->unchecked) )
238 : {
239 33 : if (T_AUTH == t->type)
240 33 : continue; /* ignore */
241 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
242 : "Expected empty transaction set, but I have:\n");
243 0 : check_log (h);
244 0 : return GNUNET_SYSERR;
245 : }
246 : }
247 40 : return GNUNET_OK;
248 : }
|