Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2014--2022 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify
6 : it under the terms of the GNU General Public License as
7 : published by the Free Software Foundation; either version 3, or
8 : (at your option) any later version.
9 :
10 : TALER is distributed in the hope that it will be useful, but
11 : 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, see
17 : <http://www.gnu.org/licenses/>
18 : */
19 : /**
20 : * @file testing/test_exchange_api.c
21 : * @brief testcase to test exchange's HTTP API interface
22 : * @author Sree Harsha Totakura <sreeharsha@totakura.in>
23 : * @author Christian Grothoff
24 : * @author Marcello Stanisci
25 : */
26 : #include "platform.h"
27 : #include "taler_util.h"
28 : #include "taler_signatures.h"
29 : #include "taler_exchange_service.h"
30 : #include "taler_json_lib.h"
31 : #include <gnunet/gnunet_util_lib.h>
32 : #include <gnunet/gnunet_testing_lib.h>
33 : #include <microhttpd.h>
34 : #include "taler_bank_service.h"
35 : #include "taler_fakebank_lib.h"
36 : #include "taler_testing_lib.h"
37 : #include "taler_extensions.h"
38 :
39 : /**
40 : * Configuration file we use. One (big) configuration is used
41 : * for the various components for this test.
42 : */
43 : static char *config_file;
44 :
45 : /**
46 : * Special configuration file to use when we want reserves
47 : * to expire 'immediately'.
48 : */
49 : static char *config_file_expire_reserve_now;
50 :
51 : /**
52 : * Our credentials.
53 : */
54 : static struct TALER_TESTING_Credentials cred;
55 :
56 : /**
57 : * Some tests behave differently when using CS as we cannot
58 : * reuse the coin private key for different denominations
59 : * due to the derivation of it with the /csr values. Hence
60 : * some tests behave differently in CS mode, hence this
61 : * flag.
62 : */
63 : static bool uses_cs;
64 :
65 : /**
66 : * Execute the taler-exchange-wirewatch command with
67 : * our configuration file.
68 : *
69 : * @param label label to use for the command.
70 : */
71 : #define CMD_EXEC_WIREWATCH(label) \
72 : TALER_TESTING_cmd_exec_wirewatch2 (label, config_file, \
73 : "exchange-account-2")
74 :
75 : /**
76 : * Execute the taler-exchange-aggregator, closer and transfer commands with
77 : * our configuration file.
78 : *
79 : * @param label label to use for the command.
80 : */
81 : #define CMD_EXEC_AGGREGATOR(label) \
82 : TALER_TESTING_cmd_sleep ("sleep-before-aggregator", 2), \
83 : TALER_TESTING_cmd_exec_aggregator (label "-aggregator", config_file), \
84 : TALER_TESTING_cmd_exec_transfer (label "-transfer", config_file)
85 :
86 :
87 : /**
88 : * Run wire transfer of funds from some user's account to the
89 : * exchange.
90 : *
91 : * @param label label to use for the command.
92 : * @param amount amount to transfer, i.e. "EUR:1"
93 : */
94 : #define CMD_TRANSFER_TO_EXCHANGE(label,amount) \
95 : TALER_TESTING_cmd_admin_add_incoming (label, amount, \
96 : &cred.ba, \
97 : cred.user42_payto)
98 :
99 : /**
100 : * Main function that will tell the interpreter what commands to
101 : * run.
102 : *
103 : * @param cls closure
104 : * @param is interpreter we use to run commands
105 : */
106 : static void
107 2 : run (void *cls,
108 : struct TALER_TESTING_Interpreter *is)
109 : {
110 : /**
111 : * Test withdrawal plus spending.
112 : */
113 : struct TALER_TESTING_Command withdraw[] = {
114 : /**
115 : * Move money to the exchange's bank account.
116 : */
117 2 : CMD_TRANSFER_TO_EXCHANGE ("create-reserve-1",
118 : "EUR:6.02"),
119 2 : TALER_TESTING_cmd_reserve_poll ("poll-reserve-1",
120 : "create-reserve-1",
121 : "EUR:6.02",
122 : GNUNET_TIME_UNIT_MINUTES,
123 : MHD_HTTP_OK),
124 2 : TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-1",
125 : "EUR:6.02",
126 : cred.user42_payto,
127 : cred.exchange_payto,
128 : "create-reserve-1"),
129 : /**
130 : * Make a reserve exist, according to the previous
131 : * transfer.
132 : */
133 2 : CMD_EXEC_WIREWATCH ("wirewatch-1"),
134 2 : TALER_TESTING_cmd_reserve_poll_finish ("finish-poll-reserve-1",
135 : GNUNET_TIME_relative_multiply (
136 : GNUNET_TIME_UNIT_SECONDS,
137 : 2),
138 : "poll-reserve-1"),
139 : /**
140 : * Withdraw EUR:5.
141 : */
142 2 : TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1",
143 : "create-reserve-1",
144 : "EUR:5",
145 : 0, /* age restriction off */
146 : MHD_HTTP_OK),
147 : /**
148 : * Idempotent withdrawal. Note that in the case of CS, this is _not_
149 : * idempotent because the blinding nonces still differ, so instead,
150 : * it is an overcharging of the reserve.
151 : */
152 2 : TALER_TESTING_cmd_withdraw_amount_reuse_key ("withdraw-coin-1-idem",
153 : "create-reserve-1",
154 : "EUR:5",
155 : 0, /* age restriction off */
156 : "withdraw-coin-1",
157 : (uses_cs)
158 2 : ? MHD_HTTP_CONFLICT
159 : : MHD_HTTP_OK),
160 : /**
161 : * Withdraw EUR:1 using the SAME private coin key as for the previous coin
162 : * (in violation of the specification, to be detected on spending!).
163 : * However, note that this does NOT work with 'CS', as for a different
164 : * denomination we get different R0/R1 values from the exchange, and
165 : * thus will generate a different coin private key as R0/R1 are hashed
166 : * into the coin priv. So here, we fail to 'reuse' the key due to the
167 : * cryptographic construction!
168 : */
169 2 : TALER_TESTING_cmd_withdraw_amount_reuse_key ("withdraw-coin-1x",
170 : "create-reserve-1",
171 : "EUR:1",
172 : 0, /* age restriction off */
173 : "withdraw-coin-1",
174 : MHD_HTTP_OK),
175 : /**
176 : * Check the reserve is depleted.
177 : */
178 2 : TALER_TESTING_cmd_status ("status-1",
179 : "create-reserve-1",
180 : "EUR:0",
181 : MHD_HTTP_OK),
182 : /*
183 : * Try to overdraw.
184 : */
185 2 : TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2",
186 : "create-reserve-1",
187 : "EUR:5",
188 : 0, /* age restriction off */
189 : MHD_HTTP_CONFLICT),
190 2 : TALER_TESTING_cmd_end ()
191 : };
192 :
193 : struct TALER_TESTING_Command spend[] = {
194 : /**
195 : * Spend the coin.
196 : */
197 2 : TALER_TESTING_cmd_set_var (
198 : "account-priv",
199 : TALER_TESTING_cmd_deposit (
200 : "deposit-simple-fail-kyc",
201 : "withdraw-coin-1",
202 : 0,
203 : cred.user42_payto,
204 : "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
205 2 : GNUNET_TIME_UNIT_ZERO,
206 : "EUR:5",
207 : MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)),
208 2 : TALER_TESTING_cmd_admin_add_kycauth (
209 : "kyc-auth-transfer",
210 : "EUR:0.01",
211 : &cred.ba,
212 : cred.user42_payto,
213 : "deposit-simple-fail-kyc"),
214 2 : CMD_EXEC_WIREWATCH (
215 : "import-kyc-account-withdraw"),
216 2 : TALER_TESTING_cmd_deposit_replay (
217 : "deposit-simple",
218 : "deposit-simple-fail-kyc",
219 : MHD_HTTP_OK),
220 2 : TALER_TESTING_cmd_deposit_replay (
221 : "deposit-simple-replay-1",
222 : "deposit-simple",
223 : MHD_HTTP_OK),
224 2 : TALER_TESTING_cmd_sleep (
225 : "sleep-before-deposit-replay",
226 : 1),
227 2 : TALER_TESTING_cmd_deposit_replay (
228 : "deposit-simple-replay-2",
229 : "deposit-simple",
230 : MHD_HTTP_OK),
231 : /* This creates a conflict, as we have the same coin public key (reuse!),
232 : but different denomination public keys (which is not allowed).
233 : However, note that this does NOT work with 'CS', as for a different
234 : denomination we get different R0/R1 values from the exchange, and
235 : thus will generate a different coin private key as R0/R1 are hashed
236 : into the coin priv. So here, we fail to 'reuse' the key due to the
237 : cryptographic construction! */
238 2 : TALER_TESTING_cmd_deposit (
239 : "deposit-reused-coin-key-failure",
240 : "withdraw-coin-1x",
241 : 0,
242 : cred.user42_payto,
243 : "{\"items\":[{\"name\":\"conflicting ice cream\",\"value\":1}]}",
244 2 : GNUNET_TIME_UNIT_ZERO,
245 : "EUR:1",
246 : uses_cs
247 2 : ? MHD_HTTP_OK
248 : : MHD_HTTP_CONFLICT),
249 : /**
250 : * Try to double spend using different wire details.
251 : */
252 2 : TALER_TESTING_cmd_admin_add_kycauth (
253 : "kyc-auth-transfer-2",
254 : "EUR:0.01",
255 : &cred.ba,
256 : cred.user43_payto,
257 : "deposit-simple-fail-kyc"),
258 2 : CMD_EXEC_WIREWATCH (
259 : "import-kyc-account-1"),
260 2 : TALER_TESTING_cmd_deposit (
261 : "deposit-double-1",
262 : "withdraw-coin-1",
263 : 0,
264 : cred.user43_payto,
265 : "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
266 2 : GNUNET_TIME_UNIT_ZERO,
267 : "EUR:5",
268 : MHD_HTTP_CONFLICT),
269 : /* Try to double spend using a different transaction id.
270 : * The test needs the contract terms to differ. This
271 : * is currently the case because of the "timestamp" field,
272 : * which is set automatically by #TALER_TESTING_cmd_deposit().
273 : * This could theoretically fail if at some point a deposit
274 : * command executes in less than 1 ms. */
275 2 : TALER_TESTING_cmd_deposit (
276 : "deposit-double-1",
277 : "withdraw-coin-1",
278 : 0,
279 : cred.user43_payto,
280 : "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
281 2 : GNUNET_TIME_UNIT_ZERO,
282 : "EUR:5",
283 : MHD_HTTP_CONFLICT),
284 : /**
285 : * Try to double spend with different proposal.
286 : */
287 2 : TALER_TESTING_cmd_deposit (
288 : "deposit-double-2",
289 : "withdraw-coin-1",
290 : 0,
291 : cred.user43_payto,
292 : "{\"items\":[{\"name\":\"ice cream\",\"value\":2}]}",
293 2 : GNUNET_TIME_UNIT_ZERO,
294 : "EUR:5",
295 : MHD_HTTP_CONFLICT),
296 2 : TALER_TESTING_cmd_end ()
297 : };
298 :
299 : struct TALER_TESTING_Command refresh[] = {
300 : /**
301 : * Try to melt the coin that shared the private key with another
302 : * coin (should fail). Note that in the CS-case, we fail also
303 : * with MHD_HTTP_CONFLICT, but for a different reason: here it
304 : * is not a denomination conflict, but a double-spending conflict.
305 : */
306 2 : TALER_TESTING_cmd_melt (
307 : "refresh-melt-reused-coin-key-failure",
308 : "withdraw-coin-1x",
309 : MHD_HTTP_CONFLICT,
310 : NULL),
311 :
312 : /* Fill reserve with EUR:5, 1ct is for fees. */
313 2 : CMD_TRANSFER_TO_EXCHANGE (
314 : "refresh-create-reserve-1",
315 : "EUR:5.01"),
316 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
317 : "ck-refresh-create-reserve-1",
318 : "EUR:5.01",
319 : cred.user42_payto,
320 : cred.exchange_payto,
321 : "refresh-create-reserve-1"),
322 : /**
323 : * Make previous command effective.
324 : */
325 2 : CMD_EXEC_WIREWATCH ("wirewatch-2"),
326 : /**
327 : * Withdraw EUR:5.
328 : */
329 2 : TALER_TESTING_cmd_withdraw_amount (
330 : "refresh-withdraw-coin-1",
331 : "refresh-create-reserve-1",
332 : "EUR:5",
333 : 0, /* age restriction off */
334 : MHD_HTTP_OK),
335 : /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin
336 : * (in full) (merchant would receive EUR:0.99 due to 1 ct
337 : * deposit fee)
338 : */
339 2 : TALER_TESTING_cmd_deposit (
340 : "refresh-deposit-partial",
341 : "refresh-withdraw-coin-1",
342 : 0,
343 : cred.user42_payto,
344 : "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}",
345 2 : GNUNET_TIME_UNIT_ZERO,
346 : "EUR:1",
347 : MHD_HTTP_OK),
348 : /**
349 : * Melt the rest of the coin's value
350 : * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */
351 2 : TALER_TESTING_cmd_melt_double (
352 : "refresh-melt-1",
353 : "refresh-withdraw-coin-1",
354 : MHD_HTTP_OK,
355 : NULL),
356 : /**
357 : * Complete (successful) melt operation, and
358 : * withdraw the coins
359 : */
360 2 : TALER_TESTING_cmd_melt_reveal (
361 : "refresh-reveal-1",
362 : "refresh-melt-1",
363 : MHD_HTTP_OK),
364 : /**
365 : * Do it again to check idempotency
366 : */
367 2 : TALER_TESTING_cmd_melt_reveal (
368 : "refresh-reveal-1-idempotency",
369 : "refresh-melt-1",
370 : MHD_HTTP_OK),
371 : /**
372 : * Try to spend a refreshed EUR:1 coin
373 : */
374 2 : TALER_TESTING_cmd_deposit (
375 : "refresh-deposit-refreshed-1a",
376 : "refresh-reveal-1-idempotency",
377 : 0,
378 : cred.user42_payto,
379 : "{\"items\":[{\"name\":\"ice cream\",\"value\":3}]}",
380 2 : GNUNET_TIME_UNIT_ZERO,
381 : "EUR:1",
382 : MHD_HTTP_OK),
383 : /**
384 : * Try to spend a refreshed EUR:0.1 coin
385 : */
386 2 : TALER_TESTING_cmd_deposit (
387 : "refresh-deposit-refreshed-1b",
388 : "refresh-reveal-1",
389 : 3,
390 : cred.user43_payto,
391 : "{\"items\":[{\"name\":\"cheap ice cream\",\"value\":3}]}",
392 2 : GNUNET_TIME_UNIT_ZERO,
393 : "EUR:0.1",
394 : MHD_HTTP_OK),
395 : /* Test running a failing melt operation (same operation
396 : * again must fail) */
397 2 : TALER_TESTING_cmd_melt (
398 : "refresh-melt-failing",
399 : "refresh-withdraw-coin-1",
400 : MHD_HTTP_CONFLICT,
401 : NULL),
402 : /* Test running a failing melt operation (on a coin that
403 : was itself revealed and subsequently deposited) */
404 2 : TALER_TESTING_cmd_melt (
405 : "refresh-melt-failing-2",
406 : "refresh-reveal-1",
407 : MHD_HTTP_CONFLICT,
408 : NULL),
409 :
410 2 : TALER_TESTING_cmd_end ()
411 : };
412 :
413 : /**
414 : * Test withdrawal with age restriction. Success is expected, so it MUST be
415 : * called _after_ TALER_TESTING_cmd_exec_offline_sign_extensions is called,
416 : * i. e. age restriction is activated in the exchange!
417 : *
418 : * FIXME[oec]: create a test that tries to withdraw coins with age restriction but
419 : * (expectedly) fails because the exchange doesn't support age restriction
420 : * yet.
421 : */
422 : struct TALER_TESTING_Command withdraw_age[] = {
423 : /**
424 : * Move money to the exchange's bank account.
425 : */
426 2 : CMD_TRANSFER_TO_EXCHANGE (
427 : "create-reserve-age",
428 : "EUR:6.01"),
429 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
430 : "check-create-reserve-age",
431 : "EUR:6.01",
432 : cred.user42_payto,
433 : cred.exchange_payto,
434 : "create-reserve-age"),
435 : /**
436 : * Make a reserve exist, according to the previous
437 : * transfer.
438 : */
439 2 : CMD_EXEC_WIREWATCH ("wirewatch-age"),
440 : /**
441 : * Withdraw EUR:5.
442 : */
443 2 : TALER_TESTING_cmd_withdraw_amount (
444 : "withdraw-coin-age-1",
445 : "create-reserve-age",
446 : "EUR:5",
447 : 13,
448 : MHD_HTTP_OK),
449 :
450 2 : TALER_TESTING_cmd_end ()
451 : };
452 :
453 : struct TALER_TESTING_Command spend_age[] = {
454 : /**
455 : * Spend the coin.
456 : */
457 2 : TALER_TESTING_cmd_deposit (
458 : "deposit-simple-age",
459 : "withdraw-coin-age-1",
460 : 0,
461 : cred.user42_payto,
462 : "{\"items\":[{\"name\":\"unique ice cream\",\"value\":1}]}",
463 2 : GNUNET_TIME_UNIT_ZERO,
464 : "EUR:4.99",
465 : MHD_HTTP_OK),
466 2 : TALER_TESTING_cmd_deposit_replay (
467 : "deposit-simple-replay-age",
468 : "deposit-simple-age",
469 : MHD_HTTP_OK),
470 2 : TALER_TESTING_cmd_deposit_replay (
471 : "deposit-simple-replay-age-1",
472 : "deposit-simple-age",
473 : MHD_HTTP_OK),
474 2 : TALER_TESTING_cmd_sleep (
475 : "sleep-before-age-deposit-replay",
476 : 1),
477 2 : TALER_TESTING_cmd_deposit_replay (
478 : "deposit-simple-replay-age-2",
479 : "deposit-simple-age",
480 : MHD_HTTP_OK),
481 2 : TALER_TESTING_cmd_end ()
482 : };
483 :
484 : struct TALER_TESTING_Command track[] = {
485 : /* Try resolving a deposit's WTID, as we never triggered
486 : * execution of transactions, the answer should be that
487 : * the exchange knows about the deposit, but has no WTID yet.
488 : */
489 2 : TALER_TESTING_cmd_deposits_get (
490 : "deposit-wtid-found",
491 : "deposit-simple",
492 : 0,
493 : MHD_HTTP_ACCEPTED,
494 : NULL),
495 : /* Try resolving a deposit's WTID for a failed deposit.
496 : * As the deposit failed, the answer should be that the
497 : * exchange does NOT know about the deposit.
498 : */
499 2 : TALER_TESTING_cmd_deposits_get (
500 : "deposit-wtid-failing",
501 : "deposit-double-2",
502 : 0,
503 : MHD_HTTP_NOT_FOUND,
504 : NULL),
505 : /* Try resolving an undefined (all zeros) WTID; this
506 : * should fail as obviously the exchange didn't use that
507 : * WTID value for any transaction.
508 : */
509 2 : TALER_TESTING_cmd_track_transfer_empty (
510 : "wire-deposit-failing",
511 : NULL,
512 : MHD_HTTP_NOT_FOUND),
513 : /* Run transfers. */
514 2 : CMD_EXEC_AGGREGATOR ("run-aggregator"),
515 : /**
516 : * Check all the transfers took place.
517 : */
518 2 : TALER_TESTING_cmd_check_bank_transfer (
519 : "check_bank_transfer-42-aggregate",
520 2 : cred.exchange_url,
521 : /* In case of CS, one transaction above succeeded that
522 : failed for RSA, hence we get a larger amount here */
523 2 : uses_cs ? "EUR:14.91" : "EUR:13.92",
524 : cred.exchange_payto,
525 : cred.user42_payto),
526 2 : TALER_TESTING_cmd_check_bank_transfer (
527 : "check_bank_transfer-43-aggregate",
528 2 : cred.exchange_url,
529 : "EUR:0.17",
530 : cred.exchange_payto,
531 : cred.user43_payto),
532 2 : TALER_TESTING_cmd_check_bank_empty ("check_bank_empty"),
533 2 : TALER_TESTING_cmd_deposits_get (
534 : "deposit-wtid-ok",
535 : "deposit-simple",
536 : 0,
537 : MHD_HTTP_OK,
538 : "check_bank_transfer-42-aggregate"),
539 2 : TALER_TESTING_cmd_track_transfer (
540 : "wire-deposit-success-bank",
541 : "check_bank_transfer-42-aggregate",
542 : MHD_HTTP_OK,
543 2 : uses_cs ? "EUR:14.91" : "EUR:13.92",
544 : "EUR:0.01"),
545 2 : TALER_TESTING_cmd_track_transfer (
546 : "wire-deposits-success-wtid",
547 : "check_bank_transfer-43-aggregate",
548 : MHD_HTTP_OK,
549 : "EUR:0.17",
550 : "EUR:0.01"),
551 2 : TALER_TESTING_cmd_end ()
552 : };
553 :
554 : /**
555 : * This block checks whether a wire deadline
556 : * very far in the future does NOT get aggregated now.
557 : */
558 : struct TALER_TESTING_Command unaggregation[] = {
559 2 : TALER_TESTING_cmd_check_bank_empty ("far-future-aggregation-a"),
560 2 : CMD_TRANSFER_TO_EXCHANGE (
561 : "create-reserve-unaggregated",
562 : "EUR:5.01"),
563 : /* "consume" reserve creation transfer. */
564 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
565 : "check-create-reserve-unaggregated",
566 : "EUR:5.01",
567 : cred.user42_payto,
568 : cred.exchange_payto,
569 : "create-reserve-unaggregated"),
570 2 : CMD_EXEC_WIREWATCH ("wirewatch-unaggregated"),
571 2 : TALER_TESTING_cmd_withdraw_amount (
572 : "withdraw-coin-unaggregated",
573 : "create-reserve-unaggregated",
574 : "EUR:5",
575 : 0, /* age restriction off */
576 : MHD_HTTP_OK),
577 2 : TALER_TESTING_cmd_deposit (
578 : "deposit-unaggregated",
579 : "withdraw-coin-unaggregated",
580 : 0,
581 : cred.user43_payto,
582 : "{\"items\":[{\"name\":\"different ice cream\",\"value\":1}]}",
583 : GNUNET_TIME_relative_multiply (
584 : GNUNET_TIME_UNIT_YEARS,
585 : 3000),
586 : "EUR:5",
587 : MHD_HTTP_OK),
588 2 : CMD_EXEC_AGGREGATOR ("aggregation-attempt"),
589 :
590 2 : TALER_TESTING_cmd_check_bank_empty (
591 : "far-future-aggregation-b"),
592 :
593 2 : TALER_TESTING_cmd_end ()
594 : };
595 :
596 : struct TALER_TESTING_Command refresh_age[] = {
597 : /* Fill reserve with EUR:5, 1ct is for fees. */
598 2 : CMD_TRANSFER_TO_EXCHANGE (
599 : "refresh-create-reserve-age-1",
600 : "EUR:6.01"),
601 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
602 : "ck-refresh-create-reserve-age-1",
603 : "EUR:6.01",
604 : cred.user42_payto,
605 : cred.exchange_payto,
606 : "refresh-create-reserve-age-1"),
607 : /**
608 : * Make previous command effective.
609 : */
610 2 : CMD_EXEC_WIREWATCH ("wirewatch-age-2"),
611 : /**
612 : * Withdraw EUR:7 with age restriction for age 13.
613 : */
614 2 : TALER_TESTING_cmd_withdraw_amount (
615 : "refresh-withdraw-coin-age-1",
616 : "refresh-create-reserve-age-1",
617 : "EUR:5",
618 : 13,
619 : MHD_HTTP_OK),
620 : /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin
621 : * (in full) (merchant would receive EUR:0.99 due to 1 ct
622 : * deposit fee)
623 : */
624 2 : TALER_TESTING_cmd_deposit (
625 : "refresh-deposit-partial-age",
626 : "refresh-withdraw-coin-age-1",
627 : 0,
628 : cred.user42_payto,
629 : "{\"items\":[{\"name\":\"special ice cream\",\"value\":\"EUR:1\"}]}",
630 2 : GNUNET_TIME_UNIT_ZERO,
631 : "EUR:1",
632 : MHD_HTTP_OK),
633 : /**
634 : * Melt the rest of the coin's value
635 : * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */
636 2 : TALER_TESTING_cmd_melt_double (
637 : "refresh-melt-age-1",
638 : "refresh-withdraw-coin-age-1",
639 : MHD_HTTP_OK,
640 : NULL),
641 : /**
642 : * Complete (successful) melt operation, and
643 : * withdraw the coins
644 : */
645 2 : TALER_TESTING_cmd_melt_reveal (
646 : "refresh-reveal-age-1",
647 : "refresh-melt-age-1",
648 : MHD_HTTP_OK),
649 : /**
650 : * Do it again to check idempotency
651 : */
652 2 : TALER_TESTING_cmd_melt_reveal (
653 : "refresh-reveal-age-1-idempotency",
654 : "refresh-melt-age-1",
655 : MHD_HTTP_OK),
656 : /**
657 : * Try to spend a refreshed EUR:1 coin
658 : */
659 2 : TALER_TESTING_cmd_deposit (
660 : "refresh-deposit-refreshed-age-1a",
661 : "refresh-reveal-age-1-idempotency",
662 : 0,
663 : cred.user42_payto,
664 : "{\"items\":[{\"name\":\"garlic ice cream\",\"value\":3}]}",
665 2 : GNUNET_TIME_UNIT_ZERO,
666 : "EUR:1",
667 : MHD_HTTP_OK),
668 : /**
669 : * Try to spend a refreshed EUR:0.1 coin
670 : */
671 2 : TALER_TESTING_cmd_deposit (
672 : "refresh-deposit-refreshed-age-1b",
673 : "refresh-reveal-age-1",
674 : 3,
675 : cred.user43_payto,
676 : "{\"items\":[{\"name\":\"spicy ice cream\",\"value\":3}]}",
677 2 : GNUNET_TIME_UNIT_ZERO,
678 : "EUR:0.1",
679 : MHD_HTTP_OK),
680 : /* Test running a failing melt operation (same operation
681 : * again must fail) */
682 2 : TALER_TESTING_cmd_melt (
683 : "refresh-melt-failing-age",
684 : "refresh-withdraw-coin-age-1",
685 : MHD_HTTP_CONFLICT,
686 : NULL),
687 : /* Test running a failing melt operation (on a coin that
688 : was itself revealed and subsequently deposited) */
689 2 : TALER_TESTING_cmd_melt (
690 : "refresh-melt-failing-age-2",
691 : "refresh-reveal-age-1",
692 : MHD_HTTP_CONFLICT,
693 : NULL),
694 2 : TALER_TESTING_cmd_end ()
695 : };
696 :
697 : /**
698 : * This block exercises the aggretation logic by making two payments
699 : * to the same merchant.
700 : */
701 : struct TALER_TESTING_Command aggregation[] = {
702 2 : CMD_TRANSFER_TO_EXCHANGE ("create-reserve-aggtest",
703 : "EUR:5.01"),
704 : /* "consume" reserve creation transfer. */
705 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
706 : "check-create-reserve-aggtest",
707 : "EUR:5.01",
708 : cred.user42_payto,
709 : cred.exchange_payto,
710 : "create-reserve-aggtest"),
711 2 : CMD_EXEC_WIREWATCH ("wirewatch-aggtest"),
712 2 : TALER_TESTING_cmd_withdraw_amount (
713 : "withdraw-coin-aggtest",
714 : "create-reserve-aggtest",
715 : "EUR:5",
716 : 0, /* age restriction off */
717 : MHD_HTTP_OK),
718 2 : TALER_TESTING_cmd_deposit (
719 : "deposit-aggtest-1",
720 : "withdraw-coin-aggtest",
721 : 0,
722 : cred.user43_payto,
723 : "{\"items\":[{\"name\":\"cinamon ice cream\",\"value\":1}]}",
724 2 : GNUNET_TIME_UNIT_ZERO,
725 : "EUR:2",
726 : MHD_HTTP_OK),
727 2 : TALER_TESTING_cmd_deposit_with_ref (
728 : "deposit-aggtest-2",
729 : "withdraw-coin-aggtest",
730 : 0,
731 : cred.user43_payto,
732 : "{\"items\":[{\"name\":\"foo bar\",\"value\":1}]}",
733 2 : GNUNET_TIME_UNIT_ZERO,
734 : "EUR:2",
735 : MHD_HTTP_OK,
736 : "deposit-aggtest-1"),
737 2 : CMD_EXEC_AGGREGATOR ("aggregation-aggtest"),
738 2 : TALER_TESTING_cmd_check_bank_transfer (
739 : "check-bank-transfer-aggtest",
740 2 : cred.exchange_url,
741 : "EUR:3.97",
742 : cred.exchange_payto,
743 : cred.user43_payto),
744 2 : TALER_TESTING_cmd_check_bank_empty ("check-bank-empty-aggtest"),
745 2 : TALER_TESTING_cmd_end ()
746 : };
747 :
748 : struct TALER_TESTING_Command refund[] = {
749 : /**
750 : * Fill reserve with EUR:5.01, as withdraw fee is 1 ct per
751 : * config.
752 : */
753 2 : CMD_TRANSFER_TO_EXCHANGE (
754 : "create-reserve-r1",
755 : "EUR:5.01"),
756 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
757 : "check-create-reserve-r1",
758 : "EUR:5.01",
759 : cred.user42_payto,
760 : cred.exchange_payto,
761 : "create-reserve-r1"),
762 : /**
763 : * Run wire-watch to trigger the reserve creation.
764 : */
765 2 : CMD_EXEC_WIREWATCH ("wirewatch-3"),
766 : /* Withdraw a 5 EUR coin, at fee of 1 ct */
767 2 : TALER_TESTING_cmd_withdraw_amount (
768 : "withdraw-coin-r1",
769 : "create-reserve-r1",
770 : "EUR:5",
771 : 0, /* age restriction off */
772 : MHD_HTTP_OK),
773 : /**
774 : * Spend 5 EUR of the 5 EUR coin (in full) (merchant would
775 : * receive EUR:4.99 due to 1 ct deposit fee)
776 : */
777 2 : TALER_TESTING_cmd_deposit (
778 : "deposit-refund-1",
779 : "withdraw-coin-r1",
780 : 0,
781 : cred.user42_payto,
782 : "{\"items\":[{\"name\":\"blue ice cream\",\"value\":\"EUR:5\"}]}",
783 : GNUNET_TIME_UNIT_MINUTES,
784 : "EUR:5",
785 : MHD_HTTP_OK),
786 : /**
787 : * Run transfers. Should do nothing as refund deadline blocks it
788 : */
789 2 : CMD_EXEC_AGGREGATOR ("run-aggregator-refund"),
790 : /* Check that aggregator didn't do anything, as expected.
791 : * Note, this operation takes two commands: one to "flush"
792 : * the preliminary transfer (used to withdraw) from the
793 : * fakebank and the second to actually check there are not
794 : * other transfers around. */
795 2 : TALER_TESTING_cmd_check_bank_empty ("check_bank_transfer-pre-refund"),
796 2 : TALER_TESTING_cmd_refund_with_id (
797 : "refund-ok",
798 : MHD_HTTP_OK,
799 : "EUR:3",
800 : "deposit-refund-1",
801 : 3),
802 2 : TALER_TESTING_cmd_refund_with_id (
803 : "refund-ok-double",
804 : MHD_HTTP_OK,
805 : "EUR:3",
806 : "deposit-refund-1",
807 : 3),
808 : /* Previous /refund(s) had id == 0. */
809 2 : TALER_TESTING_cmd_refund_with_id (
810 : "refund-conflicting",
811 : MHD_HTTP_CONFLICT,
812 : "EUR:5",
813 : "deposit-refund-1",
814 : 1),
815 2 : TALER_TESTING_cmd_deposit (
816 : "deposit-refund-insufficient-refund",
817 : "withdraw-coin-r1",
818 : 0,
819 : cred.user42_payto,
820 : "{\"items\":[{\"name\":\"fruit ice cream\",\"value\":\"EUR:4\"}]}",
821 : GNUNET_TIME_UNIT_MINUTES,
822 : "EUR:4",
823 : MHD_HTTP_CONFLICT),
824 2 : TALER_TESTING_cmd_refund_with_id (
825 : "refund-ok-increase",
826 : MHD_HTTP_OK,
827 : "EUR:2",
828 : "deposit-refund-1",
829 : 2),
830 : /**
831 : * Spend 4.99 EUR of the refunded 4.99 EUR coin (1ct gone
832 : * due to refund) (merchant would receive EUR:4.98 due to
833 : * 1 ct deposit fee) */
834 2 : TALER_TESTING_cmd_deposit (
835 : "deposit-refund-2",
836 : "withdraw-coin-r1",
837 : 0,
838 : cred.user42_payto,
839 : "{\"items\":[{\"name\":\"more ice cream\",\"value\":\"EUR:5\"}]}",
840 2 : GNUNET_TIME_UNIT_ZERO,
841 : "EUR:4.99",
842 : MHD_HTTP_OK),
843 : /**
844 : * Run transfers. This will do the transfer as refund deadline
845 : * was 0
846 : */
847 2 : CMD_EXEC_AGGREGATOR ("run-aggregator-3"),
848 : /**
849 : * Check that deposit did run.
850 : */
851 2 : TALER_TESTING_cmd_check_bank_transfer (
852 : "check_bank_transfer-pre-refund",
853 2 : cred.exchange_url,
854 : "EUR:4.97",
855 : cred.exchange_payto,
856 : cred.user42_payto),
857 : /**
858 : * Run failing refund, as past deadline & aggregation.
859 : */
860 2 : TALER_TESTING_cmd_refund (
861 : "refund-fail",
862 : MHD_HTTP_GONE,
863 : "EUR:4.99",
864 : "deposit-refund-2"),
865 2 : TALER_TESTING_cmd_check_bank_empty ("check-empty-after-refund"),
866 : /**
867 : * Test refunded coins are never executed, even past
868 : * refund deadline
869 : */
870 2 : CMD_TRANSFER_TO_EXCHANGE (
871 : "create-reserve-rb",
872 : "EUR:5.01"),
873 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
874 : "check-create-reserve-rb",
875 : "EUR:5.01",
876 : cred.user42_payto,
877 : cred.exchange_payto,
878 : "create-reserve-rb"),
879 2 : CMD_EXEC_WIREWATCH ("wirewatch-rb"),
880 2 : TALER_TESTING_cmd_withdraw_amount (
881 : "withdraw-coin-rb",
882 : "create-reserve-rb",
883 : "EUR:5",
884 : 0, /* age restriction off */
885 : MHD_HTTP_OK),
886 2 : TALER_TESTING_cmd_deposit (
887 : "deposit-refund-1b",
888 : "withdraw-coin-rb",
889 : 0,
890 : cred.user42_payto,
891 : "{\"items\":[{\"name\":\"purple ice cream\",\"value\":\"EUR:5\"}]}",
892 2 : GNUNET_TIME_UNIT_ZERO,
893 : "EUR:5",
894 : MHD_HTTP_OK),
895 : /**
896 : * Trigger refund (before aggregator had a chance to execute
897 : * deposit, even though refund deadline was zero).
898 : */
899 2 : TALER_TESTING_cmd_refund (
900 : "refund-ok-fast",
901 : MHD_HTTP_OK,
902 : "EUR:5",
903 : "deposit-refund-1b"),
904 : /**
905 : * Run transfers. This will do the transfer as refund deadline
906 : * was 0, except of course because the refund succeeded, the
907 : * transfer should no longer be done.
908 : */
909 2 : CMD_EXEC_AGGREGATOR ("run-aggregator-3b"),
910 : /* check that aggregator didn't do anything, as expected */
911 2 : TALER_TESTING_cmd_check_bank_empty ("check-refund-fast-not-run"),
912 2 : TALER_TESTING_cmd_end ()
913 : };
914 :
915 : #if FIXME_9828
916 : struct TALER_TESTING_Command recoup[] = {
917 : /**
918 : * Fill reserve with EUR:5.01, as withdraw fee is 1 ct per
919 : * config.
920 : */
921 : CMD_TRANSFER_TO_EXCHANGE (
922 : "recoup-create-reserve-1",
923 : "EUR:15.02"),
924 : TALER_TESTING_cmd_check_bank_admin_transfer (
925 : "recoup-create-reserve-1-check",
926 : "EUR:15.02",
927 : cred.user42_payto,
928 : cred.exchange_payto,
929 : "recoup-create-reserve-1"),
930 : /**
931 : * Run wire-watch to trigger the reserve creation.
932 : */
933 : CMD_EXEC_WIREWATCH ("wirewatch-4"),
934 : /* Withdraw a 5 EUR coin, at fee of 1 ct */
935 : TALER_TESTING_cmd_withdraw_amount (
936 : "recoup-withdraw-coin-1",
937 : "recoup-create-reserve-1",
938 : "EUR:5",
939 : 0, /* age restriction off */
940 : MHD_HTTP_OK),
941 : /* Withdraw a 10 EUR coin, at fee of 1 ct */
942 : TALER_TESTING_cmd_withdraw_amount (
943 : "recoup-withdraw-coin-1b",
944 : "recoup-create-reserve-1",
945 : "EUR:10",
946 : 0, /* age restriction off */
947 : MHD_HTTP_OK),
948 : /* melt 10 EUR coin to get 5 EUR refreshed coin */
949 : TALER_TESTING_cmd_melt (
950 : "recoup-melt-coin-1b",
951 : "recoup-withdraw-coin-1b",
952 : MHD_HTTP_OK,
953 : "EUR:5",
954 : NULL),
955 : TALER_TESTING_cmd_melt_reveal (
956 : "recoup-reveal-coin-1b",
957 : "recoup-melt-coin-1b",
958 : MHD_HTTP_OK),
959 : /* Revoke both 5 EUR coins */
960 : TALER_TESTING_cmd_revoke (
961 : "revoke-0-EUR:5",
962 : MHD_HTTP_OK,
963 : "recoup-withdraw-coin-1",
964 : config_file),
965 : /* Recoup coin to reserve */
966 : TALER_TESTING_cmd_recoup (
967 : "recoup-1",
968 : MHD_HTTP_OK,
969 : "recoup-withdraw-coin-1",
970 : "EUR:5"),
971 : /* Check the money is back with the reserve */
972 : TALER_TESTING_cmd_status (
973 : "recoup-reserve-status-1",
974 : "recoup-create-reserve-1",
975 : "EUR:5.0",
976 : MHD_HTTP_OK),
977 : /* Recoup-refresh coin to 10 EUR coin */
978 : TALER_TESTING_cmd_recoup_refresh (
979 : "recoup-1b",
980 : MHD_HTTP_OK,
981 : "recoup-reveal-coin-1b",
982 : "recoup-melt-coin-1b",
983 : "EUR:5"),
984 : /* melt 10 EUR coin *again* to get 1 EUR refreshed coin */
985 : TALER_TESTING_cmd_melt (
986 : "recoup-remelt-coin-1a",
987 : "recoup-withdraw-coin-1b",
988 : MHD_HTTP_OK,
989 : "EUR:1",
990 : NULL),
991 : TALER_TESTING_cmd_melt_reveal (
992 : "recoup-reveal-coin-1a",
993 : "recoup-remelt-coin-1a",
994 : MHD_HTTP_OK),
995 : /* Try melting for more than the residual value to provoke an error */
996 : TALER_TESTING_cmd_melt (
997 : "recoup-remelt-coin-1b",
998 : "recoup-withdraw-coin-1b",
999 : MHD_HTTP_OK,
1000 : "EUR:1",
1001 : NULL),
1002 : TALER_TESTING_cmd_melt (
1003 : "recoup-remelt-coin-1c",
1004 : "recoup-withdraw-coin-1b",
1005 : MHD_HTTP_OK,
1006 : "EUR:1",
1007 : NULL),
1008 : TALER_TESTING_cmd_melt (
1009 : "recoup-remelt-coin-1d",
1010 : "recoup-withdraw-coin-1b",
1011 : MHD_HTTP_OK,
1012 : "EUR:1",
1013 : NULL),
1014 : TALER_TESTING_cmd_melt (
1015 : "recoup-remelt-coin-1e",
1016 : "recoup-withdraw-coin-1b",
1017 : MHD_HTTP_OK,
1018 : "EUR:1",
1019 : NULL),
1020 : TALER_TESTING_cmd_melt (
1021 : "recoup-remelt-coin-1f",
1022 : "recoup-withdraw-coin-1b",
1023 : MHD_HTTP_OK,
1024 : "EUR:1",
1025 : NULL),
1026 : TALER_TESTING_cmd_melt (
1027 : "recoup-remelt-coin-1g",
1028 : "recoup-withdraw-coin-1b",
1029 : MHD_HTTP_OK,
1030 : "EUR:1",
1031 : NULL),
1032 : TALER_TESTING_cmd_melt (
1033 : "recoup-remelt-coin-1h",
1034 : "recoup-withdraw-coin-1b",
1035 : MHD_HTTP_OK,
1036 : "EUR:1",
1037 : NULL),
1038 : TALER_TESTING_cmd_melt (
1039 : "recoup-remelt-coin-1i",
1040 : "recoup-withdraw-coin-1b",
1041 : MHD_HTTP_OK,
1042 : "EUR:1",
1043 : NULL),
1044 : TALER_TESTING_cmd_melt (
1045 : "recoup-remelt-coin-1b-failing",
1046 : "recoup-withdraw-coin-1b",
1047 : MHD_HTTP_CONFLICT,
1048 : "EUR:1",
1049 : NULL),
1050 : /* Re-withdraw from this reserve */
1051 : TALER_TESTING_cmd_withdraw_amount (
1052 : "recoup-withdraw-coin-2",
1053 : "recoup-create-reserve-1",
1054 : "EUR:1",
1055 : 0, /* age restriction off */
1056 : MHD_HTTP_OK),
1057 : /**
1058 : * This withdrawal will test the logic to create a "recoup"
1059 : * element to insert into the reserve's history.
1060 : */
1061 : TALER_TESTING_cmd_withdraw_amount (
1062 : "recoup-withdraw-coin-2-over",
1063 : "recoup-create-reserve-1",
1064 : "EUR:10",
1065 : 0, /* age restriction off */
1066 : MHD_HTTP_CONFLICT),
1067 : TALER_TESTING_cmd_status (
1068 : "recoup-reserve-status-2",
1069 : "recoup-create-reserve-1",
1070 : "EUR:3.99",
1071 : MHD_HTTP_OK),
1072 : /* These commands should close the reserve because
1073 : * the aggregator is given a config file that overrides
1074 : * the reserve expiration time (making it now-ish) */
1075 : CMD_TRANSFER_TO_EXCHANGE ("short-lived-reserve",
1076 : "EUR:5.01"),
1077 : TALER_TESTING_cmd_check_bank_admin_transfer (
1078 : "check-short-lived-reserve",
1079 : "EUR:5.01",
1080 : cred.user42_payto,
1081 : cred.exchange_payto,
1082 : "short-lived-reserve"),
1083 : TALER_TESTING_cmd_exec_wirewatch2 (
1084 : "short-lived-aggregation",
1085 : config_file_expire_reserve_now,
1086 : "exchange-account-2"),
1087 : TALER_TESTING_cmd_exec_closer (
1088 : "close-reserves",
1089 : config_file_expire_reserve_now,
1090 : "EUR:5",
1091 : "EUR:0.01",
1092 : "short-lived-reserve"),
1093 : TALER_TESTING_cmd_exec_transfer (
1094 : "close-reserves-transfer",
1095 : config_file_expire_reserve_now),
1096 :
1097 : TALER_TESTING_cmd_status (
1098 : "short-lived-status",
1099 : "short-lived-reserve",
1100 : "EUR:0",
1101 : MHD_HTTP_OK),
1102 : TALER_TESTING_cmd_withdraw_amount (
1103 : "expired-withdraw",
1104 : "short-lived-reserve",
1105 : "EUR:1",
1106 : 0, /* age restriction off */
1107 : MHD_HTTP_CONFLICT),
1108 : TALER_TESTING_cmd_check_bank_transfer (
1109 : "check_bank_short-lived_reimburse",
1110 : cred.exchange_url,
1111 : "EUR:5",
1112 : cred.exchange_payto,
1113 : cred.user42_payto),
1114 : /* Fill reserve with EUR:2.02, as withdraw fee is 1 ct per
1115 : * config, then withdraw two coin, partially spend one, and
1116 : * then have the rest paid back. Check deposit of other coin
1117 : * fails. Do not use EUR:5 here as the EUR:5 coin was
1118 : * revoked and we did not bother to create a new one... */
1119 : CMD_TRANSFER_TO_EXCHANGE ("recoup-create-reserve-2",
1120 : "EUR:2.02"),
1121 : TALER_TESTING_cmd_check_bank_admin_transfer (
1122 : "ck-recoup-create-reserve-2",
1123 : "EUR:2.02",
1124 : cred.user42_payto,
1125 : cred.exchange_payto,
1126 : "recoup-create-reserve-2"),
1127 : /* Make previous command effective. */
1128 : CMD_EXEC_WIREWATCH ("wirewatch-5"),
1129 : /* Withdraw a 1 EUR coin, at fee of 1 ct */
1130 : TALER_TESTING_cmd_withdraw_amount (
1131 : "recoup-withdraw-coin-2a",
1132 : "recoup-create-reserve-2",
1133 : "EUR:1",
1134 : 0, /* age restriction off */
1135 : MHD_HTTP_OK),
1136 : /* Withdraw a 1 EUR coin, at fee of 1 ct */
1137 : TALER_TESTING_cmd_withdraw_amount (
1138 : "recoup-withdraw-coin-2b",
1139 : "recoup-create-reserve-2",
1140 : "EUR:1",
1141 : 0, /* age restriction off */
1142 : MHD_HTTP_OK),
1143 : TALER_TESTING_cmd_deposit (
1144 : "recoup-deposit-partial",
1145 : "recoup-withdraw-coin-2a",
1146 : 0,
1147 : cred.user42_payto,
1148 : "{\"items\":[{\"name\":\"more ice cream\",\"value\":1}]}",
1149 : GNUNET_TIME_UNIT_ZERO,
1150 : "EUR:0.5",
1151 : MHD_HTTP_OK),
1152 : TALER_TESTING_cmd_revoke (
1153 : "revoke-1-EUR:1",
1154 : MHD_HTTP_OK,
1155 : "recoup-withdraw-coin-2a",
1156 : config_file),
1157 : /* Check recoup is failing for the coin with the reused coin key
1158 : (fails either because of denomination conflict (RSA) or
1159 : double-spending (CS))*/
1160 : TALER_TESTING_cmd_recoup (
1161 : "recoup-2x",
1162 : MHD_HTTP_CONFLICT,
1163 : "withdraw-coin-1x",
1164 : "EUR:1"),
1165 : TALER_TESTING_cmd_recoup (
1166 : "recoup-2",
1167 : MHD_HTTP_OK,
1168 : "recoup-withdraw-coin-2a",
1169 : "EUR:0.5"),
1170 : /* Idempotency of recoup (withdrawal variant) */
1171 : TALER_TESTING_cmd_recoup (
1172 : "recoup-2b",
1173 : MHD_HTTP_OK,
1174 : "recoup-withdraw-coin-2a",
1175 : "EUR:0.5"),
1176 : TALER_TESTING_cmd_deposit (
1177 : "recoup-deposit-revoked",
1178 : "recoup-withdraw-coin-2b",
1179 : 0,
1180 : cred.user42_payto,
1181 : "{\"items\":[{\"name\":\"gnu ice cream\",\"value\":1}]}",
1182 : GNUNET_TIME_UNIT_ZERO,
1183 : "EUR:1",
1184 : MHD_HTTP_GONE),
1185 : /* Test deposit fails after recoup, with proof in recoup */
1186 :
1187 : /* Note that, the exchange will never return the coin's transaction
1188 : * history with recoup data, as we get a 410 on the DK! */
1189 : TALER_TESTING_cmd_deposit (
1190 : "recoup-deposit-partial-after-recoup",
1191 : "recoup-withdraw-coin-2a",
1192 : 0,
1193 : cred.user42_payto,
1194 : "{\"items\":[{\"name\":\"extra ice cream\",\"value\":1}]}",
1195 : GNUNET_TIME_UNIT_ZERO,
1196 : "EUR:0.5",
1197 : MHD_HTTP_GONE),
1198 : /* Test that revoked coins cannot be withdrawn */
1199 : CMD_TRANSFER_TO_EXCHANGE (
1200 : "recoup-create-reserve-3",
1201 : "EUR:1.01"),
1202 : TALER_TESTING_cmd_check_bank_admin_transfer (
1203 : "check-recoup-create-reserve-3",
1204 : "EUR:1.01",
1205 : cred.user42_payto,
1206 : cred.exchange_payto,
1207 : "recoup-create-reserve-3"),
1208 : CMD_EXEC_WIREWATCH ("wirewatch-6"),
1209 : TALER_TESTING_cmd_withdraw_amount (
1210 : "recoup-withdraw-coin-3-revoked",
1211 : "recoup-create-reserve-3",
1212 : "EUR:1",
1213 : 0, /* age restriction off */
1214 : MHD_HTTP_GONE),
1215 : /* check that we are empty before the rejection test */
1216 : TALER_TESTING_cmd_check_bank_empty ("check-empty-again"),
1217 :
1218 : TALER_TESTING_cmd_end ()
1219 : };
1220 : #endif
1221 :
1222 : /**
1223 : * Test batch withdrawal plus spending.
1224 : */
1225 : struct TALER_TESTING_Command batch_withdraw[] = {
1226 : /**
1227 : * Move money to the exchange's bank account.
1228 : */
1229 2 : CMD_TRANSFER_TO_EXCHANGE (
1230 : "create-batch-reserve-1",
1231 : "EUR:6.03"),
1232 2 : TALER_TESTING_cmd_reserve_poll (
1233 : "poll-batch-reserve-1",
1234 : "create-batch-reserve-1",
1235 : "EUR:6.03",
1236 : GNUNET_TIME_UNIT_MINUTES,
1237 : MHD_HTTP_OK),
1238 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
1239 : "check-create-batch-reserve-1",
1240 : "EUR:6.03",
1241 : cred.user42_payto,
1242 : cred.exchange_payto,
1243 : "create-batch-reserve-1"),
1244 : /*
1245 : * Make a reserve exist, according to the previous
1246 : * transfer.
1247 : */
1248 2 : CMD_EXEC_WIREWATCH ("wirewatch-batch-1"),
1249 2 : TALER_TESTING_cmd_reserve_poll_finish (
1250 : "finish-poll-batch-reserve-1",
1251 : GNUNET_TIME_UNIT_SECONDS,
1252 : "poll-batch-reserve-1"),
1253 : /**
1254 : * Withdraw EUR:5 AND EUR:1.
1255 : */
1256 2 : TALER_TESTING_cmd_batch_withdraw (
1257 : "batch-withdraw-coin-1",
1258 : "create-batch-reserve-1",
1259 : MHD_HTTP_OK,
1260 : "EUR:5",
1261 : "EUR:1",
1262 : NULL),
1263 : /**
1264 : * Check the reserve is (almost) depleted.
1265 : */
1266 2 : TALER_TESTING_cmd_status (
1267 : "status-batch-1",
1268 : "create-batch-reserve-1",
1269 : "EUR:0.01",
1270 : MHD_HTTP_OK),
1271 2 : TALER_TESTING_cmd_reserve_history (
1272 : "history-batch-1",
1273 : "create-batch-reserve-1",
1274 : "EUR:0.01",
1275 : MHD_HTTP_OK),
1276 : /**
1277 : * Spend the coins.
1278 : */
1279 2 : TALER_TESTING_cmd_batch_deposit (
1280 : "batch-deposit-1",
1281 : cred.user42_payto,
1282 : "{\"items\":[{\"name\":\"final ice cream\",\"value\":5}]}",
1283 2 : GNUNET_TIME_UNIT_ZERO,
1284 : MHD_HTTP_OK,
1285 : "batch-withdraw-coin-1#0",
1286 : "EUR:5",
1287 : "batch-withdraw-coin-1#1",
1288 : "EUR:1",
1289 : NULL),
1290 2 : TALER_TESTING_cmd_coin_history (
1291 : "coin-history-batch-1",
1292 : "batch-withdraw-coin-1#0",
1293 : "EUR:0.0",
1294 : MHD_HTTP_OK),
1295 2 : TALER_TESTING_cmd_end ()
1296 : };
1297 :
1298 :
1299 : #define RESERVE_OPEN_CLOSE_CHUNK 4
1300 : #define RESERVE_OPEN_CLOSE_ITERATIONS 3
1301 :
1302 : struct TALER_TESTING_Command reserve_open_close[(RESERVE_OPEN_CLOSE_ITERATIONS
1303 : * RESERVE_OPEN_CLOSE_CHUNK)
1304 : + 1];
1305 :
1306 : (void) cls;
1307 2 : for (unsigned int i = 0;
1308 8 : i < RESERVE_OPEN_CLOSE_ITERATIONS;
1309 6 : i++)
1310 : {
1311 6 : reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 0]
1312 6 : = CMD_TRANSFER_TO_EXCHANGE ("reserve-open-close-key",
1313 : "EUR:20");
1314 6 : reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 1]
1315 6 : = TALER_TESTING_cmd_exec_wirewatch2 ("reserve-open-close-wirewatch",
1316 : config_file_expire_reserve_now,
1317 : "exchange-account-2");
1318 6 : reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 2]
1319 6 : = TALER_TESTING_cmd_exec_closer ("reserve-open-close-aggregation",
1320 : config_file_expire_reserve_now,
1321 : "EUR:19.99",
1322 : "EUR:0.01",
1323 : "reserve-open-close-key");
1324 6 : reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 3]
1325 6 : = TALER_TESTING_cmd_status ("reserve-open-close-status",
1326 : "reserve-open-close-key",
1327 : "EUR:0",
1328 : MHD_HTTP_OK);
1329 : }
1330 : reserve_open_close[RESERVE_OPEN_CLOSE_ITERATIONS * RESERVE_OPEN_CLOSE_CHUNK]
1331 2 : = TALER_TESTING_cmd_end ();
1332 :
1333 : {
1334 : struct TALER_TESTING_Command commands[] = {
1335 2 : TALER_TESTING_cmd_run_fakebank ("run-fakebank",
1336 2 : cred.cfg,
1337 : "exchange-account-2"),
1338 2 : TALER_TESTING_cmd_system_start ("start-taler",
1339 : config_file,
1340 : "-e",
1341 : NULL),
1342 2 : TALER_TESTING_cmd_get_exchange ("get-exchange",
1343 2 : cred.cfg,
1344 : NULL,
1345 : true,
1346 : true),
1347 2 : TALER_TESTING_cmd_batch ("withdraw",
1348 : withdraw),
1349 2 : TALER_TESTING_cmd_batch ("spend",
1350 : spend),
1351 2 : TALER_TESTING_cmd_batch ("refresh",
1352 : refresh),
1353 2 : TALER_TESTING_cmd_batch ("withdraw-age",
1354 : withdraw_age),
1355 2 : TALER_TESTING_cmd_batch ("spend-age",
1356 : spend_age),
1357 2 : TALER_TESTING_cmd_batch ("refresh-age",
1358 : refresh_age),
1359 2 : TALER_TESTING_cmd_batch ("track",
1360 : track),
1361 2 : TALER_TESTING_cmd_batch ("unaggregation",
1362 : unaggregation),
1363 2 : TALER_TESTING_cmd_batch ("aggregation",
1364 : aggregation),
1365 2 : TALER_TESTING_cmd_batch ("refund",
1366 : refund),
1367 2 : TALER_TESTING_cmd_batch ("batch-withdraw",
1368 : batch_withdraw),
1369 : #if FIXME_9828
1370 : TALER_TESTING_cmd_batch ("recoup",
1371 : recoup),
1372 : #endif
1373 2 : TALER_TESTING_cmd_batch ("reserve-open-close",
1374 : reserve_open_close),
1375 : /* End the suite. */
1376 2 : TALER_TESTING_cmd_end ()
1377 : };
1378 :
1379 2 : TALER_TESTING_run (is,
1380 : commands);
1381 : }
1382 2 : }
1383 :
1384 :
1385 : int
1386 2 : main (int argc,
1387 : char *const *argv)
1388 : {
1389 : (void) argc;
1390 : {
1391 : char *cipher;
1392 :
1393 2 : cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]);
1394 2 : GNUNET_assert (NULL != cipher);
1395 2 : uses_cs = (0 == strcmp (cipher,
1396 : "cs"));
1397 2 : GNUNET_asprintf (&config_file,
1398 : "test_exchange_api-%s.conf",
1399 : cipher);
1400 2 : GNUNET_asprintf (&config_file_expire_reserve_now,
1401 : "test_exchange_api_expire_reserve_now-%s.conf",
1402 : cipher);
1403 2 : GNUNET_free (cipher);
1404 : }
1405 2 : return TALER_TESTING_main (argv,
1406 : "INFO",
1407 : config_file,
1408 : "exchange-account-2",
1409 : TALER_TESTING_BS_FAKEBANK,
1410 : &cred,
1411 : &run,
1412 : NULL);
1413 : }
1414 :
1415 :
1416 : /* end of test_exchange_api.c */
|